cross-state 0.6.3 → 0.6.4
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 +3 -3
- package/dist/cjs/hash.cjs +364 -282
- package/dist/cjs/hash.cjs.map +1 -1
- package/dist/cjs/immer.cjs +1 -1
- package/dist/cjs/immer.cjs.map +1 -1
- package/dist/cjs/index.cjs +175 -172
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/react.cjs +44 -8
- package/dist/cjs/react.cjs.map +1 -1
- package/dist/es/hash.mjs +365 -283
- package/dist/es/hash.mjs.map +1 -1
- package/dist/es/immer.mjs +1 -1
- package/dist/es/immer.mjs.map +1 -1
- package/dist/es/index.mjs +178 -175
- package/dist/es/index.mjs.map +1 -1
- package/dist/es/react.mjs +53 -17
- package/dist/es/react.mjs.map +1 -1
- package/dist/types/core/cache.d.ts +56 -0
- package/dist/types/core/commonTypes.d.ts +5 -5
- package/dist/types/core/index.d.ts +5 -8
- package/dist/types/core/resourceGroup.d.ts +9 -6
- package/dist/types/core/store.d.ts +40 -21
- package/dist/types/immer/immerActions.d.ts +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/lib/applyPatches.d.ts +2 -0
- package/dist/types/lib/cacheState.d.ts +19 -0
- package/dist/types/lib/calculationHelper.d.ts +3 -3
- package/dist/types/lib/clone.d.ts +1 -0
- package/dist/types/lib/debounce.d.ts +6 -0
- package/dist/types/lib/diff.d.ts +14 -7
- package/dist/types/lib/{cache.d.ts → instanceCache.d.ts} +1 -1
- package/dist/types/lib/makeSelector.d.ts +2 -1
- package/dist/types/lib/maybeAsync.d.ts +3 -0
- package/dist/types/lib/path.d.ts +14 -0
- package/dist/types/lib/propAccess.d.ts +5 -12
- package/dist/types/lib/queue.d.ts +4 -2
- package/dist/types/lib/standardMethods.d.ts +25 -0
- package/dist/types/lib/throttle.d.ts +2 -1
- package/dist/types/lib/typeHelpers.d.ts +8 -0
- package/dist/types/persist/index.d.ts +3 -0
- package/dist/types/persist/persist.d.ts +33 -0
- package/dist/types/persist/persistPathHelpers.d.ts +6 -0
- package/dist/types/persist/persistStorage.d.ts +14 -0
- package/dist/types/react/index.d.ts +3 -4
- package/dist/types/react/read.d.ts +3 -4
- package/dist/types/react/storeScope.d.ts +1 -1
- package/dist/types/react/useCache.d.ts +14 -0
- package/dist/types/react/useProp.d.ts +3 -3
- package/dist/types/react/useStore.d.ts +1 -1
- package/package.json +53 -44
- package/dist/types/core/derivedStore.d.ts +0 -38
- package/dist/types/core/fetchStore.d.ts +0 -76
- package/dist/types/core/once.d.ts +0 -13
- package/dist/types/lib/storeActions.d.ts +0 -28
- package/react.d.ts +0 -1
- package/react.js +0 -1
package/dist/cjs/hash.cjs
CHANGED
|
@@ -1,8 +1,39 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
const getAllProperties = (object) => {
|
|
3
|
+
const properties = /* @__PURE__ */ new Set();
|
|
4
|
+
do {
|
|
5
|
+
for (const key of Reflect.ownKeys(object)) {
|
|
6
|
+
properties.add([object, key]);
|
|
7
|
+
}
|
|
8
|
+
} while ((object = Reflect.getPrototypeOf(object)) && object !== Object.prototype);
|
|
9
|
+
return properties;
|
|
10
|
+
};
|
|
11
|
+
function bind(self) {
|
|
12
|
+
for (const [object, key] of getAllProperties(self.constructor.prototype)) {
|
|
13
|
+
if (key === "constructor") {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(object, key);
|
|
17
|
+
if (descriptor && typeof descriptor.value === "function") {
|
|
18
|
+
self[key] = self[key].bind(self);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const calcDuration = (t) => {
|
|
23
|
+
if (typeof t === "number")
|
|
24
|
+
return t;
|
|
25
|
+
return (t.milliseconds ?? 0) + (t.seconds ?? 0) * 1e3 + (t.minutes ?? 0) * 60 * 1e3 + (t.hours ?? 0) * 60 * 60 * 1e3 + (t.days ?? 0) * 24 * 60 * 60 * 1e3;
|
|
26
|
+
};
|
|
2
27
|
function queue() {
|
|
3
28
|
const q = [];
|
|
4
|
-
|
|
29
|
+
const completionListeners = /* @__PURE__ */ new Set();
|
|
5
30
|
let active = false;
|
|
31
|
+
const notify = () => {
|
|
32
|
+
for (const listener of completionListeners) {
|
|
33
|
+
listener();
|
|
34
|
+
}
|
|
35
|
+
completionListeners.clear();
|
|
36
|
+
};
|
|
6
37
|
const run = async () => {
|
|
7
38
|
if (!active) {
|
|
8
39
|
active = true;
|
|
@@ -14,42 +45,50 @@ function queue() {
|
|
|
14
45
|
result = await result;
|
|
15
46
|
}
|
|
16
47
|
next.resolve(result);
|
|
17
|
-
} catch (
|
|
18
|
-
next.reject(
|
|
48
|
+
} catch (error) {
|
|
49
|
+
next.reject(error);
|
|
19
50
|
}
|
|
20
51
|
}
|
|
21
52
|
active = false;
|
|
22
|
-
|
|
53
|
+
notify();
|
|
23
54
|
}
|
|
24
55
|
};
|
|
25
56
|
return Object.assign(
|
|
26
|
-
(action) => {
|
|
27
|
-
return new Promise((
|
|
28
|
-
q.push({ action, resolve
|
|
57
|
+
(action, ref) => {
|
|
58
|
+
return new Promise((resolve, reject) => {
|
|
59
|
+
q.push({ action, resolve, reject, ref });
|
|
29
60
|
run();
|
|
30
61
|
});
|
|
31
62
|
},
|
|
32
63
|
{
|
|
33
64
|
clear() {
|
|
34
65
|
q.length = 0;
|
|
35
|
-
resolve == null ? void 0 : resolve();
|
|
36
66
|
},
|
|
37
|
-
|
|
38
|
-
if (!
|
|
39
|
-
|
|
40
|
-
resolve = () => {
|
|
41
|
-
promise = void 0;
|
|
42
|
-
resolve = void 0;
|
|
43
|
-
r();
|
|
44
|
-
};
|
|
45
|
-
});
|
|
67
|
+
whenDone() {
|
|
68
|
+
if (!active) {
|
|
69
|
+
return Promise.resolve();
|
|
46
70
|
}
|
|
47
|
-
return
|
|
71
|
+
return new Promise((resolve) => {
|
|
72
|
+
completionListeners.add(resolve);
|
|
73
|
+
});
|
|
74
|
+
},
|
|
75
|
+
get size() {
|
|
76
|
+
return q.length;
|
|
77
|
+
},
|
|
78
|
+
getRefs() {
|
|
79
|
+
return q.map((item) => item.ref).filter((x) => x !== void 0);
|
|
48
80
|
}
|
|
49
81
|
}
|
|
50
82
|
);
|
|
51
83
|
}
|
|
52
|
-
const ProxyKeys = [
|
|
84
|
+
const ProxyKeys = [
|
|
85
|
+
"get",
|
|
86
|
+
"getOwnPropertyDescriptor",
|
|
87
|
+
"getPrototypeOf",
|
|
88
|
+
"has",
|
|
89
|
+
"isExtensible",
|
|
90
|
+
"ownKeys"
|
|
91
|
+
];
|
|
53
92
|
const isPlainObject = (value) => typeof value === "object" && value !== null && Object.getPrototypeOf(value) === Object.prototype;
|
|
54
93
|
function trackingProxy(value) {
|
|
55
94
|
if (!isPlainObject(value) && !Array.isArray(value)) {
|
|
@@ -61,14 +100,14 @@ function trackingProxy(value) {
|
|
|
61
100
|
Object.fromEntries(
|
|
62
101
|
ProxyKeys.map((key) => [
|
|
63
102
|
key,
|
|
64
|
-
(
|
|
65
|
-
const
|
|
66
|
-
const [proxiedValue, equals] = trackingProxy(
|
|
103
|
+
(currentValue, ...args) => {
|
|
104
|
+
const function_ = Reflect[key];
|
|
105
|
+
const [proxiedValue, equals] = trackingProxy(function_(currentValue, ...args));
|
|
67
106
|
deps.push((otherValue) => {
|
|
68
107
|
if (!isPlainObject(otherValue) && !Array.isArray(otherValue)) {
|
|
69
108
|
return false;
|
|
70
109
|
}
|
|
71
|
-
return equals(
|
|
110
|
+
return equals(function_(otherValue, ...args));
|
|
72
111
|
});
|
|
73
112
|
return proxiedValue;
|
|
74
113
|
}
|
|
@@ -114,17 +153,22 @@ class CalculationHelper {
|
|
|
114
153
|
cancelEffect();
|
|
115
154
|
delete this.current;
|
|
116
155
|
};
|
|
117
|
-
const
|
|
118
|
-
if (!checks.every((
|
|
156
|
+
const checkAll = () => {
|
|
157
|
+
if (!checks.every((check) => check())) {
|
|
119
158
|
cancel();
|
|
120
159
|
onInvalidate == null ? void 0 : onInvalidate();
|
|
121
160
|
}
|
|
122
161
|
};
|
|
123
|
-
const
|
|
162
|
+
const invalidateDependencies = () => {
|
|
163
|
+
for (const dep of deps.values()) {
|
|
164
|
+
dep.invalidate();
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
const use = (store, { disableProxy } = {}) => {
|
|
124
168
|
if (isCancled) {
|
|
125
|
-
return
|
|
169
|
+
return store.get();
|
|
126
170
|
}
|
|
127
|
-
let value =
|
|
171
|
+
let value = store.get();
|
|
128
172
|
let equals = (newValue) => {
|
|
129
173
|
return newValue === value;
|
|
130
174
|
};
|
|
@@ -135,44 +179,23 @@ class CalculationHelper {
|
|
|
135
179
|
const dep = {
|
|
136
180
|
on() {
|
|
137
181
|
this.off();
|
|
138
|
-
sub =
|
|
182
|
+
sub = store.sub(checkAll, { runNow: false });
|
|
139
183
|
},
|
|
140
184
|
off() {
|
|
141
185
|
sub == null ? void 0 : sub();
|
|
142
186
|
sub = void 0;
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
if (isActive) {
|
|
146
|
-
dep.on();
|
|
147
|
-
}
|
|
148
|
-
checks.push(() => equals(store2.get()));
|
|
149
|
-
deps.set(store2, dep);
|
|
150
|
-
return value;
|
|
151
|
-
};
|
|
152
|
-
const useFetch = (store2) => {
|
|
153
|
-
if (isCancled) {
|
|
154
|
-
return store2.fetch();
|
|
155
|
-
}
|
|
156
|
-
const value = store2.fetch();
|
|
157
|
-
const ref = store2.get().ref;
|
|
158
|
-
let sub;
|
|
159
|
-
const dep = {
|
|
160
|
-
on() {
|
|
161
|
-
this.off();
|
|
162
|
-
sub = store2.sub(check, { runNow: false });
|
|
163
187
|
},
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
188
|
+
invalidate() {
|
|
189
|
+
if ("invalidate" in store && store.invalidate instanceof Function) {
|
|
190
|
+
store.invalidate();
|
|
191
|
+
}
|
|
167
192
|
}
|
|
168
193
|
};
|
|
169
194
|
if (isActive) {
|
|
170
195
|
dep.on();
|
|
171
196
|
}
|
|
172
|
-
checks.push(() =>
|
|
173
|
-
|
|
174
|
-
});
|
|
175
|
-
deps.set(store2, dep);
|
|
197
|
+
checks.push(() => equals(store.get()));
|
|
198
|
+
deps.set(store, dep);
|
|
176
199
|
return value;
|
|
177
200
|
};
|
|
178
201
|
const updateValue = (update) => q(async () => {
|
|
@@ -181,7 +204,7 @@ class CalculationHelper {
|
|
|
181
204
|
}
|
|
182
205
|
if (update instanceof Function) {
|
|
183
206
|
try {
|
|
184
|
-
update = update(getValue());
|
|
207
|
+
update = update(getValue == null ? void 0 : getValue());
|
|
185
208
|
} catch (error) {
|
|
186
209
|
setError == null ? void 0 : setError(error);
|
|
187
210
|
return;
|
|
@@ -208,11 +231,11 @@ class CalculationHelper {
|
|
|
208
231
|
});
|
|
209
232
|
let cancelSubscription;
|
|
210
233
|
try {
|
|
211
|
-
cancelSubscription = calculate({ use,
|
|
234
|
+
cancelSubscription = calculate({ use, updateValue, updateError });
|
|
212
235
|
} catch (error) {
|
|
213
236
|
setError == null ? void 0 : setError(error);
|
|
214
237
|
}
|
|
215
|
-
this.current = { cancel, check };
|
|
238
|
+
this.current = { cancel, check: checkAll, invalidateDependencies };
|
|
216
239
|
}
|
|
217
240
|
stop() {
|
|
218
241
|
var _a;
|
|
@@ -222,105 +245,113 @@ class CalculationHelper {
|
|
|
222
245
|
var _a;
|
|
223
246
|
(_a = this.current) == null ? void 0 : _a.check();
|
|
224
247
|
}
|
|
248
|
+
invalidateDependencies() {
|
|
249
|
+
var _a;
|
|
250
|
+
(_a = this.current) == null ? void 0 : _a.invalidateDependencies();
|
|
251
|
+
}
|
|
225
252
|
}
|
|
226
|
-
function
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
253
|
+
function debounce(action, options) {
|
|
254
|
+
const wait = typeof options === "object" && "wait" in options ? calcDuration(options.wait) : calcDuration(options);
|
|
255
|
+
const maxWait = typeof options === "object" && "maxWait" in options && options.maxWait !== void 0 ? calcDuration(options.maxWait) : void 0;
|
|
256
|
+
let timeout;
|
|
257
|
+
let timeoutStarted;
|
|
258
|
+
return (...args) => {
|
|
259
|
+
const now = Date.now();
|
|
260
|
+
timeoutStarted ?? (timeoutStarted = now);
|
|
261
|
+
const deadline = Math.min(
|
|
262
|
+
//
|
|
263
|
+
now + wait,
|
|
264
|
+
timeoutStarted + (maxWait ?? Number.POSITIVE_INFINITY)
|
|
265
|
+
);
|
|
266
|
+
if (timeout !== void 0) {
|
|
267
|
+
clearTimeout(timeout);
|
|
240
268
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
269
|
+
timeout = setTimeout(() => {
|
|
270
|
+
timeout = void 0;
|
|
271
|
+
timeoutStarted = void 0;
|
|
272
|
+
action(...args);
|
|
273
|
+
}, deadline - now);
|
|
274
|
+
};
|
|
244
275
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
276
|
+
const defaultEquals = (a, b) => a === b;
|
|
277
|
+
function forwardError(error) {
|
|
278
|
+
setTimeout(() => {
|
|
279
|
+
throw error;
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
function flatClone(object) {
|
|
283
|
+
if (object instanceof Map) {
|
|
284
|
+
return new Map(object);
|
|
248
285
|
}
|
|
249
|
-
if (
|
|
250
|
-
|
|
251
|
-
}
|
|
252
|
-
const index = path.indexOf(".");
|
|
253
|
-
let key, update;
|
|
254
|
-
if (index >= 0) {
|
|
255
|
-
key = path.slice(0, index);
|
|
256
|
-
const rest = path.slice(index + 1);
|
|
257
|
-
const subObj = obj[key];
|
|
258
|
-
if (!subObj) {
|
|
259
|
-
const prefix = rootPath.slice(0, -rest.length - 1);
|
|
260
|
-
throw Error(`Cannot set ${rootPath} because ${prefix} is ${subObj}`);
|
|
261
|
-
}
|
|
262
|
-
update = set(subObj, rest, value, rootPath);
|
|
263
|
-
} else {
|
|
264
|
-
key = path;
|
|
265
|
-
update = value instanceof Function ? value(obj[key]) : value;
|
|
266
|
-
}
|
|
267
|
-
if (Array.isArray(obj)) {
|
|
268
|
-
const copy = Array.from(obj);
|
|
269
|
-
copy[key] = update;
|
|
270
|
-
return copy;
|
|
286
|
+
if (object instanceof Set) {
|
|
287
|
+
return new Set(object);
|
|
271
288
|
}
|
|
272
|
-
|
|
273
|
-
...
|
|
274
|
-
|
|
275
|
-
|
|
289
|
+
if (Array.isArray(object)) {
|
|
290
|
+
return [...object];
|
|
291
|
+
}
|
|
292
|
+
if (object instanceof Object) {
|
|
293
|
+
return { ...object };
|
|
294
|
+
}
|
|
295
|
+
return object;
|
|
276
296
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
for (const key of Reflect.ownKeys(object)) {
|
|
281
|
-
properties.add([object, key]);
|
|
282
|
-
}
|
|
283
|
-
} while ((object = Reflect.getPrototypeOf(object)) && object !== Object.prototype);
|
|
284
|
-
return properties;
|
|
285
|
-
};
|
|
286
|
-
function bind(self) {
|
|
287
|
-
for (const [object, key] of getAllProperties(self.constructor.prototype)) {
|
|
288
|
-
if (key === "constructor") {
|
|
289
|
-
continue;
|
|
290
|
-
}
|
|
291
|
-
const descriptor = Reflect.getOwnPropertyDescriptor(object, key);
|
|
292
|
-
if (descriptor && typeof descriptor.value === "function") {
|
|
293
|
-
self[key] = self[key].bind(self);
|
|
294
|
-
}
|
|
297
|
+
function castArrayPath(path) {
|
|
298
|
+
if (Array.isArray(path)) {
|
|
299
|
+
return path;
|
|
295
300
|
}
|
|
301
|
+
if (path === "") {
|
|
302
|
+
return [];
|
|
303
|
+
}
|
|
304
|
+
return path.split(".");
|
|
296
305
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
return true;
|
|
306
|
+
function get(object, path) {
|
|
307
|
+
const _path = castArrayPath(path);
|
|
308
|
+
const [first, ...rest] = _path;
|
|
309
|
+
if (first === void 0 || !object) {
|
|
310
|
+
return object;
|
|
311
|
+
}
|
|
312
|
+
if (object instanceof Map) {
|
|
313
|
+
return get(object.get(first), rest);
|
|
306
314
|
}
|
|
307
|
-
if (
|
|
308
|
-
return
|
|
315
|
+
if (object instanceof Set) {
|
|
316
|
+
return get(Array.from(object)[Number(first)], rest);
|
|
309
317
|
}
|
|
310
|
-
if (
|
|
311
|
-
|
|
312
|
-
|
|
318
|
+
if (object instanceof Object) {
|
|
319
|
+
return get(object[first], rest);
|
|
320
|
+
}
|
|
321
|
+
throw new Error(`Could not get ${path} of ${object}`);
|
|
322
|
+
}
|
|
323
|
+
function set(object, path, value, rootPath = path) {
|
|
324
|
+
const _path = castArrayPath(path);
|
|
325
|
+
const [first, ...rest] = _path;
|
|
326
|
+
if (first === void 0) {
|
|
327
|
+
return value;
|
|
328
|
+
}
|
|
329
|
+
const updateChild = (child) => {
|
|
330
|
+
if (!child && rest.length > 0) {
|
|
331
|
+
const _rootPath = castArrayPath(rootPath);
|
|
332
|
+
const prefix = _rootPath.slice(0, -rest.length);
|
|
333
|
+
throw new Error(`Cannot set ${rootPath} because ${prefix.join(".")} is ${child}`);
|
|
313
334
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
335
|
+
return set(child, rest, value, rootPath);
|
|
336
|
+
};
|
|
337
|
+
if (object instanceof Map) {
|
|
338
|
+
const copy = flatClone(object);
|
|
339
|
+
const child = copy.get(first);
|
|
340
|
+
copy.set(first, updateChild(child));
|
|
341
|
+
return copy;
|
|
317
342
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
}
|
|
343
|
+
if (object instanceof Set) {
|
|
344
|
+
const copy = [...object];
|
|
345
|
+
const child = copy[Number(first)];
|
|
346
|
+
copy[Number(first)] = updateChild(child);
|
|
347
|
+
return new Set(copy);
|
|
348
|
+
}
|
|
349
|
+
if (object instanceof Object) {
|
|
350
|
+
const copy = flatClone(object);
|
|
351
|
+
copy[first] = updateChild(copy[first]);
|
|
352
|
+
return copy;
|
|
353
|
+
}
|
|
354
|
+
throw new Error(`Could not set ${path} of ${object}`);
|
|
324
355
|
}
|
|
325
356
|
function makeSelector(selector) {
|
|
326
357
|
if (!selector) {
|
|
@@ -331,74 +362,79 @@ function makeSelector(selector) {
|
|
|
331
362
|
}
|
|
332
363
|
return (x) => get(x, selector);
|
|
333
364
|
}
|
|
334
|
-
const
|
|
335
|
-
const
|
|
336
|
-
const result =
|
|
337
|
-
this.
|
|
365
|
+
const createArrayAction = (prop) => function arrayAction(...args) {
|
|
366
|
+
const newArray = this.get().slice();
|
|
367
|
+
const result = newArray[prop](...args);
|
|
368
|
+
this.set(newArray);
|
|
338
369
|
return result;
|
|
339
370
|
};
|
|
340
|
-
const
|
|
341
|
-
splice:
|
|
342
|
-
push:
|
|
343
|
-
pop:
|
|
344
|
-
shift:
|
|
345
|
-
unshift:
|
|
346
|
-
reverse:
|
|
347
|
-
sort:
|
|
371
|
+
const arrayMethods = {
|
|
372
|
+
splice: createArrayAction("splice"),
|
|
373
|
+
push: createArrayAction("push"),
|
|
374
|
+
pop: createArrayAction("pop"),
|
|
375
|
+
shift: createArrayAction("shift"),
|
|
376
|
+
unshift: createArrayAction("unshift"),
|
|
377
|
+
reverse: createArrayAction("reverse"),
|
|
378
|
+
sort: createArrayAction("sort")
|
|
348
379
|
};
|
|
349
|
-
const
|
|
350
|
-
set
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
380
|
+
const recordMethods = {
|
|
381
|
+
// set<T extends Record<any, any>, P extends Path<T>>(
|
|
382
|
+
// this: Store<T>,
|
|
383
|
+
// path: P,
|
|
384
|
+
// value: Update<Value<T, P>>,
|
|
385
|
+
// ) {
|
|
386
|
+
// if (value instanceof Function) {
|
|
387
|
+
// value = value(get(this.get(), path));
|
|
388
|
+
// }
|
|
389
|
+
// this.set(set(this.get(), path, value));
|
|
390
|
+
// return this;
|
|
391
|
+
// },
|
|
357
392
|
delete(key) {
|
|
358
393
|
const copy = { ...this.get() };
|
|
359
394
|
delete copy[key];
|
|
360
|
-
this.
|
|
395
|
+
this.set(copy);
|
|
361
396
|
},
|
|
362
397
|
clear() {
|
|
363
|
-
this.
|
|
398
|
+
this.set({});
|
|
364
399
|
}
|
|
365
400
|
};
|
|
366
|
-
const
|
|
367
|
-
set(key, value) {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
},
|
|
401
|
+
const mapMethods = {
|
|
402
|
+
// set<K, V>(this: Store<Map<K, V>>, key: K, value: UpdateFrom<V, [V | undefined]>) {
|
|
403
|
+
// if (value instanceof Function) {
|
|
404
|
+
// value = value(this.get().get(key));
|
|
405
|
+
// }
|
|
406
|
+
// const newMap = new Map(this.get());
|
|
407
|
+
// newMap.set(key, value);
|
|
408
|
+
// this.set(newMap);
|
|
409
|
+
// return this;
|
|
410
|
+
// },
|
|
376
411
|
delete(key) {
|
|
377
412
|
const newMap = new Map(this.get());
|
|
378
413
|
const result = newMap.delete(key);
|
|
379
|
-
this.
|
|
414
|
+
this.set(newMap);
|
|
380
415
|
return result;
|
|
381
416
|
},
|
|
382
417
|
clear() {
|
|
383
|
-
this.
|
|
418
|
+
this.set(/* @__PURE__ */ new Map());
|
|
384
419
|
}
|
|
385
420
|
};
|
|
386
|
-
const
|
|
421
|
+
const setMethods = {
|
|
387
422
|
add(value) {
|
|
388
423
|
const newSet = new Set(this.get());
|
|
389
424
|
newSet.add(value);
|
|
390
|
-
this.
|
|
425
|
+
this.set(newSet);
|
|
391
426
|
},
|
|
392
427
|
delete(value) {
|
|
393
428
|
const newSet = new Set(this.get());
|
|
394
429
|
newSet.delete(value);
|
|
395
|
-
this.
|
|
430
|
+
this.set(newSet);
|
|
396
431
|
},
|
|
397
432
|
clear() {
|
|
398
|
-
this.
|
|
433
|
+
this.set(/* @__PURE__ */ new Set());
|
|
399
434
|
}
|
|
400
435
|
};
|
|
401
|
-
function throttle(
|
|
436
|
+
function throttle(action, duration) {
|
|
437
|
+
const ms = calcDuration(duration);
|
|
402
438
|
let t = 0;
|
|
403
439
|
let timeout;
|
|
404
440
|
return (...args) => {
|
|
@@ -407,44 +443,96 @@ function throttle(fn, ms) {
|
|
|
407
443
|
}
|
|
408
444
|
const dt = t + ms - Date.now();
|
|
409
445
|
if (dt <= 0) {
|
|
410
|
-
|
|
446
|
+
action(...args);
|
|
411
447
|
t = Date.now();
|
|
412
448
|
return;
|
|
413
449
|
}
|
|
414
450
|
timeout = setTimeout(() => {
|
|
415
|
-
|
|
451
|
+
action(...args);
|
|
416
452
|
t = Date.now();
|
|
417
453
|
}, dt);
|
|
418
454
|
};
|
|
419
455
|
}
|
|
420
456
|
const noop = () => void 0;
|
|
421
457
|
class Store {
|
|
422
|
-
constructor(
|
|
423
|
-
this.
|
|
458
|
+
constructor(getter, options = {}, derivedFrom) {
|
|
459
|
+
this.getter = getter;
|
|
424
460
|
this.options = options;
|
|
425
|
-
this.
|
|
426
|
-
this.listeners = /* @__PURE__ */ new
|
|
461
|
+
this.derivedFrom = derivedFrom;
|
|
462
|
+
this.listeners = /* @__PURE__ */ new Map();
|
|
427
463
|
this.effects = /* @__PURE__ */ new Map();
|
|
428
464
|
this.notifyId = {};
|
|
465
|
+
this.calculationHelper = new CalculationHelper({
|
|
466
|
+
calculate: ({ use }) => {
|
|
467
|
+
if (this.getter instanceof Function) {
|
|
468
|
+
const value = this.getter.apply({ use }, [{ use }]);
|
|
469
|
+
this._value = { v: value };
|
|
470
|
+
this.notify();
|
|
471
|
+
}
|
|
472
|
+
},
|
|
473
|
+
addEffect: this.addEffect.bind(this),
|
|
474
|
+
onInvalidate: this.reset.bind(this)
|
|
475
|
+
});
|
|
429
476
|
bind(this);
|
|
477
|
+
if (!(getter instanceof Function)) {
|
|
478
|
+
this._value = { v: getter };
|
|
479
|
+
}
|
|
430
480
|
}
|
|
431
481
|
get() {
|
|
432
|
-
|
|
482
|
+
this.calculationHelper.check();
|
|
483
|
+
if (!this._value) {
|
|
484
|
+
this.calculationHelper.execute();
|
|
485
|
+
return this.get();
|
|
486
|
+
}
|
|
487
|
+
return this._value.v;
|
|
433
488
|
}
|
|
434
|
-
|
|
489
|
+
set(...args) {
|
|
490
|
+
const path = args.length > 1 ? args[0] : [];
|
|
491
|
+
let update = args.length > 1 ? args[1] : args[0];
|
|
435
492
|
if (update instanceof Function) {
|
|
436
|
-
|
|
493
|
+
const before = this.get();
|
|
494
|
+
const valueBefore = get(before, path);
|
|
495
|
+
const valueAfter = update(valueBefore);
|
|
496
|
+
update = set(before, path, valueAfter);
|
|
497
|
+
} else if (path.length > 0) {
|
|
498
|
+
update = set(this.get(), path, update);
|
|
437
499
|
}
|
|
438
|
-
this.
|
|
500
|
+
if (this.derivedFrom && this.derivedFrom.selectors.every((selector) => typeof selector === "string")) {
|
|
501
|
+
const derivationPath = this.derivedFrom.selectors.join(".");
|
|
502
|
+
this.derivedFrom.store.set((before) => set(before, derivationPath, update));
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
if (this.derivedFrom) {
|
|
506
|
+
throw new TypeError(
|
|
507
|
+
"Can only updated computed stores that are derived from other stores using string selectors"
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
this._value = { v: update };
|
|
439
511
|
this.notify();
|
|
440
512
|
}
|
|
513
|
+
reset() {
|
|
514
|
+
this._value = void 0;
|
|
515
|
+
if (this.isActive) {
|
|
516
|
+
this.calculationHelper.execute();
|
|
517
|
+
}
|
|
518
|
+
}
|
|
441
519
|
sub(listener, options) {
|
|
442
|
-
|
|
443
|
-
|
|
520
|
+
var _a;
|
|
521
|
+
const {
|
|
522
|
+
passive,
|
|
523
|
+
runNow = true,
|
|
524
|
+
throttle: throttleOption,
|
|
525
|
+
debounce: debounceOption,
|
|
526
|
+
equals = defaultEquals
|
|
527
|
+
} = options ?? {};
|
|
528
|
+
let compareToValue = (_a = this._value) == null ? void 0 : _a.v;
|
|
444
529
|
let previousValue;
|
|
445
530
|
let hasRun = false;
|
|
446
531
|
let innerListener = (force) => {
|
|
447
|
-
|
|
532
|
+
if (!this._value) {
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
const value = this._value.v;
|
|
448
536
|
if (!force && equals(value, compareToValue)) {
|
|
449
537
|
return;
|
|
450
538
|
}
|
|
@@ -459,22 +547,46 @@ class Store {
|
|
|
459
547
|
}
|
|
460
548
|
};
|
|
461
549
|
if (throttleOption) {
|
|
462
|
-
innerListener = throttle(innerListener,
|
|
550
|
+
innerListener = throttle(innerListener, throttleOption);
|
|
551
|
+
} else if (debounceOption) {
|
|
552
|
+
innerListener = debounce(innerListener, debounceOption);
|
|
553
|
+
}
|
|
554
|
+
this.listeners.set(innerListener, !passive);
|
|
555
|
+
if (!passive) {
|
|
556
|
+
this.onSubscribe();
|
|
463
557
|
}
|
|
464
|
-
this.listeners.add(innerListener);
|
|
465
|
-
this.onSubscribe();
|
|
466
558
|
if (runNow && !hasRun) {
|
|
467
559
|
innerListener(true);
|
|
468
560
|
}
|
|
469
561
|
return () => {
|
|
470
562
|
this.listeners.delete(innerListener);
|
|
471
|
-
|
|
563
|
+
if (!passive) {
|
|
564
|
+
this.onUnsubscribe();
|
|
565
|
+
}
|
|
472
566
|
};
|
|
473
567
|
}
|
|
568
|
+
once(condition = (value) => !!value) {
|
|
569
|
+
return new Promise((resolve) => {
|
|
570
|
+
let stopped = false;
|
|
571
|
+
const cancel = this.sub(
|
|
572
|
+
(value) => {
|
|
573
|
+
if (stopped || condition && !condition(value)) {
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
resolve(value);
|
|
577
|
+
stopped = true;
|
|
578
|
+
setTimeout(() => cancel());
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
runNow: !!condition
|
|
582
|
+
}
|
|
583
|
+
);
|
|
584
|
+
});
|
|
585
|
+
}
|
|
474
586
|
map(_selector, options) {
|
|
475
587
|
const selector = makeSelector(_selector);
|
|
476
588
|
const derivedFrom = { store: this, selectors: [_selector] };
|
|
477
|
-
return new
|
|
589
|
+
return new Store(
|
|
478
590
|
({ use }) => {
|
|
479
591
|
return selector(use(this, options));
|
|
480
592
|
},
|
|
@@ -482,26 +594,41 @@ class Store {
|
|
|
482
594
|
derivedFrom
|
|
483
595
|
);
|
|
484
596
|
}
|
|
597
|
+
/** Add an effect that will be executed when the store becomes active, which means when it has at least one subscriber.
|
|
598
|
+
* @param effect
|
|
599
|
+
* If there is already a subscriber, the effect will be executed immediately.
|
|
600
|
+
* Otherweise it will be executed as soon as the first subscription is created.
|
|
601
|
+
* Every time all subscriptions are removed and the first is created again, the effect will be executed again.
|
|
602
|
+
* @param retain
|
|
603
|
+
* If provided, delay tearing down effects when the last subscriber is removed. This is useful if a short gap in subscriber coverage is supposed to be ignored. E.g. when switching pages, the old page might unsubscribe, while the new page subscribes immediately after.
|
|
604
|
+
* @returns
|
|
605
|
+
* The effect can return a teardown callback, which will be executed when the last subscription is removed and potentially the ratain time has passed.
|
|
606
|
+
*/
|
|
485
607
|
addEffect(effect, retain) {
|
|
486
608
|
this.effects.set(effect, {
|
|
487
|
-
handle: this.
|
|
609
|
+
handle: this.isActive ? effect() ?? noop : void 0,
|
|
488
610
|
retain: retain !== void 0 ? calcDuration(retain) : void 0
|
|
489
611
|
});
|
|
490
612
|
return () => {
|
|
491
613
|
const { handle, timeout } = this.effects.get(effect) ?? {};
|
|
492
614
|
handle == null ? void 0 : handle();
|
|
493
|
-
timeout !== void 0
|
|
615
|
+
if (timeout !== void 0) {
|
|
616
|
+
clearTimeout(timeout);
|
|
617
|
+
}
|
|
494
618
|
this.effects.delete(effect);
|
|
495
619
|
};
|
|
496
620
|
}
|
|
621
|
+
/** Return whether the store is currently active, which means whether it has at least one subscriber. */
|
|
497
622
|
get isActive() {
|
|
498
|
-
return this.listeners.
|
|
623
|
+
return [...this.listeners.values()].some(Boolean);
|
|
499
624
|
}
|
|
500
625
|
onSubscribe() {
|
|
501
|
-
if (this.listeners.
|
|
626
|
+
if ([...this.listeners.values()].filter(Boolean).length > 1)
|
|
502
627
|
return;
|
|
503
628
|
for (const [effect, { handle, retain, timeout }] of this.effects.entries()) {
|
|
504
|
-
timeout !== void 0
|
|
629
|
+
if (timeout !== void 0) {
|
|
630
|
+
clearTimeout(timeout);
|
|
631
|
+
}
|
|
505
632
|
this.effects.set(effect, {
|
|
506
633
|
handle: handle ?? effect() ?? noop,
|
|
507
634
|
retain,
|
|
@@ -510,11 +637,15 @@ class Store {
|
|
|
510
637
|
}
|
|
511
638
|
}
|
|
512
639
|
onUnsubscribe() {
|
|
513
|
-
if (this.listeners.
|
|
640
|
+
if ([...this.listeners.values()].some(Boolean))
|
|
514
641
|
return;
|
|
515
642
|
for (const [effect, { handle, retain, timeout }] of this.effects.entries()) {
|
|
516
|
-
!retain
|
|
517
|
-
|
|
643
|
+
if (!retain) {
|
|
644
|
+
handle == null ? void 0 : handle();
|
|
645
|
+
}
|
|
646
|
+
if (timeout !== void 0) {
|
|
647
|
+
clearTimeout(timeout);
|
|
648
|
+
}
|
|
518
649
|
this.effects.set(effect, {
|
|
519
650
|
handle: retain ? handle : void 0,
|
|
520
651
|
retain,
|
|
@@ -523,8 +654,10 @@ class Store {
|
|
|
523
654
|
}
|
|
524
655
|
}
|
|
525
656
|
notify() {
|
|
526
|
-
const n =
|
|
527
|
-
|
|
657
|
+
const n = {};
|
|
658
|
+
this.notifyId = n;
|
|
659
|
+
const snapshot = [...this.listeners.keys()];
|
|
660
|
+
for (const listener of snapshot) {
|
|
528
661
|
listener();
|
|
529
662
|
if (n !== this.notifyId)
|
|
530
663
|
break;
|
|
@@ -532,75 +665,27 @@ class Store {
|
|
|
532
665
|
}
|
|
533
666
|
}
|
|
534
667
|
const defaultOptions = {};
|
|
535
|
-
function
|
|
668
|
+
function create(initialState, options) {
|
|
669
|
+
const store = new Store(initialState, options);
|
|
536
670
|
if (initialState instanceof Function) {
|
|
537
|
-
return
|
|
671
|
+
return store;
|
|
538
672
|
}
|
|
539
673
|
let methods = options == null ? void 0 : options.methods;
|
|
540
674
|
if (initialState instanceof Map) {
|
|
541
|
-
methods = { ...
|
|
675
|
+
methods = { ...mapMethods, ...methods };
|
|
542
676
|
} else if (initialState instanceof Set) {
|
|
543
|
-
methods = { ...
|
|
677
|
+
methods = { ...setMethods, ...methods };
|
|
544
678
|
} else if (Array.isArray(initialState)) {
|
|
545
|
-
methods = { ...
|
|
679
|
+
methods = { ...arrayMethods, ...methods };
|
|
546
680
|
} else if (initialState instanceof Object) {
|
|
547
|
-
methods = { ...
|
|
681
|
+
methods = { ...recordMethods, ...methods };
|
|
548
682
|
}
|
|
549
|
-
const
|
|
550
|
-
|
|
551
|
-
Object.entries(methods ?? {}).filter(([name]) => !(name in store2)).map(([name, fn]) => [name, fn.bind(store2)])
|
|
683
|
+
const boundMethods = Object.fromEntries(
|
|
684
|
+
Object.entries(methods ?? {}).filter(([name]) => !(name in store)).map(([name, action]) => [name, action.bind(store)])
|
|
552
685
|
);
|
|
553
|
-
return Object.assign(
|
|
554
|
-
}
|
|
555
|
-
const store = Object.assign(_store, { defaultOptions });
|
|
556
|
-
class DerivedStore extends Store {
|
|
557
|
-
constructor(calculate, options = {}, derivedFrom) {
|
|
558
|
-
super(void 0);
|
|
559
|
-
this.calculate = calculate;
|
|
560
|
-
this.options = options;
|
|
561
|
-
this.derivedFrom = derivedFrom;
|
|
562
|
-
this.calculationHelper = new CalculationHelper({
|
|
563
|
-
calculate: ({ use }) => {
|
|
564
|
-
const value = this.calculate.apply({ use }, [{ use }]);
|
|
565
|
-
this.valid = true;
|
|
566
|
-
super.update(value);
|
|
567
|
-
},
|
|
568
|
-
addEffect: this.addEffect,
|
|
569
|
-
getValue: () => this.value,
|
|
570
|
-
onInvalidate: this.invalidate
|
|
571
|
-
});
|
|
572
|
-
this.valid = false;
|
|
573
|
-
}
|
|
574
|
-
get() {
|
|
575
|
-
this.calculationHelper.check();
|
|
576
|
-
if (!this.valid) {
|
|
577
|
-
this.calculationHelper.execute();
|
|
578
|
-
}
|
|
579
|
-
return super.get();
|
|
580
|
-
}
|
|
581
|
-
update(update) {
|
|
582
|
-
if (this.derivedFrom && this.derivedFrom.selectors.every((selector) => typeof selector === "string")) {
|
|
583
|
-
const path = this.derivedFrom.selectors.join(".");
|
|
584
|
-
if (update instanceof Function) {
|
|
585
|
-
const before = this.get();
|
|
586
|
-
update = update(before);
|
|
587
|
-
}
|
|
588
|
-
this.derivedFrom.store.update((before) => set(before, path, update));
|
|
589
|
-
} else {
|
|
590
|
-
throw new Error("Can only updated computed stores that are derived from other stores using string selectors");
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
invalidate() {
|
|
594
|
-
this.valid = false;
|
|
595
|
-
if (this.isActive) {
|
|
596
|
-
this.calculationHelper.execute();
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
function _derivedStore(calculate, options) {
|
|
601
|
-
return new DerivedStore(calculate, options);
|
|
686
|
+
return Object.assign(store, boundMethods);
|
|
602
687
|
}
|
|
603
|
-
const
|
|
688
|
+
const createStore = Object.assign(create, { defaultOptions });
|
|
604
689
|
function hash(value) {
|
|
605
690
|
if (value instanceof Set) {
|
|
606
691
|
return `s[${[...value].map(hash).sort().join(",")}]`;
|
|
@@ -608,7 +693,7 @@ function hash(value) {
|
|
|
608
693
|
if (value instanceof Map) {
|
|
609
694
|
return `m[${[...value.entries()].map(hash).sort().join(",")}]`;
|
|
610
695
|
}
|
|
611
|
-
if (value
|
|
696
|
+
if (Array.isArray(value)) {
|
|
612
697
|
return `[${value.map(hash).join(",")}]`;
|
|
613
698
|
}
|
|
614
699
|
if (value instanceof Object) {
|
|
@@ -616,18 +701,15 @@ function hash(value) {
|
|
|
616
701
|
}
|
|
617
702
|
return JSON.stringify(value);
|
|
618
703
|
}
|
|
619
|
-
exports.CalculationHelper = CalculationHelper;
|
|
620
704
|
exports.Store = Store;
|
|
621
|
-
exports.
|
|
705
|
+
exports.arrayMethods = arrayMethods;
|
|
706
|
+
exports.bind = bind;
|
|
622
707
|
exports.calcDuration = calcDuration;
|
|
623
|
-
exports.
|
|
624
|
-
exports.derivedStore = derivedStore;
|
|
708
|
+
exports.createStore = createStore;
|
|
625
709
|
exports.hash = hash;
|
|
626
710
|
exports.makeSelector = makeSelector;
|
|
627
|
-
exports.
|
|
628
|
-
exports.
|
|
629
|
-
exports.
|
|
630
|
-
exports.simpleShallowEquals = simpleShallowEquals;
|
|
631
|
-
exports.store = store;
|
|
711
|
+
exports.mapMethods = mapMethods;
|
|
712
|
+
exports.recordMethods = recordMethods;
|
|
713
|
+
exports.setMethods = setMethods;
|
|
632
714
|
exports.trackingProxy = trackingProxy;
|
|
633
715
|
//# sourceMappingURL=hash.cjs.map
|