{"version":3,"file":"core.cjs","sources":["../../src/core.ts"],"sourcesContent":["import {useCallback, useMemo} from \"react\";\nimport {Store, useStore} from \"@tanstack/react-store\";\nimport {isEqual} from \"lodash-es\";\n\nimport {ParamStore} from \"./store\";\nimport {getValue, isClient, isParamsTransition, paramsTransitioning, useSmartValue} from \"./utils\";\nimport {decodeParam, encodeParam} from \"./encoding\";\n\nimport {API, OptionsWithDefault, Setter} from \"./types\";\nimport {useContextApi} from \"./use-api\";\nimport {BatchingApi, defaultApi, dummyApi, withBatch} from \"./api\";\n\nexport const create = () => {\n    let isInitialized = false;\n    let paramsStore: ParamStore = null!;\n    let api: BatchingApi = null!;\n\n    const getLatestParams = (api: API) => {\n        const params = new URLSearchParams(api.getSearch());\n        const paramsMap: Record<string, string> = {};\n        for (const [key, value] of params) {\n            paramsMap[key] = value;\n        }\n        return paramsMap;\n    }\n\n    const init = (contextApi: API, isClient: boolean) => {\n        if (isClient && isInitialized) {\n            return;\n        }\n        isInitialized = true;\n        api = withBatch(contextApi ?? (isClient ? defaultApi() : dummyApi));\n        if (isClient) {\n            api.registerListener((state: unknown) => {\n                if (isParamsTransition(state)) {\n                    return;\n                }\n                paramsStore.setState(() => getLatestParams(api))\n            });\n            paramsStore = new Store<Record<string, string>>(getLatestParams(api));\n        }\n    };\n\n    const decodeWithDefault = <T, >(value: string | undefined, defaultValue: T, {\n        decode,\n        onError,\n        validate\n    }: OptionsWithDefault<T>): T => {\n        if (value === undefined) {\n            return defaultValue\n        }\n        const internalOnError = (decoded?: T) => {\n            const onErrorValue = onError?.(value, decoded)\n            return onErrorValue ?? defaultValue\n        }\n        try {\n            const decoded = decodeParam(value, decode)\n            const isValid = validate ? validate(decoded) : true\n            if (isValid) {\n                return decoded\n            } else {\n                return internalOnError(decoded)\n            }\n        } catch {\n            return internalOnError()\n        }\n    }\n\n    const useDefaultValue = <T, >({defaultValue}: OptionsWithDefault<T>) => {\n        const internalDefaultValue = useMemo(() => {\n            return getValue(defaultValue);\n        }, [defaultValue])\n\n        return useSmartValue(internalDefaultValue) as T\n    }\n\n    const useParamGet = <T, >(\n        paramName: string,\n        options: OptionsWithDefault<T>,\n    ) => {\n        const contextApi = useContextApi();\n        init(contextApi, isClient);\n\n        const internalDefaultValue = useDefaultValue(options);\n\n        // eslint-disable-next-line react-hooks/rules-of-hooks\n        const value = isClient ? useStore(paramsStore, (s) => s[paramName]) : getLatestParams(api)[paramName];\n        const decodedValue = useMemo(() => decodeWithDefault(value, internalDefaultValue, options), [value, internalDefaultValue, options]);\n\n        return useSmartValue(decodedValue) as T\n    }\n\n    const useParamSet = <T, S extends object = object>(\n        paramName: string,\n        options: OptionsWithDefault<T>,\n    ) => {\n        const contextApi = useContextApi();\n        init(contextApi, isClient);\n\n        const internalDefaultValue = useDefaultValue(options);\n\n        return useCallback((value: Setter<T>, state?: S) => {\n            if (!isClient) {\n                throw new Error(\"Cannot use react params on the server\");\n            }\n\n            const {updateType = \"replaceIn\", encode} = options;\n            const currentValue = paramsStore.state[paramName];\n            const internalValue = typeof value === \"function\"\n                ? (value as (prev: T) => T)(decodeWithDefault(currentValue, internalDefaultValue, options))\n                : value;\n\n            const newValue = encodeParam(internalValue, encode);\n\n            if (currentValue === newValue || (currentValue === undefined && isEqual(internalDefaultValue, value))) {\n                return;\n            }\n\n            paramsStore.setState((s) => {\n                return ({...s, [paramName]: newValue});\n            });\n\n            const search = api.getSearch();\n            const clearAll = !updateType.endsWith(\"In\");\n            const isReplace = updateType.startsWith(\"replace\");\n            const searchParams = !clearAll ? new URLSearchParams(search) : new URLSearchParams();\n\n            if (!isEqual(internalDefaultValue, value)) {\n                searchParams.set(paramName, newValue);\n            } else {\n                searchParams.delete(paramName);\n            }\n\n            const newHref = `?${searchParams.toString()}`\n            const internalState = {[paramsTransitioning]: true, ...state};\n            if (isReplace) {\n                api.replaceState(newHref, internalState);\n            } else {\n                api.pushState(newHref, internalState);\n            }\n        }, [paramName, internalDefaultValue, options])\n    }\n\n    const useParam = <T, >(\n        paramName: string,\n        options: OptionsWithDefault<T>,\n    ) => {\n        const value = useParamGet<T>(paramName, options);\n        const setter = useParamSet<T>(paramName, options);\n        return [value, setter] as const;\n    }\n\n    return {\n        useParamGet,\n        useParamSet,\n        useParam,\n        paramsStore,\n        api,\n    }\n}\n\nexport type ParamsCore = ReturnType<typeof create>;"],"names":["api","isClient","withBatch","defaultApi","dummyApi","isParamsTransition","Store","decodeParam","useMemo","getValue","useSmartValue","useContextApi","useStore","useCallback","encodeParam","isEqual","paramsTransitioning"],"mappings":"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"}