cross-state 0.6.10 → 0.7.1
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/dist/cjs/hash.cjs +0 -682
- package/dist/cjs/hash.cjs.map +1 -1
- package/dist/cjs/immer/index.cjs +6 -0
- package/dist/cjs/immer/index.cjs.map +1 -0
- package/dist/cjs/immer/register.cjs +6 -0
- package/dist/cjs/immer/register.cjs.map +1 -0
- package/dist/cjs/immerMethods.cjs +23 -0
- package/dist/cjs/immerMethods.cjs.map +1 -0
- package/dist/cjs/index.cjs +387 -278
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/react/index.cjs +54 -0
- package/dist/cjs/react/index.cjs.map +1 -0
- package/dist/cjs/react/register.cjs +30 -0
- package/dist/cjs/react/register.cjs.map +1 -0
- package/dist/cjs/scope.cjs +399 -0
- package/dist/cjs/scope.cjs.map +1 -0
- package/dist/cjs/{react.cjs → scope2.cjs} +50 -37
- package/dist/cjs/scope2.cjs.map +1 -0
- package/dist/cjs/store.cjs +798 -0
- package/dist/cjs/store.cjs.map +1 -0
- package/dist/es/hash.mjs +1 -683
- package/dist/es/hash.mjs.map +1 -1
- package/dist/es/immer/index.mjs +6 -0
- package/dist/es/immer/index.mjs.map +1 -0
- package/dist/es/immer/register.mjs +5 -0
- package/dist/es/immer/register.mjs.map +1 -0
- package/dist/es/immerMethods.mjs +24 -0
- package/dist/es/immerMethods.mjs.map +1 -0
- package/dist/es/index.mjs +383 -273
- package/dist/es/index.mjs.map +1 -1
- package/dist/es/react/index.mjs +55 -0
- package/dist/es/react/index.mjs.map +1 -0
- package/dist/es/react/register.mjs +29 -0
- package/dist/es/react/register.mjs.map +1 -0
- package/dist/es/scope.mjs +400 -0
- package/dist/es/scope.mjs.map +1 -0
- package/dist/es/{react.mjs → scope2.mjs} +43 -29
- package/dist/es/scope2.mjs.map +1 -0
- package/dist/es/store.mjs +799 -0
- package/dist/es/store.mjs.map +1 -0
- package/dist/types/core/cache.d.ts +7 -2
- package/dist/types/core/commonTypes.d.ts +8 -0
- package/dist/types/core/index.d.ts +6 -6
- package/dist/types/core/resourceGroup.d.ts +2 -2
- package/dist/types/core/scope.d.ts +5 -0
- package/dist/types/core/store.d.ts +8 -10
- package/dist/types/core/subscriptionCache.d.ts +51 -0
- package/dist/types/core/urlStore.d.ts +26 -0
- package/dist/types/immer/immerMethods.d.ts +10 -0
- package/dist/types/immer/index.d.ts +1 -1
- package/dist/types/immer/register.d.ts +7 -0
- package/dist/types/index.d.ts +3 -1
- package/dist/types/lib/calculationHelper.d.ts +15 -10
- package/dist/types/lib/equals.d.ts +3 -3
- package/dist/types/lib/path.d.ts +3 -3
- package/dist/types/lib/promiseWithState.d.ts +9 -0
- package/dist/types/lib/standardMethods.d.ts +2 -1
- package/dist/types/lib/trackingProxy.d.ts +2 -1
- package/dist/types/lib/typeHelpers.d.ts +3 -1
- package/dist/types/lib/updateHelpers.d.ts +1 -0
- package/dist/types/react/index.d.ts +3 -1
- package/dist/types/react/reactMethods.d.ts +9 -0
- package/dist/types/react/register.d.ts +29 -0
- package/dist/types/react/scope.d.ts +16 -0
- package/dist/types/react/useCache.d.ts +2 -1
- package/dist/types/react/useDecoupledState.d.ts +7 -0
- package/dist/types/react/useProp.d.ts +1 -2
- package/package.json +105 -27
- package/dist/cjs/immer.cjs +0 -10
- package/dist/cjs/immer.cjs.map +0 -1
- package/dist/cjs/react.cjs.map +0 -1
- package/dist/es/immer.mjs +0 -10
- package/dist/es/immer.mjs.map +0 -1
- package/dist/es/react.mjs.map +0 -1
- package/dist/types/core/storeScope.d.ts +0 -4
- package/dist/types/immer/immerActions.d.ts +0 -5
- package/dist/types/react/storeScope.d.ts +0 -12
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,295 +1,81 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
this.
|
|
10
|
-
this.delete = this.delete.bind(this);
|
|
11
|
-
this.invalidateAll = this.invalidateAll.bind(this);
|
|
12
|
-
this.clearAll = this.clearAll.bind(this);
|
|
13
|
-
}
|
|
14
|
-
add(resource) {
|
|
15
|
-
const ref = new WeakRef(resource);
|
|
16
|
-
this.refMap.set(resource, ref);
|
|
17
|
-
this.refSet.add(ref);
|
|
18
|
-
}
|
|
19
|
-
delete(resource) {
|
|
20
|
-
const ref = this.refMap.get(resource);
|
|
21
|
-
if (ref) {
|
|
22
|
-
this.refMap.delete(resource);
|
|
23
|
-
this.refSet.delete(ref);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
invalidateAll() {
|
|
27
|
-
for (const ref of this.refSet) {
|
|
28
|
-
const resource = ref.deref();
|
|
29
|
-
if (resource) {
|
|
30
|
-
resource.invalidate();
|
|
31
|
-
} else {
|
|
32
|
-
this.refSet.delete(ref);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
clearAll() {
|
|
37
|
-
for (const ref of this.refSet) {
|
|
38
|
-
const resource = ref.deref();
|
|
39
|
-
if (resource) {
|
|
40
|
-
resource.clear();
|
|
41
|
-
} else {
|
|
42
|
-
this.refSet.delete(ref);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
const allResources = /* @__PURE__ */ new ResourceGroup();
|
|
48
|
-
function createResourceGroup(name) {
|
|
49
|
-
return new ResourceGroup(name);
|
|
50
|
-
}
|
|
51
|
-
class InstanceCache {
|
|
52
|
-
constructor(factory, cacheTime) {
|
|
53
|
-
this.factory = factory;
|
|
54
|
-
this.cacheTime = cacheTime;
|
|
55
|
-
this.cache = /* @__PURE__ */ new Map();
|
|
56
|
-
this.interval = this.cacheTime ? setInterval(() => this.cleanup(), Math.max(this.cacheTime / 10, 1)) : void 0;
|
|
57
|
-
}
|
|
58
|
-
cleanup() {
|
|
59
|
-
var _a;
|
|
60
|
-
const cutoff = this.now() - (this.cacheTime ?? 0);
|
|
61
|
-
for (const [key, entry] of this.cache.entries()) {
|
|
62
|
-
if (entry.ref && entry.t <= cutoff) {
|
|
63
|
-
delete entry.ref;
|
|
64
|
-
}
|
|
65
|
-
if (!entry.ref && !((_a = entry.weakRef) == null ? void 0 : _a.deref())) {
|
|
66
|
-
this.cache.delete(key);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
get(...args) {
|
|
71
|
-
var _a;
|
|
72
|
-
const key = hash.hash(args);
|
|
73
|
-
let entry = this.cache.get(key);
|
|
74
|
-
let value = (entry == null ? void 0 : entry.ref) ?? ((_a = entry == null ? void 0 : entry.weakRef) == null ? void 0 : _a.deref());
|
|
75
|
-
if (!entry || !value) {
|
|
76
|
-
value = this.factory(...args);
|
|
77
|
-
entry = {
|
|
78
|
-
t: this.now(),
|
|
79
|
-
ref: value,
|
|
80
|
-
weakRef: new WeakRef(value)
|
|
81
|
-
};
|
|
82
|
-
this.cache.set(key, entry);
|
|
83
|
-
} else {
|
|
84
|
-
entry.t = this.now();
|
|
85
|
-
entry.ref ?? (entry.ref = value);
|
|
86
|
-
}
|
|
87
|
-
return value;
|
|
88
|
-
}
|
|
89
|
-
values() {
|
|
90
|
-
return [...this.cache.values()].map((entry) => {
|
|
91
|
-
var _a;
|
|
92
|
-
return entry.ref ?? ((_a = entry.weakRef) == null ? void 0 : _a.deref());
|
|
93
|
-
}).filter((value) => !!value);
|
|
94
|
-
}
|
|
95
|
-
stop() {
|
|
96
|
-
if (this.interval) {
|
|
97
|
-
clearInterval(this.interval);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
stats() {
|
|
101
|
-
return {
|
|
102
|
-
count: this.cache.size,
|
|
103
|
-
withRef: [...this.cache.values()].filter((x) => !!x.ref).length,
|
|
104
|
-
withWeakRef: [...this.cache.values()].filter((x) => {
|
|
105
|
-
var _a;
|
|
106
|
-
return !!((_a = x.weakRef) == null ? void 0 : _a.deref());
|
|
107
|
-
}).length
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
now() {
|
|
111
|
-
return performance.now();
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
class Cache extends hash.Store {
|
|
115
|
-
constructor(getter, options = {}, derivedFromCache, _call) {
|
|
116
|
-
super(getter, options, void 0, _call);
|
|
3
|
+
const store = require("./store.cjs");
|
|
4
|
+
const scope = require("./scope.cjs");
|
|
5
|
+
require("./hash.cjs");
|
|
6
|
+
class SubstriptionCache extends store.Store {
|
|
7
|
+
constructor(connectFunction, options = {}, derivedFromSubscriptionCache, _call) {
|
|
8
|
+
super(void 0, options, void 0, _call);
|
|
9
|
+
this.connectFunction = connectFunction;
|
|
117
10
|
this.options = options;
|
|
118
|
-
this.
|
|
119
|
-
this.state =
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
isUpdating: false
|
|
11
|
+
this.derivedFromSubscriptionCache = derivedFromSubscriptionCache;
|
|
12
|
+
this.state = store.createStore({
|
|
13
|
+
connectionState: "closed",
|
|
14
|
+
error: void 0
|
|
123
15
|
});
|
|
124
|
-
this.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
16
|
+
this.calculationHelper.options = {
|
|
17
|
+
...this.calculationHelper.options,
|
|
18
|
+
calculate: (helpers) => {
|
|
19
|
+
let result = connectFunction.apply(helpers);
|
|
20
|
+
if (result instanceof Function && result.length > 0) {
|
|
21
|
+
result = result(helpers);
|
|
22
|
+
}
|
|
23
|
+
return result;
|
|
24
|
+
},
|
|
25
|
+
onValue: (value) => {
|
|
26
|
+
this.set(value);
|
|
27
|
+
},
|
|
28
|
+
onError: (error) => {
|
|
29
|
+
this.state.set("error", error);
|
|
30
|
+
},
|
|
31
|
+
onConnectionState: (state) => {
|
|
32
|
+
this.state.set("connectionState", state);
|
|
33
|
+
},
|
|
34
|
+
onInvalidate: () => {
|
|
35
|
+
this.invalidate();
|
|
138
36
|
}
|
|
139
|
-
}
|
|
140
|
-
if (!promise || stalePromise && backgroundUpdate) {
|
|
141
|
-
return stalePromise;
|
|
142
|
-
}
|
|
143
|
-
return promise;
|
|
37
|
+
};
|
|
144
38
|
}
|
|
145
39
|
invalidate({ invalidateDependencies = true } = {}) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
if (clearOnInvalidation) {
|
|
40
|
+
const { clearOnInvalidate = defaultOptions.clearOnInvalidate } = this.options;
|
|
41
|
+
if (clearOnInvalidate) {
|
|
149
42
|
return this.clear({ invalidateDependencies });
|
|
150
43
|
}
|
|
151
44
|
if (invalidateDependencies) {
|
|
152
45
|
this.calculationHelper.invalidateDependencies();
|
|
153
46
|
}
|
|
154
|
-
|
|
155
|
-
if (
|
|
156
|
-
this.
|
|
47
|
+
this.calculationHelper.stop();
|
|
48
|
+
if (this.isActive()) {
|
|
49
|
+
this.calculationHelper.execute();
|
|
157
50
|
}
|
|
158
|
-
this.state.set((state) => ({
|
|
159
|
-
...state,
|
|
160
|
-
isStale: true,
|
|
161
|
-
isUpdating: false
|
|
162
|
-
}));
|
|
163
|
-
super.reset();
|
|
164
51
|
}
|
|
165
52
|
clear({ invalidateDependencies = true } = {}) {
|
|
166
53
|
if (invalidateDependencies) {
|
|
167
54
|
this.calculationHelper.invalidateDependencies();
|
|
168
55
|
}
|
|
169
|
-
this.
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
isUpdating: false
|
|
173
|
-
});
|
|
174
|
-
delete this.stalePromise;
|
|
175
|
-
super.reset();
|
|
176
|
-
}
|
|
177
|
-
mapValue(_selector) {
|
|
178
|
-
const selector = hash.makeSelector(_selector);
|
|
179
|
-
const derivedFromCache = {
|
|
180
|
-
cache: this.derivedFromCache ? this.derivedFromCache.cache : this,
|
|
181
|
-
selectors: this.derivedFromCache ? [...this.derivedFromCache.selectors, _selector] : [_selector]
|
|
182
|
-
};
|
|
183
|
-
const that = this;
|
|
184
|
-
return new Cache(
|
|
185
|
-
async function() {
|
|
186
|
-
const value = await this.use(that);
|
|
187
|
-
return selector(value);
|
|
188
|
-
},
|
|
189
|
-
{},
|
|
190
|
-
derivedFromCache
|
|
191
|
-
);
|
|
192
|
-
}
|
|
193
|
-
watchPromise() {
|
|
194
|
-
this.sub(
|
|
195
|
-
async (promise) => {
|
|
196
|
-
var _a, _b;
|
|
197
|
-
this.state.set((state) => ({
|
|
198
|
-
...state,
|
|
199
|
-
isUpdating: true
|
|
200
|
-
}));
|
|
201
|
-
this.setTimers();
|
|
202
|
-
try {
|
|
203
|
-
const value = await promise;
|
|
204
|
-
if (promise !== ((_a = this._value) == null ? void 0 : _a.v)) {
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
this.state.set({
|
|
208
|
-
status: "value",
|
|
209
|
-
value,
|
|
210
|
-
isStale: false,
|
|
211
|
-
isUpdating: false
|
|
212
|
-
});
|
|
213
|
-
delete this.stalePromise;
|
|
214
|
-
this.setTimers();
|
|
215
|
-
} catch (error) {
|
|
216
|
-
if (promise !== ((_b = this._value) == null ? void 0 : _b.v)) {
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
this.state.set({
|
|
220
|
-
status: "error",
|
|
221
|
-
error,
|
|
222
|
-
isStale: false,
|
|
223
|
-
isUpdating: false
|
|
224
|
-
});
|
|
225
|
-
delete this.stalePromise;
|
|
226
|
-
this.setTimers();
|
|
227
|
-
}
|
|
228
|
-
},
|
|
229
|
-
{ passive: true }
|
|
230
|
-
);
|
|
231
|
-
}
|
|
232
|
-
setTimers() {
|
|
233
|
-
if (this.invalidationTimer) {
|
|
234
|
-
clearTimeout(this.invalidationTimer);
|
|
235
|
-
}
|
|
236
|
-
this.invalidationTimer = void 0;
|
|
237
|
-
const state = this.state.get();
|
|
238
|
-
let { invalidateAfter = defaultOptions.invalidateAfter } = this.options;
|
|
239
|
-
const ref = new WeakRef(this);
|
|
240
|
-
if (state.status === "pending") {
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
if (invalidateAfter instanceof Function) {
|
|
244
|
-
invalidateAfter = invalidateAfter(state);
|
|
245
|
-
}
|
|
246
|
-
if (invalidateAfter !== null && invalidateAfter !== void 0) {
|
|
247
|
-
this.invalidationTimer = setTimeout(
|
|
248
|
-
() => {
|
|
249
|
-
var _a;
|
|
250
|
-
return (_a = ref == null ? void 0 : ref.deref()) == null ? void 0 : _a.invalidate();
|
|
251
|
-
},
|
|
252
|
-
hash.calcDuration(invalidateAfter)
|
|
253
|
-
);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
watchFocus() {
|
|
257
|
-
const { invalidateOnWindowFocus = defaultOptions.invalidateOnWindowFocus } = this.options;
|
|
258
|
-
if (!invalidateOnWindowFocus || typeof document === "undefined" || typeof document.addEventListener === "undefined") {
|
|
259
|
-
return;
|
|
56
|
+
this.calculationHelper.stop();
|
|
57
|
+
if (this.isActive()) {
|
|
58
|
+
this.calculationHelper.execute();
|
|
260
59
|
}
|
|
261
|
-
const ref = new WeakRef(this);
|
|
262
|
-
const onFocus = () => {
|
|
263
|
-
const that = ref == null ? void 0 : ref.deref();
|
|
264
|
-
if (!that) {
|
|
265
|
-
document.removeEventListener("visibilitychange", onFocus);
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
if (!document.hidden) {
|
|
269
|
-
that.invalidate();
|
|
270
|
-
}
|
|
271
|
-
};
|
|
272
|
-
document.addEventListener("visibilitychange", onFocus);
|
|
273
60
|
}
|
|
274
61
|
}
|
|
275
62
|
const defaultOptions = {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
clearUnusedAfter: { days: 1 }
|
|
63
|
+
clearUnusedAfter: { days: 1 },
|
|
64
|
+
retain: { seconds: 1 }
|
|
279
65
|
};
|
|
280
66
|
function create(cacheFunction, options) {
|
|
281
67
|
const { clearUnusedAfter = defaultOptions.clearUnusedAfter, resourceGroup } = options ?? {};
|
|
282
68
|
let baseInstance;
|
|
283
|
-
const instanceCache = new InstanceCache(
|
|
69
|
+
const instanceCache = new scope.InstanceCache(
|
|
284
70
|
(...args) => {
|
|
285
71
|
if (args.length === 0 && baseInstance) {
|
|
286
72
|
return baseInstance;
|
|
287
73
|
}
|
|
288
|
-
return new
|
|
74
|
+
return new SubstriptionCache(function() {
|
|
289
75
|
return cacheFunction.apply(this, args);
|
|
290
76
|
}, options);
|
|
291
77
|
},
|
|
292
|
-
clearUnusedAfter ?
|
|
78
|
+
clearUnusedAfter ? store.calcDuration(clearUnusedAfter) : void 0
|
|
293
79
|
);
|
|
294
80
|
const get = (...args) => {
|
|
295
81
|
return instanceCache.get(...args);
|
|
@@ -304,12 +90,8 @@ function create(cacheFunction, options) {
|
|
|
304
90
|
instance.clear();
|
|
305
91
|
}
|
|
306
92
|
};
|
|
307
|
-
const groups = Array.isArray(resourceGroup) ? resourceGroup : resourceGroup ? [resourceGroup] : [];
|
|
308
|
-
for (const group of groups.concat(allResources)) {
|
|
309
|
-
group.add({ invalidate: invalidateAll, clear: clearAll });
|
|
310
|
-
}
|
|
311
93
|
baseInstance = Object.assign(
|
|
312
|
-
new
|
|
94
|
+
new SubstriptionCache(
|
|
313
95
|
function() {
|
|
314
96
|
return cacheFunction.apply(this);
|
|
315
97
|
},
|
|
@@ -322,23 +104,350 @@ function create(cacheFunction, options) {
|
|
|
322
104
|
clearAll
|
|
323
105
|
}
|
|
324
106
|
);
|
|
107
|
+
const groups = Array.isArray(resourceGroup) ? resourceGroup : resourceGroup ? [resourceGroup] : [];
|
|
108
|
+
for (const group of groups.concat(scope.allResources)) {
|
|
109
|
+
group.add(baseInstance);
|
|
110
|
+
}
|
|
325
111
|
get(...[]);
|
|
326
112
|
return baseInstance;
|
|
327
113
|
}
|
|
328
|
-
const
|
|
114
|
+
const createSubscriptionCache = /* @__PURE__ */ Object.assign(create, {
|
|
329
115
|
defaultOptions
|
|
330
116
|
});
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
117
|
+
class UrlStore extends store.Store {
|
|
118
|
+
constructor(options) {
|
|
119
|
+
super(() => {
|
|
120
|
+
const url = new URL(window.location.href);
|
|
121
|
+
const parameters = new URLSearchParams(url[options.type].slice(1));
|
|
122
|
+
const urlValue = parameters.get(options.key);
|
|
123
|
+
const deserialize = options.deserialize ?? defaultDeserializer;
|
|
124
|
+
return urlValue !== null ? deserialize(urlValue) : options.defaultValue;
|
|
125
|
+
});
|
|
126
|
+
this.options = options;
|
|
127
|
+
this.serializedDefaultValue = this.options.serialize(this.options.defaultValue);
|
|
128
|
+
this.addEffect(() => this.watchUrl());
|
|
129
|
+
}
|
|
130
|
+
set(...args) {
|
|
131
|
+
super.set.apply(this, args);
|
|
132
|
+
this.updateUrl(super.get());
|
|
133
|
+
}
|
|
134
|
+
watchUrl() {
|
|
135
|
+
const originalPushState = window.history.pushState;
|
|
136
|
+
const originalReplaceState = window.history.replaceState;
|
|
137
|
+
window.history.pushState = (...args) => {
|
|
138
|
+
originalPushState.apply(window.history, args);
|
|
139
|
+
this.reset();
|
|
140
|
+
};
|
|
141
|
+
window.history.replaceState = (...args) => {
|
|
142
|
+
originalReplaceState.apply(window.history, args);
|
|
143
|
+
this.reset();
|
|
144
|
+
};
|
|
145
|
+
return () => {
|
|
146
|
+
window.history.pushState = originalPushState;
|
|
147
|
+
window.history.replaceState = originalReplaceState;
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
updateUrl(value) {
|
|
151
|
+
var _a, _b;
|
|
152
|
+
const url = new URL(window.location.href);
|
|
153
|
+
const parameters = new URLSearchParams(url[this.options.type].slice(1));
|
|
154
|
+
const serializedValue = value !== void 0 ? this.options.serialize(value) : void 0;
|
|
155
|
+
if (serializedValue === void 0 || serializedValue === this.serializedDefaultValue) {
|
|
156
|
+
parameters.delete(this.options.key);
|
|
157
|
+
} else {
|
|
158
|
+
parameters.set(this.options.key, serializedValue);
|
|
159
|
+
}
|
|
160
|
+
url[this.options.type] = parameters.toString();
|
|
161
|
+
window.history.replaceState(null, "", url.toString());
|
|
162
|
+
(_b = (_a = this.options).onCommit) == null ? void 0 : _b.call(_a, value);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function defaultDeserializer(value) {
|
|
166
|
+
if (value === void 0) {
|
|
167
|
+
return void 0;
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
return JSON.parse(value, (_k, v) => {
|
|
171
|
+
if (typeof v === "object" && v !== null && "__set" in v) {
|
|
172
|
+
return new Set(v.__set);
|
|
173
|
+
}
|
|
174
|
+
if (typeof v === "object" && v !== null && "__map" in v) {
|
|
175
|
+
return new Map(v.__map);
|
|
176
|
+
}
|
|
177
|
+
return v;
|
|
178
|
+
});
|
|
179
|
+
} catch {
|
|
180
|
+
return void 0;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function defaultSerializer(value) {
|
|
184
|
+
return JSON.stringify(value, (_k, v) => {
|
|
185
|
+
if (v instanceof Set) {
|
|
186
|
+
return { __set: Array.from(v) };
|
|
187
|
+
}
|
|
188
|
+
if (v instanceof Map) {
|
|
189
|
+
return { __map: Array.from(v) };
|
|
190
|
+
}
|
|
191
|
+
return v;
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
function createUrlStore(options) {
|
|
195
|
+
return new UrlStore({
|
|
196
|
+
...options,
|
|
197
|
+
type: options.type ?? "search",
|
|
198
|
+
serialize: options.serialize ?? defaultSerializer,
|
|
199
|
+
deserialize: options.deserialize ?? defaultDeserializer,
|
|
200
|
+
defaultValue: options.defaultValue ?? void 0
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
function findOrDefault(array, predicate, defaultValue) {
|
|
204
|
+
const index = array.findIndex(predicate);
|
|
205
|
+
if (index >= 0) {
|
|
206
|
+
return array[index];
|
|
207
|
+
}
|
|
208
|
+
const value = defaultValue instanceof Function ? defaultValue() : defaultValue;
|
|
209
|
+
array.push(value);
|
|
210
|
+
return value;
|
|
211
|
+
}
|
|
212
|
+
const isAncestor = (ancestor, path) => {
|
|
213
|
+
return ancestor.length <= path.length && ancestor.every((v, i) => v === "*" || path[i] === "*" || v === path[i]);
|
|
214
|
+
};
|
|
215
|
+
function maybeAsync(value, action) {
|
|
216
|
+
if (value instanceof Promise) {
|
|
217
|
+
return value.then(action);
|
|
218
|
+
}
|
|
219
|
+
return action(value);
|
|
220
|
+
}
|
|
221
|
+
function maybeAsyncArray(values) {
|
|
222
|
+
const run = (remainingValues, results) => {
|
|
223
|
+
const [first, ...rest] = remainingValues;
|
|
224
|
+
if (!first) {
|
|
225
|
+
return results;
|
|
226
|
+
}
|
|
227
|
+
return maybeAsync(first(), (result) => run(rest, results.concat(result)));
|
|
228
|
+
};
|
|
229
|
+
return run(values, []);
|
|
230
|
+
}
|
|
231
|
+
function normalizeStorage(storage) {
|
|
232
|
+
return {
|
|
233
|
+
getItem: storage.getItem.bind(storage),
|
|
234
|
+
setItem: storage.setItem.bind(storage),
|
|
235
|
+
removeItem: storage.removeItem.bind(storage),
|
|
236
|
+
keys() {
|
|
237
|
+
if ("keys" in storage) {
|
|
238
|
+
return storage.keys();
|
|
239
|
+
}
|
|
240
|
+
return maybeAsync(
|
|
241
|
+
storage.length instanceof Function ? storage.length() : storage.length,
|
|
242
|
+
(length) => {
|
|
243
|
+
const keyPromises = maybeAsyncArray(
|
|
244
|
+
Array.from({ length }, (_, index) => () => storage.key(index))
|
|
245
|
+
);
|
|
246
|
+
return maybeAsync(
|
|
247
|
+
keyPromises,
|
|
248
|
+
(keys) => keys.filter((key) => typeof key === "string")
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
function diff(a, b) {
|
|
256
|
+
const result = [..._diff(a, b)];
|
|
257
|
+
const patches = result.map(([patch]) => patch);
|
|
258
|
+
const reversePatches = result.map(([, reversePatch]) => reversePatch);
|
|
259
|
+
return [patches, reversePatches];
|
|
260
|
+
}
|
|
261
|
+
function* _diff(a, b, prefix = []) {
|
|
262
|
+
if (a === b) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
if (a instanceof Map && b instanceof Map) {
|
|
266
|
+
return yield* mapDiff(a, b, prefix);
|
|
267
|
+
}
|
|
268
|
+
if (a instanceof Set && b instanceof Set) {
|
|
269
|
+
a = [...a];
|
|
270
|
+
b = [...b];
|
|
271
|
+
}
|
|
272
|
+
if (a instanceof Object && b instanceof Object && Array.isArray(a) === Array.isArray(b)) {
|
|
273
|
+
return yield* objectDiff(a, b, prefix);
|
|
274
|
+
}
|
|
275
|
+
yield [
|
|
276
|
+
{ op: "replace", path: prefix, value: b },
|
|
277
|
+
{ op: "replace", path: prefix, value: a }
|
|
278
|
+
];
|
|
279
|
+
}
|
|
280
|
+
function* mapDiff(a, b, prefix) {
|
|
281
|
+
for (const [key, value] of a) {
|
|
282
|
+
if (!b.has(key)) {
|
|
283
|
+
yield [
|
|
284
|
+
{ op: "remove", path: [...prefix, key] },
|
|
285
|
+
{ op: "add", path: [...prefix, key], value }
|
|
286
|
+
];
|
|
287
|
+
} else {
|
|
288
|
+
yield* _diff(value, b.get(key), [...prefix, key]);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
for (const [key, value] of b) {
|
|
292
|
+
if (!a.has(key)) {
|
|
293
|
+
yield [
|
|
294
|
+
{ op: "add", path: [...prefix, key], value },
|
|
295
|
+
{ op: "remove", path: [...prefix, key] }
|
|
296
|
+
];
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function* objectDiff(a, b, prefix) {
|
|
301
|
+
const castKey = (key) => Array.isArray(a) ? Number(key) : key;
|
|
302
|
+
for (const [key, value] of Object.entries(a)) {
|
|
303
|
+
if (!(key in b)) {
|
|
304
|
+
yield [
|
|
305
|
+
{ op: "remove", path: [...prefix, castKey(key)] },
|
|
306
|
+
{ op: "add", path: [...prefix, castKey(key)], value }
|
|
307
|
+
];
|
|
308
|
+
} else {
|
|
309
|
+
yield* _diff(value, b[key], [...prefix, castKey(key)]);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
for (const [key, value] of Object.entries(b)) {
|
|
313
|
+
if (!(key in a)) {
|
|
314
|
+
yield [
|
|
315
|
+
{ op: "add", path: [...prefix, castKey(key)], value },
|
|
316
|
+
{ op: "remove", path: [...prefix, castKey(key)] }
|
|
317
|
+
];
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
class Persist {
|
|
322
|
+
constructor(store$1, options) {
|
|
323
|
+
this.store = store$1;
|
|
324
|
+
this.options = options;
|
|
325
|
+
this.queue = store.queue();
|
|
326
|
+
this.handles = /* @__PURE__ */ new Set();
|
|
327
|
+
this.stopped = false;
|
|
328
|
+
this.storage = normalizeStorage(options.storage);
|
|
329
|
+
this.channel = new BroadcastChannel(`cross-state-persist_${options.id}`);
|
|
330
|
+
this.paths = (options.paths ?? []).map(
|
|
331
|
+
(p) => typeof p === "string" || Array.isArray(p) ? {
|
|
332
|
+
path: store.castArrayPath(p)
|
|
333
|
+
} : {
|
|
334
|
+
path: store.castArrayPath(p.path),
|
|
335
|
+
throttleMs: p.throttleMs
|
|
336
|
+
}
|
|
337
|
+
).sort((a, b) => b.path.length - a.path.length);
|
|
338
|
+
if (this.paths.length === 0) {
|
|
339
|
+
this.paths.push({ path: ["*"] });
|
|
340
|
+
}
|
|
341
|
+
this.watchStore();
|
|
342
|
+
this.watchStorage();
|
|
343
|
+
}
|
|
344
|
+
watchStore() {
|
|
345
|
+
let committed = this.store.get();
|
|
346
|
+
const cancel = this.store.subscribe(
|
|
347
|
+
(value) => {
|
|
348
|
+
const [patches] = diff(committed, value);
|
|
349
|
+
committed = value;
|
|
350
|
+
for (const patch of patches) {
|
|
351
|
+
if (this.updateInProgress && store.shallowEqual(this.updateInProgress[0], patch.path) && this.updateInProgress[1] === (patch.op === "remove" ? void 0 : patch.value)) {
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
const ancestor = this.paths.find((p) => isAncestor(p.path, patch.path));
|
|
355
|
+
if (!ancestor) {
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
const pathToSave = patch.path.slice(0, ancestor.path.length);
|
|
359
|
+
this.queue(() => this.save(pathToSave), pathToSave);
|
|
360
|
+
}
|
|
361
|
+
},
|
|
362
|
+
{ runNow: false }
|
|
363
|
+
);
|
|
364
|
+
this.handles.add(cancel);
|
|
365
|
+
}
|
|
366
|
+
async watchStorage() {
|
|
367
|
+
let keys = this.storage.keys();
|
|
368
|
+
if (keys instanceof Promise) {
|
|
369
|
+
keys = await keys;
|
|
370
|
+
}
|
|
371
|
+
if (this.stopped) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
for (const key of keys) {
|
|
375
|
+
const path = JSON.parse(key);
|
|
376
|
+
this.queue(() => this.load(path));
|
|
377
|
+
}
|
|
378
|
+
const listener = (event) => {
|
|
379
|
+
this.queue(() => this.load(event.data));
|
|
380
|
+
};
|
|
381
|
+
this.channel.addEventListener("message", listener);
|
|
382
|
+
this.handles.add(() => this.channel.removeEventListener("message", listener));
|
|
383
|
+
}
|
|
384
|
+
load(path) {
|
|
385
|
+
const matchingPath = this.paths.find(
|
|
386
|
+
(p) => p.path.length === path.length && isAncestor(p.path, path)
|
|
387
|
+
);
|
|
388
|
+
if (!matchingPath) {
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
const key = JSON.stringify(path);
|
|
392
|
+
return maybeAsync(this.storage.getItem(key), (value) => {
|
|
393
|
+
if (this.stopped || !value) {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
const inSaveQueue = this.queue.getRefs().find((ref) => isAncestor(ref, path) || isAncestor(path, ref));
|
|
397
|
+
if (inSaveQueue) {
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
const parsedValue = value === "undefined" ? void 0 : JSON.parse(value);
|
|
401
|
+
this.updateInProgress = [path, parsedValue];
|
|
402
|
+
this.store.set((state) => store.set(state, path, parsedValue));
|
|
403
|
+
this.updateInProgress = void 0;
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
save(path) {
|
|
407
|
+
const key = JSON.stringify(path);
|
|
408
|
+
const value = store.get(this.store.get(), path);
|
|
409
|
+
const serializedValue = value === void 0 ? "undefined" : JSON.stringify(value);
|
|
410
|
+
return maybeAsync(this.storage.setItem(key, serializedValue), () => {
|
|
411
|
+
this.channel.postMessage(path);
|
|
412
|
+
return maybeAsync(this.storage.keys(), (keys) => {
|
|
413
|
+
const toRemove = keys.filter((k) => {
|
|
414
|
+
const parsedKey = JSON.parse(k);
|
|
415
|
+
return parsedKey.length > path.length && isAncestor(path, parsedKey);
|
|
416
|
+
});
|
|
417
|
+
return maybeAsyncArray(toRemove.map((k) => () => this.storage.removeItem(k)));
|
|
418
|
+
});
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
async stop() {
|
|
422
|
+
this.stopped = true;
|
|
423
|
+
for (const handle of this.handles) {
|
|
424
|
+
handle();
|
|
425
|
+
}
|
|
426
|
+
await this.queue.whenDone();
|
|
427
|
+
this.channel.close();
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
function persist(store2, options) {
|
|
431
|
+
return new Persist(store2, options);
|
|
432
|
+
}
|
|
433
|
+
exports.Store = store.Store;
|
|
434
|
+
exports.arrayMethods = store.arrayMethods;
|
|
435
|
+
exports.calcDuration = store.calcDuration;
|
|
436
|
+
exports.createStore = store.createStore;
|
|
437
|
+
exports.mapMethods = store.mapMethods;
|
|
438
|
+
exports.recordMethods = store.recordMethods;
|
|
439
|
+
exports.setMethods = store.setMethods;
|
|
440
|
+
exports.Cache = scope.Cache;
|
|
441
|
+
exports.InstanceCache = scope.InstanceCache;
|
|
442
|
+
exports.ResourceGroup = scope.ResourceGroup;
|
|
443
|
+
exports.Scope = scope.Scope;
|
|
444
|
+
exports.allResources = scope.allResources;
|
|
445
|
+
exports.createCache = scope.createCache;
|
|
446
|
+
exports.createResourceGroup = scope.createResourceGroup;
|
|
447
|
+
exports.createScope = scope.createScope;
|
|
448
|
+
exports.SubstriptionCache = SubstriptionCache;
|
|
449
|
+
exports.createSubscriptionCache = createSubscriptionCache;
|
|
450
|
+
exports.createUrlStore = createUrlStore;
|
|
451
|
+
exports.findOrDefault = findOrDefault;
|
|
452
|
+
exports.persist = persist;
|
|
344
453
|
//# sourceMappingURL=index.cjs.map
|