cross-state 0.6.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.
Files changed (52) hide show
  1. package/README.md +63 -0
  2. package/dist/cjs/hash.cjs +632 -0
  3. package/dist/cjs/hash.cjs.map +1 -0
  4. package/dist/cjs/immer.cjs +10 -0
  5. package/dist/cjs/immer.cjs.map +1 -0
  6. package/dist/cjs/index.cjs +286 -0
  7. package/dist/cjs/index.cjs.map +1 -0
  8. package/dist/cjs/react.cjs +220 -0
  9. package/dist/cjs/react.cjs.map +1 -0
  10. package/dist/es/hash.mjs +633 -0
  11. package/dist/es/hash.mjs.map +1 -0
  12. package/dist/es/immer.mjs +10 -0
  13. package/dist/es/immer.mjs.map +1 -0
  14. package/dist/es/index.mjs +287 -0
  15. package/dist/es/index.mjs.map +1 -0
  16. package/dist/es/react.mjs +220 -0
  17. package/dist/es/react.mjs.map +1 -0
  18. package/dist/types/core/commonTypes.d.ts +51 -0
  19. package/dist/types/core/derivedStore.d.ts +39 -0
  20. package/dist/types/core/fetchStore.d.ts +76 -0
  21. package/dist/types/core/index.d.ts +10 -0
  22. package/dist/types/core/once.d.ts +13 -0
  23. package/dist/types/core/resourceGroup.d.ts +9 -0
  24. package/dist/types/core/store.d.ts +58 -0
  25. package/dist/types/core/storeScope.d.ts +4 -0
  26. package/dist/types/immer/immerActions.d.ts +5 -0
  27. package/dist/types/immer/index.d.ts +1 -0
  28. package/dist/types/index.d.ts +4 -0
  29. package/dist/types/lib/bind.d.ts +1 -0
  30. package/dist/types/lib/cache.d.ts +17 -0
  31. package/dist/types/lib/calcDuration.d.ts +2 -0
  32. package/dist/types/lib/calculationHelper.d.ts +22 -0
  33. package/dist/types/lib/diff.d.ts +7 -0
  34. package/dist/types/lib/equals.d.ts +3 -0
  35. package/dist/types/lib/forwardError.d.ts +1 -0
  36. package/dist/types/lib/hash.d.ts +1 -0
  37. package/dist/types/lib/makeSelector.d.ts +1 -0
  38. package/dist/types/lib/maybePromise.d.ts +1 -0
  39. package/dist/types/lib/propAccess.d.ts +13 -0
  40. package/dist/types/lib/queue.d.ts +9 -0
  41. package/dist/types/lib/storeActions.d.ts +26 -0
  42. package/dist/types/lib/throttle.d.ts +1 -0
  43. package/dist/types/lib/trackingProxy.d.ts +2 -0
  44. package/dist/types/lib/unwrapPromise.d.ts +1 -0
  45. package/dist/types/react/index.d.ts +5 -0
  46. package/dist/types/react/read.d.ts +4 -0
  47. package/dist/types/react/storeScope.d.ts +12 -0
  48. package/dist/types/react/useProp.d.ts +4 -0
  49. package/dist/types/react/useStore.d.ts +4 -0
  50. package/package.json +112 -0
  51. package/react.d.ts +1 -0
  52. package/react.js +1 -0
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ [![npm badge](https://badgen.net/npm/v/schummar-state)](https://www.npmjs.com/package/schummar-state)
2
+ [![bundlephobia badge](https://badgen.net/bundlephobia/minzip/schummar-state)](https://bundlephobia.com/result?p=schummar-state)
3
+
4
+ Lighweight React hooks based state library.
5
+ Heavily inspired by [pullstate](https://github.com/lostpebble/pullstate)
6
+
7
+ # Getting started
8
+
9
+ ### Install
10
+
11
+ ```
12
+ npm install schummar-state
13
+ ```
14
+
15
+ ### Create a store
16
+
17
+ ```ts
18
+ import { Store } from 'schummar-state';
19
+
20
+ export const store = new Store({
21
+ counter: 0,
22
+ });
23
+ ```
24
+
25
+ You can easily use multiple stores in parallel.
26
+
27
+ ### Use store in a component
28
+
29
+ ```tsx
30
+ import store from './store.ts';
31
+
32
+ export function App() {
33
+ const counter = store.useState((state) => state.counter);
34
+
35
+ return (
36
+ <div>
37
+ <div>Counter: {counter}</div>
38
+ </div>
39
+ );
40
+ }
41
+ ```
42
+
43
+ ### Update a store
44
+
45
+ ```tsx
46
+ import store from './store.ts';
47
+
48
+ export function App() {
49
+ const counter = store.useState((state) => state.counter);
50
+
51
+ const increment = () =>
52
+ store.update((state) => {
53
+ state.counter++;
54
+ });
55
+
56
+ return (
57
+ <div>
58
+ <div>Counter: {counter}</div>
59
+ <button onClick={increment}>Increment</button>
60
+ </div>
61
+ );
62
+ }
63
+ ```
@@ -0,0 +1,632 @@
1
+ "use strict";
2
+ function queue() {
3
+ const q = [];
4
+ let promise, resolve;
5
+ let active = false;
6
+ const run = async () => {
7
+ if (!active) {
8
+ active = true;
9
+ let next;
10
+ while (next = q.shift()) {
11
+ try {
12
+ let result = next.action();
13
+ if (result instanceof Promise) {
14
+ result = await result;
15
+ }
16
+ next.resolve(result);
17
+ } catch (e) {
18
+ next.reject(e);
19
+ }
20
+ }
21
+ active = false;
22
+ resolve == null ? void 0 : resolve();
23
+ }
24
+ };
25
+ return Object.assign(
26
+ (action) => {
27
+ return new Promise((resolve2, reject) => {
28
+ q.push({ action, resolve: resolve2, reject });
29
+ run();
30
+ });
31
+ },
32
+ {
33
+ clear() {
34
+ q.length = 0;
35
+ resolve == null ? void 0 : resolve();
36
+ },
37
+ get whenDone() {
38
+ if (!promise) {
39
+ promise = new Promise((r) => {
40
+ resolve = () => {
41
+ promise = void 0;
42
+ resolve = void 0;
43
+ r();
44
+ };
45
+ });
46
+ }
47
+ return promise;
48
+ }
49
+ }
50
+ );
51
+ }
52
+ const ProxyKeys = ["get", "getOwnPropertyDescriptor", "getPrototypeOf", "has", "isExtensible", "ownKeys"];
53
+ const isPlainObject = (value) => typeof value === "object" && value !== null && Object.getPrototypeOf(value) === Object.prototype;
54
+ function trackingProxy(value) {
55
+ if (!isPlainObject(value) && !Array.isArray(value)) {
56
+ return [value, (other) => other === value];
57
+ }
58
+ const deps = new Array();
59
+ const proxy = new Proxy(
60
+ value,
61
+ Object.fromEntries(
62
+ ProxyKeys.map((key) => [
63
+ key,
64
+ (value2, ...args) => {
65
+ const fn = Reflect[key];
66
+ const [proxiedValue, equals] = trackingProxy(fn(value2, ...args));
67
+ deps.push((otherValue) => {
68
+ if (!isPlainObject(otherValue) && !Array.isArray(otherValue)) {
69
+ return false;
70
+ }
71
+ return equals(fn(otherValue, ...args));
72
+ });
73
+ return proxiedValue;
74
+ }
75
+ ])
76
+ )
77
+ );
78
+ return [proxy, (other) => !!other && deps.every((equals) => equals(other))];
79
+ }
80
+ class CalculationHelper {
81
+ constructor(options) {
82
+ this.options = options;
83
+ options.addEffect(() => {
84
+ if (this.current) {
85
+ this.current.check();
86
+ } else {
87
+ this.execute();
88
+ }
89
+ });
90
+ }
91
+ execute() {
92
+ this.stop();
93
+ const { calculate, addEffect, getValue, setValue, setError, onInvalidate } = this.options;
94
+ const checks = new Array();
95
+ const deps = /* @__PURE__ */ new Map();
96
+ const q = queue();
97
+ let isActive = false;
98
+ let isCancled = false;
99
+ const cancelEffect = addEffect(() => {
100
+ isActive = true;
101
+ for (const dep of deps.values()) {
102
+ dep.on();
103
+ }
104
+ return () => {
105
+ isActive = false;
106
+ for (const dep of deps.values()) {
107
+ dep.off();
108
+ }
109
+ };
110
+ });
111
+ const cancel = () => {
112
+ isCancled = true;
113
+ cancelSubscription == null ? void 0 : cancelSubscription();
114
+ cancelEffect();
115
+ delete this.current;
116
+ };
117
+ const check = () => {
118
+ if (!checks.every((check2) => check2())) {
119
+ cancel();
120
+ onInvalidate == null ? void 0 : onInvalidate();
121
+ }
122
+ };
123
+ const use = (store2, { disableProxy } = {}) => {
124
+ if (isCancled) {
125
+ return store2.get();
126
+ }
127
+ let value = store2.get();
128
+ let equals = (newValue) => {
129
+ return newValue === value;
130
+ };
131
+ if (!disableProxy) {
132
+ [value, equals] = trackingProxy(value);
133
+ }
134
+ let sub;
135
+ const dep = {
136
+ on() {
137
+ this.off();
138
+ sub = store2.sub(check, { runNow: false });
139
+ },
140
+ off() {
141
+ sub == null ? void 0 : sub();
142
+ 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
+ },
164
+ off() {
165
+ sub == null ? void 0 : sub();
166
+ sub = void 0;
167
+ }
168
+ };
169
+ if (isActive) {
170
+ dep.on();
171
+ }
172
+ checks.push(() => {
173
+ return store2.get().ref === ref;
174
+ });
175
+ deps.set(store2, dep);
176
+ return value;
177
+ };
178
+ const updateValue = (update) => q(async () => {
179
+ if (isCancled) {
180
+ return;
181
+ }
182
+ if (update instanceof Function) {
183
+ try {
184
+ update = update(getValue());
185
+ } catch (error) {
186
+ setError == null ? void 0 : setError(error);
187
+ return;
188
+ }
189
+ }
190
+ if (update instanceof Promise) {
191
+ try {
192
+ update = await update;
193
+ } catch (error) {
194
+ if (!isCancled) {
195
+ setError == null ? void 0 : setError(error);
196
+ }
197
+ return;
198
+ }
199
+ }
200
+ if (!isCancled) {
201
+ setValue == null ? void 0 : setValue(update);
202
+ }
203
+ });
204
+ const updateError = (error) => q(() => {
205
+ if (!isCancled) {
206
+ setError == null ? void 0 : setError(error);
207
+ }
208
+ });
209
+ let cancelSubscription;
210
+ try {
211
+ cancelSubscription = calculate({ use, useFetch, updateValue, updateError });
212
+ } catch (error) {
213
+ setError == null ? void 0 : setError(error);
214
+ }
215
+ this.current = { cancel, check };
216
+ }
217
+ stop() {
218
+ var _a;
219
+ (_a = this.current) == null ? void 0 : _a.cancel();
220
+ }
221
+ check() {
222
+ var _a;
223
+ (_a = this.current) == null ? void 0 : _a.check();
224
+ }
225
+ }
226
+ function get(obj, path) {
227
+ if (path === "") {
228
+ return obj;
229
+ }
230
+ if (!(obj instanceof Object)) {
231
+ throw new Error(`Could not get ${path} of ${obj}`);
232
+ }
233
+ const index = path.indexOf(".");
234
+ if (index >= 0) {
235
+ const key = path.slice(0, index);
236
+ const rest = path.slice(index + 1);
237
+ const subObj = obj[key];
238
+ if (!subObj) {
239
+ return void 0;
240
+ }
241
+ return get(subObj, rest);
242
+ }
243
+ return obj[path];
244
+ }
245
+ function set(obj, path, value, rootPath = path) {
246
+ if (path === "") {
247
+ return value;
248
+ }
249
+ if (!(obj instanceof Object)) {
250
+ throw new Error(`Could not set ${path} of ${obj}`);
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;
271
+ }
272
+ return {
273
+ ...obj,
274
+ [key]: update
275
+ };
276
+ }
277
+ function makeSelector(selector) {
278
+ if (!selector) {
279
+ return (x) => x;
280
+ }
281
+ if (selector instanceof Function) {
282
+ return selector;
283
+ }
284
+ return (x) => get(x, selector);
285
+ }
286
+ const getAllProperties = (object) => {
287
+ const properties = /* @__PURE__ */ new Set();
288
+ do {
289
+ for (const key of Reflect.ownKeys(object)) {
290
+ properties.add([object, key]);
291
+ }
292
+ } while ((object = Reflect.getPrototypeOf(object)) && object !== Object.prototype);
293
+ return properties;
294
+ };
295
+ function bind(self) {
296
+ for (const [object, key] of getAllProperties(self.constructor.prototype)) {
297
+ if (key === "constructor") {
298
+ continue;
299
+ }
300
+ const descriptor = Reflect.getOwnPropertyDescriptor(object, key);
301
+ if (descriptor && typeof descriptor.value === "function") {
302
+ self[key] = self[key].bind(self);
303
+ }
304
+ }
305
+ }
306
+ const calcDuration = (t) => {
307
+ if (typeof t === "number")
308
+ return t;
309
+ 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;
310
+ };
311
+ const defaultEquals = (a, b) => a === b;
312
+ const simpleShallowEquals = (a, b) => {
313
+ if (a === b) {
314
+ return true;
315
+ }
316
+ if (Array.isArray(a) && Array.isArray(b)) {
317
+ return a.length === b.length && a.every((value, i) => value === b[i]);
318
+ }
319
+ if (typeof a === "object" && typeof b === "object") {
320
+ if (a === null || b === null) {
321
+ return false;
322
+ }
323
+ const e1 = Object.entries(a);
324
+ const e2 = Object.entries(b);
325
+ return e1.length === e2.length && e1.every(([key, value]) => value === b[key]);
326
+ }
327
+ return false;
328
+ };
329
+ function forwardError(error) {
330
+ setTimeout(() => {
331
+ throw error;
332
+ });
333
+ }
334
+ const arrMod = (prop) => function(...args) {
335
+ const newArr = this.get().slice();
336
+ const result = newArr[prop](...args);
337
+ this.update(newArr);
338
+ return result;
339
+ };
340
+ const arrayActions = {
341
+ splice: arrMod("splice"),
342
+ push: arrMod("push"),
343
+ pop: arrMod("pop"),
344
+ shift: arrMod("shift"),
345
+ unshift: arrMod("unshift"),
346
+ reverse: arrMod("reverse"),
347
+ sort: arrMod("sort")
348
+ };
349
+ const recordActions = {
350
+ set(key, value) {
351
+ if (value instanceof Function) {
352
+ value = value(this.get()[key]);
353
+ }
354
+ this.update({ ...this.get(), [key]: value });
355
+ return this;
356
+ },
357
+ delete(key) {
358
+ const copy = { ...this.get() };
359
+ delete copy[key];
360
+ this.update(copy);
361
+ },
362
+ clear() {
363
+ this.update({});
364
+ }
365
+ };
366
+ const mapActions = {
367
+ set(key, value) {
368
+ const newMap = new Map(this.get());
369
+ newMap.set(key, value);
370
+ this.update(newMap);
371
+ return this;
372
+ },
373
+ delete(key) {
374
+ const newMap = new Map(this.get());
375
+ const result = newMap.delete(key);
376
+ this.update(newMap);
377
+ return result;
378
+ },
379
+ clear() {
380
+ this.update(/* @__PURE__ */ new Map());
381
+ }
382
+ };
383
+ const setActions = {
384
+ add(value) {
385
+ const newSet = new Set(this.get());
386
+ newSet.add(value);
387
+ this.update(newSet);
388
+ },
389
+ delete(value) {
390
+ const newSet = new Set(this.get());
391
+ newSet.delete(value);
392
+ this.update(newSet);
393
+ },
394
+ clear() {
395
+ this.update(/* @__PURE__ */ new Set());
396
+ }
397
+ };
398
+ function throttle(fn, ms) {
399
+ let t = 0;
400
+ let timeout;
401
+ return (...args) => {
402
+ if (timeout !== void 0) {
403
+ clearTimeout(timeout);
404
+ }
405
+ const dt = t + ms - Date.now();
406
+ if (dt <= 0) {
407
+ fn(...args);
408
+ t = Date.now();
409
+ return;
410
+ }
411
+ timeout = setTimeout(() => {
412
+ fn(...args);
413
+ t = Date.now();
414
+ }, dt);
415
+ };
416
+ }
417
+ const noop = () => void 0;
418
+ class Store {
419
+ constructor(initialValue, options = {}) {
420
+ this.initialValue = initialValue;
421
+ this.options = options;
422
+ this.value = this.initialValue;
423
+ this.listeners = /* @__PURE__ */ new Set();
424
+ this.effects = /* @__PURE__ */ new Map();
425
+ this.notifyId = {};
426
+ bind(this);
427
+ }
428
+ get() {
429
+ return this.value;
430
+ }
431
+ update(update) {
432
+ if (update instanceof Function) {
433
+ update = update(this.get());
434
+ }
435
+ this.value = update;
436
+ this.notify();
437
+ }
438
+ sub(listener, options) {
439
+ const { runNow = true, throttle: throttleOption, equals = defaultEquals } = options ?? {};
440
+ let compareToValue = this.get();
441
+ let previousValue;
442
+ let hasRun = false;
443
+ let innerListener = (force) => {
444
+ const value = this.get();
445
+ if (!force && equals(value, compareToValue)) {
446
+ return;
447
+ }
448
+ compareToValue = value;
449
+ const _previousValue = previousValue;
450
+ previousValue = value;
451
+ hasRun = true;
452
+ try {
453
+ listener(value, _previousValue);
454
+ } catch (error) {
455
+ forwardError(error);
456
+ }
457
+ };
458
+ if (throttleOption) {
459
+ innerListener = throttle(innerListener, calcDuration(throttleOption));
460
+ }
461
+ this.listeners.add(innerListener);
462
+ this.onSubscribe();
463
+ if (runNow && !hasRun) {
464
+ innerListener(true);
465
+ }
466
+ return () => {
467
+ this.listeners.delete(innerListener);
468
+ this.onUnsubscribe();
469
+ };
470
+ }
471
+ map(_selector, options) {
472
+ const selector = makeSelector(_selector);
473
+ const derivedFrom = { store: this, selectors: [_selector] };
474
+ return new DerivedStore(({ use }) => {
475
+ return selector(use(this, options));
476
+ }, derivedFrom);
477
+ }
478
+ addEffect(effect, retain) {
479
+ this.effects.set(effect, {
480
+ handle: this.listeners.size > 0 ? effect() ?? noop : void 0,
481
+ retain: retain !== void 0 ? calcDuration(retain) : void 0
482
+ });
483
+ return () => {
484
+ const { handle, timeout } = this.effects.get(effect) ?? {};
485
+ handle == null ? void 0 : handle();
486
+ timeout !== void 0 && clearTimeout(timeout);
487
+ this.effects.delete(effect);
488
+ };
489
+ }
490
+ get isActive() {
491
+ return this.listeners.size > 0;
492
+ }
493
+ onSubscribe() {
494
+ if (this.listeners.size > 1)
495
+ return;
496
+ for (const [effect, { handle, retain, timeout }] of this.effects.entries()) {
497
+ timeout !== void 0 && clearTimeout(timeout);
498
+ this.effects.set(effect, {
499
+ handle: handle ?? effect() ?? noop,
500
+ retain,
501
+ timeout: void 0
502
+ });
503
+ }
504
+ }
505
+ onUnsubscribe() {
506
+ if (this.listeners.size > 0)
507
+ return;
508
+ for (const [effect, { handle, retain, timeout }] of this.effects.entries()) {
509
+ !retain && (handle == null ? void 0 : handle());
510
+ timeout !== void 0 && clearTimeout(timeout);
511
+ this.effects.set(effect, {
512
+ handle: retain ? handle : void 0,
513
+ retain,
514
+ timeout: retain && handle ? setTimeout(handle, retain) : void 0
515
+ });
516
+ }
517
+ }
518
+ notify() {
519
+ const n = this.notifyId = {};
520
+ for (const listener of [...this.listeners]) {
521
+ listener();
522
+ if (n !== this.notifyId)
523
+ break;
524
+ }
525
+ }
526
+ }
527
+ const defaultOptions = {};
528
+ function _store(initialState, options) {
529
+ if (initialState instanceof Function) {
530
+ return new DerivedStore(initialState);
531
+ }
532
+ let methods = options == null ? void 0 : options.methods;
533
+ if (initialState instanceof Map) {
534
+ methods = { ...mapActions, ...methods };
535
+ } else if (initialState instanceof Set) {
536
+ methods = { ...setActions, ...methods };
537
+ } else if (Array.isArray(initialState)) {
538
+ methods = { ...arrayActions, ...methods };
539
+ } else if (initialState instanceof Object) {
540
+ methods = { ...recordActions, ...methods };
541
+ }
542
+ const store2 = new Store(initialState, options);
543
+ const boundActions = Object.fromEntries(
544
+ Object.entries(methods ?? {}).filter(([name]) => !(name in store2)).map(([name, fn]) => [name, fn.bind(store2)])
545
+ );
546
+ return Object.assign(store2, boundActions);
547
+ }
548
+ const store = Object.assign(_store, { defaultOptions });
549
+ class DerivedStore extends Store {
550
+ constructor(calculate, derivedFrom) {
551
+ super(void 0);
552
+ this.calculate = calculate;
553
+ this.derivedFrom = derivedFrom;
554
+ this.calculationHelper = new CalculationHelper({
555
+ calculate: ({ use }) => {
556
+ const value = this.calculate.apply({ use }, [{ use }]);
557
+ this.valid = true;
558
+ super.update(value);
559
+ },
560
+ addEffect: this.addEffect,
561
+ getValue: () => this.value,
562
+ onInvalidate: this.invalidate
563
+ });
564
+ this.valid = false;
565
+ }
566
+ get() {
567
+ if (!this.valid) {
568
+ this.calculationHelper.execute();
569
+ }
570
+ return super.get();
571
+ }
572
+ update(update) {
573
+ if (this.derivedFrom && this.derivedFrom.selectors.every((selector) => typeof selector === "string")) {
574
+ const path = this.derivedFrom.selectors.join(".");
575
+ if (update instanceof Function) {
576
+ const before = get(this.derivedFrom.store, path);
577
+ update = update(before);
578
+ }
579
+ this.derivedFrom.store.update((before) => set(before, path, update));
580
+ } else {
581
+ throw new Error("Can only updated computed stores that are derived from other stores using string selectors");
582
+ }
583
+ }
584
+ map(_selector) {
585
+ const selector = makeSelector(_selector);
586
+ const derivedFrom = this.derivedFrom ?? { store: this, selectors: [] };
587
+ const newDerivedFrom = { ...derivedFrom, selectors: derivedFrom.selectors.concat(_selector) };
588
+ return new DerivedStore(({ use }) => {
589
+ return selector(use(this));
590
+ }, newDerivedFrom);
591
+ }
592
+ invalidate() {
593
+ this.valid = false;
594
+ if (this.isActive) {
595
+ this.calculationHelper.execute();
596
+ }
597
+ }
598
+ }
599
+ function _derivedStore(calculate) {
600
+ return new DerivedStore(calculate);
601
+ }
602
+ const derivedStore = Object.assign(_derivedStore, {});
603
+ function hash(value) {
604
+ if (value instanceof Set) {
605
+ return `s[${[...value].map(hash).sort().join(",")}]`;
606
+ }
607
+ if (value instanceof Map) {
608
+ return `m[${[...value.entries()].map(hash).sort().join(",")}]`;
609
+ }
610
+ if (value instanceof Array) {
611
+ return `[${value.map(hash).join(",")}]`;
612
+ }
613
+ if (value instanceof Object) {
614
+ return `o[${Object.entries(value).map(hash).sort().join(",")}]`;
615
+ }
616
+ return JSON.stringify(value);
617
+ }
618
+ exports.CalculationHelper = CalculationHelper;
619
+ exports.Store = Store;
620
+ exports.arrayActions = arrayActions;
621
+ exports.calcDuration = calcDuration;
622
+ exports.defaultEquals = defaultEquals;
623
+ exports.derivedStore = derivedStore;
624
+ exports.hash = hash;
625
+ exports.makeSelector = makeSelector;
626
+ exports.mapActions = mapActions;
627
+ exports.recordActions = recordActions;
628
+ exports.setActions = setActions;
629
+ exports.simpleShallowEquals = simpleShallowEquals;
630
+ exports.store = store;
631
+ exports.trackingProxy = trackingProxy;
632
+ //# sourceMappingURL=hash.cjs.map