@solidjs/signals 2.0.0-rc.4 → 2.0.0-rc.5
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/dev.js +1169 -186
- package/dist/node.cjs +2041 -1167
- package/dist/prod/boundaries.js +4 -1
- package/dist/prod/core/async.js +124 -95
- package/dist/prod/core/constants.js +55 -1
- package/dist/prod/core/core.js +297 -222
- package/dist/prod/core/effect.js +28 -28
- package/dist/prod/core/error.js +13 -1
- package/dist/prod/core/external.js +2 -2
- package/dist/prod/core/graph.js +27 -27
- package/dist/prod/core/heap.js +30 -30
- package/dist/prod/core/lanes.js +32 -32
- package/dist/prod/core/optimistic.js +54 -54
- package/dist/prod/core/owner.js +34 -34
- package/dist/prod/core/scheduler.js +318 -137
- package/dist/prod/core/verdict.js +112 -59
- package/dist/prod/index.js +3 -3
- package/dist/prod/map.js +106 -106
- package/dist/prod/signals.js +253 -25
- package/dist/prod/store/next/optimistic.js +262 -123
- package/dist/prod/store/next/patch.js +6 -6
- package/dist/prod/store/next/projection.js +23 -19
- package/dist/prod/store/next/store.js +129 -35
- package/dist/prod/store/store.js +2 -2
- package/dist/types/core/async.d.ts +2 -0
- package/dist/types/core/attribution.d.ts +9 -4
- package/dist/types/core/constants.d.ts +54 -0
- package/dist/types/core/core.d.ts +19 -20
- package/dist/types/core/error.d.ts +9 -0
- package/dist/types/core/index.d.ts +2 -2
- package/dist/types/core/scheduler.d.ts +34 -0
- package/dist/types/core/types.d.ts +12 -0
- package/dist/types/index.d.ts +3 -3
- package/dist/types/signals.d.ts +108 -0
- package/dist/types/store/next/optimistic.d.ts +13 -10
- package/dist/types/store/next/projection.d.ts +1 -1
- package/dist/types/store/next/store.d.ts +22 -0
- package/dist/types/store/next/target.d.ts +15 -0
- package/dist/types-cjs/core/async.d.cts +2 -0
- package/dist/types-cjs/core/attribution.d.cts +9 -4
- package/dist/types-cjs/core/constants.d.cts +54 -0
- package/dist/types-cjs/core/core.d.cts +19 -20
- package/dist/types-cjs/core/error.d.cts +9 -0
- package/dist/types-cjs/core/index.d.cts +2 -2
- package/dist/types-cjs/core/scheduler.d.cts +34 -0
- package/dist/types-cjs/core/types.d.cts +12 -0
- package/dist/types-cjs/index.d.cts +3 -3
- package/dist/types-cjs/signals.d.cts +108 -0
- package/dist/types-cjs/store/next/optimistic.d.cts +13 -10
- package/dist/types-cjs/store/next/projection.d.cts +1 -1
- package/dist/types-cjs/store/next/store.d.cts +22 -0
- package/dist/types-cjs/store/next/target.d.cts +15 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { unwrapOverride, $REFRESH, CONFIG_OWNED_WRITE, NOT_PENDING, CONFIG_OPTIMISTIC, STATUS_UNINITIALIZED, STATUS_ERROR, CONFIG_CHILDREN_FORBIDDEN } from "../../core/constants.js";
|
|
1
|
+
import { unwrapOverride, $REFRESH, CONFIG_OWNED_WRITE, NOT_PENDING, CONFIG_OPTIMISTIC, CONFIG_HELD_TRUTH, STATUS_UNINITIALIZED, STATUS_ERROR, CONFIG_CHILDREN_FORBIDDEN, CONFIG_AUTHORITATIVE_READ } from "../../core/constants.js";
|
|
2
2
|
|
|
3
|
-
import { setSignal, isEqual, read, pendingCheckActive, latestReadActive, readNodeFast, READ_SLOW, signal, ext, setLatestReadActive, prepareComputed } from "../../core/core.js";
|
|
3
|
+
import { setSignal, isEqual, read, pendingCheckActive, latestReadActive, readNodeFast, READ_SLOW, signal, ext, setLatestReadActive, prepareComputed, context } from "../../core/core.js";
|
|
4
4
|
|
|
5
5
|
import { projectionWriteActive, setProjectionWriteActive, activeTransition, schedule, currentTransition, setStoreCommitHook } from "../../core/scheduler.js";
|
|
6
6
|
|
|
@@ -193,7 +193,7 @@ function getNode(e, t, n) {
|
|
|
193
193
|
// Optimistic families: arm the override slot — setSignal routes armed
|
|
194
194
|
// nodes through the core engine (lanes, ownership, reverts all native).
|
|
195
195
|
if (e.fam?.opt) {
|
|
196
|
-
ext(o).
|
|
196
|
+
ext(o).Oe = NOT_PENDING;
|
|
197
197
|
o.T |= CONFIG_OPTIMISTIC;
|
|
198
198
|
}
|
|
199
199
|
// A node born inside a live mark's identity scope inherits the mark
|
|
@@ -226,7 +226,7 @@ function getHasNode(e, t, n) {
|
|
|
226
226
|
}, e.fam?.node ?? undefined);
|
|
227
227
|
o.T |= CONFIG_OWNED_WRITE;
|
|
228
228
|
if (e.fam?.opt) {
|
|
229
|
-
ext(o).
|
|
229
|
+
ext(o).Oe = NOT_PENDING;
|
|
230
230
|
o.T |= CONFIG_OPTIMISTIC;
|
|
231
231
|
}
|
|
232
232
|
if (affectsScopesLive()) inheritAffectsMarks(o, e.v, t);
|
|
@@ -247,7 +247,7 @@ function getKeySetNode(e) {
|
|
|
247
247
|
}, e.fam?.node ?? undefined);
|
|
248
248
|
n.T |= CONFIG_OWNED_WRITE;
|
|
249
249
|
if (e.fam?.opt) {
|
|
250
|
-
ext(n).
|
|
250
|
+
ext(n).Oe = NOT_PENDING;
|
|
251
251
|
n.T |= CONFIG_OPTIMISTIC;
|
|
252
252
|
}
|
|
253
253
|
e.k = t;
|
|
@@ -267,7 +267,7 @@ function getDeepNode(e) {
|
|
|
267
267
|
}, e.fam?.node ?? undefined);
|
|
268
268
|
n.T |= CONFIG_OWNED_WRITE;
|
|
269
269
|
if (e.fam?.opt) {
|
|
270
|
-
ext(n).
|
|
270
|
+
ext(n).Oe = NOT_PENDING;
|
|
271
271
|
n.T |= CONFIG_OPTIMISTIC;
|
|
272
272
|
}
|
|
273
273
|
if (affectsScopesLive()) inheritAffectsMarks(n, e.v, $TRACK);
|
|
@@ -350,8 +350,22 @@ function cloneRaw(e, t) {
|
|
|
350
350
|
}
|
|
351
351
|
|
|
352
352
|
function ensurePB(e) {
|
|
353
|
-
if (activeTransition !== null) foldBatches.set(e, activeTransition);
|
|
354
353
|
let t = e.pb;
|
|
354
|
+
// Truth-staged backing hand-off (#3164 fold): a TENTATIVE draft opening on
|
|
355
|
+
// a target whose pending backing is truth-staged (a landing folded into a
|
|
356
|
+
// retaining transaction — it carries a foldBatches stamp) must not share
|
|
357
|
+
// the container. Tentative writes would pollute staged truth, and the
|
|
358
|
+
// tentative discard (notifyOptimisticWrites nulls pb) would destroy the
|
|
359
|
+
// landing. Park the staged backing and open a fresh draft seeded from the
|
|
360
|
+
// optimistic view below; the tentative discard restores it. The
|
|
361
|
+
// tentativePBs guard scopes this to draft OPEN: the draft's own backing
|
|
362
|
+
// (foldBatches-stamped by its first write when an action's transition is
|
|
363
|
+
// ambient) must not be parked by its own later writes.
|
|
364
|
+
if (t !== null && !tentativePBs.has(t) && e.fam?.opt === true && !projectionWriteActive && !getWriteOverride() && foldBatches.has(e)) {
|
|
365
|
+
stagedTruthPB.set(e, t);
|
|
366
|
+
t = e.pb = null;
|
|
367
|
+
}
|
|
368
|
+
if (activeTransition !== null) foldBatches.set(e, activeTransition);
|
|
355
369
|
if (t === null) {
|
|
356
370
|
// Prototype-chain overlay (#3044): plain-data non-array containers
|
|
357
371
|
// outside projection/optimistic families open drafts in O(1) — own keys
|
|
@@ -369,18 +383,19 @@ function ensurePB(e) {
|
|
|
369
383
|
// seed from committed truth — seeding overrides there would fold a lane
|
|
370
384
|
// value into the committed home ("authority wins at reveal" would break).
|
|
371
385
|
if (e.fam?.opt && !projectionWriteActive && !getWriteOverride()) {
|
|
386
|
+
tentativePBs.add(t);
|
|
372
387
|
const n = e.n;
|
|
373
388
|
if (n !== null) {
|
|
374
389
|
for (const e of Reflect.ownKeys(n)) {
|
|
375
390
|
const r = n[e];
|
|
376
|
-
if (hasActiveOverride(r)) t[e] = unwrapOverride(r.o?.
|
|
391
|
+
if (hasActiveOverride(r)) t[e] = unwrapOverride(r.o?.Oe);
|
|
377
392
|
}
|
|
378
393
|
}
|
|
379
394
|
const r = e.h;
|
|
380
395
|
if (r !== null) {
|
|
381
396
|
for (const e of Reflect.ownKeys(r)) {
|
|
382
397
|
const n = r[e];
|
|
383
|
-
if (hasActiveOverride(n) && !unwrapOverride(n.o?.
|
|
398
|
+
if (hasActiveOverride(n) && !unwrapOverride(n.o?.Oe)) delete t[e];
|
|
384
399
|
}
|
|
385
400
|
}
|
|
386
401
|
}
|
|
@@ -406,7 +421,7 @@ function ensurePB(e) {
|
|
|
406
421
|
* foldHeld's node stamps). */ function heldMaskView(e) {
|
|
407
422
|
const t = e.ht;
|
|
408
423
|
if (t === null) return null;
|
|
409
|
-
if (t !== PLAIN_HOLD && currentTransition(t)?.
|
|
424
|
+
if (t !== PLAIN_HOLD && currentTransition(t)?.sn === true) return e.ht = e.hv = null;
|
|
410
425
|
return e.hv;
|
|
411
426
|
}
|
|
412
427
|
|
|
@@ -491,6 +506,17 @@ function queueFold(e) {
|
|
|
491
506
|
* Refreshed on every write; resolved through currentTransition at drain
|
|
492
507
|
* (transitions merge — same rule as heldMaskView). */ const foldBatches = new WeakMap;
|
|
493
508
|
|
|
509
|
+
/** Parked truth-staged pending backings (#3164 fold): a tentative draft that
|
|
510
|
+
* opens while a folded landing's backing is live moves the staged container
|
|
511
|
+
* here (see ensurePB); the tentative discard in notifyOptimisticWrites
|
|
512
|
+
* restores it in place of the usual null. */ const stagedTruthPB = new WeakMap;
|
|
513
|
+
|
|
514
|
+
/** Backings opened by TENTATIVE drafts (optimistic user setters): ensurePB's
|
|
515
|
+
* truth-park must not fire against the draft's own container on its second
|
|
516
|
+
* and later writes (the first write stamps foldBatches whenever an action's
|
|
517
|
+
* transition is ambient). Entries die with their draft — tentative backings
|
|
518
|
+
* are consumed at setter exit. */ const tentativePBs = new WeakSet;
|
|
519
|
+
|
|
494
520
|
/** Committed-time privatization for parent-chain slot updates (path copying). */ function privatizeCommitted(e) {
|
|
495
521
|
if (ownedRaw.has(e.v)) return;
|
|
496
522
|
const t = cloneRaw(e.v, e);
|
|
@@ -525,7 +551,7 @@ function drainFolds() {
|
|
|
525
551
|
// keys; observed keys also hit the pending-node held check below).
|
|
526
552
|
const e = foldBatches.get(t);
|
|
527
553
|
if (e !== undefined) {
|
|
528
|
-
if (currentTransition(e).
|
|
554
|
+
if (currentTransition(e).sn === false) {
|
|
529
555
|
foldOlds.set(t, n);
|
|
530
556
|
continue;
|
|
531
557
|
}
|
|
@@ -781,7 +807,13 @@ function drainFolds() {
|
|
|
781
807
|
// IMMEDIATE — landed truth shows to untracked readers even while a
|
|
782
808
|
// downstream consumer's own async still holds the effect-level reveal
|
|
783
809
|
// (spec-async "verdicts never inherit consumers' in-flight state").
|
|
784
|
-
|
|
810
|
+
// EXCEPT under an active transaction (#3164 fold): a landing riding a
|
|
811
|
+
// retaining transaction (the optimistic module's aroundWrite binds it)
|
|
812
|
+
// stages instead — ensurePB stamped foldBatches, so the backing commits
|
|
813
|
+
// with the transaction and the reveal is atomic at settle. The pinned
|
|
814
|
+
// immediate-commit contract is stated over the no-transaction microtask
|
|
815
|
+
// posture, which `activeTransition === null` is exactly.
|
|
816
|
+
if (e.fam !== null && e.pb !== null && getWriteOverride() && activeTransition === null) {
|
|
785
817
|
// Landed truth (post-await write-override): immediately visible to every
|
|
786
818
|
// reader — any staged held view is superseded.
|
|
787
819
|
if (e.ht !== null) e.ht = e.hv = null;
|
|
@@ -976,7 +1008,7 @@ const UNSAFE_KEYS = new Set([ "__proto__", "prototype", "constructor" ]);
|
|
|
976
1008
|
* / onSettled callbacks) get COMMITTED visibility (#3006), same as core. */ function inOwnerContext() {
|
|
977
1009
|
const e = getOwner();
|
|
978
1010
|
if (e === null) return false;
|
|
979
|
-
const t = e.
|
|
1011
|
+
const t = e.Gt ? e.Dt : e;
|
|
980
1012
|
return t != null && !(t.T & CONFIG_CHILDREN_FORBIDDEN);
|
|
981
1013
|
}
|
|
982
1014
|
|
|
@@ -987,7 +1019,7 @@ const UNSAFE_KEYS = new Set([ "__proto__", "prototype", "constructor" ]);
|
|
|
987
1019
|
* committed to them regardless of staged writes. */ function inForbiddenScope() {
|
|
988
1020
|
const e = getOwner();
|
|
989
1021
|
if (e === null) return false;
|
|
990
|
-
const t = e.
|
|
1022
|
+
const t = e.Gt ? e.Dt : e;
|
|
991
1023
|
return t != null && !!(t.T & CONFIG_CHILDREN_FORBIDDEN);
|
|
992
1024
|
}
|
|
993
1025
|
|
|
@@ -998,7 +1030,7 @@ const UNSAFE_KEYS = new Set([ "__proto__", "prototype", "constructor" ]);
|
|
|
998
1030
|
if (t === null) return false;
|
|
999
1031
|
for (const e of Reflect.ownKeys(t)) {
|
|
1000
1032
|
const n = t[e];
|
|
1001
|
-
if (n.Pe !== NOT_PENDING && n.
|
|
1033
|
+
if (n.Pe !== NOT_PENDING && n.Ae != null && n.Ae.sn !== true) return true;
|
|
1002
1034
|
}
|
|
1003
1035
|
return false;
|
|
1004
1036
|
}
|
|
@@ -1018,16 +1050,37 @@ function readSource(e) {
|
|
|
1018
1050
|
// servable). Drafts (setter window OR projection write-override) and
|
|
1019
1051
|
// owner-context reads see the pending backing; context-free reads see
|
|
1020
1052
|
// committed. Node reads apply the same rule, so both homes agree.
|
|
1021
|
-
if (e.pb !== null && (inDraft(e) || getWriteOverride() ||
|
|
1053
|
+
if (e.pb !== null && (inDraft(e) || getWriteOverride() ||
|
|
1054
|
+
// Owner-context readers see the pending backing — EXCEPT held truth
|
|
1055
|
+
// on an optimistic family (#3164 fold): a live pb on an opt family
|
|
1056
|
+
// outside the draft/write-override windows is a staged landing
|
|
1057
|
+
// (tentative drafts never outlive their setter), and only the
|
|
1058
|
+
// authoritative postures and latest() see it (the backing-level twin
|
|
1059
|
+
// of core read()'s A17-for-held-truth arm; ordinary readers keep
|
|
1060
|
+
// committed until the transaction's reveal).
|
|
1061
|
+
inOwnerContext() && !heldTruthMasked(e) ||
|
|
1022
1062
|
// A projection's pending backing is authoritative-elect: serve it to
|
|
1023
1063
|
// context-free readers too UNLESS a transition is holding the node
|
|
1024
1064
|
// commits (downstream async hold — stale committed is the contract)
|
|
1025
1065
|
// or the reader is a CHILDREN_FORBIDDEN scope, which never observes
|
|
1026
1066
|
// its own unsettled write (#3082, signal parity per #3006).
|
|
1027
|
-
e.fam !== null && !foldHeld(e) && !inForbiddenScope())) return e.pb;
|
|
1067
|
+
e.fam !== null && !heldTruthMasked(e) && !foldHeld(e) && !inForbiddenScope())) return e.pb;
|
|
1028
1068
|
return e.v;
|
|
1029
1069
|
}
|
|
1030
1070
|
|
|
1071
|
+
/** #3164 fold: HELD truth on an optimistic family — a pending backing
|
|
1072
|
+
* stamped by a live transition that retains optimism — is masked from
|
|
1073
|
+
* ordinary readers (they keep committed until the transaction's reveal);
|
|
1074
|
+
* the authoritative postures and latest() tunnel through. Un-stamped
|
|
1075
|
+
* backings and optimism-free transitions keep ordinary mid-batch/
|
|
1076
|
+
* speculation visibility. */ function heldTruthMasked(e) {
|
|
1077
|
+
if (e.fam?.opt !== true || latestReadActive || authoritativeServe()) return false;
|
|
1078
|
+
const t = foldBatches.get(e);
|
|
1079
|
+
// opt families are only created by createOptimisticStore, whose module
|
|
1080
|
+
// install populates optHooks — the assertion holds by construction.
|
|
1081
|
+
return t !== undefined && optHooks.retainsOptimism(t);
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1031
1084
|
const hasOwn = Object.prototype.hasOwnProperty;
|
|
1032
1085
|
|
|
1033
1086
|
// Allocation-free own-accessor probe (replaces eager descriptor scans — the
|
|
@@ -1057,7 +1110,27 @@ function isOwnAccessor(e, t) {
|
|
|
1057
1110
|
|
|
1058
1111
|
/** Active optimistic override on an armed node (armed slot idles at
|
|
1059
1112
|
* NOT_PENDING; undefined = unarmed plain node). */ function hasActiveOverride(e) {
|
|
1060
|
-
return e.o?.
|
|
1113
|
+
return e.o?.Oe !== undefined && e.o?.Oe !== NOT_PENDING;
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
/** The reading computation is until()'s authoritative-view predicate — same
|
|
1117
|
+
* source of truth as core read()'s A17 carve-out (`context`, which persists
|
|
1118
|
+
* under untrack). optimisticView()'s composition gate consults exactly this:
|
|
1119
|
+
* write-side machinery (patch emission, tentative re-application) must keep
|
|
1120
|
+
* composing even when it runs inside an authoritative-write bracket. */ function authoritativeRead() {
|
|
1121
|
+
const e = context;
|
|
1122
|
+
return e !== null && (e.T & CONFIG_AUTHORITATIVE_READ) !== 0;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
/** Serve-side authoritative gate: until()'s predicate PLUS truth authors —
|
|
1126
|
+
* the projection derive's draft (wrapDraft trap brackets, runAuthoritative;
|
|
1127
|
+
* the same posture pair ensurePB classifies drafts by). A source computing
|
|
1128
|
+
* the next truth must never read its callers' tentative overlays: a derive
|
|
1129
|
+
* continuation's `store.push` computing its index from an action's
|
|
1130
|
+
* optimistic row landed truth in the wrong slot and corrupted committed
|
|
1131
|
+
* state (#3108). Trap-level overlay serves gate on this so values, length,
|
|
1132
|
+
* membership, and keys leave the authoritative view together. */ function authoritativeServe() {
|
|
1133
|
+
return projectionWriteActive || getWriteOverride() || authoritativeRead();
|
|
1061
1134
|
}
|
|
1062
1135
|
|
|
1063
1136
|
/** Context-aware node view for reads outside tracking: active override >
|
|
@@ -1069,7 +1142,17 @@ function isOwnAccessor(e, t) {
|
|
|
1069
1142
|
* keys, which are served by the trap, not the node). */ function nodeValue(e, t) {
|
|
1070
1143
|
// latest() sees the in-flight parked value like an owner-context reader
|
|
1071
1144
|
// does (#3075) — signal/memo parity for store-node-backed keys.
|
|
1072
|
-
|
|
1145
|
+
// Authoritative-view reads (until()'s predicate) skip the override arm
|
|
1146
|
+
// only: staged pending values are authoritative, overrides are the
|
|
1147
|
+
// caller's optimism.
|
|
1148
|
+
const n = !authoritativeServe() && hasActiveOverride(e) ? unwrapOverride(e.o?.Oe) : e.Pe !== NOT_PENDING && (latestReadActive ||
|
|
1149
|
+
// Owner-context pending visibility — except HELD truth (#3164,
|
|
1150
|
+
// see CONFIG_HELD_TRUTH: fold-staged or entangle-stolen
|
|
1151
|
+
// confirming truth), which only authoritative/latest readers
|
|
1152
|
+
// see (core read()'s A17-for-held-truth twin; ordinary readers
|
|
1153
|
+
// keep committed until the transaction's reveal — latest() is
|
|
1154
|
+
// exempted by the leading arm above).
|
|
1155
|
+
(inOwnerContext() || authoritativeServe()) && !(e.T & CONFIG_HELD_TRUTH && !authoritativeServe())) ? e.Pe : t;
|
|
1073
1156
|
return n === FORCE ? t : n;
|
|
1074
1157
|
}
|
|
1075
1158
|
|
|
@@ -1094,15 +1177,20 @@ function isOwnAccessor(e, t) {
|
|
|
1094
1177
|
read(getNode(e, t, n));
|
|
1095
1178
|
}
|
|
1096
1179
|
}
|
|
1097
|
-
|
|
1180
|
+
// Truth authors read the backing's own length — an optimistic row from
|
|
1181
|
+
// the caller's transaction must not shift where the author's next write
|
|
1182
|
+
// lands (#3108).
|
|
1183
|
+
return (authoritativeServe() ? r : optHooks.optimisticView(e, r)).length;
|
|
1098
1184
|
}
|
|
1099
1185
|
if (inDraft(e)) {
|
|
1100
1186
|
// Optimistic drafts before their first write have no pending backing yet;
|
|
1101
1187
|
// reads must still see the live optimistic view (compose, not clobber —
|
|
1102
1188
|
// #2951). Once ensurePB runs, the seeded clone carries the view.
|
|
1103
|
-
|
|
1189
|
+
// AUTHORITATIVE drafts (projection derive) never overlay — ensurePB's
|
|
1190
|
+
// seeding rule, applied to the read side (#3108).
|
|
1191
|
+
if (e.fam?.opt && e.pb === null && !authoritativeServe()) {
|
|
1104
1192
|
const n = e.n?.[t];
|
|
1105
|
-
if (n !== undefined && hasActiveOverride(n)) f = unwrapOverride(n.o?.
|
|
1193
|
+
if (n !== undefined && hasActiveOverride(n)) f = unwrapOverride(n.o?.Oe);
|
|
1106
1194
|
}
|
|
1107
1195
|
} else {
|
|
1108
1196
|
if (i !== undefined) {
|
|
@@ -1285,9 +1373,12 @@ const traps = {
|
|
|
1285
1373
|
if (e.s) return serveShallow(e, t, r);
|
|
1286
1374
|
return isWrappable(r) ? draftServe(e, wrapNext(r, e, t)) : r;
|
|
1287
1375
|
}
|
|
1288
|
-
} else if (f === undefined && inDraft(e) && e.fam?.opt && e.pb === null
|
|
1376
|
+
} else if (f === undefined && inDraft(e) && e.fam?.opt && e.pb === null &&
|
|
1377
|
+
// AUTHORITATIVE drafts (landing folds) never seed from overrides —
|
|
1378
|
+
// the caller's optimism is not truth (has-trap twin below).
|
|
1379
|
+
!authoritativeServe()) {
|
|
1289
1380
|
const n = e.n?.[t];
|
|
1290
|
-
if (n !== undefined && hasActiveOverride(n)) f = unwrapOverride(n.o?.
|
|
1381
|
+
if (n !== undefined && hasActiveOverride(n)) f = unwrapOverride(n.o?.Oe);
|
|
1291
1382
|
}
|
|
1292
1383
|
if (e.s) return serveShallow(e, t, f);
|
|
1293
1384
|
return isWrappable(f) ? draftServe(e, wrapNext(f, e, t)) : f;
|
|
@@ -1307,15 +1398,17 @@ const traps = {
|
|
|
1307
1398
|
if (!inDraft(e)) {
|
|
1308
1399
|
if (getObserver() !== null) {
|
|
1309
1400
|
const n = getHasNode(e, t, r);
|
|
1310
|
-
|
|
1401
|
+
// Authoritative-view readers get the right answer for free: core read()
|
|
1402
|
+
// skips the override arm for them, so nv is authoritative presence.
|
|
1403
|
+
const i = read(n);
|
|
1311
1404
|
if (hasActiveOverride(n)) r = !!i;
|
|
1312
|
-
} else {
|
|
1405
|
+
} else if (!authoritativeServe()) {
|
|
1313
1406
|
const n = e.h?.[t];
|
|
1314
|
-
if (n !== undefined && hasActiveOverride(n)) r = !!unwrapOverride(n.o?.
|
|
1407
|
+
if (n !== undefined && hasActiveOverride(n)) r = !!unwrapOverride(n.o?.Oe);
|
|
1315
1408
|
}
|
|
1316
|
-
} else if (e.fam?.opt && e.pb === null) {
|
|
1409
|
+
} else if (e.fam?.opt && e.pb === null && !authoritativeServe()) {
|
|
1317
1410
|
const n = e.h?.[t];
|
|
1318
|
-
if (n !== undefined && hasActiveOverride(n)) r = !!unwrapOverride(n.o?.
|
|
1411
|
+
if (n !== undefined && hasActiveOverride(n)) r = !!unwrapOverride(n.o?.Oe);
|
|
1319
1412
|
}
|
|
1320
1413
|
return r;
|
|
1321
1414
|
},
|
|
@@ -1338,14 +1431,15 @@ const traps = {
|
|
|
1338
1431
|
// Optimistic membership overlay: presence-node overrides add/remove keys
|
|
1339
1432
|
// (per-transaction lifecycle rides the nodes — §6, FINDING-2's fix).
|
|
1340
1433
|
// Draft reads before the first write overlay too (pb, once created, is
|
|
1341
|
-
// seeded with the view).
|
|
1342
|
-
|
|
1434
|
+
// seeded with the view). Authoritative-view reads (until()'s predicate,
|
|
1435
|
+
// truth-author drafts) skip the overlay.
|
|
1436
|
+
if (!authoritativeServe() && e.fam?.opt && e.h !== null && (!inDraft(e) || e.pb === null)) {
|
|
1343
1437
|
let t = null;
|
|
1344
1438
|
for (const r of Reflect.ownKeys(e.h)) {
|
|
1345
1439
|
const i = e.h[r];
|
|
1346
1440
|
if (!hasActiveOverride(i)) continue;
|
|
1347
1441
|
t ??= new Set(n);
|
|
1348
|
-
if (unwrapOverride(i.o?.
|
|
1442
|
+
if (unwrapOverride(i.o?.Oe)) t.add(r); else t.delete(r);
|
|
1349
1443
|
}
|
|
1350
1444
|
if (t !== null) return [ ...t ];
|
|
1351
1445
|
}
|
|
@@ -1360,10 +1454,10 @@ const traps = {
|
|
|
1360
1454
|
if (e.del !== null && e.del.has(t)) return undefined;
|
|
1361
1455
|
if (r === undefined) r = Object.getOwnPropertyDescriptor(e.v, t);
|
|
1362
1456
|
}
|
|
1363
|
-
if (e.fam?.opt && !inDraft(e)) {
|
|
1457
|
+
if (!authoritativeServe() && e.fam?.opt && !inDraft(e)) {
|
|
1364
1458
|
const n = e.h?.[t];
|
|
1365
1459
|
if (n !== undefined && hasActiveOverride(n)) {
|
|
1366
|
-
if (!unwrapOverride(n.o?.
|
|
1460
|
+
if (!unwrapOverride(n.o?.Oe)) return undefined;
|
|
1367
1461
|
// opt delete
|
|
1368
1462
|
if (r === undefined) {
|
|
1369
1463
|
const n = e.n?.[t];
|
|
@@ -1725,4 +1819,4 @@ function snapshotWalk(e, t, n) {
|
|
|
1725
1819
|
return f ?? r;
|
|
1726
1820
|
}
|
|
1727
1821
|
|
|
1728
|
-
export { adoptPB, bumpDeep, createStoreNext, deepNext, getHasNode, getKeySetNode, getNode, hasAccessorFlag, hasActiveOverride, materializePB, notifyFold, notifyFoldTail, notifyKeyDiff, notifyKeyValue, pcOf, runAuthoritative, snapshotNext, storeHasFamily, storeHasOptimisticFamily, storeIsShallow, storeSetterNext, targetIsPlain, targetsEqual, unwrapValue, wrapNext };
|
|
1822
|
+
export { adoptPB, arrayStructureChanged, authoritativeRead, authoritativeServe, bumpDeep, createStoreNext, deepNext, getHasNode, getKeySetNode, getNode, hasAccessorFlag, hasActiveOverride, materializePB, membershipChanged, notifyFold, notifyFoldTail, notifyKeyDiff, notifyKeyValue, pcOf, runAuthoritative, snapshotNext, stagedTruthPB, storeHasFamily, storeHasOptimisticFamily, storeIsShallow, storeSetterNext, targetIsPlain, targetsEqual, unwrapValue, wrapNext };
|
package/dist/prod/store/store.js
CHANGED
|
@@ -252,7 +252,7 @@ s) {
|
|
|
252
252
|
// Callers guard on `pendingCheckActive`, which only flips inside
|
|
253
253
|
// isPending() — the verdict layer is loaded and its hook installed.
|
|
254
254
|
const o = e[STORE_NODE]?.[$AFFECTS];
|
|
255
|
-
if (o?.o?.t) GlobalQueue.
|
|
255
|
+
if (o?.o?.t) GlobalQueue.Wt(o);
|
|
256
256
|
if (affectsScopes.size) {
|
|
257
257
|
// Chained backings (§7b): a wrapper's STORE_VALUE can be another store's
|
|
258
258
|
// proxy — marks cover by identity of the BASE raw, so resolve the chain
|
|
@@ -263,7 +263,7 @@ s) {
|
|
|
263
263
|
let t = r;
|
|
264
264
|
for (;;) {
|
|
265
265
|
if (s.scope.has(t)) {
|
|
266
|
-
GlobalQueue.
|
|
266
|
+
GlobalQueue.Wt(e);
|
|
267
267
|
break;
|
|
268
268
|
}
|
|
269
269
|
const o = t?.[$TARGET];
|
|
@@ -16,6 +16,8 @@ export declare function releaseSettledDependents(el: Computed<any>): void;
|
|
|
16
16
|
export declare function settleErroredDependents(el: Computed<any>, error: any): void;
|
|
17
17
|
export declare function settlePendingSource(el: Computed<any>): void;
|
|
18
18
|
export declare function isThenable<T>(value: T | PromiseLike<T>): value is PromiseLike<T>;
|
|
19
|
+
/** Fire and clear a node's iterator-flight cancellation hook (#3122). */
|
|
20
|
+
export declare function releaseFlightTeardown(el: Computed<any>): void;
|
|
19
21
|
export declare function handleAsync<T>(el: Computed<T>, result: T | PromiseLike<T> | AsyncIterable<T>, setter?: (value: T) => void): T;
|
|
20
22
|
export declare function clearStatus(el: Computed<any>, clearUninitialized?: boolean): void;
|
|
21
23
|
export declare function notifyStatus(el: Computed<any>, status: number, error: any, blockStatus?: boolean, lane?: OptimisticLane): void;
|
|
@@ -60,11 +60,16 @@ export interface RerunEvent {
|
|
|
60
60
|
/** Wall time of this run including nested recomputes (ms). */
|
|
61
61
|
totalMs: number;
|
|
62
62
|
/**
|
|
63
|
-
* Whether the run
|
|
63
|
+
* Whether the run produced a changed value. A PLAIN memo run with
|
|
64
64
|
* `changed: false` was pure waste — the equality cutoff stopped it from
|
|
65
|
-
* notifying anyone
|
|
66
|
-
*
|
|
67
|
-
*
|
|
65
|
+
* notifying anyone. Effects run with `_equals: false` in core (their
|
|
66
|
+
* effect phase re-fires on every recompute), so the engine derives this
|
|
67
|
+
* fact itself: an effect run whose compute output is identical to the
|
|
68
|
+
* previous run's reports `changed: false` — the phase re-fired with the
|
|
69
|
+
* same input, pure waste. Side-effect-only computes (`undefined` output)
|
|
70
|
+
* are exempt: identity of `undefined` proves nothing about their work.
|
|
71
|
+
* Summed as `wastedMs` in costs() (plain, non-held runs only — see
|
|
72
|
+
* `phase`).
|
|
68
73
|
*/
|
|
69
74
|
changed: boolean;
|
|
70
75
|
/**
|
|
@@ -51,6 +51,60 @@ export declare const CONFIG_CHILD_COMPANIONS: number;
|
|
|
51
51
|
* moved into the cold extension (§12), and an unconditional `_x` deref per
|
|
52
52
|
* marked node measurably taxed the propagation hot path (diamond -22%). */
|
|
53
53
|
export declare const CONFIG_FW_CHILDREN: number;
|
|
54
|
+
/** Authoritative-view reader (`until()`): while this node computes, reads
|
|
55
|
+
* dodge active optimistic OVERRIDES only — the predicate must observe
|
|
56
|
+
* arriving truth, never the caller's own tentative writes (which would
|
|
57
|
+
* trivially satisfy it). Everything else reads normally, INCLUDING
|
|
58
|
+
* transition-staged `_pendingValue`: staged data is authoritative (optimism
|
|
59
|
+
* lives only in override slots), and a hold that refused staged reads would
|
|
60
|
+
* deadlock on data the open transaction itself is holding (a refresh the
|
|
61
|
+
* action issued lands staged and cannot commit until the hold releases).
|
|
62
|
+
* read() checks the bit on the reading computation (`context`) directly — no
|
|
63
|
+
* ambient flag — so a shared computed the predicate pulls recomputes as
|
|
64
|
+
* itself (no bit) under the normal view, and its cache never forks. */
|
|
65
|
+
export declare const CONFIG_AUTHORITATIVE_READ: number;
|
|
66
|
+
/** Sticky mark: an authoritative-view reader read this node PAST an active
|
|
67
|
+
* override. The ack shape — an authoritative arrival EQUAL to the override —
|
|
68
|
+
* rides paths that are deliberately silent under A17 (every ordinary reader
|
|
69
|
+
* sees the override, so an equal landing changes nothing for them). A marked
|
|
70
|
+
* node notifies those readers on such paths anyway, so the landed truth is
|
|
71
|
+
* seen without re-firing ordinary subscribers. Never cleared — only nodes an
|
|
72
|
+
* until() predicate observed mid-override pay. */
|
|
73
|
+
export declare const CONFIG_AUTHORITATIVE_OBSERVED: number;
|
|
74
|
+
/** Promise-delivery effect (resolve()/until()): commits its computed value
|
|
75
|
+
* directly even when recomputing under its own held transition. These
|
|
76
|
+
* effects deliver applies on a microtask (#2930) instead of the stashed
|
|
77
|
+
* effect queues, so the value must ride the same immediate schedule — a
|
|
78
|
+
* staged value with an immediate apply delivers stale state (resolve) or
|
|
79
|
+
* deadlocks the hold (until). Safe because the node is a private leaf: no
|
|
80
|
+
* subscriber reads an effect's value, only its own apply does. */
|
|
81
|
+
export declare const CONFIG_DIRECT_COMMIT: number;
|
|
82
|
+
/** Fresh-pull reader (awaitable `refresh()`'s waiter effect): a read of a
|
|
83
|
+
* dirty source recomputes it inline even when the height gate defers to the
|
|
84
|
+
* flush. Closes the same-flush ordering race where a waiter created
|
|
85
|
+
* alongside a refresh() mark read the PRE-re-ask value as settled and
|
|
86
|
+
* delivered stale; with the pull, the waiter either parks on the re-ask's
|
|
87
|
+
* pending window (async — woken by the settle walk, which runs on every
|
|
88
|
+
* landing including equal-value ones) or serves its sync answer. resolve()
|
|
89
|
+
* deliberately keeps that race — its contract is "first settled value"
|
|
90
|
+
* (#2930), not "next quiescent state". */
|
|
91
|
+
export declare const CONFIG_FRESH_READ: number;
|
|
92
|
+
/** HELD truth (#3164): this node's staged `_pendingValue` is confirming
|
|
93
|
+
* truth riding a transaction that retains optimism, revealed only at that
|
|
94
|
+
* transaction's settle. Two arming sites, one meaning: the store fold
|
|
95
|
+
* (a landing staged into the retaining transaction) and until()'s
|
|
96
|
+
* flip-entanglement (a foreign carrier's staged write, stolen when it
|
|
97
|
+
* flipped the awaited predicate truthy). Until the reveal, ordinary
|
|
98
|
+
* readers — lane and speculative recomputes included — keep committed:
|
|
99
|
+
* the staging notified subscribers as a plain write, so without the mask
|
|
100
|
+
* a mid-hold recompute composes live optimism with the confirming truth,
|
|
101
|
+
* a frame no timeline contains (GabbeV's union tear). Authoritative
|
|
102
|
+
* readers (until()'s predicate) and latest() tunnel through — the
|
|
103
|
+
* exemption that keeps holds deadlock-free. Override-covered nodes never
|
|
104
|
+
* arm: the override is their display and its revert their notification
|
|
105
|
+
* (A17). Cleared at commit (the commit IS the reveal); subscribers masked
|
|
106
|
+
* during the hold are woken by finalizePureQueue's post-revert pass. */
|
|
107
|
+
export declare const CONFIG_HELD_TRUTH: number;
|
|
54
108
|
export declare const STATUS_NONE = 0;
|
|
55
109
|
export declare const STATUS_PENDING: number;
|
|
56
110
|
export declare const STATUS_ERROR: number;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type Refreshable } from "./constants.js";
|
|
2
1
|
import { type OptimisticLane } from "./lanes.js";
|
|
3
2
|
import type { Computed, FirewallSignal, NodeExtension, NodeOptions, Owner, Signal } from "./types.js";
|
|
4
3
|
export declare const PRIMITIVE_IN_FORBIDDEN_SCOPE_MESSAGE = "[PRIMITIVE_IN_FORBIDDEN_SCOPE] Cannot create reactive primitives inside createTrackedEffect or owner-backed onSettled";
|
|
@@ -107,6 +106,19 @@ export declare const READ_SLOW: unique symbol;
|
|
|
107
106
|
* snapshot / transition / lane / dev-strictRead state all take the full
|
|
108
107
|
* resolution. Anything slow returns READ_SLOW; the caller then calls read().
|
|
109
108
|
*/
|
|
109
|
+
/**
|
|
110
|
+
* Wake only authoritative-view readers (until() predicates) subscribed to `el`.
|
|
111
|
+
* The A17-silent ack paths — an authoritative arrival equal to the active
|
|
112
|
+
* override — use this so the predicate re-evaluates without re-firing
|
|
113
|
+
* ordinary subscribers whose visible (override) value did not change.
|
|
114
|
+
* Pay-for-use: reached through GlobalQueue._notifyAuthoritativeObservers,
|
|
115
|
+
* installed at first until() call — apps that never use until() shake it.
|
|
116
|
+
*/
|
|
117
|
+
export declare function notifyAuthoritativeObservers(el: Signal<any> | Computed<any>): void;
|
|
118
|
+
/** Installs the until() machinery hook. Idempotent; called by until() before
|
|
119
|
+
* any authoritative-view read happens (same late-binding contract as the
|
|
120
|
+
* optimistic engine). */
|
|
121
|
+
export declare function installAuthoritativeRead(): void;
|
|
110
122
|
export declare function readNodeFast<T>(el: Signal<T>): T | typeof READ_SLOW;
|
|
111
123
|
export declare function read<T>(el: Signal<T> | Computed<T>): T;
|
|
112
124
|
/**
|
|
@@ -155,23 +167,10 @@ export declare function setMemo<T>(el: Computed<T>, v: T | ((prev: T) => T)): T;
|
|
|
155
167
|
export declare function runWithOwner<T>(owner: Owner | null, fn: () => T): T;
|
|
156
168
|
export declare function staleValues<T>(fn: () => T, set?: boolean): T;
|
|
157
169
|
/**
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
* write-like invalidation operation: it does not read the target's value, and
|
|
164
|
-
* refreshing a plain signal accessor is a no-op.
|
|
165
|
-
*
|
|
166
|
-
* Use it to invalidate cached async values (e.g. force a re-fetch) without
|
|
167
|
-
* tearing the consumer down.
|
|
168
|
-
*
|
|
169
|
-
* @example
|
|
170
|
-
* ```ts
|
|
171
|
-
* const user = createMemo(async () => fetch(`/users/${id()}`).then(r => r.json()));
|
|
172
|
-
*
|
|
173
|
-
* // Re-fetch on demand
|
|
174
|
-
* <button onClick={() => refresh(user)}>Reload</button>
|
|
175
|
-
* ```
|
|
170
|
+
* Core marking half of `refresh()` (the public wrapper lives in signals.ts —
|
|
171
|
+
* it validates the target, marks through here, then builds the quiescence
|
|
172
|
+
* promise on the resolve()/until() effect machinery). Flags the node's next
|
|
173
|
+
* recompute as a quiet re-ask and schedules it; no-ops for non-derived or
|
|
174
|
+
* disposed targets and for same-tick manual writes.
|
|
176
175
|
*/
|
|
177
|
-
export declare function
|
|
176
|
+
export declare function markRefresh(node: Computed<any>): void;
|
|
@@ -39,6 +39,15 @@ export declare class StatusError extends Error {
|
|
|
39
39
|
}
|
|
40
40
|
/** Return the user's error from an internal status wrapper. */
|
|
41
41
|
export declare function unwrapStatusError(error: unknown): unknown;
|
|
42
|
+
/**
|
|
43
|
+
* Rejection value of `until(fn, { timeout })` when the predicate does not turn
|
|
44
|
+
* truthy within the window. Inside an `action()`, the rejection is thrown back
|
|
45
|
+
* in at the `yield` point — catchable there, or the action fails and its
|
|
46
|
+
* optimistic state reverts.
|
|
47
|
+
*/
|
|
48
|
+
export declare class TimeoutError extends Error {
|
|
49
|
+
constructor(message?: string);
|
|
50
|
+
}
|
|
42
51
|
export declare class NoOwnerError extends Error {
|
|
43
52
|
constructor();
|
|
44
53
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { ContextNotFoundError, NoOwnerError, NotReadyError } from "./error.js";
|
|
2
|
-
export { isEqual, untrack, runWithOwner, computed, signal, read, setSignal, setMemo, suppressComputedRecompute, optimisticSignal, optimisticComputed,
|
|
1
|
+
export { ContextNotFoundError, NoOwnerError, NotReadyError, TimeoutError } from "./error.js";
|
|
2
|
+
export { isEqual, untrack, runWithOwner, computed, signal, read, setSignal, setMemo, suppressComputedRecompute, optimisticSignal, optimisticComputed, installAuthoritativeRead, markRefresh, staleValues, setSnapshotCapture, markSnapshotScope, releaseSnapshotScope, clearSnapshots } from "./core.js";
|
|
3
3
|
export { enableExternalSource, _resetExternalSourceConfig, type ExternalSourceFactory, type ExternalSource, type ExternalSourceConfig } from "./external.js";
|
|
4
4
|
export { createOwner, createRoot, dispose, getNextChildId, getObserver, getOwner, isDisposed, cleanup, peekNextChildId } from "./owner.js";
|
|
5
5
|
export { createContext, getContext, setContext, type Context, type ContextRecord } from "./context.js";
|
|
@@ -40,6 +40,24 @@ export interface Transition {
|
|
|
40
40
|
_done: boolean | Transition;
|
|
41
41
|
_gatedSubs: Set<Computed<any>>;
|
|
42
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Flip-entanglement (#3164 follow-up): `until()` is a declaration of
|
|
45
|
+
* relatedness — the predicate names the condition that confirms the awaiting
|
|
46
|
+
* transaction. When the predicate settles truthy, every live foreign
|
|
47
|
+
* transition whose staged write it read IS the confirming event by the
|
|
48
|
+
* user's own definition, so it merges into the awaiting transaction and
|
|
49
|
+
* reveals at the joint settle — the cross-primitive twin of the family fold
|
|
50
|
+
* (a landing on an optimism-carrying family joins the retaining
|
|
51
|
+
* transaction). Non-flipping updates never pass through here: falsy
|
|
52
|
+
* evaluations don't entangle, so unrelated traffic on the watched sources
|
|
53
|
+
* reveals freely on its own schedule.
|
|
54
|
+
*
|
|
55
|
+
* Runs inside the predicate's compute (pure phase) — the confirming
|
|
56
|
+
* transition's stamps are still live and its commit decision hasn't run, so
|
|
57
|
+
* the merge lands before any reveal. Only the tree-shaken graphs that call
|
|
58
|
+
* `until()` retain this.
|
|
59
|
+
*/
|
|
60
|
+
export declare function entangleConfirmingTransitions(obs: Computed<any>, target: Transition): void;
|
|
43
61
|
export declare function schedule(): void;
|
|
44
62
|
/**
|
|
45
63
|
* Permanently halts the reactive system. Called when a user error escapes
|
|
@@ -112,6 +130,10 @@ export declare class GlobalQueue extends Queue {
|
|
|
112
130
|
static _laneReadsCommitted: ((el: OptimisticNode, owner: OptimisticNode, c: Computed<any>) => boolean) | null;
|
|
113
131
|
static _recomputeLane: ((el: Computed<any>, own: boolean) => OptimisticLane | null | false) | null;
|
|
114
132
|
static _laneAsyncPending: ((el: Computed<any>) => void) | null;
|
|
133
|
+
/** Authoritative-view reader wakeup (until()): installed at first until() call.
|
|
134
|
+
* Call sites are gated by CONFIG_AUTHORITATIVE_OBSERVED, which only until()'s
|
|
135
|
+
* carve-out read can set, so `!` invocations are safe once the gate holds. */
|
|
136
|
+
static _notifyAuthoritativeObservers: ((el: Signal<any> | Computed<any>) => void) | null;
|
|
115
137
|
static _laneAsyncSettled: ((el: Computed<any>) => void) | null;
|
|
116
138
|
static _trackOptimisticStore: ((store: any) => void) | null;
|
|
117
139
|
flush(): void;
|
|
@@ -190,3 +212,15 @@ export declare function flush<T>(fn: () => T): T;
|
|
|
190
212
|
export declare function currentTransition(transition: Transition): Transition;
|
|
191
213
|
export declare function setActiveTransition(transition: Transition | null): void;
|
|
192
214
|
export declare function runInTransition<T>(transition: Transition, fn: () => T): T;
|
|
215
|
+
/** Run `fn` with `transition` as BOTH the ambient transaction and the
|
|
216
|
+
* registration batch, restoring both after. runInTransition alone is not
|
|
217
|
+
* enough for code that WRITES on behalf of a transaction from inside someone
|
|
218
|
+
* else's window (optimistic replay re-arming a still-open action's edits
|
|
219
|
+
* during a landing commit, #3123): registrations route through the queue's
|
|
220
|
+
* batch pointer, and a bare activeTransition swap leaves them in the ambient
|
|
221
|
+
* batch — a plain batch "completes" at the next flush and reverts optimistic
|
|
222
|
+
* registrations that were supposed to live with the transaction.
|
|
223
|
+
* initTransition is the wrong tool here: it MERGES the currently ambient
|
|
224
|
+
* transaction into the target, entangling whatever the interrupted window
|
|
225
|
+
* belonged to. */
|
|
226
|
+
export declare function runAsTransitionBatch<T>(transition: Transition, fn: () => T): T;
|
|
@@ -27,6 +27,11 @@ export interface NodeOptions<T> {
|
|
|
27
27
|
ownedWrite?: boolean;
|
|
28
28
|
/** Exclude this signal from snapshot capture (internal — not part of public API) */
|
|
29
29
|
_noSnapshot?: boolean;
|
|
30
|
+
/** Extra CONFIG_* bits OR'd into the node's config at creation (internal —
|
|
31
|
+
* not part of public API). Used by resolve()/until() for
|
|
32
|
+
* CONFIG_DIRECT_COMMIT / CONFIG_AUTHORITATIVE_READ, keeping the per-flag
|
|
33
|
+
* option arms out of the core creation path. */
|
|
34
|
+
_extraConfig?: number;
|
|
30
35
|
unobserved?: () => void;
|
|
31
36
|
lazy?: boolean;
|
|
32
37
|
sync?: boolean;
|
|
@@ -73,6 +78,13 @@ export interface NodeExtension {
|
|
|
73
78
|
*/
|
|
74
79
|
_affectsCount: number;
|
|
75
80
|
_inFlight: PromiseLike<any> | AsyncIterable<any> | null;
|
|
81
|
+
/** Cancellation for the CURRENT iterator flight (#3122): closes the
|
|
82
|
+
* iterator (`it.return()`), idempotent. Fired at the sites that release
|
|
83
|
+
* `_inFlight` so a superseded stream stops at supersede time — its owner
|
|
84
|
+
* cleanup registration may ride the zombie-disposal channel, which a held
|
|
85
|
+
* transition defers until the SUPERSEDING flight settles. Null for plain
|
|
86
|
+
* promise flights (no cancellation hook exists). */
|
|
87
|
+
_flightTeardown: (() => void) | null;
|
|
76
88
|
_error: unknown;
|
|
77
89
|
_blocked: boolean | undefined;
|
|
78
90
|
_pendingSources: Set<Computed<any>> | undefined;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { $REFRESH, ContextNotFoundError, NoOwnerError, NotReadyError, action, createContext, createOwner, createRoot, runWithOwner, flush, getNextChildId, peekNextChildId, getContext, setContext, getOwner, isDisposed, getObserver, isEqual, untrack, isPending, latest,
|
|
1
|
+
export { $REFRESH, ContextNotFoundError, NoOwnerError, NotReadyError, TimeoutError, action, createContext, createOwner, createRoot, runWithOwner, flush, getNextChildId, peekNextChildId, getContext, setContext, getOwner, isDisposed, getObserver, isEqual, untrack, isPending, latest, SUPPORTS_PROXY, setSnapshotCapture, markSnapshotScope, releaseSnapshotScope, clearSnapshots, enforceLoadingBoundary, enableExternalSource, resetErrorHalt } from "./core/index.js";
|
|
2
2
|
import { type Dev } from "./core/index.js";
|
|
3
3
|
export declare const DEV: Dev | undefined;
|
|
4
4
|
export type { Owner, Context, ContextRecord, IQueue, ExternalSourceFactory, ExternalSource, ExternalSourceConfig, Refreshable, Dev, DevHooks, DiagnosticCapture, DiagnosticCode, DiagnosticEvent, DiagnosticKind, Diagnostics, DiagnosticSeverity } from "./core/index.js";
|
|
5
|
-
export { createSignal, createMemo, createEffect, createRenderEffect, createTrackedEffect, createReaction, createOptimistic, resolve, onSettled, onCleanup } from "./signals.js";
|
|
6
|
-
export type { Accessor, SourceAccessor, Setter, Signal, ComputeFunction, EffectFunction, EffectBundle, EffectOptions, SignalOptions, MemoOptions, NoInfer } from "./signals.js";
|
|
5
|
+
export { createSignal, createMemo, createEffect, createRenderEffect, createTrackedEffect, createReaction, createOptimistic, refresh, resolve, until, onSettled, onCleanup } from "./signals.js";
|
|
6
|
+
export type { Truthy, UntilOptions, Accessor, SourceAccessor, Setter, Signal, ComputeFunction, EffectFunction, EffectBundle, EffectOptions, SignalOptions, MemoOptions, NoInfer } from "./signals.js";
|
|
7
7
|
export { affects } from "./affects.js";
|
|
8
8
|
export { mapArray, repeat, type Maybe } from "./map.js";
|
|
9
9
|
export * from "./store/index.js";
|