@reckona/mreact-reactive-core 0.0.162 → 0.0.164
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/cell.d.ts.map +1 -1
- package/dist/cell.js +9 -1
- package/dist/cell.js.map +1 -1
- package/dist/computed.d.ts.map +1 -1
- package/dist/computed.js +31 -3
- package/dist/computed.js.map +1 -1
- package/dist/internal.d.ts +4 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +3 -0
- package/dist/internal.js.map +1 -1
- package/dist/state.d.ts +3 -0
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js.map +1 -1
- package/dist/tracking.d.ts.map +1 -1
- package/dist/tracking.js +25 -2
- package/dist/tracking.js.map +1 -1
- package/package.json +1 -1
- package/src/cell.ts +10 -1
- package/src/computed.ts +39 -4
- package/src/internal.ts +4 -0
- package/src/state.ts +3 -0
- package/src/tracking.ts +33 -2
package/dist/cell.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cell.d.ts","sourceRoot":"","sources":["../src/cell.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"cell.d.ts","sourceRoot":"","sources":["../src/cell.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AA6BvC,wBAAgB,4BAA4B,IAAI,IAAI,CAInD;AA6ED,wBAAgB,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAiB3C"}
|
package/dist/cell.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { runtimeState } from "./state.js";
|
|
1
2
|
import { notifySubscribers, sourceSubscriberCount, trackSource } from "./tracking.js";
|
|
2
3
|
const clientDevtoolsDisabled = typeof __MREACT_CLIENT_DEVTOOLS__ !== "undefined" &&
|
|
3
4
|
__MREACT_CLIENT_DEVTOOLS__ === false;
|
|
@@ -60,7 +61,14 @@ function writeCellValue(state, next) {
|
|
|
60
61
|
if (!clientDevtoolsDisabled && cachedDevtoolsHook !== null) {
|
|
61
62
|
emitCellSetEvent(state.source, previous, resolved);
|
|
62
63
|
}
|
|
63
|
-
|
|
64
|
+
const subscribers = state.source.subscribers;
|
|
65
|
+
if (subscribers !== null) {
|
|
66
|
+
if (runtimeState.batchDepth > 0 && !(subscribers instanceof Set)) {
|
|
67
|
+
if (!subscribers.disposed && !subscribers.queued) {
|
|
68
|
+
subscribers.markDirty();
|
|
69
|
+
}
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
64
72
|
notifySubscribers(state.source);
|
|
65
73
|
}
|
|
66
74
|
}
|
package/dist/cell.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cell.js","sourceRoot":"","sources":["../src/cell.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAItF,MAAM,sBAAsB,GAC1B,OAAO,0BAA0B,KAAK,WAAW;IACjD,0BAA0B,KAAK,KAAK,CAAC;AAUvC,6EAA6E;AAC7E,6EAA6E;AAC7E,4EAA4E;AAC5E,uEAAuE;AACvE,6EAA6E;AAC7E,4EAA4E;AAC5E,IAAI,kBAAkB,GAAoC,sBAAsB;IAC9E,CAAC,CAAC,IAAI;IACN,CAAC,CAAC,SAAS,CAAC;AAEd,MAAM,UAAU,4BAA4B;IAC1C,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC5B,kBAAkB,GAAG,SAAS,CAAC;IACjC,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,IAAI,GAAI,UAAiC,CAAC,gBAAgB,CAAC;IACjE,MAAM,QAAQ,GAAG,IAAI,KAAK,SAAS,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACrF,kBAAkB,GAAG,QAAQ,CAAC;IAC9B,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,gBAAgB,CAAI,MAAc,EAAE,QAAW,EAAE,KAAQ;IAChE,4EAA4E;IAC5E,0EAA0E;IAC1E,oEAAoE;IACpE,MAAM,IAAI,GAAI,UAAiC,CAAC,gBAAgB,CAAC;IACjE,MAAM,IAAI,GACR,kBAAkB,KAAK,SAAS,IAAI,kBAAkB,KAAK,IAAI;QAC7D,CAAC,CAAC,kBAAkB;QACpB,CAAC,CAAC,mBAAmB,EAAE,CAAC;IAE5B,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IAEvB,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO;IACT,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;QACd,OAAO,EAAE,+BAA+B;QACxC,QAAQ;QACR,WAAW,EAAE,qBAAqB,CAAC,MAAM,CAAC;QAC1C,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,IAAI,EAAE,mBAAmB;QACzB,KAAK;KACN,CAAC,CAAC;AACL,CAAC;AAOD,4EAA4E;AAC5E,gEAAgE;AAChE,SAAS,cAAc,CAAI,KAAmB,EAAE,IAA0B;IACxE,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC;IAC7B,MAAM,QAAQ,GACZ,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC,CAAE,IAAuB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEzE,IAAI,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC;QAClC,OAAO;IACT,CAAC;IAED,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC;IAEvB,4EAA4E;IAC5E,4EAA4E;IAC5E,0EAA0E;IAC1E,IAAI,CAAC,sBAAsB,IAAI,kBAAkB,KAAK,IAAI,EAAE,CAAC;QAC3D,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACrD,CAAC;IAED,
|
|
1
|
+
{"version":3,"file":"cell.js","sourceRoot":"","sources":["../src/cell.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Cell } from \"./types.js\";\nimport type { Source } from \"./state.js\";\nimport { runtimeState } from \"./state.js\";\nimport { notifySubscribers, sourceSubscriberCount, trackSource } from \"./tracking.js\";\n\ndeclare const __MREACT_CLIENT_DEVTOOLS__: boolean | undefined;\n\nconst clientDevtoolsDisabled =\n typeof __MREACT_CLIENT_DEVTOOLS__ !== \"undefined\" &&\n __MREACT_CLIENT_DEVTOOLS__ === false;\n\ninterface DevtoolsHook {\n emit?: ((event: Record<string, unknown>) => void) | undefined;\n}\n\ntype GlobalWithDevtools = typeof globalThis & {\n __mreactDevtools?: DevtoolsHook | undefined;\n};\n\n// Write-path devtools cache: `undefined` = not sampled yet, `null` = sampled\n// and absent, object = sampled and attached. The no-devtools write fast path\n// is a single module-local null comparison instead of a globalThis property\n// walk per write. A late attach is observed at the next batch or flush\n// boundary (see invalidateDevtoolsWriteCache callers); a detach or hook swap\n// is observed on the next write because the emit path revalidates identity.\nlet cachedDevtoolsHook: DevtoolsHook | null | undefined = clientDevtoolsDisabled\n ? null\n : undefined;\n\nexport function invalidateDevtoolsWriteCache(): void {\n if (!clientDevtoolsDisabled) {\n cachedDevtoolsHook = undefined;\n }\n}\n\nfunction resolveDevtoolsHook(): DevtoolsHook | null {\n const hook = (globalThis as GlobalWithDevtools).__mreactDevtools;\n const resolved = hook !== undefined && typeof hook.emit === \"function\" ? hook : null;\n cachedDevtoolsHook = resolved;\n return resolved;\n}\n\nfunction emitCellSetEvent<T>(source: Source, previous: T, value: T): void {\n // Cold path: only reached while a devtools hook is (or was) attached, or on\n // the first write after a cache invalidation. Revalidate against the live\n // global so a disposed or swapped hook never receives stale events.\n const live = (globalThis as GlobalWithDevtools).__mreactDevtools;\n const hook =\n cachedDevtoolsHook !== undefined && cachedDevtoolsHook === live\n ? cachedDevtoolsHook\n : resolveDevtoolsHook();\n\n if (hook === null) {\n return;\n }\n\n const emit = hook.emit;\n\n if (typeof emit !== \"function\") {\n return;\n }\n\n emit.call(hook, {\n package: \"@reckona/mreact-reactive-core\",\n previous,\n subscribers: sourceSubscriberCount(source),\n timestamp: Date.now(),\n type: \"reactive:cell:set\",\n value,\n });\n}\n\ninterface CellState<T> {\n value: T;\n readonly source: Source;\n}\n\n// One shared write function keeps the hot store/notify sequence in a single\n// optimizable function instead of a fresh fat closure per cell.\nfunction writeCellValue<T>(state: CellState<T>, next: T | ((prev: T) => T)): void {\n const previous = state.value;\n const resolved =\n typeof next === \"function\" ? (next as (prev: T) => T)(previous) : next;\n\n if (Object.is(previous, resolved)) {\n return;\n }\n\n state.value = resolved;\n\n // clientDevtoolsDisabled folds to true under the client build define, which\n // makes this branch statically dead so bundlers drop the emit path (and its\n // globalThis.__mreactDevtools references) from production client bundles.\n if (!clientDevtoolsDisabled && cachedDevtoolsHook !== null) {\n emitCellSetEvent(state.source, previous, resolved);\n }\n\n const subscribers = state.source.subscribers;\n if (subscribers !== null) {\n if (runtimeState.batchDepth > 0 && !(subscribers instanceof Set)) {\n if (!subscribers.disposed && !subscribers.queued) {\n subscribers.markDirty();\n }\n return;\n }\n\n notifySubscribers(state.source);\n }\n}\n\nexport function cell<T>(initial: T): Cell<T> {\n const state: CellState<T> = {\n source: {\n subscribers: null,\n },\n value: initial,\n };\n\n return {\n get(): T {\n trackSource(state.source);\n return state.value;\n },\n set(next: T | ((prev: T) => T)): void {\n writeCellValue(state, next);\n },\n };\n}\n"]}
|
package/dist/computed.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"computed.d.ts","sourceRoot":"","sources":["../src/computed.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,yEAAyE;AACzE,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;AAEpE,sDAAsD;AACtD,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;CAC1C;AAED,0EAA0E;AAC1E,wBAAgB,QAAQ,CAAC,CAAC,EACxB,EAAE,EAAE,MAAM,CAAC,EACX,OAAO,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,GACjD,YAAY,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"computed.d.ts","sourceRoot":"","sources":["../src/computed.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,yEAAyE;AACzE,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;AAEpE,sDAAsD;AACtD,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;CAC1C;AAED,0EAA0E;AAC1E,wBAAgB,QAAQ,CAAC,CAAC,EACxB,EAAE,EAAE,MAAM,CAAC,EACX,OAAO,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,GACjD,YAAY,CAAC,CAAC,CAAC,CA4KjB"}
|
package/dist/computed.js
CHANGED
|
@@ -23,7 +23,7 @@ export function computed(fn, options) {
|
|
|
23
23
|
}
|
|
24
24
|
dirty = true;
|
|
25
25
|
if (source.subscribers !== null) {
|
|
26
|
-
if (runtimeState.notificationDepth > 0) {
|
|
26
|
+
if (runtimeState.notificationDepth > 0 || runtimeState.batchDepth > 0) {
|
|
27
27
|
computation.queued = true;
|
|
28
28
|
runtimeState.pendingComputed.add(computation);
|
|
29
29
|
return;
|
|
@@ -45,6 +45,7 @@ export function computed(fn, options) {
|
|
|
45
45
|
computation.queued = false;
|
|
46
46
|
runtimeState.pendingComputed.delete(computation);
|
|
47
47
|
cleanupDeps(computation);
|
|
48
|
+
computation.orderedDeps = undefined;
|
|
48
49
|
source.subscribers = null;
|
|
49
50
|
},
|
|
50
51
|
};
|
|
@@ -78,17 +79,42 @@ export function computed(fn, options) {
|
|
|
78
79
|
const previousTracker = runtimeState.activeTracker;
|
|
79
80
|
const previousDepsSize = computation.deps.size;
|
|
80
81
|
const nextTrackingVersion = nextTrackingVersionFor(computation);
|
|
81
|
-
computation.trackingAddedDeps =
|
|
82
|
+
computation.trackingAddedDeps = undefined;
|
|
82
83
|
computation.trackingCount = 0;
|
|
84
|
+
computation.trackingOrderedIndex =
|
|
85
|
+
computation.orderedDeps === undefined ? undefined : 0;
|
|
86
|
+
computation.trackingOrderedMismatch = false;
|
|
83
87
|
computation.trackingVersion = nextTrackingVersion;
|
|
84
88
|
runtimeState.activeTracker = computation;
|
|
85
89
|
try {
|
|
86
90
|
const nextValue = fn();
|
|
87
91
|
const addedDeps = computation.trackingAddedDeps;
|
|
88
92
|
const trackedCount = computation.trackingCount ?? 0;
|
|
89
|
-
|
|
93
|
+
const addedDepsCount = addedDeps?.length ?? 0;
|
|
94
|
+
const orderedMismatch = computation.trackingOrderedMismatch;
|
|
95
|
+
if (trackedCount !== previousDepsSize || addedDepsCount > 0) {
|
|
96
|
+
const orderedIndex = computation.trackingOrderedIndex;
|
|
97
|
+
if (computation.trackingTouchedDeps === undefined &&
|
|
98
|
+
orderedIndex !== undefined &&
|
|
99
|
+
orderedIndex > 0 &&
|
|
100
|
+
computation.orderedDeps !== undefined) {
|
|
101
|
+
computation.trackingTouchedDeps = computation.orderedDeps.slice(0, orderedIndex);
|
|
102
|
+
}
|
|
90
103
|
cleanupUntrackedDeps(computation, nextTrackingVersion);
|
|
91
104
|
}
|
|
105
|
+
if (orderedMismatch !== true &&
|
|
106
|
+
trackedCount === previousDepsSize &&
|
|
107
|
+
addedDepsCount === 0) {
|
|
108
|
+
// Keep the previous stable order.
|
|
109
|
+
}
|
|
110
|
+
else if (previousDepsSize === 0 &&
|
|
111
|
+
addedDeps !== undefined &&
|
|
112
|
+
trackedCount === addedDeps.length) {
|
|
113
|
+
computation.orderedDeps = addedDeps;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
computation.orderedDeps = undefined;
|
|
117
|
+
}
|
|
92
118
|
value = nextValue;
|
|
93
119
|
hasValue = true;
|
|
94
120
|
dirty = false;
|
|
@@ -102,6 +128,8 @@ export function computed(fn, options) {
|
|
|
102
128
|
finally {
|
|
103
129
|
computation.trackingAddedDeps = undefined;
|
|
104
130
|
computation.trackingCount = undefined;
|
|
131
|
+
computation.trackingOrderedIndex = undefined;
|
|
132
|
+
computation.trackingOrderedMismatch = undefined;
|
|
105
133
|
computation.trackingTouchedDeps = undefined;
|
|
106
134
|
runtimeState.activeTracker = previousTracker;
|
|
107
135
|
}
|
package/dist/computed.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"computed.js","sourceRoot":"","sources":["../src/computed.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,2BAA2B,EAC3B,sBAAsB,EACtB,WAAW,GACZ,MAAM,eAAe,CAAC;AAWvB,0EAA0E;AAC1E,MAAM,UAAU,QAAQ,CACtB,EAAW,EACX,OAAkD;IAElD,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,KAAQ,CAAC;IACb,IAAI,KAAK,GAAG,IAAI,CAAC;IACjB,MAAM,MAAM,GAAG,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC;IAExF,MAAM,MAAM,GAAW;QACrB,WAAW,EAAE,IAAI;KAClB,CAAC;IAEF,MAAM,WAAW,GAAwB;QACvC,EAAE,EAAE,YAAY,CAAC,iBAAiB;QAClC,IAAI,EAAE,IAAI,GAAG,EAAE;QACf,QAAQ,EAAE,KAAK;QACf,MAAM,EAAE,KAAK;QACb,SAAS;YACP,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,MAAM,CAAC,WAAW,KAAK,IAAI,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;oBACtD,OAAO;gBACT,CAAC;YACH,CAAC;YAED,KAAK,GAAG,IAAI,CAAC;YAEb,IAAI,MAAM,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;gBAChC,IAAI,YAAY,CAAC,iBAAiB,GAAG,CAAC,EAAE,CAAC;oBACvC,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC;oBAC1B,YAAY,CAAC,eAAe,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;oBAC9C,OAAO;gBACT,CAAC;gBAED,gBAAgB,EAAE,CAAC;YACrB,CAAC;QACH,CAAC;QACD,GAAG;YACD,gBAAgB,EAAE,CAAC;QACrB,CAAC;QACD,WAAW,CAAC,MAAM;YAChB,sBAAsB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO;YACL,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;gBACzB,OAAO;YACT,CAAC;YAED,WAAW,CAAC,QAAQ,GAAG,IAAI,CAAC;YAC5B,WAAW,CAAC,MAAM,GAAG,KAAK,CAAC;YAC3B,YAAY,CAAC,eAAe,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YACjD,WAAW,CAAC,WAAW,CAAC,CAAC;YACzB,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC;QAC5B,CAAC;KACF,CAAC;IAEF,YAAY,CAAC,iBAAiB,IAAI,CAAC,CAAC;IAEpC,SAAS,gBAAgB;QACvB,MAAM,gBAAgB,GAAG,QAAQ,CAAC;QAClC,MAAM,aAAa,GAAG,KAAK,CAAC;QAE5B,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,SAAS,EAAE,CAAC;YAE9B,IAAI,CAAC,gBAAgB,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,SAAS,CAAC,EAAE,CAAC;gBAC3D,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,YAAY,CAAC,UAAU,IAAI,CAAC,CAAC;YAE7B,IAAI,CAAC;gBACH,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC5B,CAAC;oBAAS,CAAC;gBACT,YAAY,CAAC,UAAU,IAAI,CAAC,CAAC;gBAE7B,IAAI,YAAY,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;oBAClC,oBAAoB,EAAE,CAAC;gBACzB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,SAAS,SAAS;QAChB,IAAI,CAAC,KAAK,IAAI,QAAQ,EAAE,CAAC;YACvB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,eAAe,GAAG,YAAY,CAAC,aAAa,CAAC;QACnD,MAAM,gBAAgB,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;QAC/C,MAAM,mBAAmB,GAAG,sBAAsB,CAAC,WAAW,CAAC,CAAC;QAEhE,WAAW,CAAC,iBAAiB,GAAG,EAAE,CAAC;QACnC,WAAW,CAAC,aAAa,GAAG,CAAC,CAAC;QAC9B,WAAW,CAAC,eAAe,GAAG,mBAAmB,CAAC;QAClD,YAAY,CAAC,aAAa,GAAG,WAAW,CAAC;QAEzC,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,EAAE,EAAE,CAAC;YAEvB,MAAM,SAAS,GAAG,WAAW,CAAC,iBAAiB,CAAC;YAChD,MAAM,YAAY,GAAG,WAAW,CAAC,aAAa,IAAI,CAAC,CAAC;YAEpD,IAAI,YAAY,KAAK,gBAAgB,IAAI,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtE,oBAAoB,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;YACzD,CAAC;YAED,KAAK,GAAG,SAAS,CAAC;YAClB,QAAQ,GAAG,IAAI,CAAC;YAChB,KAAK,GAAG,KAAK,CAAC;YAEd,OAAO,KAAK,CAAC;QACf,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,gBAAgB,CAAC,WAAW,CAAC,CAAC;YAC9B,KAAK,GAAG,IAAI,CAAC;YAEb,MAAM,KAAK,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,WAAW,CAAC,iBAAiB,GAAG,SAAS,CAAC;YAC1C,WAAW,CAAC,aAAa,GAAG,SAAS,CAAC;YACtC,WAAW,CAAC,mBAAmB,GAAG,SAAS,CAAC;YAC5C,YAAY,CAAC,aAAa,GAAG,eAAe,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,OAAO;QACL,GAAG;YACD,WAAW,CAAC,MAAM,CAAC,CAAC;YAEpB,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,aAAa,GAAG,YAAY,CAAC,aAAa,CAAC;gBAEjD,IAAI,aAAa,KAAK,IAAI,IAAI,aAAa,KAAK,WAAW,EAAE,CAAC;oBAC5D,2BAA2B,CAAC,aAAa,CAAC,CAAC;gBAC7C,CAAC;YACH,CAAC;YAED,OAAO,SAAS,EAAE,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { ReactiveComputation, Source } from \"./state.js\";\nimport { schedulePendingFlush } from \"./scheduler.js\";\nimport { runtimeState } from \"./state.js\";\nimport {\n cleanupAddedDeps,\n cleanupDeps,\n cleanupUntrackedDeps,\n nextTrackingVersionFor,\n notifySubscribers,\n preserveIncrementalTracking,\n trackIncrementalSource,\n trackSource,\n} from \"./tracking.js\";\nimport type { ReadonlyCell } from \"./types.js\";\n\n/** Equality function used to decide whether a computed value changed. */\nexport type ComputedEquality<T> = (previous: T, next: T) => boolean;\n\n/** Options for creating a computed reactive value. */\nexport interface ComputedOptions<T> {\n equals?: ComputedEquality<T> | undefined;\n}\n\n/** Creates a lazily evaluated reactive value derived from other cells. */\nexport function computed<T>(\n fn: () => T,\n options?: ComputedOptions<T> | ComputedEquality<T>,\n): ReadonlyCell<T> {\n let hasValue = false;\n let value: T;\n let dirty = true;\n const equals = typeof options === \"function\" ? options : (options?.equals ?? Object.is);\n\n const source: Source = {\n subscribers: null,\n };\n\n const computation: ReactiveComputation = {\n id: runtimeState.nextComputationId,\n deps: new Set(),\n disposed: false,\n queued: false,\n markDirty() {\n if (dirty) {\n if (source.subscribers === null || computation.queued) {\n return;\n }\n }\n\n dirty = true;\n\n if (source.subscribers !== null) {\n if (runtimeState.notificationDepth > 0) {\n computation.queued = true;\n runtimeState.pendingComputed.add(computation);\n return;\n }\n\n publishIfChanged();\n }\n },\n run() {\n publishIfChanged();\n },\n trackSource(source) {\n trackIncrementalSource(source, computation);\n },\n dispose() {\n if (computation.disposed) {\n return;\n }\n\n computation.disposed = true;\n computation.queued = false;\n runtimeState.pendingComputed.delete(computation);\n cleanupDeps(computation);\n source.subscribers = null;\n },\n };\n\n runtimeState.nextComputationId += 1;\n\n function publishIfChanged(): void {\n const previousHasValue = hasValue;\n const previousValue = value;\n\n try {\n const nextValue = recompute();\n\n if (!previousHasValue || !equals(previousValue, nextValue)) {\n notifySubscribers(source);\n }\n } catch {\n runtimeState.batchDepth += 1;\n\n try {\n notifySubscribers(source);\n } finally {\n runtimeState.batchDepth -= 1;\n\n if (runtimeState.batchDepth === 0) {\n schedulePendingFlush();\n }\n }\n }\n }\n\n function recompute(): T {\n if (!dirty && hasValue) {\n return value;\n }\n\n const previousTracker = runtimeState.activeTracker;\n const previousDepsSize = computation.deps.size;\n const nextTrackingVersion = nextTrackingVersionFor(computation);\n\n computation.trackingAddedDeps = [];\n computation.trackingCount = 0;\n computation.trackingVersion = nextTrackingVersion;\n runtimeState.activeTracker = computation;\n\n try {\n const nextValue = fn();\n\n const addedDeps = computation.trackingAddedDeps;\n const trackedCount = computation.trackingCount ?? 0;\n\n if (trackedCount !== previousDepsSize || (addedDeps?.length ?? 0) > 0) {\n cleanupUntrackedDeps(computation, nextTrackingVersion);\n }\n\n value = nextValue;\n hasValue = true;\n dirty = false;\n\n return value;\n } catch (error) {\n cleanupAddedDeps(computation);\n dirty = true;\n\n throw error;\n } finally {\n computation.trackingAddedDeps = undefined;\n computation.trackingCount = undefined;\n computation.trackingTouchedDeps = undefined;\n runtimeState.activeTracker = previousTracker;\n }\n }\n\n return {\n get(): T {\n trackSource(source);\n\n if (dirty) {\n const activeTracker = runtimeState.activeTracker;\n\n if (activeTracker !== null && activeTracker !== computation) {\n preserveIncrementalTracking(activeTracker);\n }\n }\n\n return recompute();\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"computed.js","sourceRoot":"","sources":["../src/computed.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveComputation, Source } from \"./state.js\";\nimport { schedulePendingFlush } from \"./scheduler.js\";\nimport { runtimeState } from \"./state.js\";\nimport {\n cleanupAddedDeps,\n cleanupDeps,\n cleanupUntrackedDeps,\n nextTrackingVersionFor,\n notifySubscribers,\n preserveIncrementalTracking,\n trackIncrementalSource,\n trackSource,\n} from \"./tracking.js\";\nimport type { ReadonlyCell } from \"./types.js\";\n\n/** Equality function used to decide whether a computed value changed. */\nexport type ComputedEquality<T> = (previous: T, next: T) => boolean;\n\n/** Options for creating a computed reactive value. */\nexport interface ComputedOptions<T> {\n equals?: ComputedEquality<T> | undefined;\n}\n\n/** Creates a lazily evaluated reactive value derived from other cells. */\nexport function computed<T>(\n fn: () => T,\n options?: ComputedOptions<T> | ComputedEquality<T>,\n): ReadonlyCell<T> {\n let hasValue = false;\n let value: T;\n let dirty = true;\n const equals = typeof options === \"function\" ? options : (options?.equals ?? Object.is);\n\n const source: Source = {\n subscribers: null,\n };\n\n const computation: ReactiveComputation = {\n id: runtimeState.nextComputationId,\n deps: new Set(),\n disposed: false,\n queued: false,\n markDirty() {\n if (dirty) {\n if (source.subscribers === null || computation.queued) {\n return;\n }\n }\n\n dirty = true;\n\n if (source.subscribers !== null) {\n if (runtimeState.notificationDepth > 0 || runtimeState.batchDepth > 0) {\n computation.queued = true;\n runtimeState.pendingComputed.add(computation);\n return;\n }\n\n publishIfChanged();\n }\n },\n run() {\n publishIfChanged();\n },\n trackSource(source) {\n trackIncrementalSource(source, computation);\n },\n dispose() {\n if (computation.disposed) {\n return;\n }\n\n computation.disposed = true;\n computation.queued = false;\n runtimeState.pendingComputed.delete(computation);\n cleanupDeps(computation);\n computation.orderedDeps = undefined;\n source.subscribers = null;\n },\n };\n\n runtimeState.nextComputationId += 1;\n\n function publishIfChanged(): void {\n const previousHasValue = hasValue;\n const previousValue = value;\n\n try {\n const nextValue = recompute();\n\n if (!previousHasValue || !equals(previousValue, nextValue)) {\n notifySubscribers(source);\n }\n } catch {\n runtimeState.batchDepth += 1;\n\n try {\n notifySubscribers(source);\n } finally {\n runtimeState.batchDepth -= 1;\n\n if (runtimeState.batchDepth === 0) {\n schedulePendingFlush();\n }\n }\n }\n }\n\n function recompute(): T {\n if (!dirty && hasValue) {\n return value;\n }\n\n const previousTracker = runtimeState.activeTracker;\n const previousDepsSize = computation.deps.size;\n const nextTrackingVersion = nextTrackingVersionFor(computation);\n\n computation.trackingAddedDeps = undefined;\n computation.trackingCount = 0;\n computation.trackingOrderedIndex =\n computation.orderedDeps === undefined ? undefined : 0;\n computation.trackingOrderedMismatch = false;\n computation.trackingVersion = nextTrackingVersion;\n runtimeState.activeTracker = computation;\n\n try {\n const nextValue = fn();\n\n const addedDeps = computation.trackingAddedDeps as Source[] | undefined;\n const trackedCount = computation.trackingCount ?? 0;\n const addedDepsCount = addedDeps?.length ?? 0;\n const orderedMismatch = computation.trackingOrderedMismatch as boolean | undefined;\n\n if (trackedCount !== previousDepsSize || addedDepsCount > 0) {\n const orderedIndex = computation.trackingOrderedIndex;\n\n if (\n computation.trackingTouchedDeps === undefined &&\n orderedIndex !== undefined &&\n orderedIndex > 0 &&\n computation.orderedDeps !== undefined\n ) {\n computation.trackingTouchedDeps = computation.orderedDeps.slice(0, orderedIndex);\n }\n\n cleanupUntrackedDeps(computation, nextTrackingVersion);\n }\n\n if (\n orderedMismatch !== true &&\n trackedCount === previousDepsSize &&\n addedDepsCount === 0\n ) {\n // Keep the previous stable order.\n } else if (\n previousDepsSize === 0 &&\n addedDeps !== undefined &&\n trackedCount === addedDeps.length\n ) {\n computation.orderedDeps = addedDeps;\n } else {\n computation.orderedDeps = undefined;\n }\n\n value = nextValue;\n hasValue = true;\n dirty = false;\n\n return value;\n } catch (error) {\n cleanupAddedDeps(computation);\n dirty = true;\n\n throw error;\n } finally {\n computation.trackingAddedDeps = undefined;\n computation.trackingCount = undefined;\n computation.trackingOrderedIndex = undefined;\n computation.trackingOrderedMismatch = undefined;\n computation.trackingTouchedDeps = undefined;\n runtimeState.activeTracker = previousTracker;\n }\n }\n\n return {\n get(): T {\n trackSource(source);\n\n if (dirty) {\n const activeTracker = runtimeState.activeTracker;\n\n if (activeTracker !== null && activeTracker !== computation) {\n preserveIncrementalTracking(activeTracker);\n }\n }\n\n return recompute();\n },\n };\n}\n"]}
|
package/dist/internal.d.ts
CHANGED
|
@@ -6,6 +6,10 @@ export { registerCleanup, withCleanupScope } from "./cleanup-scope.js";
|
|
|
6
6
|
export { flushQueuedComputations, schedulePendingFlush, setScheduler } from "./scheduler.js";
|
|
7
7
|
/** Computed flush helper used by batched reactive updates. */
|
|
8
8
|
export { flushPendingComputed } from "./tracking.js";
|
|
9
|
+
/** Low-level source helpers used by reactive DOM keyed item proxies. */
|
|
10
|
+
export { notifySubscribers, trackSource } from "./tracking.js";
|
|
9
11
|
/** Shared global runtime state helper for singleton package state. */
|
|
10
12
|
export { getGlobalRuntimeState } from "./runtime-state.js";
|
|
13
|
+
export { runtimeState } from "./state.js";
|
|
14
|
+
export type { Source } from "./state.js";
|
|
11
15
|
//# sourceMappingURL=internal.d.ts.map
|
package/dist/internal.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,4DAA4D;AAC5D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACvE,uEAAuE;AACvE,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7F,8DAA8D;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,sEAAsE;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,4DAA4D;AAC5D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACvE,uEAAuE;AACvE,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7F,8DAA8D;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,wEAAwE;AACxE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC/D,sEAAsE;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,YAAY,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/internal.js
CHANGED
|
@@ -4,6 +4,9 @@ export { registerCleanup, withCleanupScope } from "./cleanup-scope.js";
|
|
|
4
4
|
export { flushQueuedComputations, schedulePendingFlush, setScheduler } from "./scheduler.js";
|
|
5
5
|
/** Computed flush helper used by batched reactive updates. */
|
|
6
6
|
export { flushPendingComputed } from "./tracking.js";
|
|
7
|
+
/** Low-level source helpers used by reactive DOM keyed item proxies. */
|
|
8
|
+
export { notifySubscribers, trackSource } from "./tracking.js";
|
|
7
9
|
/** Shared global runtime state helper for singleton package state. */
|
|
8
10
|
export { getGlobalRuntimeState } from "./runtime-state.js";
|
|
11
|
+
export { runtimeState } from "./state.js";
|
|
9
12
|
//# sourceMappingURL=internal.js.map
|
package/dist/internal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAEA,4DAA4D;AAC5D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACvE,uEAAuE;AACvE,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7F,8DAA8D;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,sEAAsE;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["/** Scheduler type used by reactive-core internal flush control. */\nexport type { Scheduler } from \"./scheduler.js\";\n/** Cleanup scope helpers used by reactive DOM and tests. */\nexport { registerCleanup, withCleanupScope } from \"./cleanup-scope.js\";\n/** Scheduler controls used by reactive-core tests and integrations. */\nexport { flushQueuedComputations, schedulePendingFlush, setScheduler } from \"./scheduler.js\";\n/** Computed flush helper used by batched reactive updates. */\nexport { flushPendingComputed } from \"./tracking.js\";\n/** Shared global runtime state helper for singleton package state. */\nexport { getGlobalRuntimeState } from \"./runtime-state.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAEA,4DAA4D;AAC5D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACvE,uEAAuE;AACvE,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7F,8DAA8D;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,wEAAwE;AACxE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC/D,sEAAsE;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC","sourcesContent":["/** Scheduler type used by reactive-core internal flush control. */\nexport type { Scheduler } from \"./scheduler.js\";\n/** Cleanup scope helpers used by reactive DOM and tests. */\nexport { registerCleanup, withCleanupScope } from \"./cleanup-scope.js\";\n/** Scheduler controls used by reactive-core tests and integrations. */\nexport { flushQueuedComputations, schedulePendingFlush, setScheduler } from \"./scheduler.js\";\n/** Computed flush helper used by batched reactive updates. */\nexport { flushPendingComputed } from \"./tracking.js\";\n/** Low-level source helpers used by reactive DOM keyed item proxies. */\nexport { notifySubscribers, trackSource } from \"./tracking.js\";\n/** Shared global runtime state helper for singleton package state. */\nexport { getGlobalRuntimeState } from \"./runtime-state.js\";\nexport { runtimeState } from \"./state.js\";\nexport type { Source } from \"./state.js\";\n"]}
|
package/dist/state.d.ts
CHANGED
|
@@ -6,8 +6,11 @@ export interface Source {
|
|
|
6
6
|
export interface ReactiveComputation {
|
|
7
7
|
readonly id: number;
|
|
8
8
|
deps: Set<Source>;
|
|
9
|
+
orderedDeps?: Source[] | undefined;
|
|
9
10
|
trackingAddedDeps?: Source[] | undefined;
|
|
10
11
|
trackingCount?: number | undefined;
|
|
12
|
+
trackingOrderedIndex?: number | undefined;
|
|
13
|
+
trackingOrderedMismatch?: boolean | undefined;
|
|
11
14
|
trackingTouchedDeps?: Source[] | undefined;
|
|
12
15
|
trackingVersion?: number | undefined;
|
|
13
16
|
disposed: boolean;
|
package/dist/state.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,MAAM;IAKrB,WAAW,EAAE,mBAAmB,GAAG,GAAG,CAAC,mBAAmB,CAAC,GAAG,IAAI,CAAC;IACnE,SAAS,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACzC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,mBAAmB,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC3C,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,IAAI,IAAI,CAAC;IAClB,GAAG,IAAI,IAAI,CAAC;IACZ,OAAO,IAAI,IAAI,CAAC;IAChB,WAAW,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,MAAM,MAAM,OAAO,GAAG,mBAAmB,GAAG,IAAI,CAAC;AAEjD,eAAO,MAAM,YAAY,EAAE;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC1D,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAC;CAS3C,CAAC"}
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,MAAM;IAKrB,WAAW,EAAE,mBAAmB,GAAG,GAAG,CAAC,mBAAmB,CAAC,GAAG,IAAI,CAAC;IACnE,SAAS,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACnC,iBAAiB,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACzC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,oBAAoB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,uBAAuB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9C,mBAAmB,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC3C,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,IAAI,IAAI,CAAC;IAClB,GAAG,IAAI,IAAI,CAAC;IACZ,OAAO,IAAI,IAAI,CAAC;IAChB,WAAW,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,MAAM,MAAM,OAAO,GAAG,mBAAmB,GAAG,IAAI,CAAC;AAEjD,eAAO,MAAM,YAAY,EAAE;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC1D,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAC;CAS3C,CAAC"}
|
package/dist/state.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,+BAA+B,EAAE,MAAM,sBAAsB,CAAC;AAEvE,wEAAwE;AACxE,6EAA6E;AAC7E,+BAA+B;AAC/B,+BAA+B,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,+BAA+B,EAAE,MAAM,sBAAsB,CAAC;AAEvE,wEAAwE;AACxE,6EAA6E;AAC7E,+BAA+B;AAC/B,+BAA+B,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAgCjD,MAAM,CAAC,MAAM,YAAY,GAQrB;IACF,aAAa,EAAE,IAAI;IACnB,UAAU,EAAE,CAAC;IACb,YAAY,EAAE,SAAS;IACvB,gBAAgB,EAAE,KAAK;IACvB,iBAAiB,EAAE,CAAC;IACpB,iBAAiB,EAAE,CAAC;IACpB,eAAe,EAAE,IAAI,GAAG,EAAE;CAC3B,CAAC","sourcesContent":["import { warnOnDuplicateReactiveCoreCopy } from \"./duplicate-guard.js\";\n\n// This module holds the per-copy reactive runtime identity, so a second\n// evaluation in the same browser page is exactly the duplication that breaks\n// cross-package cell tracking.\nwarnOnDuplicateReactiveCoreCopy(import.meta.url);\n\nexport interface Source {\n // null while nothing subscribes, the computation itself while exactly one\n // does, and a Set from the second subscriber on (kept as a Set until it\n // empties back to null). Most sources never allocate a Set at all, and hot\n // write sites can gate on a null check instead of a Set.size accessor.\n subscribers: ReactiveComputation | Set<ReactiveComputation> | null;\n trackedBy?: ReactiveComputation | undefined;\n trackedVersion?: number | undefined;\n}\n\nexport interface ReactiveComputation {\n readonly id: number;\n deps: Set<Source>;\n orderedDeps?: Source[] | undefined;\n trackingAddedDeps?: Source[] | undefined;\n trackingCount?: number | undefined;\n trackingOrderedIndex?: number | undefined;\n trackingOrderedMismatch?: boolean | undefined;\n trackingTouchedDeps?: Source[] | undefined;\n trackingVersion?: number | undefined;\n disposed: boolean;\n queued: boolean;\n markDirty(): void;\n run(): void;\n dispose(): void;\n trackSource?(source: Source): void;\n}\n\nexport type Tracker = ReactiveComputation | null;\n\nexport const runtimeState: {\n activeTracker: Tracker;\n batchDepth: number;\n cleanupOwner: ((dispose: () => void) => void) | undefined;\n flushingComputed: boolean;\n nextComputationId: number;\n notificationDepth: number;\n pendingComputed: Set<ReactiveComputation>;\n} = {\n activeTracker: null,\n batchDepth: 0,\n cleanupOwner: undefined,\n flushingComputed: false,\n nextComputationId: 0,\n notificationDepth: 0,\n pendingComputed: new Set(),\n};\n"]}
|
package/dist/tracking.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracking.d.ts","sourceRoot":"","sources":["../src/tracking.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,mBAAmB,EAAE,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AAIjF,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAchD;AAgCD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAI5D;AAED,wBAAgB,WAAW,CAAC,WAAW,EAAE,mBAAmB,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"tracking.d.ts","sourceRoot":"","sources":["../src/tracking.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,mBAAmB,EAAE,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AAIjF,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAchD;AAgCD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAI5D;AAED,wBAAgB,WAAW,CAAC,WAAW,EAAE,mBAAmB,GAAG,IAAI,CAclE;AAED,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,mBAAmB,GAAG,MAAM,CAc/E;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,mBAAmB,GAC/B,IAAI,CA+CN;AAED,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,mBAAmB,GAAG,IAAI,CAgBlF;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,mBAAmB,EAChC,eAAe,EAAE,MAAM,GACtB,IAAI,CAyBN;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,mBAAmB,GAAG,IAAI,CAmBvE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAuDtD;AAED,8EAA8E;AAC9E,wBAAgB,oBAAoB,IAAI,IAAI,CAmC3C"}
|
package/dist/tracking.js
CHANGED
|
@@ -53,6 +53,7 @@ export function cleanupDeps(computation) {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
computation.deps.clear();
|
|
56
|
+
computation.orderedDeps = undefined;
|
|
56
57
|
}
|
|
57
58
|
export function nextTrackingVersionFor(computation) {
|
|
58
59
|
const nextTrackingVersion = (computation.trackingVersion ?? 0) + 1;
|
|
@@ -75,16 +76,32 @@ export function trackIncrementalSource(source, computation) {
|
|
|
75
76
|
if (source.trackedBy === computation && source.trackedVersion === trackingVersion) {
|
|
76
77
|
return;
|
|
77
78
|
}
|
|
79
|
+
const orderedIndex = computation.trackingOrderedIndex;
|
|
80
|
+
const orderedDeps = computation.orderedDeps;
|
|
81
|
+
if (orderedIndex !== undefined &&
|
|
82
|
+
computation.trackingOrderedMismatch !== true &&
|
|
83
|
+
orderedDeps !== undefined) {
|
|
84
|
+
if (orderedDeps[orderedIndex] === source) {
|
|
85
|
+
computation.trackingOrderedIndex = orderedIndex + 1;
|
|
86
|
+
computation.trackingCount = (computation.trackingCount ?? 0) + 1;
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
computation.trackingOrderedMismatch = true;
|
|
90
|
+
if (orderedIndex > 0) {
|
|
91
|
+
computation.trackingTouchedDeps = orderedDeps.slice(0, orderedIndex);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const alreadyTrackedByComputation = source.trackedBy === computation;
|
|
78
95
|
source.trackedBy = computation;
|
|
79
96
|
source.trackedVersion = trackingVersion;
|
|
80
97
|
computation.trackingCount = (computation.trackingCount ?? 0) + 1;
|
|
81
98
|
computation.trackingTouchedDeps?.push(source);
|
|
82
|
-
if (computation.deps.has(source)) {
|
|
99
|
+
if (alreadyTrackedByComputation || computation.deps.has(source)) {
|
|
83
100
|
return;
|
|
84
101
|
}
|
|
85
102
|
addSourceSubscriber(source, computation);
|
|
86
103
|
computation.deps.add(source);
|
|
87
|
-
computation.trackingAddedDeps
|
|
104
|
+
(computation.trackingAddedDeps ??= []).push(source);
|
|
88
105
|
}
|
|
89
106
|
export function preserveIncrementalTracking(computation) {
|
|
90
107
|
const trackingVersion = computation.trackingVersion;
|
|
@@ -140,6 +157,12 @@ export function notifySubscribers(source) {
|
|
|
140
157
|
return;
|
|
141
158
|
}
|
|
142
159
|
if (!(subscribers instanceof Set)) {
|
|
160
|
+
if (runtimeState.batchDepth > 0) {
|
|
161
|
+
if (!subscribers.disposed && !subscribers.queued) {
|
|
162
|
+
subscribers.markDirty();
|
|
163
|
+
}
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
143
166
|
runtimeState.notificationDepth += 1;
|
|
144
167
|
try {
|
|
145
168
|
if (!subscribers.disposed && !subscribers.queued) {
|
package/dist/tracking.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracking.js","sourceRoot":"","sources":["../src/tracking.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAyC,MAAM,YAAY,CAAC;AAEjF,MAAM,iCAAiC,GAAG,GAAG,CAAC;AAE9C,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,MAAM,OAAO,GAAG,YAAY,CAAC,aAAa,CAAC;IAE3C,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACzC,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACtC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC3B,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAc,EAAE,WAAgC;IAC3E,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IAEvC,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACzB,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;IACnC,CAAC;SAAM,IAAI,WAAW,YAAY,GAAG,EAAE,CAAC;QACtC,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC/B,CAAC;SAAM,IAAI,WAAW,KAAK,WAAW,EAAE,CAAC;QACvC,MAAM,CAAC,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB,CAAC,MAAc,EAAE,WAAgC;IAC9E,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IAEvC,IAAI,WAAW,KAAK,WAAW,EAAE,CAAC;QAChC,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,WAAW,YAAY,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;QAClE,IAAI,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC;QAC5B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAc;IAClD,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IAEvC,OAAO,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,YAAY,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,WAAgC;IAC1D,KAAK,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC;YAC9C,SAAS;QACX,CAAC;QAED,IAAI,GAAG,CAAC,SAAS,KAAK,WAAW,EAAE,CAAC;YAClC,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;YAC1B,GAAG,CAAC,cAAc,GAAG,SAAS,CAAC;QACjC,CAAC;IACH,CAAC;IAED,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,WAAgC;IACrE,MAAM,mBAAmB,GAAG,CAAC,WAAW,CAAC,eAAe,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAEnE,IAAI,MAAM,CAAC,aAAa,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAC9C,OAAO,mBAAmB,CAAC;IAC7B,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,GAAG,CAAC,SAAS,KAAK,WAAW,EAAE,CAAC;YAClC,GAAG,CAAC,cAAc,GAAG,SAAS,CAAC;QACjC,CAAC;IACH,CAAC;IAED,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,MAAc,EACd,WAAgC;IAEhC,MAAM,eAAe,GAAG,WAAW,CAAC,eAAe,CAAC;IAEpD,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QAClC,WAAW,CAAC,MAAM,CAAC,CAAC;QACpB,OAAO;IACT,CAAC;IAED,IAAI,MAAM,CAAC,SAAS,KAAK,WAAW,IAAI,MAAM,CAAC,cAAc,KAAK,eAAe,EAAE,CAAC;QAClF,OAAO;IACT,CAAC;IAED,MAAM,CAAC,SAAS,GAAG,WAAW,CAAC;IAC/B,MAAM,CAAC,cAAc,GAAG,eAAe,CAAC;IACxC,WAAW,CAAC,aAAa,GAAG,CAAC,WAAW,CAAC,aAAa,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACjE,WAAW,CAAC,mBAAmB,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAE9C,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QACjC,OAAO;IACT,CAAC;IAED,mBAAmB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACzC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,WAAW,CAAC,iBAAiB,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,WAAgC;IAC1E,MAAM,eAAe,GAAG,WAAW,CAAC,eAAe,CAAC;IAEpD,IAAI,eAAe,KAAK,SAAS,IAAI,WAAW,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;QACnF,OAAO;IACT,CAAC;IAED,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,KAAK,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,GAAG,CAAC,SAAS,KAAK,WAAW,IAAI,GAAG,CAAC,cAAc,KAAK,eAAe,EAAE,CAAC;YAC5E,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,WAAW,CAAC,mBAAmB,GAAG,WAAW,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,WAAgC,EAChC,eAAuB;IAEvB,MAAM,WAAW,GACf,WAAW,CAAC,mBAAmB,KAAK,SAAS;QAC3C,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC;IAE/C,KAAK,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC;QACnC,IACE,WAAW,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI;YAC9B,CAAC,GAAG,CAAC,SAAS,KAAK,WAAW,IAAI,GAAG,CAAC,cAAc,KAAK,eAAe,CAAC,EACzE,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC;YAC9C,SAAS;QACX,CAAC;QAED,IAAI,GAAG,CAAC,SAAS,KAAK,WAAW,EAAE,CAAC;YAClC,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;YAC1B,GAAG,CAAC,cAAc,GAAG,SAAS,CAAC;QACjC,CAAC;QAED,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,WAAgC;IAC/D,MAAM,SAAS,GAAG,WAAW,CAAC,iBAAiB,CAAC;IAEhD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC;YAC9C,SAAS;QACX,CAAC;QAED,IAAI,GAAG,CAAC,SAAS,KAAK,WAAW,EAAE,CAAC;YAClC,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;YAC1B,GAAG,CAAC,cAAc,GAAG,SAAS,CAAC;QACjC,CAAC;QAED,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IAEvC,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACzB,OAAO;IACT,CAAC;IAED,IAAI,CAAC,CAAC,WAAW,YAAY,GAAG,CAAC,EAAE,CAAC;QAClC,YAAY,CAAC,iBAAiB,IAAI,CAAC,CAAC;QAEpC,IAAI,CAAC;YACH,IAAI,CAAC,WAAW,CAAC,QAAQ,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;gBACjD,WAAW,CAAC,SAAS,EAAE,CAAC;YAC1B,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,iBAAiB,IAAI,CAAC,CAAC;YAEpC,IAAI,YAAY,CAAC,iBAAiB,KAAK,CAAC,IAAI,YAAY,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;gBAC1E,oBAAoB,EAAE,CAAC;YACzB,CAAC;QACH,CAAC;QACD,OAAO;IACT,CAAC;IAED,YAAY,CAAC,iBAAiB,IAAI,CAAC,CAAC;IAEpC,IAAI,CAAC;QACH,MAAM,gBAAgB,GACpB,WAAW,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QAEzE,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;YACnC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC;gBAC3D,gBAAgB,CAAC,SAAS,EAAE,CAAC;YAC/B,CAAC;QACH,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,UAAU,IAAI,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC1D,IAAI,CAAC,UAAU,CAAC,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;oBAC/C,UAAU,CAAC,SAAS,EAAE,CAAC;gBACzB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,iBAAiB,IAAI,CAAC,CAAC;QAEpC,IAAI,YAAY,CAAC,iBAAiB,KAAK,CAAC,IAAI,YAAY,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;YAC1E,oBAAoB,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,oBAAoB;IAClC,IAAI,YAAY,CAAC,gBAAgB,EAAE,CAAC;QAClC,OAAO;IACT,CAAC;IAED,YAAY,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAErC,IAAI,CAAC;QACH,KACE,IAAI,SAAS,GAAG,CAAC,EACjB,YAAY,CAAC,eAAe,CAAC,IAAI,GAAG,CAAC,EACrC,SAAS,IAAI,CAAC,EACd,CAAC;YACD,IAAI,SAAS,IAAI,iCAAiC,EAAE,CAAC;gBACnD,YAAY,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;gBACrC,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;YAC5D,CAAC;YAED,MAAM,YAAY,GAChB,YAAY,CAAC,eAAe,CAAC,IAAI,KAAK,CAAC;gBACrC,CAAC,CAAC,CAAC,YAAY,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAA4B,CAAC;gBAC7E,CAAC,CAAC,mBAAmB,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;YACxD,YAAY,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;YAErC,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;gBACvC,WAAW,CAAC,MAAM,GAAG,KAAK,CAAC;gBAE3B,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;oBAC1B,WAAW,CAAC,GAAG,EAAE,CAAC;gBACpB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,gBAAgB,GAAG,KAAK,CAAC;IACxC,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAC1B,YAA8C;IAE9C,MAAM,OAAO,GAA0B,EAAE,CAAC;IAC1C,IAAI,UAAU,GAAG,CAAC,CAAC,CAAC;IACpB,IAAI,SAAS,GAAG,IAAI,CAAC;IAErB,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAE1B,IAAI,WAAW,CAAC,EAAE,GAAG,UAAU,EAAE,CAAC;YAChC,SAAS,GAAG,KAAK,CAAC;QACpB,CAAC;QAED,UAAU,GAAG,WAAW,CAAC,EAAE,CAAC;IAC9B,CAAC;IAED,OAAO,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QACpC,CAAC,CAAC,OAAO;QACT,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;AAC1C,CAAC","sourcesContent":["import { runtimeState, type ReactiveComputation, type Source } from \"./state.js\";\n\nconst maxPendingComputedFlushIterations = 100;\n\nexport function trackSource(source: Source): void {\n const tracker = runtimeState.activeTracker;\n\n if (tracker === null || tracker.disposed) {\n return;\n }\n\n if (tracker.trackSource !== undefined) {\n tracker.trackSource(source);\n return;\n }\n\n addSourceSubscriber(source, tracker);\n tracker.deps.add(source);\n}\n\nfunction addSourceSubscriber(source: Source, computation: ReactiveComputation): void {\n const subscribers = source.subscribers;\n\n if (subscribers === null) {\n source.subscribers = computation;\n } else if (subscribers instanceof Set) {\n subscribers.add(computation);\n } else if (subscribers !== computation) {\n source.subscribers = new Set([subscribers, computation]);\n }\n}\n\nfunction removeSourceSubscriber(source: Source, computation: ReactiveComputation): boolean {\n const subscribers = source.subscribers;\n\n if (subscribers === computation) {\n source.subscribers = null;\n return true;\n }\n\n if (subscribers instanceof Set && subscribers.delete(computation)) {\n if (subscribers.size === 0) {\n source.subscribers = null;\n }\n return true;\n }\n\n return false;\n}\n\nexport function sourceSubscriberCount(source: Source): number {\n const subscribers = source.subscribers;\n\n return subscribers === null ? 0 : subscribers instanceof Set ? subscribers.size : 1;\n}\n\nexport function cleanupDeps(computation: ReactiveComputation): void {\n for (const dep of computation.deps) {\n if (!removeSourceSubscriber(dep, computation)) {\n continue;\n }\n\n if (dep.trackedBy === computation) {\n dep.trackedBy = undefined;\n dep.trackedVersion = undefined;\n }\n }\n\n computation.deps.clear();\n}\n\nexport function nextTrackingVersionFor(computation: ReactiveComputation): number {\n const nextTrackingVersion = (computation.trackingVersion ?? 0) + 1;\n\n if (Number.isSafeInteger(nextTrackingVersion)) {\n return nextTrackingVersion;\n }\n\n for (const dep of computation.deps) {\n if (dep.trackedBy === computation) {\n dep.trackedVersion = undefined;\n }\n }\n\n return 1;\n}\n\nexport function trackIncrementalSource(\n source: Source,\n computation: ReactiveComputation,\n): void {\n const trackingVersion = computation.trackingVersion;\n\n if (trackingVersion === undefined) {\n trackSource(source);\n return;\n }\n\n if (source.trackedBy === computation && source.trackedVersion === trackingVersion) {\n return;\n }\n\n source.trackedBy = computation;\n source.trackedVersion = trackingVersion;\n computation.trackingCount = (computation.trackingCount ?? 0) + 1;\n computation.trackingTouchedDeps?.push(source);\n\n if (computation.deps.has(source)) {\n return;\n }\n\n addSourceSubscriber(source, computation);\n computation.deps.add(source);\n computation.trackingAddedDeps?.push(source);\n}\n\nexport function preserveIncrementalTracking(computation: ReactiveComputation): void {\n const trackingVersion = computation.trackingVersion;\n\n if (trackingVersion === undefined || computation.trackingTouchedDeps !== undefined) {\n return;\n }\n\n const touchedDeps: Source[] = [];\n\n for (const dep of computation.deps) {\n if (dep.trackedBy === computation && dep.trackedVersion === trackingVersion) {\n touchedDeps.push(dep);\n }\n }\n\n computation.trackingTouchedDeps = touchedDeps;\n}\n\nexport function cleanupUntrackedDeps(\n computation: ReactiveComputation,\n trackingVersion: number,\n): void {\n const touchedDeps =\n computation.trackingTouchedDeps === undefined\n ? undefined\n : new Set(computation.trackingTouchedDeps);\n\n for (const dep of computation.deps) {\n if (\n touchedDeps?.has(dep) === true ||\n (dep.trackedBy === computation && dep.trackedVersion === trackingVersion)\n ) {\n continue;\n }\n\n if (!removeSourceSubscriber(dep, computation)) {\n continue;\n }\n\n if (dep.trackedBy === computation) {\n dep.trackedBy = undefined;\n dep.trackedVersion = undefined;\n }\n\n computation.deps.delete(dep);\n }\n}\n\nexport function cleanupAddedDeps(computation: ReactiveComputation): void {\n const addedDeps = computation.trackingAddedDeps;\n\n if (addedDeps === undefined) {\n return;\n }\n\n for (const dep of addedDeps) {\n if (!removeSourceSubscriber(dep, computation)) {\n continue;\n }\n\n if (dep.trackedBy === computation) {\n dep.trackedBy = undefined;\n dep.trackedVersion = undefined;\n }\n\n computation.deps.delete(dep);\n }\n}\n\nexport function notifySubscribers(source: Source): void {\n const subscribers = source.subscribers;\n\n if (subscribers === null) {\n return;\n }\n\n if (!(subscribers instanceof Set)) {\n runtimeState.notificationDepth += 1;\n\n try {\n if (!subscribers.disposed && !subscribers.queued) {\n subscribers.markDirty();\n }\n } finally {\n runtimeState.notificationDepth -= 1;\n\n if (runtimeState.notificationDepth === 0 && runtimeState.batchDepth === 0) {\n flushPendingComputed();\n }\n }\n return;\n }\n\n runtimeState.notificationDepth += 1;\n\n try {\n const singleSubscriber =\n subscribers.size === 1 ? subscribers.values().next().value : undefined;\n\n if (singleSubscriber !== undefined) {\n if (!singleSubscriber.disposed && !singleSubscriber.queued) {\n singleSubscriber.markDirty();\n }\n } else {\n for (const subscriber of orderedComputations(subscribers)) {\n if (!subscriber.disposed && !subscriber.queued) {\n subscriber.markDirty();\n }\n }\n }\n } finally {\n runtimeState.notificationDepth -= 1;\n\n if (runtimeState.notificationDepth === 0 && runtimeState.batchDepth === 0) {\n flushPendingComputed();\n }\n }\n}\n\n/** Flushes computed values that were dirtied during batched notifications. */\nexport function flushPendingComputed(): void {\n if (runtimeState.flushingComputed) {\n return;\n }\n\n runtimeState.flushingComputed = true;\n\n try {\n for (\n let iteration = 0;\n runtimeState.pendingComputed.size > 0;\n iteration += 1\n ) {\n if (iteration >= maxPendingComputedFlushIterations) {\n runtimeState.pendingComputed.clear();\n throw new Error(\"Reactive computed flush limit exceeded\");\n }\n\n const computations =\n runtimeState.pendingComputed.size === 1\n ? [runtimeState.pendingComputed.values().next().value as ReactiveComputation]\n : orderedComputations(runtimeState.pendingComputed);\n runtimeState.pendingComputed.clear();\n\n for (const computation of computations) {\n computation.queued = false;\n\n if (!computation.disposed) {\n computation.run();\n }\n }\n }\n } finally {\n runtimeState.flushingComputed = false;\n }\n}\n\nfunction orderedComputations(\n computations: ReadonlySet<ReactiveComputation>,\n): ReactiveComputation[] {\n const ordered: ReactiveComputation[] = [];\n let previousId = -1;\n let monotonic = true;\n\n for (const computation of computations) {\n ordered.push(computation);\n\n if (computation.id < previousId) {\n monotonic = false;\n }\n\n previousId = computation.id;\n }\n\n return monotonic || ordered.length < 2\n ? ordered\n : ordered.sort((a, b) => a.id - b.id);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tracking.js","sourceRoot":"","sources":["../src/tracking.ts"],"names":[],"mappings":"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","sourcesContent":["import { runtimeState, type ReactiveComputation, type Source } from \"./state.js\";\n\nconst maxPendingComputedFlushIterations = 100;\n\nexport function trackSource(source: Source): void {\n const tracker = runtimeState.activeTracker;\n\n if (tracker === null || tracker.disposed) {\n return;\n }\n\n if (tracker.trackSource !== undefined) {\n tracker.trackSource(source);\n return;\n }\n\n addSourceSubscriber(source, tracker);\n tracker.deps.add(source);\n}\n\nfunction addSourceSubscriber(source: Source, computation: ReactiveComputation): void {\n const subscribers = source.subscribers;\n\n if (subscribers === null) {\n source.subscribers = computation;\n } else if (subscribers instanceof Set) {\n subscribers.add(computation);\n } else if (subscribers !== computation) {\n source.subscribers = new Set([subscribers, computation]);\n }\n}\n\nfunction removeSourceSubscriber(source: Source, computation: ReactiveComputation): boolean {\n const subscribers = source.subscribers;\n\n if (subscribers === computation) {\n source.subscribers = null;\n return true;\n }\n\n if (subscribers instanceof Set && subscribers.delete(computation)) {\n if (subscribers.size === 0) {\n source.subscribers = null;\n }\n return true;\n }\n\n return false;\n}\n\nexport function sourceSubscriberCount(source: Source): number {\n const subscribers = source.subscribers;\n\n return subscribers === null ? 0 : subscribers instanceof Set ? subscribers.size : 1;\n}\n\nexport function cleanupDeps(computation: ReactiveComputation): void {\n for (const dep of computation.deps) {\n if (!removeSourceSubscriber(dep, computation)) {\n continue;\n }\n\n if (dep.trackedBy === computation) {\n dep.trackedBy = undefined;\n dep.trackedVersion = undefined;\n }\n }\n\n computation.deps.clear();\n computation.orderedDeps = undefined;\n}\n\nexport function nextTrackingVersionFor(computation: ReactiveComputation): number {\n const nextTrackingVersion = (computation.trackingVersion ?? 0) + 1;\n\n if (Number.isSafeInteger(nextTrackingVersion)) {\n return nextTrackingVersion;\n }\n\n for (const dep of computation.deps) {\n if (dep.trackedBy === computation) {\n dep.trackedVersion = undefined;\n }\n }\n\n return 1;\n}\n\nexport function trackIncrementalSource(\n source: Source,\n computation: ReactiveComputation,\n): void {\n const trackingVersion = computation.trackingVersion;\n\n if (trackingVersion === undefined) {\n trackSource(source);\n return;\n }\n\n if (source.trackedBy === computation && source.trackedVersion === trackingVersion) {\n return;\n }\n\n const orderedIndex = computation.trackingOrderedIndex;\n const orderedDeps = computation.orderedDeps;\n\n if (\n orderedIndex !== undefined &&\n computation.trackingOrderedMismatch !== true &&\n orderedDeps !== undefined\n ) {\n if (orderedDeps[orderedIndex] === source) {\n computation.trackingOrderedIndex = orderedIndex + 1;\n computation.trackingCount = (computation.trackingCount ?? 0) + 1;\n return;\n }\n\n computation.trackingOrderedMismatch = true;\n\n if (orderedIndex > 0) {\n computation.trackingTouchedDeps = orderedDeps.slice(0, orderedIndex);\n }\n }\n\n const alreadyTrackedByComputation = source.trackedBy === computation;\n\n source.trackedBy = computation;\n source.trackedVersion = trackingVersion;\n computation.trackingCount = (computation.trackingCount ?? 0) + 1;\n computation.trackingTouchedDeps?.push(source);\n\n if (alreadyTrackedByComputation || computation.deps.has(source)) {\n return;\n }\n\n addSourceSubscriber(source, computation);\n computation.deps.add(source);\n (computation.trackingAddedDeps ??= []).push(source);\n}\n\nexport function preserveIncrementalTracking(computation: ReactiveComputation): void {\n const trackingVersion = computation.trackingVersion;\n\n if (trackingVersion === undefined || computation.trackingTouchedDeps !== undefined) {\n return;\n }\n\n const touchedDeps: Source[] = [];\n\n for (const dep of computation.deps) {\n if (dep.trackedBy === computation && dep.trackedVersion === trackingVersion) {\n touchedDeps.push(dep);\n }\n }\n\n computation.trackingTouchedDeps = touchedDeps;\n}\n\nexport function cleanupUntrackedDeps(\n computation: ReactiveComputation,\n trackingVersion: number,\n): void {\n const touchedDeps =\n computation.trackingTouchedDeps === undefined\n ? undefined\n : new Set(computation.trackingTouchedDeps);\n\n for (const dep of computation.deps) {\n if (\n touchedDeps?.has(dep) === true ||\n (dep.trackedBy === computation && dep.trackedVersion === trackingVersion)\n ) {\n continue;\n }\n\n if (!removeSourceSubscriber(dep, computation)) {\n continue;\n }\n\n if (dep.trackedBy === computation) {\n dep.trackedBy = undefined;\n dep.trackedVersion = undefined;\n }\n\n computation.deps.delete(dep);\n }\n}\n\nexport function cleanupAddedDeps(computation: ReactiveComputation): void {\n const addedDeps = computation.trackingAddedDeps;\n\n if (addedDeps === undefined) {\n return;\n }\n\n for (const dep of addedDeps) {\n if (!removeSourceSubscriber(dep, computation)) {\n continue;\n }\n\n if (dep.trackedBy === computation) {\n dep.trackedBy = undefined;\n dep.trackedVersion = undefined;\n }\n\n computation.deps.delete(dep);\n }\n}\n\nexport function notifySubscribers(source: Source): void {\n const subscribers = source.subscribers;\n\n if (subscribers === null) {\n return;\n }\n\n if (!(subscribers instanceof Set)) {\n if (runtimeState.batchDepth > 0) {\n if (!subscribers.disposed && !subscribers.queued) {\n subscribers.markDirty();\n }\n return;\n }\n\n runtimeState.notificationDepth += 1;\n\n try {\n if (!subscribers.disposed && !subscribers.queued) {\n subscribers.markDirty();\n }\n } finally {\n runtimeState.notificationDepth -= 1;\n\n if (runtimeState.notificationDepth === 0 && runtimeState.batchDepth === 0) {\n flushPendingComputed();\n }\n }\n return;\n }\n\n runtimeState.notificationDepth += 1;\n\n try {\n const singleSubscriber =\n subscribers.size === 1 ? subscribers.values().next().value : undefined;\n\n if (singleSubscriber !== undefined) {\n if (!singleSubscriber.disposed && !singleSubscriber.queued) {\n singleSubscriber.markDirty();\n }\n } else {\n for (const subscriber of orderedComputations(subscribers)) {\n if (!subscriber.disposed && !subscriber.queued) {\n subscriber.markDirty();\n }\n }\n }\n } finally {\n runtimeState.notificationDepth -= 1;\n\n if (runtimeState.notificationDepth === 0 && runtimeState.batchDepth === 0) {\n flushPendingComputed();\n }\n }\n}\n\n/** Flushes computed values that were dirtied during batched notifications. */\nexport function flushPendingComputed(): void {\n if (runtimeState.flushingComputed) {\n return;\n }\n\n runtimeState.flushingComputed = true;\n\n try {\n for (\n let iteration = 0;\n runtimeState.pendingComputed.size > 0;\n iteration += 1\n ) {\n if (iteration >= maxPendingComputedFlushIterations) {\n runtimeState.pendingComputed.clear();\n throw new Error(\"Reactive computed flush limit exceeded\");\n }\n\n const computations =\n runtimeState.pendingComputed.size === 1\n ? [runtimeState.pendingComputed.values().next().value as ReactiveComputation]\n : orderedComputations(runtimeState.pendingComputed);\n runtimeState.pendingComputed.clear();\n\n for (const computation of computations) {\n computation.queued = false;\n\n if (!computation.disposed) {\n computation.run();\n }\n }\n }\n } finally {\n runtimeState.flushingComputed = false;\n }\n}\n\nfunction orderedComputations(\n computations: ReadonlySet<ReactiveComputation>,\n): ReactiveComputation[] {\n const ordered: ReactiveComputation[] = [];\n let previousId = -1;\n let monotonic = true;\n\n for (const computation of computations) {\n ordered.push(computation);\n\n if (computation.id < previousId) {\n monotonic = false;\n }\n\n previousId = computation.id;\n }\n\n return monotonic || ordered.length < 2\n ? ordered\n : ordered.sort((a, b) => a.id - b.id);\n}\n"]}
|
package/package.json
CHANGED
package/src/cell.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Cell } from "./types.js";
|
|
2
2
|
import type { Source } from "./state.js";
|
|
3
|
+
import { runtimeState } from "./state.js";
|
|
3
4
|
import { notifySubscribers, sourceSubscriberCount, trackSource } from "./tracking.js";
|
|
4
5
|
|
|
5
6
|
declare const __MREACT_CLIENT_DEVTOOLS__: boolean | undefined;
|
|
@@ -94,7 +95,15 @@ function writeCellValue<T>(state: CellState<T>, next: T | ((prev: T) => T)): voi
|
|
|
94
95
|
emitCellSetEvent(state.source, previous, resolved);
|
|
95
96
|
}
|
|
96
97
|
|
|
97
|
-
|
|
98
|
+
const subscribers = state.source.subscribers;
|
|
99
|
+
if (subscribers !== null) {
|
|
100
|
+
if (runtimeState.batchDepth > 0 && !(subscribers instanceof Set)) {
|
|
101
|
+
if (!subscribers.disposed && !subscribers.queued) {
|
|
102
|
+
subscribers.markDirty();
|
|
103
|
+
}
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
98
107
|
notifySubscribers(state.source);
|
|
99
108
|
}
|
|
100
109
|
}
|
package/src/computed.ts
CHANGED
|
@@ -50,7 +50,7 @@ export function computed<T>(
|
|
|
50
50
|
dirty = true;
|
|
51
51
|
|
|
52
52
|
if (source.subscribers !== null) {
|
|
53
|
-
if (runtimeState.notificationDepth > 0) {
|
|
53
|
+
if (runtimeState.notificationDepth > 0 || runtimeState.batchDepth > 0) {
|
|
54
54
|
computation.queued = true;
|
|
55
55
|
runtimeState.pendingComputed.add(computation);
|
|
56
56
|
return;
|
|
@@ -74,6 +74,7 @@ export function computed<T>(
|
|
|
74
74
|
computation.queued = false;
|
|
75
75
|
runtimeState.pendingComputed.delete(computation);
|
|
76
76
|
cleanupDeps(computation);
|
|
77
|
+
computation.orderedDeps = undefined;
|
|
77
78
|
source.subscribers = null;
|
|
78
79
|
},
|
|
79
80
|
};
|
|
@@ -114,21 +115,53 @@ export function computed<T>(
|
|
|
114
115
|
const previousDepsSize = computation.deps.size;
|
|
115
116
|
const nextTrackingVersion = nextTrackingVersionFor(computation);
|
|
116
117
|
|
|
117
|
-
computation.trackingAddedDeps =
|
|
118
|
+
computation.trackingAddedDeps = undefined;
|
|
118
119
|
computation.trackingCount = 0;
|
|
120
|
+
computation.trackingOrderedIndex =
|
|
121
|
+
computation.orderedDeps === undefined ? undefined : 0;
|
|
122
|
+
computation.trackingOrderedMismatch = false;
|
|
119
123
|
computation.trackingVersion = nextTrackingVersion;
|
|
120
124
|
runtimeState.activeTracker = computation;
|
|
121
125
|
|
|
122
126
|
try {
|
|
123
127
|
const nextValue = fn();
|
|
124
128
|
|
|
125
|
-
const addedDeps = computation.trackingAddedDeps;
|
|
129
|
+
const addedDeps = computation.trackingAddedDeps as Source[] | undefined;
|
|
126
130
|
const trackedCount = computation.trackingCount ?? 0;
|
|
131
|
+
const addedDepsCount = addedDeps?.length ?? 0;
|
|
132
|
+
const orderedMismatch = computation.trackingOrderedMismatch as boolean | undefined;
|
|
133
|
+
|
|
134
|
+
if (trackedCount !== previousDepsSize || addedDepsCount > 0) {
|
|
135
|
+
const orderedIndex = computation.trackingOrderedIndex;
|
|
136
|
+
|
|
137
|
+
if (
|
|
138
|
+
computation.trackingTouchedDeps === undefined &&
|
|
139
|
+
orderedIndex !== undefined &&
|
|
140
|
+
orderedIndex > 0 &&
|
|
141
|
+
computation.orderedDeps !== undefined
|
|
142
|
+
) {
|
|
143
|
+
computation.trackingTouchedDeps = computation.orderedDeps.slice(0, orderedIndex);
|
|
144
|
+
}
|
|
127
145
|
|
|
128
|
-
if (trackedCount !== previousDepsSize || (addedDeps?.length ?? 0) > 0) {
|
|
129
146
|
cleanupUntrackedDeps(computation, nextTrackingVersion);
|
|
130
147
|
}
|
|
131
148
|
|
|
149
|
+
if (
|
|
150
|
+
orderedMismatch !== true &&
|
|
151
|
+
trackedCount === previousDepsSize &&
|
|
152
|
+
addedDepsCount === 0
|
|
153
|
+
) {
|
|
154
|
+
// Keep the previous stable order.
|
|
155
|
+
} else if (
|
|
156
|
+
previousDepsSize === 0 &&
|
|
157
|
+
addedDeps !== undefined &&
|
|
158
|
+
trackedCount === addedDeps.length
|
|
159
|
+
) {
|
|
160
|
+
computation.orderedDeps = addedDeps;
|
|
161
|
+
} else {
|
|
162
|
+
computation.orderedDeps = undefined;
|
|
163
|
+
}
|
|
164
|
+
|
|
132
165
|
value = nextValue;
|
|
133
166
|
hasValue = true;
|
|
134
167
|
dirty = false;
|
|
@@ -142,6 +175,8 @@ export function computed<T>(
|
|
|
142
175
|
} finally {
|
|
143
176
|
computation.trackingAddedDeps = undefined;
|
|
144
177
|
computation.trackingCount = undefined;
|
|
178
|
+
computation.trackingOrderedIndex = undefined;
|
|
179
|
+
computation.trackingOrderedMismatch = undefined;
|
|
145
180
|
computation.trackingTouchedDeps = undefined;
|
|
146
181
|
runtimeState.activeTracker = previousTracker;
|
|
147
182
|
}
|
package/src/internal.ts
CHANGED
|
@@ -6,5 +6,9 @@ export { registerCleanup, withCleanupScope } from "./cleanup-scope.js";
|
|
|
6
6
|
export { flushQueuedComputations, schedulePendingFlush, setScheduler } from "./scheduler.js";
|
|
7
7
|
/** Computed flush helper used by batched reactive updates. */
|
|
8
8
|
export { flushPendingComputed } from "./tracking.js";
|
|
9
|
+
/** Low-level source helpers used by reactive DOM keyed item proxies. */
|
|
10
|
+
export { notifySubscribers, trackSource } from "./tracking.js";
|
|
9
11
|
/** Shared global runtime state helper for singleton package state. */
|
|
10
12
|
export { getGlobalRuntimeState } from "./runtime-state.js";
|
|
13
|
+
export { runtimeState } from "./state.js";
|
|
14
|
+
export type { Source } from "./state.js";
|
package/src/state.ts
CHANGED
|
@@ -18,8 +18,11 @@ export interface Source {
|
|
|
18
18
|
export interface ReactiveComputation {
|
|
19
19
|
readonly id: number;
|
|
20
20
|
deps: Set<Source>;
|
|
21
|
+
orderedDeps?: Source[] | undefined;
|
|
21
22
|
trackingAddedDeps?: Source[] | undefined;
|
|
22
23
|
trackingCount?: number | undefined;
|
|
24
|
+
trackingOrderedIndex?: number | undefined;
|
|
25
|
+
trackingOrderedMismatch?: boolean | undefined;
|
|
23
26
|
trackingTouchedDeps?: Source[] | undefined;
|
|
24
27
|
trackingVersion?: number | undefined;
|
|
25
28
|
disposed: boolean;
|
package/src/tracking.ts
CHANGED
|
@@ -67,6 +67,7 @@ export function cleanupDeps(computation: ReactiveComputation): void {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
computation.deps.clear();
|
|
70
|
+
computation.orderedDeps = undefined;
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
export function nextTrackingVersionFor(computation: ReactiveComputation): number {
|
|
@@ -100,18 +101,41 @@ export function trackIncrementalSource(
|
|
|
100
101
|
return;
|
|
101
102
|
}
|
|
102
103
|
|
|
104
|
+
const orderedIndex = computation.trackingOrderedIndex;
|
|
105
|
+
const orderedDeps = computation.orderedDeps;
|
|
106
|
+
|
|
107
|
+
if (
|
|
108
|
+
orderedIndex !== undefined &&
|
|
109
|
+
computation.trackingOrderedMismatch !== true &&
|
|
110
|
+
orderedDeps !== undefined
|
|
111
|
+
) {
|
|
112
|
+
if (orderedDeps[orderedIndex] === source) {
|
|
113
|
+
computation.trackingOrderedIndex = orderedIndex + 1;
|
|
114
|
+
computation.trackingCount = (computation.trackingCount ?? 0) + 1;
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
computation.trackingOrderedMismatch = true;
|
|
119
|
+
|
|
120
|
+
if (orderedIndex > 0) {
|
|
121
|
+
computation.trackingTouchedDeps = orderedDeps.slice(0, orderedIndex);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const alreadyTrackedByComputation = source.trackedBy === computation;
|
|
126
|
+
|
|
103
127
|
source.trackedBy = computation;
|
|
104
128
|
source.trackedVersion = trackingVersion;
|
|
105
129
|
computation.trackingCount = (computation.trackingCount ?? 0) + 1;
|
|
106
130
|
computation.trackingTouchedDeps?.push(source);
|
|
107
131
|
|
|
108
|
-
if (computation.deps.has(source)) {
|
|
132
|
+
if (alreadyTrackedByComputation || computation.deps.has(source)) {
|
|
109
133
|
return;
|
|
110
134
|
}
|
|
111
135
|
|
|
112
136
|
addSourceSubscriber(source, computation);
|
|
113
137
|
computation.deps.add(source);
|
|
114
|
-
computation.trackingAddedDeps
|
|
138
|
+
(computation.trackingAddedDeps ??= []).push(source);
|
|
115
139
|
}
|
|
116
140
|
|
|
117
141
|
export function preserveIncrementalTracking(computation: ReactiveComputation): void {
|
|
@@ -191,6 +215,13 @@ export function notifySubscribers(source: Source): void {
|
|
|
191
215
|
}
|
|
192
216
|
|
|
193
217
|
if (!(subscribers instanceof Set)) {
|
|
218
|
+
if (runtimeState.batchDepth > 0) {
|
|
219
|
+
if (!subscribers.disposed && !subscribers.queued) {
|
|
220
|
+
subscribers.markDirty();
|
|
221
|
+
}
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
|
|
194
225
|
runtimeState.notificationDepth += 1;
|
|
195
226
|
|
|
196
227
|
try {
|