UNPKG

svelte-ux

Version:

- Increment version in `package.json` and commit as `Version bump to x.y.z` - `npm run publish`

150 lines (149 loc) 5.24 kB
import { derived } from 'svelte/store'; import { isEqual } from 'lodash-es'; import * as Serialize from '../utils/serialize'; import rollup from '../utils/rollup'; /** * Set a single querystring param * @param name * @param defaultValue * @returns */ export function queryParamStore(name, page, defaultValue, paramType) { const store = derived(page, ($page) => { var _a; const values = $page.url.searchParams.getAll(name); return (_a = decodeParam(values, paramType)) !== null && _a !== void 0 ? _a : defaultValue; }); /** * Apply new value to existing `URLSearchParams` */ function apply(params, newValue) { // Do not update querystring with initialValue.. if (typeof window !== 'undefined') { applyParam(params, name, newValue, defaultValue, paramType); } } return { subscribe: store.subscribe, apply, }; } /** * Set all query string params based on object. Each object property represents a single query param * @param defaultValues * @returns */ export function queryParamsStore(page, defaultValues, paramTypes) { const store = derived(page, ($page) => { const state = { ...defaultValues }; // Group by key const groupedParams = rollup([...$page.url.searchParams], (items) => items.map((x) => x[1]), [([key, value]) => key]); for (const [key, values] of groupedParams) { const paramType = typeof paramTypes === 'function' ? paramTypes(key) : paramTypes === null || paramTypes === void 0 ? void 0 : paramTypes[key]; state[key] = decodeParam(values, paramType); } return state; }); /** * Create new `URLSearchParams` from values and paramTypes mapping */ function create(newValues) { // Do not update querystring with initialValue.. if (typeof window !== 'undefined') { const params = new URLSearchParams(); // queryParamsStore controls full params so start fresh if (newValues != null) { Object.entries(newValues).forEach(([key, value]) => { const paramType = typeof paramTypes === 'function' ? paramTypes(key) : paramTypes === null || paramTypes === void 0 ? void 0 : paramTypes[key]; applyParam(params, key, value, defaultValues === null || defaultValues === void 0 ? void 0 : defaultValues[key], paramType); }); } return params; } } return { subscribe: store.subscribe, create, }; } function applyParam(params, key, value, defaultValue, paramType) { const config = getParamConfig(paramType); if (isEqual(defaultValue, value)) { // Skip - only update param if different from default } else if (value == null || (Array.isArray(value) && value.length === 0)) { params.delete(key); } else { params.set(key, config.encode(value)); } } function decodeParam(values, paramType) { const config = getParamConfig(paramType); return config.decode(values); } function getParamConfig(paramType) { switch (paramType) { case 'string': return { encode: Serialize.encodeString, decode: Serialize.decodeString, }; case 'string[]': return { encode: Serialize.encodeDelimitedArray, decode: Serialize.decodeDelimitedArray, }; case 'number': return { encode: Serialize.encodeNumber, decode: Serialize.decodeNumber, }; case 'number[]': return { encode: Serialize.encodeDelimitedNumericArray, decode: Serialize.decodeDelimitedNumericArray, }; case 'boolean': return { encode: Serialize.encodeBoolean, decode: Serialize.decodeBoolean, }; case 'date': return { encode: Serialize.encodeDate, decode: Serialize.decodeDate, }; case 'datetime': return { encode: Serialize.encodeDateTime, decode: Serialize.decodeDateTime, }; case 'json': return { encode: Serialize.encodeJson, decode: Serialize.decodeJson, }; case 'object': return { encode: Serialize.encodeObject, decode: Serialize.decodeObject, }; default: throw new Error('No param config found'); } } /** * * @param params * @returns */ function stringify(params) { // Use `encodeURIComponent` instead of `params.toString()` as is more lenient (doesn't encode `(` or `)` where are used ) // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent // https://stackoverflow.com/a/62969380/191902 return Object.entries(params) .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`) .join('&'); }