valdres 1.0.0-beta.6 → 1.0.0-beta.8
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/index.js +723 -152
- package/dist/types/index.d.ts +5 -0
- package/dist/types/lib/atomFamilyIndex.d.ts +3 -1
- package/dist/types/lib/createStoreData.d.ts +4 -0
- package/dist/types/lib/notifyChangeListeners.d.ts +96 -0
- package/dist/types/lib/onStoreChange.d.ts +15 -0
- package/dist/types/lib/propagateUpdatedAtoms.d.ts +5 -4
- package/dist/types/lib/resolveAtomDefaultValue.d.ts +3 -0
- package/dist/types/lib/setAtoms.d.ts +2 -1
- package/dist/types/lib/setValueInData.d.ts +2 -4
- package/dist/types/lib/snapshot.d.ts +7 -0
- package/dist/types/lib/trackScopeValue.d.ts +10 -0
- package/dist/types/lib/transaction.d.ts +9 -1
- package/dist/types/lib/unsetValue.d.ts +50 -0
- package/dist/types/store.d.ts +3 -1
- package/dist/types/types/Atom.d.ts +6 -0
- package/dist/types/types/Selector.d.ts +5 -0
- package/dist/types/types/SnapshotEntry.d.ts +24 -0
- package/dist/types/types/Store.d.ts +60 -1
- package/dist/types/types/StoreChange.d.ts +62 -0
- package/dist/types/types/StoreChangeCallback.d.ts +16 -0
- package/dist/types/types/StoreChangeMeta.d.ts +11 -0
- package/dist/types/types/StoreChangeSource.d.ts +21 -0
- package/dist/types/types/StoreData.d.ts +22 -1
- package/dist/types/types/Subscription.d.ts +7 -0
- package/dist/types/types/TransactionInterface.d.ts +4 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -108,6 +108,11 @@ var isSelector = (state) => state && Object.hasOwn(state, "get");
|
|
|
108
108
|
// src/utils/isAtomFamily.ts
|
|
109
109
|
var isAtomFamily = (state) => state && Object.hasOwn(state, "__valdresAtomFamilyMap");
|
|
110
110
|
|
|
111
|
+
// src/utils/isPromiseLike.ts
|
|
112
|
+
var isPromiseLike = (object) => {
|
|
113
|
+
return object && object.then && typeof object.then === "function";
|
|
114
|
+
};
|
|
115
|
+
|
|
111
116
|
// src/utils/isFamilyState.ts
|
|
112
117
|
var isFamilyState = (state) => state && Object.hasOwn(state, "family");
|
|
113
118
|
|
|
@@ -117,45 +122,7 @@ var isFamilyAtom = (state) => isFamilyState(state) && isAtom(state);
|
|
|
117
122
|
// src/utils/isSelectorFamily.ts
|
|
118
123
|
var isSelectorFamily = (state) => state && Object.hasOwn(state, "__valdresSelectorFamilyMap");
|
|
119
124
|
|
|
120
|
-
// src/
|
|
121
|
-
var isPromiseLike = (object) => {
|
|
122
|
-
return object && object.then && typeof object.then === "function";
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
// src/utils/deepFreeze.ts
|
|
126
|
-
var deepFreeze = (obj, seen) => {
|
|
127
|
-
if (obj === null || obj === undefined)
|
|
128
|
-
return obj;
|
|
129
|
-
if (typeof obj !== "object" && typeof obj !== "function")
|
|
130
|
-
return obj;
|
|
131
|
-
if (Object.isFrozen(obj) || seen?.has(obj))
|
|
132
|
-
return obj;
|
|
133
|
-
if (Array.isArray(obj)) {
|
|
134
|
-
for (const item of obj) {
|
|
135
|
-
if (item && typeof item === "object") {
|
|
136
|
-
seen ??= new WeakSet;
|
|
137
|
-
seen.add(obj);
|
|
138
|
-
deepFreeze(item, seen);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
} else {
|
|
142
|
-
const propNames = Object.getOwnPropertyNames(obj);
|
|
143
|
-
for (const name of propNames) {
|
|
144
|
-
const value = obj[name];
|
|
145
|
-
if (value && typeof value === "object") {
|
|
146
|
-
seen ??= new WeakSet;
|
|
147
|
-
seen.add(obj);
|
|
148
|
-
deepFreeze(value, seen);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
return Object.freeze(obj);
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
// src/lib/IS_PROD.ts
|
|
156
|
-
var IS_PROD = typeof process !== "undefined" && process.env != null && process.env.NODE_ENV === "production";
|
|
157
|
-
|
|
158
|
-
// src/lib/setValueInData.ts
|
|
125
|
+
// src/lib/trackScopeValue.ts
|
|
159
126
|
var trackScopeValue = (key, data) => {
|
|
160
127
|
const parent = data.parent;
|
|
161
128
|
const indexKeys = data.scopeIndexKeys;
|
|
@@ -170,30 +137,6 @@ var trackScopeValue = (key, data) => {
|
|
|
170
137
|
set.add(data);
|
|
171
138
|
indexKeys.add(key);
|
|
172
139
|
};
|
|
173
|
-
var setValueInData = (atom, value, data) => {
|
|
174
|
-
const isNewAtomInScope = data.parent && Object.hasOwn(atom, "defaultValue") && !data.values.has(atom);
|
|
175
|
-
let written;
|
|
176
|
-
if (atom.mutable || IS_PROD) {
|
|
177
|
-
data.values.set(atom, value);
|
|
178
|
-
written = value;
|
|
179
|
-
} else {
|
|
180
|
-
const frozenValue = value !== null && (typeof value === "object" || typeof value === "function") ? deepFreeze(value) : value;
|
|
181
|
-
data.values.set(atom, frozenValue);
|
|
182
|
-
written = frozenValue;
|
|
183
|
-
}
|
|
184
|
-
if (isNewAtomInScope) {
|
|
185
|
-
trackScopeValue(atom, data);
|
|
186
|
-
const subs = data.subscriptions.get(atom);
|
|
187
|
-
if (subs) {
|
|
188
|
-
for (const sub of subs)
|
|
189
|
-
sub.reRoot?.();
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
if (atom.maxAge !== undefined) {
|
|
193
|
-
data.lastValueWriteAt.set(atom, Date.now());
|
|
194
|
-
}
|
|
195
|
-
return written;
|
|
196
|
-
};
|
|
197
140
|
|
|
198
141
|
// src/lib/atomFamilyIndex.ts
|
|
199
142
|
var getAtomFamilyRenderedMap = (index) => {
|
|
@@ -292,13 +235,29 @@ var recursivelyUpdateIndexes = (data, family) => {
|
|
|
292
235
|
recursivelyUpdateIndexes(scopedData, family);
|
|
293
236
|
}
|
|
294
237
|
};
|
|
238
|
+
var ensureFamilyAncestorChain = (family, data) => {
|
|
239
|
+
if (!data.parent)
|
|
240
|
+
return;
|
|
241
|
+
const parentIndex = initFamilyIndex(family, data.parent);
|
|
242
|
+
const own = data.values.get(family).__index;
|
|
243
|
+
if (own.parentIndex !== parentIndex) {
|
|
244
|
+
own.parentIndex = parentIndex;
|
|
245
|
+
own.rendered = null;
|
|
246
|
+
own.renderedArray = null;
|
|
247
|
+
data.values.set(family, renderAtomFamilyIndex(own));
|
|
248
|
+
recursivelyUpdateIndexes(data, family);
|
|
249
|
+
}
|
|
250
|
+
};
|
|
295
251
|
var addFamilyAtomsToSet = (family, familyAtoms, data, timestamp) => {
|
|
296
252
|
if (familyAtoms.size === 0)
|
|
297
|
-
return;
|
|
253
|
+
return false;
|
|
298
254
|
const index = findFamilyIndex(family, data);
|
|
299
255
|
if (!index)
|
|
300
256
|
throw new Error("index not found");
|
|
257
|
+
let membershipChanged = false;
|
|
301
258
|
for (const atom of familyAtoms) {
|
|
259
|
+
if (!(index.created.has(atom) && !index.deleted.has(atom)))
|
|
260
|
+
membershipChanged = true;
|
|
302
261
|
index.created.set(atom, timestamp);
|
|
303
262
|
index.deleted.delete(atom);
|
|
304
263
|
}
|
|
@@ -306,6 +265,7 @@ var addFamilyAtomsToSet = (family, familyAtoms, data, timestamp) => {
|
|
|
306
265
|
index.renderedArray = null;
|
|
307
266
|
data.values.set(family, renderAtomFamilyIndex(index));
|
|
308
267
|
recursivelyUpdateIndexes(data, family);
|
|
268
|
+
return membershipChanged;
|
|
309
269
|
};
|
|
310
270
|
|
|
311
271
|
// src/errors/lib/generateSelectorTrace.ts
|
|
@@ -403,6 +363,276 @@ var cleanUpRejectedPromise = (selector, data, promise) => {
|
|
|
403
363
|
data.values.delete(selector);
|
|
404
364
|
};
|
|
405
365
|
|
|
366
|
+
// src/lib/notifyChangeListeners.ts
|
|
367
|
+
var changeListenerRegistry = { count: 0, selectorCount: 0 };
|
|
368
|
+
var hasChangeListener = (data) => {
|
|
369
|
+
if (changeListenerRegistry.count === 0)
|
|
370
|
+
return false;
|
|
371
|
+
let store = data;
|
|
372
|
+
while (store) {
|
|
373
|
+
const listeners = store.changeListeners;
|
|
374
|
+
if (listeners !== undefined && listeners.size > 0)
|
|
375
|
+
return true;
|
|
376
|
+
store = store.parent;
|
|
377
|
+
}
|
|
378
|
+
return false;
|
|
379
|
+
};
|
|
380
|
+
var hasSelectorChangeListener = (data) => {
|
|
381
|
+
if (changeListenerRegistry.selectorCount === 0)
|
|
382
|
+
return false;
|
|
383
|
+
let store = data;
|
|
384
|
+
while (store) {
|
|
385
|
+
const listeners = store.changeListeners;
|
|
386
|
+
if (listeners !== undefined) {
|
|
387
|
+
for (const flags of listeners.values()) {
|
|
388
|
+
if (flags.selectors)
|
|
389
|
+
return true;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
store = store.parent;
|
|
393
|
+
}
|
|
394
|
+
return false;
|
|
395
|
+
};
|
|
396
|
+
var scopePath = (data) => {
|
|
397
|
+
const path = [];
|
|
398
|
+
let store = data;
|
|
399
|
+
while (store && store.parent) {
|
|
400
|
+
path.push(store.id);
|
|
401
|
+
store = store.parent;
|
|
402
|
+
}
|
|
403
|
+
path.reverse();
|
|
404
|
+
return path;
|
|
405
|
+
};
|
|
406
|
+
var notifyChangeListeners = (groups, meta) => {
|
|
407
|
+
let buckets;
|
|
408
|
+
for (const group of groups) {
|
|
409
|
+
if (group.changes.length === 0)
|
|
410
|
+
continue;
|
|
411
|
+
let store = group.data;
|
|
412
|
+
while (store) {
|
|
413
|
+
const listeners = store.changeListeners;
|
|
414
|
+
if (listeners !== undefined && listeners.size > 0) {
|
|
415
|
+
if (!buckets)
|
|
416
|
+
buckets = new Map;
|
|
417
|
+
let bucket = buckets.get(store);
|
|
418
|
+
if (!bucket) {
|
|
419
|
+
bucket = [];
|
|
420
|
+
buckets.set(store, bucket);
|
|
421
|
+
}
|
|
422
|
+
for (const change of group.changes)
|
|
423
|
+
bucket.push(change);
|
|
424
|
+
}
|
|
425
|
+
store = store.parent;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
if (!buckets)
|
|
429
|
+
return;
|
|
430
|
+
for (const [store, changes] of buckets) {
|
|
431
|
+
const listeners = store.changeListeners;
|
|
432
|
+
if (listeners === undefined || listeners.size === 0)
|
|
433
|
+
continue;
|
|
434
|
+
let hasSelector;
|
|
435
|
+
let hasAtom;
|
|
436
|
+
let atomOnly;
|
|
437
|
+
let selectorOnly;
|
|
438
|
+
let firstError;
|
|
439
|
+
let hasError = false;
|
|
440
|
+
for (const [listener, flags] of [...listeners]) {
|
|
441
|
+
let payload;
|
|
442
|
+
if (flags.atoms && flags.selectors) {
|
|
443
|
+
payload = changes;
|
|
444
|
+
} else if (flags.atoms) {
|
|
445
|
+
if (atomOnly === undefined) {
|
|
446
|
+
hasSelector ??= changes.some((c) => c.type === "selector");
|
|
447
|
+
atomOnly = hasSelector ? changes.filter((c) => c.type === "atom") : changes;
|
|
448
|
+
}
|
|
449
|
+
payload = atomOnly;
|
|
450
|
+
} else if (flags.selectors) {
|
|
451
|
+
if (selectorOnly === undefined) {
|
|
452
|
+
hasAtom ??= changes.some((c) => c.type === "atom");
|
|
453
|
+
selectorOnly = hasAtom ? changes.filter((c) => c.type === "selector") : changes;
|
|
454
|
+
}
|
|
455
|
+
payload = selectorOnly;
|
|
456
|
+
} else {
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
if (payload.length === 0)
|
|
460
|
+
continue;
|
|
461
|
+
try {
|
|
462
|
+
listener(payload, meta);
|
|
463
|
+
} catch (error) {
|
|
464
|
+
if (!hasError) {
|
|
465
|
+
firstError = error;
|
|
466
|
+
hasError = true;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
if (hasError)
|
|
471
|
+
throw firstError;
|
|
472
|
+
}
|
|
473
|
+
};
|
|
474
|
+
var buildChangeGroup = (data, changedAtoms, deletedAtoms, changedSelectors) => {
|
|
475
|
+
const scope = scopePath(data);
|
|
476
|
+
const changes = [];
|
|
477
|
+
let seen;
|
|
478
|
+
if (changedAtoms) {
|
|
479
|
+
for (const atom of changedAtoms) {
|
|
480
|
+
if (atom.__valdresInternal || isAtomFamily(atom))
|
|
481
|
+
continue;
|
|
482
|
+
if (seen?.has(atom))
|
|
483
|
+
continue;
|
|
484
|
+
(seen ??= new Set).add(atom);
|
|
485
|
+
changes.push({
|
|
486
|
+
type: "atom",
|
|
487
|
+
kind: "set",
|
|
488
|
+
state: atom,
|
|
489
|
+
value: data.values.get(atom),
|
|
490
|
+
scope
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
if (deletedAtoms) {
|
|
495
|
+
for (const atom of deletedAtoms) {
|
|
496
|
+
if (atom.__valdresInternal || isAtomFamily(atom))
|
|
497
|
+
continue;
|
|
498
|
+
changes.push({ type: "atom", kind: "delete", state: atom, scope });
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
if (changedSelectors) {
|
|
502
|
+
for (const selector of changedSelectors) {
|
|
503
|
+
if (selector.__valdresInternal || isSelectorFamily(selector))
|
|
504
|
+
continue;
|
|
505
|
+
if (!data.values.has(selector))
|
|
506
|
+
continue;
|
|
507
|
+
changes.push({
|
|
508
|
+
type: "selector",
|
|
509
|
+
state: selector,
|
|
510
|
+
value: data.values.get(selector),
|
|
511
|
+
scope
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return { data, changes };
|
|
516
|
+
};
|
|
517
|
+
var emitGroup = (group, report) => {
|
|
518
|
+
if (group.changes.length === 0)
|
|
519
|
+
return;
|
|
520
|
+
if (typeof report === "string") {
|
|
521
|
+
notifyChangeListeners([group], { source: report });
|
|
522
|
+
} else {
|
|
523
|
+
report.groups.push(group);
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
var reportAtomChanges = (atoms, data, report, changedSelectors) => {
|
|
527
|
+
if (!hasChangeListener(data))
|
|
528
|
+
return;
|
|
529
|
+
const selectors = changedSelectors && changedSelectors.size > 0 && hasSelectorChangeListener(data) ? changedSelectors : undefined;
|
|
530
|
+
emitGroup(buildChangeGroup(data, atoms, undefined, selectors), report);
|
|
531
|
+
};
|
|
532
|
+
var reportUnsetAtom = (atom, data, revertedValue, report) => {
|
|
533
|
+
if (!hasChangeListener(data))
|
|
534
|
+
return;
|
|
535
|
+
const group = {
|
|
536
|
+
data,
|
|
537
|
+
changes: [
|
|
538
|
+
{
|
|
539
|
+
type: "atom",
|
|
540
|
+
kind: "unset",
|
|
541
|
+
state: atom,
|
|
542
|
+
value: revertedValue,
|
|
543
|
+
scope: scopePath(data)
|
|
544
|
+
}
|
|
545
|
+
]
|
|
546
|
+
};
|
|
547
|
+
emitGroup(group, report);
|
|
548
|
+
};
|
|
549
|
+
var reportDeletedAtoms = (atoms, data, report, changedSelectors) => {
|
|
550
|
+
if (!hasChangeListener(data))
|
|
551
|
+
return;
|
|
552
|
+
const selectors = changedSelectors && changedSelectors.size > 0 && hasSelectorChangeListener(data) ? changedSelectors : undefined;
|
|
553
|
+
emitGroup(buildChangeGroup(data, undefined, atoms, selectors), report);
|
|
554
|
+
};
|
|
555
|
+
var reportSelectorChanges = (changedSelectors, data, report) => {
|
|
556
|
+
if (changedSelectors.size === 0)
|
|
557
|
+
return;
|
|
558
|
+
if (!hasSelectorChangeListener(data))
|
|
559
|
+
return;
|
|
560
|
+
emitGroup(buildChangeGroup(data, undefined, undefined, changedSelectors), report);
|
|
561
|
+
};
|
|
562
|
+
var createChangeSink = (name, source = "transaction") => ({
|
|
563
|
+
source,
|
|
564
|
+
name,
|
|
565
|
+
groups: []
|
|
566
|
+
});
|
|
567
|
+
var flushChangeSink = (sink) => {
|
|
568
|
+
if (sink.groups.length > 0) {
|
|
569
|
+
notifyChangeListeners(sink.groups, { source: sink.source, name: sink.name });
|
|
570
|
+
}
|
|
571
|
+
};
|
|
572
|
+
|
|
573
|
+
// src/utils/deepFreeze.ts
|
|
574
|
+
var deepFreeze = (obj, seen) => {
|
|
575
|
+
if (obj === null || obj === undefined)
|
|
576
|
+
return obj;
|
|
577
|
+
if (typeof obj !== "object" && typeof obj !== "function")
|
|
578
|
+
return obj;
|
|
579
|
+
if (Object.isFrozen(obj) || seen?.has(obj))
|
|
580
|
+
return obj;
|
|
581
|
+
if (Array.isArray(obj)) {
|
|
582
|
+
for (const item of obj) {
|
|
583
|
+
if (item && typeof item === "object") {
|
|
584
|
+
seen ??= new WeakSet;
|
|
585
|
+
seen.add(obj);
|
|
586
|
+
deepFreeze(item, seen);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
} else {
|
|
590
|
+
const propNames = Object.getOwnPropertyNames(obj);
|
|
591
|
+
for (const name of propNames) {
|
|
592
|
+
const value = obj[name];
|
|
593
|
+
if (value && typeof value === "object") {
|
|
594
|
+
seen ??= new WeakSet;
|
|
595
|
+
seen.add(obj);
|
|
596
|
+
deepFreeze(value, seen);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
return Object.freeze(obj);
|
|
601
|
+
};
|
|
602
|
+
|
|
603
|
+
// src/lib/IS_PROD.ts
|
|
604
|
+
var IS_PROD = typeof process !== "undefined" && process.env != null && process.env.NODE_ENV === "production";
|
|
605
|
+
|
|
606
|
+
// src/lib/setValueInData.ts
|
|
607
|
+
var setValueInData = (atom, value, data) => {
|
|
608
|
+
const isNewAtomInScope = data.parent && Object.hasOwn(atom, "defaultValue") && !data.values.has(atom);
|
|
609
|
+
const isNewFamilyInScope = !!data.parent && !data.values.has(atom) && isAtomFamily(atom);
|
|
610
|
+
let written;
|
|
611
|
+
if (atom.mutable || IS_PROD) {
|
|
612
|
+
data.values.set(atom, value);
|
|
613
|
+
written = value;
|
|
614
|
+
} else {
|
|
615
|
+
const frozenValue = value !== null && (typeof value === "object" || typeof value === "function") ? deepFreeze(value) : value;
|
|
616
|
+
data.values.set(atom, frozenValue);
|
|
617
|
+
written = frozenValue;
|
|
618
|
+
}
|
|
619
|
+
if (isNewAtomInScope) {
|
|
620
|
+
trackScopeValue(atom, data);
|
|
621
|
+
const subs = data.subscriptions.get(atom);
|
|
622
|
+
if (subs) {
|
|
623
|
+
for (const sub of subs)
|
|
624
|
+
sub.reRoot?.();
|
|
625
|
+
}
|
|
626
|
+
} else if (isNewFamilyInScope) {
|
|
627
|
+
trackScopeValue(atom, data);
|
|
628
|
+
ensureFamilyAncestorChain(atom, data);
|
|
629
|
+
}
|
|
630
|
+
if (atom.maxAge !== undefined) {
|
|
631
|
+
data.lastValueWriteAt.set(atom, Date.now());
|
|
632
|
+
}
|
|
633
|
+
return written;
|
|
634
|
+
};
|
|
635
|
+
|
|
406
636
|
// src/lib/initSelector.ts
|
|
407
637
|
var neverAbortedSignal = new AbortController().signal;
|
|
408
638
|
var syncOptionsCache = new WeakMap;
|
|
@@ -549,7 +779,7 @@ var handleSelectorResult = (value, selector, data) => {
|
|
|
549
779
|
const initializedAtomsSet = new Set;
|
|
550
780
|
const res = initSelector(selector, data, initializedAtomsSet);
|
|
551
781
|
if (initializedAtomsSet.size > 0) {
|
|
552
|
-
propagateAtomUpdate([...initializedAtomsSet], data);
|
|
782
|
+
propagateAtomUpdate([...initializedAtomsSet], data, false, undefined, "async-set");
|
|
553
783
|
}
|
|
554
784
|
return res;
|
|
555
785
|
}).catch(() => {
|
|
@@ -590,7 +820,12 @@ var handleSelectorResult = (value, selector, data) => {
|
|
|
590
820
|
const dependents = data.stateDependents.get(selector);
|
|
591
821
|
const subs = data.subscriptions.get(selector);
|
|
592
822
|
if (subs && subs.size > 0 || dependents && dependents.size > 0) {
|
|
593
|
-
|
|
823
|
+
const changedSelectors = changeListenerRegistry.selectorCount !== 0 && hasSelectorChangeListener(data) ? new Set : undefined;
|
|
824
|
+
propagateDirtySelectors([], new Set(dependents), data, new Set(subs), new Map, false, undefined, changedSelectors);
|
|
825
|
+
if (changedSelectors) {
|
|
826
|
+
changedSelectors.add(selector);
|
|
827
|
+
reportSelectorChanges(changedSelectors, data, "async-set");
|
|
828
|
+
}
|
|
594
829
|
}
|
|
595
830
|
}).catch(() => {
|
|
596
831
|
pendingAsyncDeps.delete(value);
|
|
@@ -718,7 +953,7 @@ var addSetToSet = (fromSet, toSet) => {
|
|
|
718
953
|
}
|
|
719
954
|
}
|
|
720
955
|
};
|
|
721
|
-
var propagateDeletedAtoms = (atoms, data, subscriptions = new Set, deletedFamilyAtoms = new Map, timestamp = performance.now(), notify) => {
|
|
956
|
+
var propagateDeletedAtoms = (atoms, data, subscriptions = new Set, deletedFamilyAtoms = new Map, timestamp = performance.now(), notify, report) => {
|
|
722
957
|
const notifyEntry = notify ? notifyEntryFor(notify, data) : undefined;
|
|
723
958
|
if (notifyEntry) {
|
|
724
959
|
subscriptions = notifyEntry.subscriptions;
|
|
@@ -743,30 +978,35 @@ var propagateDeletedAtoms = (atoms, data, subscriptions = new Set, deletedFamily
|
|
|
743
978
|
deleteFamilyAtomsFromSet(family, familyAtoms, data, timestamp);
|
|
744
979
|
}
|
|
745
980
|
}
|
|
746
|
-
|
|
981
|
+
const selectorActive = report !== undefined && changeListenerRegistry.selectorCount !== 0 && hasSelectorChangeListener(data);
|
|
982
|
+
const changedSelectors = selectorActive ? new Set : undefined;
|
|
983
|
+
propagateDirtySelectors(atoms, selectors, data, subscriptions, deletedFamilyAtoms, false, notify, changedSelectors);
|
|
747
984
|
if (notifyEntry)
|
|
748
985
|
collectFamilyAtomsForNotify(notifyEntry, deletedFamilyAtoms);
|
|
749
|
-
|
|
750
|
-
|
|
986
|
+
const hasScopeCascade = !!data.scopes && data.scopes.size > 0;
|
|
987
|
+
const watching = report !== undefined && changeListenerRegistry.count !== 0;
|
|
988
|
+
let localSink;
|
|
989
|
+
let effectiveReport = report;
|
|
990
|
+
if (selectorActive && hasScopeCascade && typeof report === "string") {
|
|
991
|
+
localSink = createChangeSink(undefined, report);
|
|
992
|
+
effectiveReport = localSink;
|
|
993
|
+
}
|
|
994
|
+
const reportIsSink = effectiveReport !== undefined && typeof effectiveReport !== "string";
|
|
995
|
+
if (watching && reportIsSink)
|
|
996
|
+
reportDeletedAtoms(atoms, data, effectiveReport, changedSelectors);
|
|
997
|
+
if (hasScopeCascade) {
|
|
998
|
+
const scopeAtoms = atoms.slice();
|
|
751
999
|
for (const family of deletedFamilyAtoms.keys()) {
|
|
752
|
-
|
|
753
|
-
if (scopesWithFamily) {
|
|
754
|
-
for (const scope of scopesWithFamily) {
|
|
755
|
-
let list = scopeFamilies.get(scope);
|
|
756
|
-
if (!list) {
|
|
757
|
-
list = [];
|
|
758
|
-
scopeFamilies.set(scope, list);
|
|
759
|
-
}
|
|
760
|
-
list.push(family);
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
for (const [scope, familiesInScope] of scopeFamilies) {
|
|
765
|
-
propagateInScope(familiesInScope, scope, false, notify);
|
|
1000
|
+
scopeAtoms.push(family);
|
|
766
1001
|
}
|
|
1002
|
+
propagateToScopes(scopeAtoms, data, false, notify, effectiveReport);
|
|
767
1003
|
}
|
|
1004
|
+
if (watching && !reportIsSink)
|
|
1005
|
+
reportDeletedAtoms(atoms, data, effectiveReport, changedSelectors);
|
|
1006
|
+
if (localSink)
|
|
1007
|
+
flushChangeSink(localSink);
|
|
768
1008
|
};
|
|
769
|
-
var propagateAtomUpdate = (atoms, data, isInitOnly = false, notify) => {
|
|
1009
|
+
var propagateAtomUpdate = (atoms, data, isInitOnly = false, notify, report, skipFamilyIndexUpdate = false, reportAtoms = true) => {
|
|
770
1010
|
if (atoms.length === 1) {
|
|
771
1011
|
const atom = atoms[0];
|
|
772
1012
|
if (!isFamilyAtom(atom) && !isAtomFamily(atom)) {
|
|
@@ -779,6 +1019,9 @@ var propagateAtomUpdate = (atoms, data, isInitOnly = false, notify) => {
|
|
|
779
1019
|
else
|
|
780
1020
|
callSubscribers(subs);
|
|
781
1021
|
}
|
|
1022
|
+
if (reportAtoms && report !== undefined && changeListenerRegistry.count !== 0 && !isInitOnly) {
|
|
1023
|
+
reportAtomChanges(atoms, data, report);
|
|
1024
|
+
}
|
|
782
1025
|
return;
|
|
783
1026
|
}
|
|
784
1027
|
}
|
|
@@ -790,13 +1033,14 @@ var propagateAtomUpdate = (atoms, data, isInitOnly = false, notify) => {
|
|
|
790
1033
|
for (const atom of atoms) {
|
|
791
1034
|
addSetToSet(data.stateDependents.get(atom), selectors);
|
|
792
1035
|
addSetToSet(data.subscriptions.get(atom), subscriptions);
|
|
793
|
-
if (isFamilyAtom(atom)) {
|
|
1036
|
+
if (isFamilyAtom(atom) && !skipFamilyIndexUpdate) {
|
|
794
1037
|
if (!updatedFamilyAtoms.has(atom.family)) {
|
|
795
1038
|
updatedFamilyAtoms.set(atom.family, new Set);
|
|
796
1039
|
}
|
|
797
1040
|
updatedFamilyAtoms.get(atom.family).add(atom);
|
|
798
1041
|
}
|
|
799
1042
|
}
|
|
1043
|
+
let membershipChanged;
|
|
800
1044
|
if (updatedFamilyAtoms.size > 0) {
|
|
801
1045
|
const timestamp = performance.now();
|
|
802
1046
|
for (const [family, familyAtoms] of updatedFamilyAtoms) {
|
|
@@ -804,7 +1048,11 @@ var propagateAtomUpdate = (atoms, data, isInitOnly = false, notify) => {
|
|
|
804
1048
|
addSetToSet(data.subscriptions.get(family), subscriptions);
|
|
805
1049
|
if (familyAtoms.size === 0)
|
|
806
1050
|
throw new Error("Should not be possible");
|
|
807
|
-
addFamilyAtomsToSet(family, familyAtoms, data, timestamp)
|
|
1051
|
+
if (addFamilyAtomsToSet(family, familyAtoms, data, timestamp)) {
|
|
1052
|
+
if (!membershipChanged)
|
|
1053
|
+
membershipChanged = new Set;
|
|
1054
|
+
membershipChanged.add(family);
|
|
1055
|
+
}
|
|
808
1056
|
}
|
|
809
1057
|
}
|
|
810
1058
|
if (data.scopes && data.scopes.size > 0) {
|
|
@@ -814,32 +1062,68 @@ var propagateAtomUpdate = (atoms, data, isInitOnly = false, notify) => {
|
|
|
814
1062
|
}
|
|
815
1063
|
}
|
|
816
1064
|
}
|
|
817
|
-
|
|
1065
|
+
const selectorActive = report !== undefined && !isInitOnly && changeListenerRegistry.selectorCount !== 0 && hasSelectorChangeListener(data);
|
|
1066
|
+
const changedSelectors = selectorActive ? new Set : undefined;
|
|
1067
|
+
propagateDirtySelectors(atoms, selectors, data, subscriptions, updatedFamilyAtoms, isInitOnly, notify, changedSelectors);
|
|
818
1068
|
if (notifyEntry)
|
|
819
1069
|
collectFamilyAtomsForNotify(notifyEntry, updatedFamilyAtoms);
|
|
820
|
-
|
|
821
|
-
|
|
1070
|
+
const hasScopes = !!data.scopes && data.scopes.size > 0;
|
|
1071
|
+
const watching = report !== undefined && changeListenerRegistry.count !== 0 && !isInitOnly;
|
|
1072
|
+
let localSink;
|
|
1073
|
+
let effectiveReport = report;
|
|
1074
|
+
if (selectorActive && hasScopes && typeof report === "string") {
|
|
1075
|
+
localSink = createChangeSink(undefined, report);
|
|
1076
|
+
effectiveReport = localSink;
|
|
1077
|
+
}
|
|
1078
|
+
const reportIsSink = effectiveReport !== undefined && typeof effectiveReport !== "string";
|
|
1079
|
+
const emitOrigin = (rpt) => {
|
|
1080
|
+
if (reportAtoms) {
|
|
1081
|
+
reportAtomChanges(atoms, data, rpt, changedSelectors);
|
|
1082
|
+
} else if (changedSelectors && changedSelectors.size > 0) {
|
|
1083
|
+
reportSelectorChanges(changedSelectors, data, rpt);
|
|
1084
|
+
}
|
|
1085
|
+
};
|
|
1086
|
+
if (watching && reportIsSink)
|
|
1087
|
+
emitOrigin(effectiveReport);
|
|
1088
|
+
if (hasScopes) {
|
|
1089
|
+
let scopeAtoms = atoms;
|
|
1090
|
+
if (membershipChanged) {
|
|
1091
|
+
scopeAtoms = atoms.slice();
|
|
1092
|
+
for (const family of membershipChanged) {
|
|
1093
|
+
if (!scopeAtoms.includes(family))
|
|
1094
|
+
scopeAtoms.push(family);
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
propagateToScopes(scopeAtoms, data, isInitOnly, notify, effectiveReport);
|
|
822
1098
|
}
|
|
1099
|
+
if (watching && !reportIsSink)
|
|
1100
|
+
emitOrigin(effectiveReport);
|
|
1101
|
+
if (localSink)
|
|
1102
|
+
flushChangeSink(localSink);
|
|
823
1103
|
};
|
|
824
|
-
var propagateInScope = (atoms, data, isInitOnly = false, notify) => {
|
|
1104
|
+
var propagateInScope = (atoms, data, isInitOnly = false, notify, report) => {
|
|
825
1105
|
const subscriptions = notify ? notifyEntryFor(notify, data).subscriptions : new Set;
|
|
826
1106
|
const families = new Map;
|
|
827
1107
|
const selectors = new Set;
|
|
828
1108
|
for (const atom of atoms) {
|
|
829
1109
|
addSetToSet(data.stateDependents.get(atom), selectors);
|
|
830
1110
|
}
|
|
831
|
-
|
|
1111
|
+
const changedSelectors = report !== undefined && !isInitOnly && changeListenerRegistry.selectorCount !== 0 && hasSelectorChangeListener(data) ? new Set : undefined;
|
|
1112
|
+
propagateDirtySelectors(atoms, selectors, data, subscriptions, families, isInitOnly, notify, changedSelectors);
|
|
1113
|
+
if (changedSelectors && changedSelectors.size > 0) {
|
|
1114
|
+
reportSelectorChanges(changedSelectors, data, report);
|
|
1115
|
+
}
|
|
832
1116
|
if (data.scopes && data.scopes.size > 0) {
|
|
833
|
-
propagateToScopes(atoms, data, isInitOnly, notify);
|
|
1117
|
+
propagateToScopes(atoms, data, isInitOnly, notify, report);
|
|
834
1118
|
}
|
|
835
1119
|
};
|
|
836
|
-
var propagateToScopes = (atoms, data, isInitOnly, notify) => {
|
|
1120
|
+
var propagateToScopes = (atoms, data, isInitOnly, notify, report) => {
|
|
837
1121
|
if (atoms.length === 1) {
|
|
838
1122
|
const atom = atoms[0];
|
|
839
1123
|
const shadowingScopes = isAtomFamily(atom) ? undefined : data.scopeValueIndex.get(atom);
|
|
840
1124
|
for (const [, scope] of data.scopes) {
|
|
841
1125
|
if (!shadowingScopes || !shadowingScopes.has(scope)) {
|
|
842
|
-
propagateInScope(atoms, scope, isInitOnly, notify);
|
|
1126
|
+
propagateInScope(atoms, scope, isInitOnly, notify, report);
|
|
843
1127
|
}
|
|
844
1128
|
}
|
|
845
1129
|
return;
|
|
@@ -859,7 +1143,7 @@ var propagateToScopes = (atoms, data, isInitOnly, notify) => {
|
|
|
859
1143
|
}
|
|
860
1144
|
if (!anyShadowed) {
|
|
861
1145
|
for (const [, scope] of data.scopes) {
|
|
862
|
-
propagateInScope(atoms, scope, isInitOnly, notify);
|
|
1146
|
+
propagateInScope(atoms, scope, isInitOnly, notify, report);
|
|
863
1147
|
}
|
|
864
1148
|
return;
|
|
865
1149
|
}
|
|
@@ -876,20 +1160,20 @@ var propagateToScopes = (atoms, data, isInitOnly, notify) => {
|
|
|
876
1160
|
}
|
|
877
1161
|
}
|
|
878
1162
|
if (atomsToUpdateInScope.length > 0) {
|
|
879
|
-
propagateInScope(atomsToUpdateInScope, scope, isInitOnly, notify);
|
|
1163
|
+
propagateInScope(atomsToUpdateInScope, scope, isInitOnly, notify, report);
|
|
880
1164
|
}
|
|
881
1165
|
}
|
|
882
1166
|
};
|
|
883
|
-
var propagateDirtySelectors = (updatedAtoms, selectors, data, subscriptions, families, isInitOnly = false, notify) => {
|
|
1167
|
+
var propagateDirtySelectors = (updatedAtoms, selectors, data, subscriptions, families, isInitOnly = false, notify, changedSelectors) => {
|
|
884
1168
|
const updatedInitializedAtoms = new Set(updatedAtoms);
|
|
885
1169
|
if (selectors.size > 0) {
|
|
886
|
-
propagateSelectorUpdates(selectors, data, subscriptions, updatedInitializedAtoms, isInitOnly);
|
|
1170
|
+
propagateSelectorUpdates(selectors, data, subscriptions, updatedInitializedAtoms, isInitOnly, changedSelectors);
|
|
887
1171
|
}
|
|
888
1172
|
if (!notify && subscriptions.size > 0) {
|
|
889
1173
|
callSubscribers(subscriptions, families);
|
|
890
1174
|
}
|
|
891
1175
|
};
|
|
892
|
-
var propagateDownstreamTopo = (seeds, data, collectedSubscribers, updatedInitializedAtoms, isInitOnly) => {
|
|
1176
|
+
var propagateDownstreamTopo = (seeds, data, collectedSubscribers, updatedInitializedAtoms, isInitOnly, changedSelectors) => {
|
|
893
1177
|
const closure = new Set(seeds);
|
|
894
1178
|
{
|
|
895
1179
|
const stack = [...seeds];
|
|
@@ -989,8 +1273,11 @@ var propagateDownstreamTopo = (seeds, data, collectedSubscribers, updatedInitial
|
|
|
989
1273
|
}
|
|
990
1274
|
}
|
|
991
1275
|
advance(selector, wasValueUpdated);
|
|
992
|
-
if (wasValueUpdated
|
|
993
|
-
|
|
1276
|
+
if (wasValueUpdated) {
|
|
1277
|
+
if (changedSelectors)
|
|
1278
|
+
changedSelectors.add(selector);
|
|
1279
|
+
if (subscribers)
|
|
1280
|
+
addSetToSet(subscribers, collectedSubscribers);
|
|
994
1281
|
}
|
|
995
1282
|
}
|
|
996
1283
|
if (!graphMutated)
|
|
@@ -1038,6 +1325,8 @@ var propagateDownstreamTopo = (seeds, data, collectedSubscribers, updatedInitial
|
|
|
1038
1325
|
}
|
|
1039
1326
|
}
|
|
1040
1327
|
if (wasValueUpdated) {
|
|
1328
|
+
if (changedSelectors)
|
|
1329
|
+
changedSelectors.add(selector);
|
|
1041
1330
|
if (subscribers)
|
|
1042
1331
|
addSetToSet(subscribers, collectedSubscribers);
|
|
1043
1332
|
const downstream = data.stateDependents.get(selector);
|
|
@@ -1050,7 +1339,7 @@ var propagateDownstreamTopo = (seeds, data, collectedSubscribers, updatedInitial
|
|
|
1050
1339
|
work = next;
|
|
1051
1340
|
}
|
|
1052
1341
|
};
|
|
1053
|
-
var propagateSelectorUpdates = (selectors, data, collectedSubscribers, updatedInitializedAtoms, isInitOnly = false) => {
|
|
1342
|
+
var propagateSelectorUpdates = (selectors, data, collectedSubscribers, updatedInitializedAtoms, isInitOnly = false, changedSelectors) => {
|
|
1054
1343
|
if (selectors.size === 0)
|
|
1055
1344
|
return;
|
|
1056
1345
|
let downstreamSeeds;
|
|
@@ -1086,6 +1375,8 @@ var propagateSelectorUpdates = (selectors, data, collectedSubscribers, updatedIn
|
|
|
1086
1375
|
}
|
|
1087
1376
|
if (!wasValueUpdated)
|
|
1088
1377
|
continue;
|
|
1378
|
+
if (changedSelectors)
|
|
1379
|
+
changedSelectors.add(selector);
|
|
1089
1380
|
if (subscribers)
|
|
1090
1381
|
addSetToSet(subscribers, collectedSubscribers);
|
|
1091
1382
|
const downstream = data.stateDependents.get(selector);
|
|
@@ -1097,7 +1388,7 @@ var propagateSelectorUpdates = (selectors, data, collectedSubscribers, updatedIn
|
|
|
1097
1388
|
}
|
|
1098
1389
|
}
|
|
1099
1390
|
if (downstreamSeeds && downstreamSeeds.size > 0) {
|
|
1100
|
-
propagateDownstreamTopo(downstreamSeeds, data, collectedSubscribers, updatedInitializedAtoms, isInitOnly);
|
|
1391
|
+
propagateDownstreamTopo(downstreamSeeds, data, collectedSubscribers, updatedInitializedAtoms, isInitOnly, changedSelectors);
|
|
1101
1392
|
}
|
|
1102
1393
|
};
|
|
1103
1394
|
|
|
@@ -1128,12 +1419,12 @@ var handlePromise = (atom, promise, currentValue, data, skipOnSet) => {
|
|
|
1128
1419
|
if (atom.onSet && !skipOnSet)
|
|
1129
1420
|
atom.onSet(resolvedValue, data);
|
|
1130
1421
|
resolvePendingDefault(atom, data, resolvedValue);
|
|
1131
|
-
propagateAtomUpdate([atom], data);
|
|
1422
|
+
propagateAtomUpdate([atom], data, false, undefined, "async-set");
|
|
1132
1423
|
}).catch(() => {
|
|
1133
1424
|
if (data.values.get(atom) !== promise)
|
|
1134
1425
|
return;
|
|
1135
1426
|
setValueInData(atom, currentValue, data);
|
|
1136
|
-
propagateAtomUpdate([atom], data);
|
|
1427
|
+
propagateAtomUpdate([atom], data, false, undefined, "async-set");
|
|
1137
1428
|
});
|
|
1138
1429
|
};
|
|
1139
1430
|
var setAtom = (atom, newValue, data, skipOnSet = false) => {
|
|
@@ -1155,9 +1446,9 @@ var setAtom = (atom, newValue, data, skipOnSet = false) => {
|
|
|
1155
1446
|
handlePromise(atom, promise, currentValue, data, skipOnSet);
|
|
1156
1447
|
if (initializedAtomsSet && initializedAtomsSet.size > 0) {
|
|
1157
1448
|
initializedAtomsSet.add(atom);
|
|
1158
|
-
propagateAtomUpdate([...initializedAtomsSet], data);
|
|
1449
|
+
propagateAtomUpdate([...initializedAtomsSet], data, false, undefined, "set");
|
|
1159
1450
|
} else {
|
|
1160
|
-
propagateAtomUpdate([atom], data);
|
|
1451
|
+
propagateAtomUpdate([atom], data, false, undefined, "set");
|
|
1161
1452
|
}
|
|
1162
1453
|
return promise;
|
|
1163
1454
|
}
|
|
@@ -1171,9 +1462,9 @@ var setAtom = (atom, newValue, data, skipOnSet = false) => {
|
|
|
1171
1462
|
resolvePendingDefault(atom, data, syncValue);
|
|
1172
1463
|
if (initializedAtomsSet && initializedAtomsSet.size > 0) {
|
|
1173
1464
|
initializedAtomsSet.add(atom);
|
|
1174
|
-
propagateAtomUpdate([...initializedAtomsSet], data);
|
|
1465
|
+
propagateAtomUpdate([...initializedAtomsSet], data, false, undefined, "set");
|
|
1175
1466
|
} else {
|
|
1176
|
-
propagateAtomUpdate([atom], data);
|
|
1467
|
+
propagateAtomUpdate([atom], data, false, undefined, "set");
|
|
1177
1468
|
}
|
|
1178
1469
|
return syncValue;
|
|
1179
1470
|
};
|
|
@@ -1194,7 +1485,7 @@ var getAtomInitValue = (atom, data, initializedAtomsSet) => {
|
|
|
1194
1485
|
if (data.values.get(atom) !== value)
|
|
1195
1486
|
return;
|
|
1196
1487
|
setValueInData(atom, resolvedValue, data);
|
|
1197
|
-
propagateAtomUpdate([atom], data);
|
|
1488
|
+
propagateAtomUpdate([atom], data, false, undefined, "async-set");
|
|
1198
1489
|
}, () => {
|
|
1199
1490
|
if (data.values.get(atom) === value) {
|
|
1200
1491
|
data.values.delete(atom);
|
|
@@ -1218,6 +1509,23 @@ var initAtom = (atom, data, initializedAtomsSet) => {
|
|
|
1218
1509
|
}, data);
|
|
1219
1510
|
};
|
|
1220
1511
|
|
|
1512
|
+
// src/lib/resolveAtomDefaultValue.ts
|
|
1513
|
+
var resolveAtomDefaultValue = (atom, data, initializedAtomsSet) => {
|
|
1514
|
+
if (atom.defaultValue === undefined) {
|
|
1515
|
+
let resolve;
|
|
1516
|
+
const promise = new Promise((r) => {
|
|
1517
|
+
resolve = r;
|
|
1518
|
+
});
|
|
1519
|
+
data.pendingDefaults.set(atom, { promise, resolve });
|
|
1520
|
+
return promise;
|
|
1521
|
+
} else if (typeof atom.defaultValue === "function") {
|
|
1522
|
+
return atom.defaultValue();
|
|
1523
|
+
} else if (isSelector(atom.defaultValue)) {
|
|
1524
|
+
return getState(atom.defaultValue, data, initializedAtomsSet);
|
|
1525
|
+
}
|
|
1526
|
+
return atom.defaultValue;
|
|
1527
|
+
};
|
|
1528
|
+
|
|
1221
1529
|
// src/lib/getState.ts
|
|
1222
1530
|
function getState(state, data, initializedAtomsSet, circularDependencySet) {
|
|
1223
1531
|
if (data.values.has(state))
|
|
@@ -1229,7 +1537,21 @@ function getState(state, data, initializedAtomsSet, circularDependencySet) {
|
|
|
1229
1537
|
const familyValue = data.values.get(state.family);
|
|
1230
1538
|
if (familyValue?.__index) {
|
|
1231
1539
|
if (isAtomDeletedInFamilyIndex(state, familyValue.__index)) {
|
|
1232
|
-
|
|
1540
|
+
const value = resolveAtomDefaultValue(state, data, initializedAtomsSet);
|
|
1541
|
+
const cached = setValueInData(state, value, data);
|
|
1542
|
+
if (isPromiseLike(cached)) {
|
|
1543
|
+
cached.then((resolvedValue) => {
|
|
1544
|
+
if (data.values.get(state) !== cached)
|
|
1545
|
+
return;
|
|
1546
|
+
setValueInData(state, resolvedValue, data);
|
|
1547
|
+
propagateAtomUpdate([state], data, false, undefined, undefined, true);
|
|
1548
|
+
}, () => {
|
|
1549
|
+
if (data.values.get(state) === cached) {
|
|
1550
|
+
data.values.delete(state);
|
|
1551
|
+
}
|
|
1552
|
+
});
|
|
1553
|
+
}
|
|
1554
|
+
return cached;
|
|
1233
1555
|
}
|
|
1234
1556
|
}
|
|
1235
1557
|
}
|
|
@@ -1287,6 +1609,63 @@ var resolveReactive = (value, data) => {
|
|
|
1287
1609
|
return value;
|
|
1288
1610
|
};
|
|
1289
1611
|
|
|
1612
|
+
// src/lib/unsetValue.ts
|
|
1613
|
+
var InvalidStateError = "unset() expects an atom.";
|
|
1614
|
+
var detachOwnValue = (atom, data) => {
|
|
1615
|
+
if (!data.values.has(atom))
|
|
1616
|
+
return false;
|
|
1617
|
+
data.values.delete(atom);
|
|
1618
|
+
if (atom.maxAge !== undefined)
|
|
1619
|
+
data.lastValueWriteAt.delete(atom);
|
|
1620
|
+
const parent = data.parent;
|
|
1621
|
+
if (parent) {
|
|
1622
|
+
const scopes = parent.scopeValueIndex.get(atom);
|
|
1623
|
+
if (scopes) {
|
|
1624
|
+
scopes.delete(data);
|
|
1625
|
+
if (scopes.size === 0)
|
|
1626
|
+
parent.scopeValueIndex.delete(atom);
|
|
1627
|
+
}
|
|
1628
|
+
data.scopeIndexKeys.delete(atom);
|
|
1629
|
+
}
|
|
1630
|
+
return true;
|
|
1631
|
+
};
|
|
1632
|
+
var reDelegateScopeSubscriptions = (atom, data) => {
|
|
1633
|
+
const subs = data.subscriptions.get(atom);
|
|
1634
|
+
if (subs) {
|
|
1635
|
+
for (const sub of subs)
|
|
1636
|
+
sub.reDelegate?.();
|
|
1637
|
+
}
|
|
1638
|
+
};
|
|
1639
|
+
var effectiveValueAfterUnset = (atom, data) => {
|
|
1640
|
+
const parent = data.parent;
|
|
1641
|
+
if (parent) {
|
|
1642
|
+
const initSet = new Set;
|
|
1643
|
+
const value = getState(atom, parent, initSet);
|
|
1644
|
+
if (initSet.size > 0)
|
|
1645
|
+
propagateAtomUpdate([...initSet], parent, true);
|
|
1646
|
+
return value;
|
|
1647
|
+
}
|
|
1648
|
+
if (data.values.has(atom))
|
|
1649
|
+
return data.values.get(atom);
|
|
1650
|
+
return getAtomInitValue(atom, data, new Set);
|
|
1651
|
+
};
|
|
1652
|
+
var unsetValue = (atom, data) => {
|
|
1653
|
+
if (!isAtom(atom))
|
|
1654
|
+
throw new Error(InvalidStateError);
|
|
1655
|
+
if (!detachOwnValue(atom, data))
|
|
1656
|
+
return;
|
|
1657
|
+
if (hasChangeListener(data)) {
|
|
1658
|
+
const sink = createChangeSink(undefined, "unset");
|
|
1659
|
+
reportUnsetAtom(atom, data, effectiveValueAfterUnset(atom, data), sink);
|
|
1660
|
+
propagateAtomUpdate([atom], data, false, undefined, sink, false, false);
|
|
1661
|
+
reDelegateScopeSubscriptions(atom, data);
|
|
1662
|
+
flushChangeSink(sink);
|
|
1663
|
+
} else {
|
|
1664
|
+
propagateAtomUpdate([atom], data, false);
|
|
1665
|
+
reDelegateScopeSubscriptions(atom, data);
|
|
1666
|
+
}
|
|
1667
|
+
};
|
|
1668
|
+
|
|
1290
1669
|
// src/lib/createStoreData.ts
|
|
1291
1670
|
var nextId = 0;
|
|
1292
1671
|
var generateId = () => "__valdres_store_" + nextId++;
|
|
@@ -1320,7 +1699,10 @@ Object.defineProperties(lazyProto, {
|
|
|
1320
1699
|
function createStoreData(id, parent, options) {
|
|
1321
1700
|
const data = Object.create(lazyProto);
|
|
1322
1701
|
data.id = id ?? generateId();
|
|
1323
|
-
|
|
1702
|
+
const enumerable = options?.enumerable ?? parent?.enumerable ?? false;
|
|
1703
|
+
if (enumerable)
|
|
1704
|
+
data.enumerable = true;
|
|
1705
|
+
data.values = enumerable ? new Map : new WeakMap;
|
|
1324
1706
|
data.scopes = new Map;
|
|
1325
1707
|
data.scopeValueIndex = new WeakMap;
|
|
1326
1708
|
data.pendingDefaults = new WeakMap;
|
|
@@ -1341,7 +1723,42 @@ var deleteFamilyAtom = (atom, data) => {
|
|
|
1341
1723
|
if (atom.family) {
|
|
1342
1724
|
atom.family.release(...atom.familyArgs);
|
|
1343
1725
|
}
|
|
1344
|
-
propagateDeletedAtoms([atom], data);
|
|
1726
|
+
propagateDeletedAtoms([atom], data, undefined, undefined, undefined, undefined, "delete");
|
|
1727
|
+
};
|
|
1728
|
+
|
|
1729
|
+
// src/lib/onStoreChange.ts
|
|
1730
|
+
var onStoreChange = (callback, data, options) => {
|
|
1731
|
+
const atoms = options?.atoms ?? true;
|
|
1732
|
+
const selectors = options?.selectors ?? false;
|
|
1733
|
+
if (!atoms && !selectors)
|
|
1734
|
+
return () => {};
|
|
1735
|
+
let listeners = data.changeListeners;
|
|
1736
|
+
if (!listeners) {
|
|
1737
|
+
listeners = new Map;
|
|
1738
|
+
data.changeListeners = listeners;
|
|
1739
|
+
}
|
|
1740
|
+
const prev = listeners.get(callback);
|
|
1741
|
+
listeners.set(callback, { atoms, selectors });
|
|
1742
|
+
if (!prev)
|
|
1743
|
+
changeListenerRegistry.count++;
|
|
1744
|
+
const prevSelectors = prev?.selectors ?? false;
|
|
1745
|
+
if (selectors && !prevSelectors)
|
|
1746
|
+
changeListenerRegistry.selectorCount++;
|
|
1747
|
+
else if (!selectors && prevSelectors)
|
|
1748
|
+
changeListenerRegistry.selectorCount--;
|
|
1749
|
+
return () => {
|
|
1750
|
+
const current = data.changeListeners;
|
|
1751
|
+
if (!current)
|
|
1752
|
+
return;
|
|
1753
|
+
const flags = current.get(callback);
|
|
1754
|
+
if (flags && current.delete(callback)) {
|
|
1755
|
+
changeListenerRegistry.count--;
|
|
1756
|
+
if (flags.selectors)
|
|
1757
|
+
changeListenerRegistry.selectorCount--;
|
|
1758
|
+
if (current.size === 0)
|
|
1759
|
+
data.changeListeners = undefined;
|
|
1760
|
+
}
|
|
1761
|
+
};
|
|
1345
1762
|
};
|
|
1346
1763
|
|
|
1347
1764
|
// src/lib/resetAtom.ts
|
|
@@ -1350,7 +1767,7 @@ var resetAtom = (atom, data) => {
|
|
|
1350
1767
|
let value = getAtomInitValue(atom, data, initializedAtomsSet);
|
|
1351
1768
|
setValueInData(atom, value, data);
|
|
1352
1769
|
if (!isPromiseLike(value)) {
|
|
1353
|
-
propagateAtomUpdate([atom], data);
|
|
1770
|
+
propagateAtomUpdate([atom], data, false, undefined, "reset");
|
|
1354
1771
|
}
|
|
1355
1772
|
if (initializedAtomsSet.size > 0) {
|
|
1356
1773
|
throw new Error("Todo - propagateAtomUpdate on reset");
|
|
@@ -1358,6 +1775,38 @@ var resetAtom = (atom, data) => {
|
|
|
1358
1775
|
return value;
|
|
1359
1776
|
};
|
|
1360
1777
|
|
|
1778
|
+
// src/lib/snapshot.ts
|
|
1779
|
+
var warnedStores = new WeakSet;
|
|
1780
|
+
var collect = (data, scope, out) => {
|
|
1781
|
+
for (const [state, value] of data.values) {
|
|
1782
|
+
if (state.__valdresInternal)
|
|
1783
|
+
continue;
|
|
1784
|
+
if (isAtomFamily(state) || isSelectorFamily(state))
|
|
1785
|
+
continue;
|
|
1786
|
+
out.push({
|
|
1787
|
+
type: isSelector(state) ? "selector" : "atom",
|
|
1788
|
+
state,
|
|
1789
|
+
value,
|
|
1790
|
+
scope
|
|
1791
|
+
});
|
|
1792
|
+
}
|
|
1793
|
+
for (const [id, scopeData] of data.scopes) {
|
|
1794
|
+
collect(scopeData, [...scope, id], out);
|
|
1795
|
+
}
|
|
1796
|
+
};
|
|
1797
|
+
var snapshot = (data) => {
|
|
1798
|
+
if (!data.enumerable) {
|
|
1799
|
+
if (!warnedStores.has(data)) {
|
|
1800
|
+
warnedStores.add(data);
|
|
1801
|
+
console.warn("store.snapshot() requires an enumerable store. Create it with " + "`store({ enumerable: true })` or `store(id, { enumerable: true })` " + "to retain state enumerably. Returning [].");
|
|
1802
|
+
}
|
|
1803
|
+
return [];
|
|
1804
|
+
}
|
|
1805
|
+
const out = [];
|
|
1806
|
+
collect(data, [], out);
|
|
1807
|
+
return out;
|
|
1808
|
+
};
|
|
1809
|
+
|
|
1361
1810
|
// src/utils/isFamily.ts
|
|
1362
1811
|
var isFamily = (state) => isAtomFamily(state) || isSelectorFamily(state);
|
|
1363
1812
|
|
|
@@ -1447,11 +1896,11 @@ var installMaxAgeTimer = (state, data) => {
|
|
|
1447
1896
|
const existing = globalState?.maxAgeInterval;
|
|
1448
1897
|
if (existing) {
|
|
1449
1898
|
existing.refCount++;
|
|
1450
|
-
const metaAtom2 = state.__cacheMeta ??= { equal, defaultValue: null };
|
|
1899
|
+
const metaAtom2 = state.__cacheMeta ??= { equal, defaultValue: null, __valdresInternal: true };
|
|
1451
1900
|
for (const s of globalState.stores) {
|
|
1452
1901
|
if (s !== data && s.values.has(metaAtom2)) {
|
|
1453
1902
|
setValueInData(metaAtom2, s.values.get(metaAtom2), data);
|
|
1454
|
-
propagateAtomUpdate([metaAtom2], data);
|
|
1903
|
+
propagateAtomUpdate([metaAtom2], data, false, undefined, "revalidate");
|
|
1455
1904
|
break;
|
|
1456
1905
|
}
|
|
1457
1906
|
}
|
|
@@ -1478,7 +1927,7 @@ var installMaxAgeTimer = (state, data) => {
|
|
|
1478
1927
|
const getMaxAge = () => resolveReactive(state.maxAge, data);
|
|
1479
1928
|
const getSWR = () => state.staleWhileRevalidate !== undefined ? resolveReactive(state.staleWhileRevalidate, data) : Infinity;
|
|
1480
1929
|
const getStaleIfError = () => state.staleIfError !== undefined ? resolveReactive(state.staleIfError, data) : Infinity;
|
|
1481
|
-
const metaAtom = state.__cacheMeta ??= { equal, defaultValue: null };
|
|
1930
|
+
const metaAtom = state.__cacheMeta ??= { equal, defaultValue: null, __valdresInternal: true };
|
|
1482
1931
|
const updateMeta = () => {
|
|
1483
1932
|
const meta = {
|
|
1484
1933
|
isRevalidating: revalidating,
|
|
@@ -1490,11 +1939,11 @@ var installMaxAgeTimer = (state, data) => {
|
|
|
1490
1939
|
if (globalState) {
|
|
1491
1940
|
for (const store of globalState.stores) {
|
|
1492
1941
|
setValueInData(metaAtom, meta, store);
|
|
1493
|
-
propagateAtomUpdate([metaAtom], store);
|
|
1942
|
+
propagateAtomUpdate([metaAtom], store, false, undefined, "revalidate");
|
|
1494
1943
|
}
|
|
1495
1944
|
} else {
|
|
1496
1945
|
setValueInData(metaAtom, meta, data);
|
|
1497
|
-
propagateAtomUpdate([metaAtom], data);
|
|
1946
|
+
propagateAtomUpdate([metaAtom], data, false, undefined, "revalidate");
|
|
1498
1947
|
}
|
|
1499
1948
|
};
|
|
1500
1949
|
const isPastStaleIfErrorWindow = () => {
|
|
@@ -1505,11 +1954,11 @@ var installMaxAgeTimer = (state, data) => {
|
|
|
1505
1954
|
if (globalState) {
|
|
1506
1955
|
for (const store of globalState.stores) {
|
|
1507
1956
|
setValueInData(atom, val, store);
|
|
1508
|
-
propagateAtomUpdate([atom], store);
|
|
1957
|
+
propagateAtomUpdate([atom], store, false, undefined, "revalidate");
|
|
1509
1958
|
}
|
|
1510
1959
|
} else {
|
|
1511
1960
|
setValueInData(atom, val, data);
|
|
1512
|
-
propagateAtomUpdate([atom], data);
|
|
1961
|
+
propagateAtomUpdate([atom], data, false, undefined, "revalidate");
|
|
1513
1962
|
}
|
|
1514
1963
|
};
|
|
1515
1964
|
const getValueStore = () => {
|
|
@@ -1640,15 +2089,24 @@ var installMaxAgeTimer = (state, data) => {
|
|
|
1640
2089
|
var subscribe = (state, callback, requireDeepEqualCheckBeforeCallback, data) => {
|
|
1641
2090
|
let parentUnsubscribe;
|
|
1642
2091
|
let dropDelegate;
|
|
1643
|
-
|
|
2092
|
+
let reDelegate;
|
|
2093
|
+
if (data.parent && (isAtom(state) || isAtomFamily(state))) {
|
|
1644
2094
|
const originalCallback = callback;
|
|
1645
|
-
|
|
2095
|
+
const delegateToParent = () => subscribe(state, originalCallback, requireDeepEqualCheckBeforeCallback, data.parent);
|
|
2096
|
+
if (isAtomFamily(state) || !data.values.has(state)) {
|
|
2097
|
+
parentUnsubscribe = delegateToParent();
|
|
2098
|
+
}
|
|
1646
2099
|
dropDelegate = () => {
|
|
1647
2100
|
if (parentUnsubscribe) {
|
|
1648
2101
|
parentUnsubscribe();
|
|
1649
2102
|
parentUnsubscribe = undefined;
|
|
1650
2103
|
}
|
|
1651
2104
|
};
|
|
2105
|
+
reDelegate = () => {
|
|
2106
|
+
if (!parentUnsubscribe) {
|
|
2107
|
+
parentUnsubscribe = delegateToParent();
|
|
2108
|
+
}
|
|
2109
|
+
};
|
|
1652
2110
|
callback = (arg) => {
|
|
1653
2111
|
dropDelegate();
|
|
1654
2112
|
originalCallback(arg);
|
|
@@ -1673,13 +2131,15 @@ var subscribe = (state, callback, requireDeepEqualCheckBeforeCallback, data) =>
|
|
|
1673
2131
|
callback,
|
|
1674
2132
|
state,
|
|
1675
2133
|
requireDeepEqualCheckBeforeCallback,
|
|
1676
|
-
reRoot: dropDelegate
|
|
2134
|
+
reRoot: dropDelegate,
|
|
2135
|
+
reDelegate
|
|
1677
2136
|
};
|
|
1678
2137
|
} else {
|
|
1679
2138
|
subscription = {
|
|
1680
2139
|
callback,
|
|
1681
2140
|
requireDeepEqualCheckBeforeCallback,
|
|
1682
|
-
reRoot: dropDelegate
|
|
2141
|
+
reRoot: dropDelegate,
|
|
2142
|
+
reDelegate
|
|
1683
2143
|
};
|
|
1684
2144
|
}
|
|
1685
2145
|
subscribers.add(subscription);
|
|
@@ -1735,10 +2195,10 @@ var writeAtoms = (pairs, data, initializedAtomsSet, skipOnSet = false, onSetQueu
|
|
|
1735
2195
|
};
|
|
1736
2196
|
|
|
1737
2197
|
// src/lib/setAtoms.ts
|
|
1738
|
-
var setAtoms = (pairs, data, initializedAtomsSet, skipOnSet = false) => {
|
|
2198
|
+
var setAtoms = (pairs, data, initializedAtomsSet, skipOnSet = false, report) => {
|
|
1739
2199
|
const updatedAtoms = writeAtoms(pairs, data, initializedAtomsSet, skipOnSet);
|
|
1740
2200
|
if (updatedAtoms.length > 0) {
|
|
1741
|
-
propagateAtomUpdate(updatedAtoms, data);
|
|
2201
|
+
propagateAtomUpdate(updatedAtoms, data, false, undefined, report);
|
|
1742
2202
|
}
|
|
1743
2203
|
};
|
|
1744
2204
|
|
|
@@ -1753,9 +2213,11 @@ class Transaction {
|
|
|
1753
2213
|
data;
|
|
1754
2214
|
parentTransaction;
|
|
1755
2215
|
dirty;
|
|
2216
|
+
name;
|
|
1756
2217
|
_scopedTransactions;
|
|
1757
2218
|
_initializedAtomsSet;
|
|
1758
2219
|
_deleteSet;
|
|
2220
|
+
_unsetSet;
|
|
1759
2221
|
_selectorDependencies;
|
|
1760
2222
|
_selectorCache;
|
|
1761
2223
|
_atomMap;
|
|
@@ -1763,6 +2225,7 @@ class Transaction {
|
|
|
1763
2225
|
this.data = data;
|
|
1764
2226
|
this.parentTransaction = parentTransaction;
|
|
1765
2227
|
this.dirty = false;
|
|
2228
|
+
this.name = undefined;
|
|
1766
2229
|
this._atomMap = new Map;
|
|
1767
2230
|
if (childTransaction) {
|
|
1768
2231
|
this._scopedTransactions = new Map([
|
|
@@ -1773,6 +2236,9 @@ class Transaction {
|
|
|
1773
2236
|
hasTxnOrData = (state) => {
|
|
1774
2237
|
if (this._atomMap.has(state))
|
|
1775
2238
|
return true;
|
|
2239
|
+
if (this._unsetSet?.has(state)) {
|
|
2240
|
+
return this.parentTransaction ? this.parentTransaction.hasTxnOrData(state) : false;
|
|
2241
|
+
}
|
|
1776
2242
|
if (this.data.values.has(state))
|
|
1777
2243
|
return true;
|
|
1778
2244
|
if (this.parentTransaction)
|
|
@@ -1783,6 +2249,9 @@ class Transaction {
|
|
|
1783
2249
|
if (this._atomMap.has(state)) {
|
|
1784
2250
|
return this._atomMap.get(state);
|
|
1785
2251
|
}
|
|
2252
|
+
if (this._unsetSet?.has(state)) {
|
|
2253
|
+
return this.parentTransaction ? this.parentTransaction.valueFromTxnOrData(state) : undefined;
|
|
2254
|
+
}
|
|
1786
2255
|
if (this.data.values.has(state)) {
|
|
1787
2256
|
return this.data.values.get(state);
|
|
1788
2257
|
}
|
|
@@ -1795,6 +2264,9 @@ class Transaction {
|
|
|
1795
2264
|
if (this.hasTxnOrData(state)) {
|
|
1796
2265
|
return this.valueFromTxnOrData(state);
|
|
1797
2266
|
}
|
|
2267
|
+
if (this._unsetSet?.has(state)) {
|
|
2268
|
+
return this.data.parent ? getState(state, this.data.parent, this.initializedAtomsSet) : getAtomInitValue(state, this.data, this.initializedAtomsSet);
|
|
2269
|
+
}
|
|
1798
2270
|
return getState(state, this.data, this.initializedAtomsSet);
|
|
1799
2271
|
} else if (isSelector(state)) {
|
|
1800
2272
|
if (this.dirty) {
|
|
@@ -1830,6 +2302,7 @@ class Transaction {
|
|
|
1830
2302
|
resolved = deepFreeze(resolved);
|
|
1831
2303
|
}
|
|
1832
2304
|
this._atomMap.set(atom, resolved);
|
|
2305
|
+
this._unsetSet?.delete(atom);
|
|
1833
2306
|
if (!this.dirty)
|
|
1834
2307
|
this.dirty = true;
|
|
1835
2308
|
if (isFamilyAtom(atom)) {
|
|
@@ -1858,6 +2331,7 @@ class Transaction {
|
|
|
1858
2331
|
if (index.deleted.has(atom))
|
|
1859
2332
|
index.deleted.delete(atom);
|
|
1860
2333
|
this._atomMap.set(atom, value);
|
|
2334
|
+
this._unsetSet?.delete(atom);
|
|
1861
2335
|
}
|
|
1862
2336
|
index.rendered = null;
|
|
1863
2337
|
index.renderedArray = null;
|
|
@@ -1881,6 +2355,22 @@ class Transaction {
|
|
|
1881
2355
|
this._atomMap.delete(atom);
|
|
1882
2356
|
}
|
|
1883
2357
|
};
|
|
2358
|
+
unset = (atom) => {
|
|
2359
|
+
if (!isAtom(atom))
|
|
2360
|
+
throw new Error("unset() expects an atom.");
|
|
2361
|
+
this._atomMap.delete(atom);
|
|
2362
|
+
if (!this._unsetSet)
|
|
2363
|
+
this._unsetSet = new Set;
|
|
2364
|
+
this._unsetSet.add(atom);
|
|
2365
|
+
};
|
|
2366
|
+
applyUnsets = (unsetSet, data) => {
|
|
2367
|
+
const unsetAtoms = [];
|
|
2368
|
+
for (const atom of unsetSet) {
|
|
2369
|
+
if (detachOwnValue(atom, data))
|
|
2370
|
+
unsetAtoms.push(atom);
|
|
2371
|
+
}
|
|
2372
|
+
return unsetAtoms;
|
|
2373
|
+
};
|
|
1884
2374
|
scope = (scopeId, callback) => {
|
|
1885
2375
|
if (this.data.scopes.has(scopeId)) {
|
|
1886
2376
|
return this.scopedTransaction(scopeId).execute(callback, false);
|
|
@@ -1900,6 +2390,7 @@ class Transaction {
|
|
|
1900
2390
|
reset = (atom) => {
|
|
1901
2391
|
const value = getAtomInitValue(atom, this.data, this.initializedAtomsSet);
|
|
1902
2392
|
this._atomMap.set(atom, value);
|
|
2393
|
+
this._unsetSet?.delete(atom);
|
|
1903
2394
|
return value;
|
|
1904
2395
|
};
|
|
1905
2396
|
execute = (callback, autoCommit = true) => {
|
|
@@ -1916,19 +2407,58 @@ class Transaction {
|
|
|
1916
2407
|
}
|
|
1917
2408
|
};
|
|
1918
2409
|
commit = () => {
|
|
2410
|
+
if (changeListenerRegistry.count === 0) {
|
|
2411
|
+
this.commitWork(undefined);
|
|
2412
|
+
return;
|
|
2413
|
+
}
|
|
2414
|
+
const sink = createChangeSink(this.name);
|
|
2415
|
+
try {
|
|
2416
|
+
this.commitWork(sink);
|
|
2417
|
+
} catch (error) {
|
|
2418
|
+
try {
|
|
2419
|
+
flushChangeSink(sink);
|
|
2420
|
+
} catch {}
|
|
2421
|
+
throw error;
|
|
2422
|
+
}
|
|
2423
|
+
flushChangeSink(sink);
|
|
2424
|
+
};
|
|
2425
|
+
commitWork = (sink) => {
|
|
1919
2426
|
if (!this._scopedTransactions) {
|
|
1920
2427
|
const initializedAtomsSet = new Set;
|
|
1921
|
-
if (this.
|
|
2428
|
+
if (this._unsetSet?.size) {
|
|
1922
2429
|
const notify2 = new Map;
|
|
1923
2430
|
const updatedAtoms = writeAtoms(this._atomMap, this.data, initializedAtomsSet);
|
|
1924
2431
|
if (updatedAtoms.length > 0) {
|
|
1925
|
-
propagateAtomUpdate(updatedAtoms, this.data, false, notify2);
|
|
2432
|
+
propagateAtomUpdate(updatedAtoms, this.data, false, notify2, sink);
|
|
2433
|
+
}
|
|
2434
|
+
if (this._deleteSet?.size) {
|
|
2435
|
+
deleteAtomFamilyAtoms(this._deleteSet, this.data);
|
|
2436
|
+
propagateDeletedAtoms([...this._deleteSet], this.data, undefined, undefined, undefined, notify2, sink);
|
|
2437
|
+
}
|
|
2438
|
+
const unsetAtoms = this.applyUnsets(this._unsetSet, this.data);
|
|
2439
|
+
if (unsetAtoms.length > 0) {
|
|
2440
|
+
if (sink) {
|
|
2441
|
+
for (const atom of unsetAtoms) {
|
|
2442
|
+
reportUnsetAtom(atom, this.data, effectiveValueAfterUnset(atom, this.data), sink);
|
|
2443
|
+
}
|
|
2444
|
+
}
|
|
2445
|
+
propagateAtomUpdate(unsetAtoms, this.data, false, notify2, sink, false, false);
|
|
2446
|
+
}
|
|
2447
|
+
notifyDeferred(notify2);
|
|
2448
|
+
for (const atom of unsetAtoms) {
|
|
2449
|
+
reDelegateScopeSubscriptions(atom, this.data);
|
|
2450
|
+
}
|
|
2451
|
+
} else if (this._deleteSet?.size) {
|
|
2452
|
+
const notify2 = new Map;
|
|
2453
|
+
const updatedAtoms = writeAtoms(this._atomMap, this.data, initializedAtomsSet);
|
|
2454
|
+
if (updatedAtoms.length > 0) {
|
|
2455
|
+
propagateAtomUpdate(updatedAtoms, this.data, false, notify2, sink);
|
|
1926
2456
|
}
|
|
1927
2457
|
deleteAtomFamilyAtoms(this._deleteSet, this.data);
|
|
1928
|
-
propagateDeletedAtoms([...this._deleteSet], this.data, undefined, undefined, undefined, notify2);
|
|
2458
|
+
propagateDeletedAtoms([...this._deleteSet], this.data, undefined, undefined, undefined, notify2, sink);
|
|
1929
2459
|
notifyDeferred(notify2);
|
|
1930
2460
|
} else {
|
|
1931
|
-
setAtoms(this._atomMap, this.data, initializedAtomsSet);
|
|
2461
|
+
setAtoms(this._atomMap, this.data, initializedAtomsSet, false, sink);
|
|
1932
2462
|
}
|
|
1933
2463
|
return;
|
|
1934
2464
|
}
|
|
@@ -1942,6 +2472,9 @@ class Transaction {
|
|
|
1942
2472
|
deleteAtomFamilyAtoms(txn._deleteSet, entry.data);
|
|
1943
2473
|
entry.deleted = [...txn._deleteSet];
|
|
1944
2474
|
}
|
|
2475
|
+
if (txn._unsetSet?.size) {
|
|
2476
|
+
entry.unsetAtoms = txn.applyUnsets(txn._unsetSet, entry.data);
|
|
2477
|
+
}
|
|
1945
2478
|
}
|
|
1946
2479
|
for (const entry of plan) {
|
|
1947
2480
|
for (const [atom, value, data] of entry.onSets) {
|
|
@@ -1949,15 +2482,30 @@ class Transaction {
|
|
|
1949
2482
|
}
|
|
1950
2483
|
}
|
|
1951
2484
|
const notify = new Map;
|
|
1952
|
-
for (const { data, updatedAtoms, deleted } of plan) {
|
|
2485
|
+
for (const { data, updatedAtoms, deleted, unsetAtoms } of plan) {
|
|
1953
2486
|
if (updatedAtoms.length > 0) {
|
|
1954
|
-
propagateAtomUpdate(updatedAtoms, data, false, notify);
|
|
2487
|
+
propagateAtomUpdate(updatedAtoms, data, false, notify, sink);
|
|
1955
2488
|
}
|
|
1956
2489
|
if (deleted) {
|
|
1957
|
-
propagateDeletedAtoms(deleted, data, undefined, undefined, undefined, notify);
|
|
2490
|
+
propagateDeletedAtoms(deleted, data, undefined, undefined, undefined, notify, sink);
|
|
2491
|
+
}
|
|
2492
|
+
if (unsetAtoms && unsetAtoms.length > 0) {
|
|
2493
|
+
if (sink) {
|
|
2494
|
+
for (const atom of unsetAtoms) {
|
|
2495
|
+
reportUnsetAtom(atom, data, effectiveValueAfterUnset(atom, data), sink);
|
|
2496
|
+
}
|
|
2497
|
+
}
|
|
2498
|
+
propagateAtomUpdate(unsetAtoms, data, false, notify, sink, false, false);
|
|
1958
2499
|
}
|
|
1959
2500
|
}
|
|
1960
2501
|
notifyDeferred(notify);
|
|
2502
|
+
for (const { data, unsetAtoms } of plan) {
|
|
2503
|
+
if (unsetAtoms) {
|
|
2504
|
+
for (const atom of unsetAtoms) {
|
|
2505
|
+
reDelegateScopeSubscriptions(atom, data);
|
|
2506
|
+
}
|
|
2507
|
+
}
|
|
2508
|
+
}
|
|
1961
2509
|
};
|
|
1962
2510
|
collectStores = (plan) => {
|
|
1963
2511
|
plan.push({
|
|
@@ -1965,6 +2513,7 @@ class Transaction {
|
|
|
1965
2513
|
data: this.data,
|
|
1966
2514
|
updatedAtoms: [],
|
|
1967
2515
|
deleted: undefined,
|
|
2516
|
+
unsetAtoms: undefined,
|
|
1968
2517
|
onSets: []
|
|
1969
2518
|
});
|
|
1970
2519
|
if (this._scopedTransactions) {
|
|
@@ -2007,7 +2556,13 @@ class Transaction {
|
|
|
2007
2556
|
if (moveUpIfParent && this.parentTransaction)
|
|
2008
2557
|
return this.parentTransaction.cloneFamilyIntoTxn(family, parentIndex, moveUpIfParent);
|
|
2009
2558
|
const currentFamilyList = this.get(family);
|
|
2010
|
-
const
|
|
2559
|
+
const scopeFirstMaterialization = this.data.parent && !this._atomMap.has(family) && !this.data.values.has(family);
|
|
2560
|
+
let clonedIndex;
|
|
2561
|
+
if (scopeFirstMaterialization) {
|
|
2562
|
+
clonedIndex = createAtomFamilyIndex(parentIndex ?? currentFamilyList.__index);
|
|
2563
|
+
} else {
|
|
2564
|
+
clonedIndex = cloneAtomFamilyIndex(currentFamilyList.__index, parentIndex);
|
|
2565
|
+
}
|
|
2011
2566
|
if (this._scopedTransactions?.size) {
|
|
2012
2567
|
for (const [, scopedTxn] of this._scopedTransactions) {
|
|
2013
2568
|
scopedTxn.cloneFamilyIntoTxn(family, clonedIndex, false);
|
|
@@ -2028,8 +2583,9 @@ class Transaction {
|
|
|
2028
2583
|
}
|
|
2029
2584
|
}
|
|
2030
2585
|
}
|
|
2031
|
-
var transaction = (callback, data) => {
|
|
2586
|
+
var transaction = (callback, data, name) => {
|
|
2032
2587
|
const txn = new Transaction(data);
|
|
2588
|
+
txn.name = name;
|
|
2033
2589
|
return txn.execute(callback);
|
|
2034
2590
|
};
|
|
2035
2591
|
|
|
@@ -2140,12 +2696,19 @@ function storeFromStoreData(data, detach) {
|
|
|
2140
2696
|
flushPendingTxn();
|
|
2141
2697
|
return deleteFamilyAtom(atom, data);
|
|
2142
2698
|
};
|
|
2699
|
+
const unset = (atom) => {
|
|
2700
|
+
if (data.batchUpdates)
|
|
2701
|
+
flushPendingTxn();
|
|
2702
|
+
return unsetValue(atom, data);
|
|
2703
|
+
};
|
|
2143
2704
|
const sub = (state, callback, deepEqualCheckBeforeCallback = true) => subscribe(state, callback, deepEqualCheckBeforeCallback, data);
|
|
2144
|
-
const txn = (callback) => {
|
|
2705
|
+
const txn = (callback, name) => {
|
|
2145
2706
|
if (data.batchUpdates)
|
|
2146
2707
|
flushPendingTxn();
|
|
2147
|
-
return transaction(callback, data);
|
|
2708
|
+
return transaction(callback, data, name);
|
|
2148
2709
|
};
|
|
2710
|
+
const onChange = (callback, options) => onStoreChange(callback, data, options);
|
|
2711
|
+
const storeSnapshot = () => snapshot(data);
|
|
2149
2712
|
const scope = (scopeId, callback) => {
|
|
2150
2713
|
if (callback) {
|
|
2151
2714
|
if (!data.scopes.has(scopeId)) {
|
|
@@ -2198,8 +2761,11 @@ function storeFromStoreData(data, detach) {
|
|
|
2198
2761
|
txn,
|
|
2199
2762
|
reset,
|
|
2200
2763
|
del,
|
|
2764
|
+
unset,
|
|
2201
2765
|
data,
|
|
2202
2766
|
scope,
|
|
2767
|
+
onChange,
|
|
2768
|
+
snapshot: storeSnapshot,
|
|
2203
2769
|
detach
|
|
2204
2770
|
};
|
|
2205
2771
|
} else {
|
|
@@ -2210,8 +2776,11 @@ function storeFromStoreData(data, detach) {
|
|
|
2210
2776
|
txn,
|
|
2211
2777
|
reset,
|
|
2212
2778
|
del,
|
|
2779
|
+
unset,
|
|
2213
2780
|
data,
|
|
2214
|
-
scope
|
|
2781
|
+
scope,
|
|
2782
|
+
onChange,
|
|
2783
|
+
snapshot: storeSnapshot
|
|
2215
2784
|
};
|
|
2216
2785
|
}
|
|
2217
2786
|
}
|
|
@@ -2392,12 +2961,13 @@ var unmountOrphanedDeps = (state, data, visited) => {
|
|
|
2392
2961
|
};
|
|
2393
2962
|
|
|
2394
2963
|
// src/store.ts
|
|
2395
|
-
|
|
2396
|
-
const
|
|
2397
|
-
const
|
|
2964
|
+
function store(idOrOptions, maybeOptions) {
|
|
2965
|
+
const optionsObject = typeof idOrOptions === "object" && idOrOptions !== null ? idOrOptions : undefined;
|
|
2966
|
+
const id = typeof idOrOptions === "string" ? idOrOptions : optionsObject?.id;
|
|
2967
|
+
const options = optionsObject ?? maybeOptions;
|
|
2398
2968
|
const data = createStoreData(id, undefined, options);
|
|
2399
2969
|
return storeFromStoreData(data);
|
|
2400
|
-
}
|
|
2970
|
+
}
|
|
2401
2971
|
|
|
2402
2972
|
// src/globalStore.ts
|
|
2403
2973
|
var globalStore = Object.assign(store("valdres-global-store"), {
|
|
@@ -2451,9 +3021,9 @@ var globalAtom = (defaultValue, options) => {
|
|
|
2451
3021
|
const getSelf = () => globalStore.get(atom);
|
|
2452
3022
|
const setSelf = (newValue) => globalStore.set(atom, newValue);
|
|
2453
3023
|
const resetSelf = () => {
|
|
2454
|
-
const
|
|
3024
|
+
const snapshot2 = [...stores];
|
|
2455
3025
|
const subscribedStores = [];
|
|
2456
|
-
for (const s of
|
|
3026
|
+
for (const s of snapshot2) {
|
|
2457
3027
|
if (isLive(atom, s)) {
|
|
2458
3028
|
subscribedStores.push(s);
|
|
2459
3029
|
}
|
|
@@ -2463,7 +3033,7 @@ var globalAtom = (defaultValue, options) => {
|
|
|
2463
3033
|
if (!firstError)
|
|
2464
3034
|
firstError = e;
|
|
2465
3035
|
};
|
|
2466
|
-
for (const s of
|
|
3036
|
+
for (const s of snapshot2) {
|
|
2467
3037
|
try {
|
|
2468
3038
|
unmountAtom(atom, s);
|
|
2469
3039
|
} catch (e) {
|
|
@@ -2475,11 +3045,11 @@ var globalAtom = (defaultValue, options) => {
|
|
|
2475
3045
|
atom.maxAgeInterval.refCount = 0;
|
|
2476
3046
|
atom.maxAgeInterval = undefined;
|
|
2477
3047
|
}
|
|
2478
|
-
for (const store2 of
|
|
3048
|
+
for (const store2 of snapshot2) {
|
|
2479
3049
|
stores.delete(store2);
|
|
2480
3050
|
store2.values.delete(atom);
|
|
2481
3051
|
try {
|
|
2482
|
-
propagateAtomUpdate([atom], store2);
|
|
3052
|
+
propagateAtomUpdate([atom], store2, false, undefined, "reset");
|
|
2483
3053
|
} catch (e) {
|
|
2484
3054
|
recordError(e);
|
|
2485
3055
|
}
|
|
@@ -2703,9 +3273,10 @@ var cacheMeta = (sourceAtom) => {
|
|
|
2703
3273
|
if (sourceAtom.__cacheMetaSelector)
|
|
2704
3274
|
return sourceAtom.__cacheMetaSelector;
|
|
2705
3275
|
if (!sourceAtom.__cacheMeta) {
|
|
2706
|
-
sourceAtom.__cacheMeta = { equal, defaultValue: null };
|
|
3276
|
+
sourceAtom.__cacheMeta = { equal, defaultValue: null, __valdresInternal: true };
|
|
2707
3277
|
}
|
|
2708
3278
|
sourceAtom.__cacheMetaSelector = selector((get) => get(sourceAtom.__cacheMeta));
|
|
3279
|
+
sourceAtom.__cacheMetaSelector.__valdresInternal = true;
|
|
2709
3280
|
return sourceAtom.__cacheMetaSelector;
|
|
2710
3281
|
};
|
|
2711
3282
|
// src/indexConstructor.ts
|
|
@@ -2781,9 +3352,9 @@ var isFamilySelector = (state) => isFamilyState(state) && isSelector(state);
|
|
|
2781
3352
|
|
|
2782
3353
|
// src/index.ts
|
|
2783
3354
|
if (globalThis.__valdres__) {
|
|
2784
|
-
throw new Error(`Error! An instance of valdres is already loaded. Loaded: ${globalThis.__valdres__}. Attempted to load: ${"1.0.0-beta.
|
|
3355
|
+
throw new Error(`Error! An instance of valdres is already loaded. Loaded: ${globalThis.__valdres__}. Attempted to load: ${"1.0.0-beta.8"}`);
|
|
2785
3356
|
} else {
|
|
2786
|
-
globalThis.__valdres__ = "1.0.0-beta.
|
|
3357
|
+
globalThis.__valdres__ = "1.0.0-beta.8";
|
|
2787
3358
|
}
|
|
2788
3359
|
export {
|
|
2789
3360
|
store,
|