zustand-querystring 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-OEB5LU3Z.mjs";
5
5
 
6
6
  // src/middleware.ts
7
- import { cloneDeep, isEqual, mergeWith } from "lodash-es";
7
+ import { isEqual, mergeWith } from "lodash-es";
8
8
  var compact = (newState, initialState) => {
9
9
  const output = {};
10
10
  Object.keys(newState).forEach((key) => {
@@ -43,13 +43,16 @@ var translateSelectionToState = (selection, state) => {
43
43
  var queryStringImpl = (fn, options) => (set, get, api) => {
44
44
  const defaultedOptions = {
45
45
  key: "state",
46
+ format: {
47
+ stringify,
48
+ parse
49
+ },
46
50
  ...options
47
51
  };
48
- const { url } = defaultedOptions;
49
- const getStateFromUrl = (url2) => {
50
- const match = url2.searchParams.get(defaultedOptions.key);
52
+ const getStateFromUrl = (url) => {
53
+ const match = url.searchParams.get(defaultedOptions.key);
51
54
  if (match) {
52
- return parse(match);
55
+ return defaultedOptions.format.parse(match);
53
56
  }
54
57
  return null;
55
58
  };
@@ -61,17 +64,17 @@ var queryStringImpl = (fn, options) => (set, get, api) => {
61
64
  }
62
65
  return state != null ? state : {};
63
66
  };
64
- const initialize = (url2, initialState) => {
67
+ const initialize = (url, initialState) => {
65
68
  try {
66
- const stateFromURl = getStateFromUrl(url2);
69
+ const stateFromURl = getStateFromUrl(url);
67
70
  if (!stateFromURl) {
68
71
  return initialState;
69
72
  }
70
73
  const merged = mergeWith(
71
- cloneDeep(initialState),
72
- getSelectedState(stateFromURl, url2.pathname)
74
+ {},
75
+ initialState,
76
+ getSelectedState(stateFromURl, url.pathname)
73
77
  );
74
- set(merged, true);
75
78
  return merged;
76
79
  } catch (error) {
77
80
  console.error(error);
@@ -79,28 +82,29 @@ var queryStringImpl = (fn, options) => (set, get, api) => {
79
82
  }
80
83
  };
81
84
  if (typeof window !== "undefined") {
82
- const initialState = cloneDeep(
83
- fn(
84
- (...args) => {
85
- set(...args);
86
- setQuery();
87
- },
88
- get,
89
- api
90
- )
85
+ const initialState = fn(
86
+ (...args) => {
87
+ set(...args);
88
+ setQuery();
89
+ },
90
+ get,
91
+ api
91
92
  );
92
93
  const setQuery = () => {
93
- const url2 = new URL(window.location.href);
94
- const selectedState = getSelectedState(get(), url2.pathname);
94
+ const url = new URL(window.location.href);
95
+ const selectedState = getSelectedState(get(), url.pathname);
95
96
  const newCompacted = compact(selectedState, initialState);
96
- const previous = url2.search;
97
+ const previous = url.search;
97
98
  if (Object.keys(newCompacted).length) {
98
- url2.searchParams.set(defaultedOptions.key, stringify(newCompacted));
99
+ url.searchParams.set(
100
+ defaultedOptions.key,
101
+ defaultedOptions.format.stringify(newCompacted)
102
+ );
99
103
  } else {
100
- url2.searchParams.delete(defaultedOptions.key);
104
+ url.searchParams.delete(defaultedOptions.key);
101
105
  }
102
- if (url2.search !== previous) {
103
- history.replaceState(history.state, "", url2);
106
+ if (url.search !== previous) {
107
+ history.replaceState(history.state, "", url);
104
108
  }
105
109
  };
106
110
  if (!api.__ZUSTAND_QUERYSTRING_INIT__) {
@@ -120,9 +124,16 @@ var queryStringImpl = (fn, options) => (set, get, api) => {
120
124
  originalSetState(...args);
121
125
  setQuery();
122
126
  };
123
- return initialize(new URL(window.location.href), initialState);
124
- } else if (url) {
125
- return initialize(new URL(url, "http://localhost"), fn(set, get, api));
127
+ const initialized = initialize(new URL(window.location.href), initialState);
128
+ api.getInitialState = () => initialized;
129
+ return initialized;
130
+ } else if (defaultedOptions.url) {
131
+ const initialized = initialize(
132
+ new URL(defaultedOptions.url, "http://localhost"),
133
+ fn(set, get, api)
134
+ );
135
+ api.getInitialState = () => initialized;
136
+ return initialized;
126
137
  }
127
138
  return fn(set, get, api);
128
139
  };
@@ -0,0 +1,4 @@
1
+ export { QueryStringOptions, querystring } from './middleware.mjs';
2
+ export { parse, stringify } from './parser.mjs';
3
+ export { createURL } from './utils.mjs';
4
+ import 'zustand/vanilla';
package/dist/index.js CHANGED
@@ -17,14 +17,14 @@ var __copyProps = (to, from, except, desc) => {
17
17
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
18
 
19
19
  // src/index.ts
20
- var src_exports = {};
21
- __export(src_exports, {
20
+ var index_exports = {};
21
+ __export(index_exports, {
22
22
  createURL: () => createURL,
23
23
  parse: () => parse,
24
24
  querystring: () => querystring,
25
25
  stringify: () => stringify
26
26
  });
27
- module.exports = __toCommonJS(src_exports);
27
+ module.exports = __toCommonJS(index_exports);
28
28
 
29
29
  // src/middleware.ts
30
30
  var import_lodash_es = require("lodash-es");
@@ -76,13 +76,16 @@ var translateSelectionToState = (selection, state) => {
76
76
  var queryStringImpl = (fn, options) => (set, get, api) => {
77
77
  const defaultedOptions = {
78
78
  key: "state",
79
+ format: {
80
+ stringify,
81
+ parse
82
+ },
79
83
  ...options
80
84
  };
81
- const { url } = defaultedOptions;
82
- const getStateFromUrl = (url2) => {
83
- const match = url2.searchParams.get(defaultedOptions.key);
85
+ const getStateFromUrl = (url) => {
86
+ const match = url.searchParams.get(defaultedOptions.key);
84
87
  if (match) {
85
- return parse(match);
88
+ return defaultedOptions.format.parse(match);
86
89
  }
87
90
  return null;
88
91
  };
@@ -94,17 +97,17 @@ var queryStringImpl = (fn, options) => (set, get, api) => {
94
97
  }
95
98
  return state != null ? state : {};
96
99
  };
97
- const initialize = (url2, initialState) => {
100
+ const initialize = (url, initialState) => {
98
101
  try {
99
- const stateFromURl = getStateFromUrl(url2);
102
+ const stateFromURl = getStateFromUrl(url);
100
103
  if (!stateFromURl) {
101
104
  return initialState;
102
105
  }
103
106
  const merged = (0, import_lodash_es.mergeWith)(
104
- (0, import_lodash_es.cloneDeep)(initialState),
105
- getSelectedState(stateFromURl, url2.pathname)
107
+ {},
108
+ initialState,
109
+ getSelectedState(stateFromURl, url.pathname)
106
110
  );
107
- set(merged, true);
108
111
  return merged;
109
112
  } catch (error) {
110
113
  console.error(error);
@@ -112,28 +115,29 @@ var queryStringImpl = (fn, options) => (set, get, api) => {
112
115
  }
113
116
  };
114
117
  if (typeof window !== "undefined") {
115
- const initialState = (0, import_lodash_es.cloneDeep)(
116
- fn(
117
- (...args) => {
118
- set(...args);
119
- setQuery();
120
- },
121
- get,
122
- api
123
- )
118
+ const initialState = fn(
119
+ (...args) => {
120
+ set(...args);
121
+ setQuery();
122
+ },
123
+ get,
124
+ api
124
125
  );
125
126
  const setQuery = () => {
126
- const url2 = new URL(window.location.href);
127
- const selectedState = getSelectedState(get(), url2.pathname);
127
+ const url = new URL(window.location.href);
128
+ const selectedState = getSelectedState(get(), url.pathname);
128
129
  const newCompacted = compact(selectedState, initialState);
129
- const previous = url2.search;
130
+ const previous = url.search;
130
131
  if (Object.keys(newCompacted).length) {
131
- url2.searchParams.set(defaultedOptions.key, stringify(newCompacted));
132
+ url.searchParams.set(
133
+ defaultedOptions.key,
134
+ defaultedOptions.format.stringify(newCompacted)
135
+ );
132
136
  } else {
133
- url2.searchParams.delete(defaultedOptions.key);
137
+ url.searchParams.delete(defaultedOptions.key);
134
138
  }
135
- if (url2.search !== previous) {
136
- history.replaceState(history.state, "", url2);
139
+ if (url.search !== previous) {
140
+ history.replaceState(history.state, "", url);
137
141
  }
138
142
  };
139
143
  if (!api.__ZUSTAND_QUERYSTRING_INIT__) {
@@ -153,9 +157,16 @@ var queryStringImpl = (fn, options) => (set, get, api) => {
153
157
  originalSetState(...args);
154
158
  setQuery();
155
159
  };
156
- return initialize(new URL(window.location.href), initialState);
157
- } else if (url) {
158
- return initialize(new URL(url, "http://localhost"), fn(set, get, api));
160
+ const initialized = initialize(new URL(window.location.href), initialState);
161
+ api.getInitialState = () => initialized;
162
+ return initialized;
163
+ } else if (defaultedOptions.url) {
164
+ const initialized = initialize(
165
+ new URL(defaultedOptions.url, "http://localhost"),
166
+ fn(set, get, api)
167
+ );
168
+ api.getInitialState = () => initialized;
169
+ return initialized;
159
170
  }
160
171
  return fn(set, get, api);
161
172
  };
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  querystring
3
- } from "./chunk-HU2467IM.mjs";
3
+ } from "./chunk-L542GMLN.mjs";
4
4
  import {
5
5
  createURL
6
6
  } from "./chunk-HC4H2XL3.mjs";
@@ -0,0 +1,21 @@
1
+ import { StoreMutatorIdentifier, StateCreator } from 'zustand/vanilla';
2
+
3
+ type DeepSelect<T> = T extends object ? {
4
+ [P in keyof T]?: DeepSelect<T[P]> | boolean;
5
+ } : boolean;
6
+ type DeepPartial<T> = T extends object ? {
7
+ [P in keyof T]?: DeepPartial<T[P]>;
8
+ } : T;
9
+ interface QueryStringOptions<T> {
10
+ url?: string;
11
+ select?: (pathname: string) => DeepSelect<T>;
12
+ key?: string;
13
+ format?: {
14
+ stringify: (value: DeepPartial<T>) => string;
15
+ parse: (value: string) => DeepPartial<T>;
16
+ };
17
+ }
18
+ type QueryString = <T, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, Mps, Mcs>, options?: QueryStringOptions<T>) => StateCreator<T, Mps, Mcs>;
19
+ declare const querystring: QueryString;
20
+
21
+ export { type QueryStringOptions, querystring };
@@ -3,12 +3,19 @@ import { StoreMutatorIdentifier, StateCreator } from 'zustand/vanilla';
3
3
  type DeepSelect<T> = T extends object ? {
4
4
  [P in keyof T]?: DeepSelect<T[P]> | boolean;
5
5
  } : boolean;
6
+ type DeepPartial<T> = T extends object ? {
7
+ [P in keyof T]?: DeepPartial<T[P]>;
8
+ } : T;
6
9
  interface QueryStringOptions<T> {
7
10
  url?: string;
8
11
  select?: (pathname: string) => DeepSelect<T>;
9
12
  key?: string;
13
+ format?: {
14
+ stringify: (value: DeepPartial<T>) => string;
15
+ parse: (value: string) => DeepPartial<T>;
16
+ };
10
17
  }
11
18
  type QueryString = <T, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, Mps, Mcs>, options?: QueryStringOptions<T>) => StateCreator<T, Mps, Mcs>;
12
19
  declare const querystring: QueryString;
13
20
 
14
- export { QueryStringOptions, querystring };
21
+ export { type QueryStringOptions, querystring };
@@ -71,13 +71,16 @@ var translateSelectionToState = (selection, state) => {
71
71
  var queryStringImpl = (fn, options) => (set, get, api) => {
72
72
  const defaultedOptions = {
73
73
  key: "state",
74
+ format: {
75
+ stringify,
76
+ parse
77
+ },
74
78
  ...options
75
79
  };
76
- const { url } = defaultedOptions;
77
- const getStateFromUrl = (url2) => {
78
- const match = url2.searchParams.get(defaultedOptions.key);
80
+ const getStateFromUrl = (url) => {
81
+ const match = url.searchParams.get(defaultedOptions.key);
79
82
  if (match) {
80
- return parse(match);
83
+ return defaultedOptions.format.parse(match);
81
84
  }
82
85
  return null;
83
86
  };
@@ -89,17 +92,17 @@ var queryStringImpl = (fn, options) => (set, get, api) => {
89
92
  }
90
93
  return state != null ? state : {};
91
94
  };
92
- const initialize = (url2, initialState) => {
95
+ const initialize = (url, initialState) => {
93
96
  try {
94
- const stateFromURl = getStateFromUrl(url2);
97
+ const stateFromURl = getStateFromUrl(url);
95
98
  if (!stateFromURl) {
96
99
  return initialState;
97
100
  }
98
101
  const merged = (0, import_lodash_es.mergeWith)(
99
- (0, import_lodash_es.cloneDeep)(initialState),
100
- getSelectedState(stateFromURl, url2.pathname)
102
+ {},
103
+ initialState,
104
+ getSelectedState(stateFromURl, url.pathname)
101
105
  );
102
- set(merged, true);
103
106
  return merged;
104
107
  } catch (error) {
105
108
  console.error(error);
@@ -107,28 +110,29 @@ var queryStringImpl = (fn, options) => (set, get, api) => {
107
110
  }
108
111
  };
109
112
  if (typeof window !== "undefined") {
110
- const initialState = (0, import_lodash_es.cloneDeep)(
111
- fn(
112
- (...args) => {
113
- set(...args);
114
- setQuery();
115
- },
116
- get,
117
- api
118
- )
113
+ const initialState = fn(
114
+ (...args) => {
115
+ set(...args);
116
+ setQuery();
117
+ },
118
+ get,
119
+ api
119
120
  );
120
121
  const setQuery = () => {
121
- const url2 = new URL(window.location.href);
122
- const selectedState = getSelectedState(get(), url2.pathname);
122
+ const url = new URL(window.location.href);
123
+ const selectedState = getSelectedState(get(), url.pathname);
123
124
  const newCompacted = compact(selectedState, initialState);
124
- const previous = url2.search;
125
+ const previous = url.search;
125
126
  if (Object.keys(newCompacted).length) {
126
- url2.searchParams.set(defaultedOptions.key, stringify(newCompacted));
127
+ url.searchParams.set(
128
+ defaultedOptions.key,
129
+ defaultedOptions.format.stringify(newCompacted)
130
+ );
127
131
  } else {
128
- url2.searchParams.delete(defaultedOptions.key);
132
+ url.searchParams.delete(defaultedOptions.key);
129
133
  }
130
- if (url2.search !== previous) {
131
- history.replaceState(history.state, "", url2);
134
+ if (url.search !== previous) {
135
+ history.replaceState(history.state, "", url);
132
136
  }
133
137
  };
134
138
  if (!api.__ZUSTAND_QUERYSTRING_INIT__) {
@@ -148,9 +152,16 @@ var queryStringImpl = (fn, options) => (set, get, api) => {
148
152
  originalSetState(...args);
149
153
  setQuery();
150
154
  };
151
- return initialize(new URL(window.location.href), initialState);
152
- } else if (url) {
153
- return initialize(new URL(url, "http://localhost"), fn(set, get, api));
155
+ const initialized = initialize(new URL(window.location.href), initialState);
156
+ api.getInitialState = () => initialized;
157
+ return initialized;
158
+ } else if (defaultedOptions.url) {
159
+ const initialized = initialize(
160
+ new URL(defaultedOptions.url, "http://localhost"),
161
+ fn(set, get, api)
162
+ );
163
+ api.getInitialState = () => initialized;
164
+ return initialized;
154
165
  }
155
166
  return fn(set, get, api);
156
167
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  querystring
3
- } from "./chunk-HU2467IM.mjs";
3
+ } from "./chunk-L542GMLN.mjs";
4
4
  import "./chunk-OEB5LU3Z.mjs";
5
5
  export {
6
6
  querystring
@@ -0,0 +1,4 @@
1
+ declare function stringify(input: unknown): string;
2
+ declare function parse(str: string): any;
3
+
4
+ export { parse, stringify };
@@ -0,0 +1,7 @@
1
+ declare const createURL: ({ baseUrl, key, state, }: {
2
+ baseUrl: string;
3
+ key: string;
4
+ state: Object;
5
+ }) => string;
6
+
7
+ export { createURL };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zustand-querystring",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -41,10 +41,10 @@
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/lodash-es": "^4.17.12",
44
- "rimraf": "^3.0.2",
45
- "tsup": "^6.7.0",
46
- "typescript": "^4.9.5",
47
- "zustand": "^4.5.4"
44
+ "rimraf": "^6.0.1",
45
+ "tsup": "^8.4.0",
46
+ "typescript": "^5.8.2",
47
+ "zustand": "^5.0.3"
48
48
  },
49
49
  "scripts": {
50
50
  "build": "tsup src --dts",