zustand-querystring 0.0.11 → 0.0.12
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.
- package/README.md +12 -2
- package/lib/middleware.js +20 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
# zustand-querystring
|
|
2
2
|
|
|
3
|
-
A zustand middleware that
|
|
3
|
+
A zustand middleware that syncs state with the querystring.
|
|
4
4
|
|
|
5
5
|
Try on [StackBlitz](https://stackblitz.com/github/nitedani/zustand-querystring/tree/main/examples/react) (You need to click "Open in New Tab")
|
|
6
6
|
|
|
7
|
+
Examples:
|
|
8
|
+
- [React](./examples/react/)
|
|
9
|
+
- [NextJS](./examples/next/)
|
|
10
|
+
- [Rakkas](./example/rakkas/)
|
|
11
|
+
|
|
7
12
|
Quickstart:
|
|
8
13
|
```ts
|
|
9
14
|
import create from "zustand";
|
|
@@ -48,4 +53,9 @@ export const useStore = create<Store>()(
|
|
|
48
53
|
}
|
|
49
54
|
)
|
|
50
55
|
);
|
|
51
|
-
```
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
querystring options:
|
|
59
|
+
- <b>select</b> - the select option controls what part of the state is synced with the query string
|
|
60
|
+
- <b>key: string</b> - the key option controls how the state is stored in the querystring (default: $)
|
|
61
|
+
- <b>url</b> - the url option is used to provide the request url on the server side render
|
package/lib/middleware.js
CHANGED
|
@@ -48,7 +48,7 @@ const queryStringImpl = (fn, options) => (set, get, api) => {
|
|
|
48
48
|
...options,
|
|
49
49
|
};
|
|
50
50
|
const stateMatcher = new RegExp(`${escapeStringRegexp(defaultedOptions.key)}=(.*);;`);
|
|
51
|
-
const
|
|
51
|
+
const splitMatcher = new RegExp(`${escapeStringRegexp(defaultedOptions.key)}=.*;;`);
|
|
52
52
|
const parseQueryString = querystring => {
|
|
53
53
|
const match = querystring.match(stateMatcher);
|
|
54
54
|
if (match) {
|
|
@@ -96,31 +96,44 @@ const queryStringImpl = (fn, options) => (set, get, api) => {
|
|
|
96
96
|
if (typeof window !== 'undefined') {
|
|
97
97
|
const setQuery = () => {
|
|
98
98
|
const selectedState = getSelectedState(get(), location.pathname);
|
|
99
|
-
const currentQueryString = location.search
|
|
99
|
+
const currentQueryString = location.search;
|
|
100
100
|
const currentParsed = parseQueryString(currentQueryString);
|
|
101
101
|
const newMerged = {
|
|
102
102
|
...currentParsed,
|
|
103
103
|
...selectedState,
|
|
104
104
|
};
|
|
105
|
-
const
|
|
105
|
+
const splitIgnored = currentQueryString.split(splitMatcher);
|
|
106
|
+
let ignored = '';
|
|
107
|
+
for (let str of splitIgnored) {
|
|
108
|
+
if (!str || str === '?' || str === '&') {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (str.startsWith('&') || str.startsWith('?')) {
|
|
112
|
+
str = str.substring(1);
|
|
113
|
+
}
|
|
114
|
+
if (str.endsWith('&')) {
|
|
115
|
+
str = str.substring(0, str.length - 1);
|
|
116
|
+
}
|
|
117
|
+
ignored += (ignored ? '&' : '?') + str;
|
|
118
|
+
}
|
|
106
119
|
const newCompacted = compact(newMerged, initialState);
|
|
107
120
|
if (Object.keys(newCompacted).length) {
|
|
108
121
|
const stringified = stringify(newCompacted).substring(1);
|
|
109
122
|
const newQueryState = `${defaultedOptions.key}=${stringified};;`;
|
|
110
123
|
let newQueryString = '';
|
|
111
124
|
if (currentParsed) {
|
|
112
|
-
newQueryString = currentQueryString.replace(
|
|
125
|
+
newQueryString = currentQueryString.replace(splitMatcher, newQueryState);
|
|
113
126
|
}
|
|
114
127
|
else if (ignored) {
|
|
115
128
|
newQueryString = ignored + '&' + newQueryState;
|
|
116
129
|
}
|
|
117
130
|
else {
|
|
118
|
-
newQueryString = newQueryState;
|
|
131
|
+
newQueryString = '?' + newQueryState;
|
|
119
132
|
}
|
|
120
|
-
history.replaceState(history.state, '', location.pathname +
|
|
133
|
+
history.replaceState(history.state, '', location.pathname + newQueryString);
|
|
121
134
|
}
|
|
122
135
|
else {
|
|
123
|
-
history.replaceState(history.state, '', location.pathname +
|
|
136
|
+
history.replaceState(history.state, '', location.pathname + ignored);
|
|
124
137
|
}
|
|
125
138
|
};
|
|
126
139
|
// @ts-ignore
|