@reckona/mreact-reactive-core 0.0.152 → 0.0.154
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/batch.d.ts.map +1 -1
- package/dist/batch.js +3 -0
- package/dist/batch.js.map +1 -1
- package/dist/cell.d.ts +1 -0
- package/dist/cell.d.ts.map +1 -1
- package/dist/cell.js +72 -38
- package/dist/cell.js.map +1 -1
- package/dist/computed.d.ts.map +1 -1
- package/dist/computed.js +8 -6
- package/dist/computed.js.map +1 -1
- package/dist/effect.d.ts.map +1 -1
- package/dist/effect.js +6 -2
- package/dist/effect.js.map +1 -1
- package/dist/scheduler.d.ts +1 -0
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +10 -0
- package/dist/scheduler.js.map +1 -1
- package/dist/state.d.ts +1 -2
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js.map +1 -1
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +2 -1
- package/dist/testing.js.map +1 -1
- package/dist/tracking.d.ts +2 -0
- package/dist/tracking.d.ts.map +1 -1
- package/dist/tracking.js +53 -51
- package/dist/tracking.js.map +1 -1
- package/package.json +1 -1
- package/src/batch.ts +3 -0
- package/src/cell.ts +100 -47
- package/src/computed.ts +8 -5
- package/src/effect.ts +6 -1
- package/src/scheduler.ts +12 -0
- package/src/state.ts +5 -2
- package/src/testing.ts +2 -1
- package/src/tracking.ts +62 -52
package/README.md
CHANGED
|
@@ -52,6 +52,8 @@ document.startViewTransition(() => {
|
|
|
52
52
|
|
|
53
53
|
If you need the DOM committed synchronously before the current task continues, for example to measure layout right after an update, wrap the update in `flushSync` from the React DOM-compatible entrypoint (`react-dom` in mreact apps, `@reckona/mreact-dom` standalone), which drains pending reactive computations before returning. Updates deferred through `startTransition` or `useDeferredValue` run on a macrotask scheduler and are not guaranteed to land inside a view transition capture.
|
|
54
54
|
|
|
55
|
+
`batchAsync()` keeps effect flushing suspended for the full callback, including every awaited step, then releases the queued work once when the callback resolves or rejects. Use it for short transaction-style updates where intermediate effects would be misleading; avoid wrapping long I/O or user interaction flows because observers will not see effects until the batch finishes, even though direct `.get()` reads still see the latest cell values.
|
|
56
|
+
|
|
55
57
|
## Testing
|
|
56
58
|
|
|
57
59
|
`@reckona/mreact-reactive-core/testing` exports `flushMicrotasks()` and
|
package/dist/batch.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../src/batch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../src/batch.ts"],"names":[],"mappings":"AAKA,wBAAgB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAcvC;AAED,wBAAsB,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAcxE"}
|
package/dist/batch.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { runtimeState } from "./state.js";
|
|
2
|
+
import { invalidateDevtoolsWriteCache } from "./cell.js";
|
|
2
3
|
import { schedulePendingFlush } from "./scheduler.js";
|
|
3
4
|
import { flushPendingComputed } from "./tracking.js";
|
|
4
5
|
export function batch(fn) {
|
|
6
|
+
invalidateDevtoolsWriteCache();
|
|
5
7
|
runtimeState.batchDepth += 1;
|
|
6
8
|
try {
|
|
7
9
|
return fn();
|
|
@@ -15,6 +17,7 @@ export function batch(fn) {
|
|
|
15
17
|
}
|
|
16
18
|
}
|
|
17
19
|
export async function batchAsync(fn) {
|
|
20
|
+
invalidateDevtoolsWriteCache();
|
|
18
21
|
runtimeState.batchDepth += 1;
|
|
19
22
|
try {
|
|
20
23
|
return await fn();
|
package/dist/batch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batch.js","sourceRoot":"","sources":["../src/batch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAErD,MAAM,UAAU,KAAK,CAAI,EAAW;IAClC,YAAY,CAAC,UAAU,IAAI,CAAC,CAAC;IAE7B,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,CAAC;IACd,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,UAAU,IAAI,CAAC,CAAC;QAE7B,IAAI,YAAY,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;YAClC,oBAAoB,EAAE,CAAC;YACvB,oBAAoB,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAI,EAAwB;IAC1D,YAAY,CAAC,UAAU,IAAI,CAAC,CAAC;IAE7B,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAC;IACpB,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,UAAU,IAAI,CAAC,CAAC;QAE7B,IAAI,YAAY,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;YAClC,oBAAoB,EAAE,CAAC;YACvB,oBAAoB,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import { runtimeState } from \"./state.js\";\nimport { schedulePendingFlush } from \"./scheduler.js\";\nimport { flushPendingComputed } from \"./tracking.js\";\n\nexport function batch<T>(fn: () => T): T {\n runtimeState.batchDepth += 1;\n\n try {\n return fn();\n } finally {\n runtimeState.batchDepth -= 1;\n\n if (runtimeState.batchDepth === 0) {\n flushPendingComputed();\n schedulePendingFlush();\n }\n }\n}\n\nexport async function batchAsync<T>(fn: () => Promise<T> | T): Promise<T> {\n runtimeState.batchDepth += 1;\n\n try {\n return await fn();\n } finally {\n runtimeState.batchDepth -= 1;\n\n if (runtimeState.batchDepth === 0) {\n flushPendingComputed();\n schedulePendingFlush();\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"batch.js","sourceRoot":"","sources":["../src/batch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,4BAA4B,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAErD,MAAM,UAAU,KAAK,CAAI,EAAW;IAClC,4BAA4B,EAAE,CAAC;IAC/B,YAAY,CAAC,UAAU,IAAI,CAAC,CAAC;IAE7B,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,CAAC;IACd,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,UAAU,IAAI,CAAC,CAAC;QAE7B,IAAI,YAAY,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;YAClC,oBAAoB,EAAE,CAAC;YACvB,oBAAoB,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAI,EAAwB;IAC1D,4BAA4B,EAAE,CAAC;IAC/B,YAAY,CAAC,UAAU,IAAI,CAAC,CAAC;IAE7B,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAC;IACpB,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,UAAU,IAAI,CAAC,CAAC;QAE7B,IAAI,YAAY,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;YAClC,oBAAoB,EAAE,CAAC;YACvB,oBAAoB,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import { runtimeState } from \"./state.js\";\nimport { invalidateDevtoolsWriteCache } from \"./cell.js\";\nimport { schedulePendingFlush } from \"./scheduler.js\";\nimport { flushPendingComputed } from \"./tracking.js\";\n\nexport function batch<T>(fn: () => T): T {\n invalidateDevtoolsWriteCache();\n runtimeState.batchDepth += 1;\n\n try {\n return fn();\n } finally {\n runtimeState.batchDepth -= 1;\n\n if (runtimeState.batchDepth === 0) {\n flushPendingComputed();\n schedulePendingFlush();\n }\n }\n}\n\nexport async function batchAsync<T>(fn: () => Promise<T> | T): Promise<T> {\n invalidateDevtoolsWriteCache();\n runtimeState.batchDepth += 1;\n\n try {\n return await fn();\n } finally {\n runtimeState.batchDepth -= 1;\n\n if (runtimeState.batchDepth === 0) {\n flushPendingComputed();\n schedulePendingFlush();\n }\n }\n}\n"]}
|
package/dist/cell.d.ts
CHANGED
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;AA4BvC,wBAAgB,4BAA4B,IAAI,IAAI,CAInD;AAqED,wBAAgB,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAiB3C"}
|
package/dist/cell.js
CHANGED
|
@@ -1,49 +1,83 @@
|
|
|
1
|
-
import { notifySubscribers, trackSource } from "./tracking.js";
|
|
1
|
+
import { notifySubscribers, sourceSubscriberCount, trackSource } from "./tracking.js";
|
|
2
2
|
const clientDevtoolsDisabled = typeof __MREACT_CLIENT_DEVTOOLS__ !== "undefined" &&
|
|
3
3
|
__MREACT_CLIENT_DEVTOOLS__ === false;
|
|
4
|
+
// Write-path devtools cache: `undefined` = not sampled yet, `null` = sampled
|
|
5
|
+
// and absent, object = sampled and attached. The no-devtools write fast path
|
|
6
|
+
// is a single module-local null comparison instead of a globalThis property
|
|
7
|
+
// walk per write. A late attach is observed at the next batch or flush
|
|
8
|
+
// boundary (see invalidateDevtoolsWriteCache callers); a detach or hook swap
|
|
9
|
+
// is observed on the next write because the emit path revalidates identity.
|
|
10
|
+
let cachedDevtoolsHook = clientDevtoolsDisabled
|
|
11
|
+
? null
|
|
12
|
+
: undefined;
|
|
13
|
+
export function invalidateDevtoolsWriteCache() {
|
|
14
|
+
if (!clientDevtoolsDisabled) {
|
|
15
|
+
cachedDevtoolsHook = undefined;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function resolveDevtoolsHook() {
|
|
19
|
+
const hook = globalThis.__mreactDevtools;
|
|
20
|
+
const resolved = hook !== undefined && typeof hook.emit === "function" ? hook : null;
|
|
21
|
+
cachedDevtoolsHook = resolved;
|
|
22
|
+
return resolved;
|
|
23
|
+
}
|
|
24
|
+
function emitCellSetEvent(source, previous, value) {
|
|
25
|
+
// Cold path: only reached while a devtools hook is (or was) attached, or on
|
|
26
|
+
// the first write after a cache invalidation. Revalidate against the live
|
|
27
|
+
// global so a disposed or swapped hook never receives stale events.
|
|
28
|
+
const live = globalThis.__mreactDevtools;
|
|
29
|
+
const hook = cachedDevtoolsHook !== undefined && cachedDevtoolsHook === live
|
|
30
|
+
? cachedDevtoolsHook
|
|
31
|
+
: resolveDevtoolsHook();
|
|
32
|
+
if (hook === null) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const emit = hook.emit;
|
|
36
|
+
if (typeof emit !== "function") {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
emit.call(hook, {
|
|
40
|
+
package: "@reckona/mreact-reactive-core",
|
|
41
|
+
previous,
|
|
42
|
+
subscribers: sourceSubscriberCount(source),
|
|
43
|
+
timestamp: Date.now(),
|
|
44
|
+
type: "reactive:cell:set",
|
|
45
|
+
value,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
// One shared write function keeps the hot store/notify sequence in a single
|
|
49
|
+
// optimizable function instead of a fresh fat closure per cell.
|
|
50
|
+
function writeCellValue(state, next) {
|
|
51
|
+
const previous = state.value;
|
|
52
|
+
const resolved = typeof next === "function" ? next(previous) : next;
|
|
53
|
+
if (Object.is(previous, resolved)) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
state.value = resolved;
|
|
57
|
+
// clientDevtoolsDisabled folds to true under the client build define, which
|
|
58
|
+
// makes this branch statically dead so bundlers drop the emit path (and its
|
|
59
|
+
// globalThis.__mreactDevtools references) from production client bundles.
|
|
60
|
+
if (!clientDevtoolsDisabled && cachedDevtoolsHook !== null) {
|
|
61
|
+
emitCellSetEvent(state.source, previous, resolved);
|
|
62
|
+
}
|
|
63
|
+
if (state.source.subscribers !== null) {
|
|
64
|
+
notifySubscribers(state.source);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
4
67
|
export function cell(initial) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
68
|
+
const state = {
|
|
69
|
+
source: {
|
|
70
|
+
subscribers: null,
|
|
71
|
+
},
|
|
72
|
+
value: initial,
|
|
8
73
|
};
|
|
9
74
|
return {
|
|
10
75
|
get() {
|
|
11
|
-
trackSource(source);
|
|
12
|
-
return
|
|
76
|
+
trackSource(state.source);
|
|
77
|
+
return state.value;
|
|
13
78
|
},
|
|
14
79
|
set(next) {
|
|
15
|
-
|
|
16
|
-
if (Object.is(current, resolved)) {
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
if (clientDevtoolsDisabled) {
|
|
20
|
-
current = resolved;
|
|
21
|
-
}
|
|
22
|
-
else {
|
|
23
|
-
const devtools = globalThis.__mreactDevtools;
|
|
24
|
-
const emit = devtools?.emit;
|
|
25
|
-
if (typeof emit !== "function") {
|
|
26
|
-
current = resolved;
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
const previous = current;
|
|
30
|
-
current = resolved;
|
|
31
|
-
emit.call(devtools, {
|
|
32
|
-
package: "@reckona/mreact-reactive-core",
|
|
33
|
-
previous,
|
|
34
|
-
subscribers: source.subscribers.size,
|
|
35
|
-
timestamp: Date.now(),
|
|
36
|
-
type: "reactive:cell:set",
|
|
37
|
-
value: resolved,
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
const singleSubscriber = source.singleSubscriber;
|
|
42
|
-
if (singleSubscriber !== undefined &&
|
|
43
|
-
(singleSubscriber.disposed || singleSubscriber.queued)) {
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
notifySubscribers(source);
|
|
80
|
+
writeCellValue(state, next);
|
|
47
81
|
},
|
|
48
82
|
};
|
|
49
83
|
}
|
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,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
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 { 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 if (state.source.subscribers !== null) {\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":"
|
|
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,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;AAEpE,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;CAC1C;AAED,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,CAyIjB"}
|
package/dist/computed.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { schedulePendingFlush } from "./scheduler.js";
|
|
2
2
|
import { runtimeState } from "./state.js";
|
|
3
|
-
import { cleanupAddedDeps, cleanupDeps, cleanupUntrackedDeps, notifySubscribers, preserveIncrementalTracking, trackIncrementalSource, trackSource, } from "./tracking.js";
|
|
3
|
+
import { cleanupAddedDeps, cleanupDeps, cleanupUntrackedDeps, nextTrackingVersionFor, notifySubscribers, preserveIncrementalTracking, trackIncrementalSource, trackSource, } from "./tracking.js";
|
|
4
4
|
export function computed(fn, options) {
|
|
5
5
|
let hasValue = false;
|
|
6
6
|
let value;
|
|
7
7
|
let dirty = true;
|
|
8
8
|
const equals = typeof options === "function" ? options : (options?.equals ?? Object.is);
|
|
9
9
|
const source = {
|
|
10
|
-
subscribers:
|
|
10
|
+
subscribers: null,
|
|
11
11
|
};
|
|
12
12
|
const computation = {
|
|
13
13
|
id: runtimeState.nextComputationId,
|
|
@@ -16,12 +16,12 @@ export function computed(fn, options) {
|
|
|
16
16
|
queued: false,
|
|
17
17
|
markDirty() {
|
|
18
18
|
if (dirty) {
|
|
19
|
-
if (source.subscribers
|
|
19
|
+
if (source.subscribers === null || computation.queued) {
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
dirty = true;
|
|
24
|
-
if (source.subscribers
|
|
24
|
+
if (source.subscribers !== null) {
|
|
25
25
|
if (runtimeState.notificationDepth > 0) {
|
|
26
26
|
computation.queued = true;
|
|
27
27
|
runtimeState.pendingComputed.add(computation);
|
|
@@ -41,8 +41,10 @@ export function computed(fn, options) {
|
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
43
43
|
computation.disposed = true;
|
|
44
|
+
computation.queued = false;
|
|
45
|
+
runtimeState.pendingComputed.delete(computation);
|
|
44
46
|
cleanupDeps(computation);
|
|
45
|
-
source.subscribers
|
|
47
|
+
source.subscribers = null;
|
|
46
48
|
},
|
|
47
49
|
};
|
|
48
50
|
runtimeState.nextComputationId += 1;
|
|
@@ -74,7 +76,7 @@ export function computed(fn, options) {
|
|
|
74
76
|
}
|
|
75
77
|
const previousTracker = runtimeState.activeTracker;
|
|
76
78
|
const previousDepsSize = computation.deps.size;
|
|
77
|
-
const nextTrackingVersion = (computation
|
|
79
|
+
const nextTrackingVersion = nextTrackingVersionFor(computation);
|
|
78
80
|
computation.trackingAddedDeps = [];
|
|
79
81
|
computation.trackingCount = 0;
|
|
80
82
|
computation.trackingVersion = nextTrackingVersion;
|
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,iBAAiB,EACjB,2BAA2B,EAC3B,sBAAsB,EACtB,WAAW,GACZ,MAAM,eAAe,CAAC;AASvB,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
|
|
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\nexport type ComputedEquality<T> = (previous: T, next: T) => boolean;\n\nexport interface ComputedOptions<T> {\n equals?: ComputedEquality<T> | undefined;\n}\n\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"]}
|
package/dist/effect.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"effect.d.ts","sourceRoot":"","sources":["../src/effect.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"effect.d.ts","sourceRoot":"","sources":["../src/effect.ts"],"names":[],"mappings":"AAiBA,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,MAAM,IAAI,CA2GhE"}
|
package/dist/effect.js
CHANGED
|
@@ -2,7 +2,7 @@ import { queueComputation } from "./scheduler.js";
|
|
|
2
2
|
import { currentReactiveDevtools } from "./devtools.js";
|
|
3
3
|
import { registerCleanup } from "./cleanup-scope.js";
|
|
4
4
|
import { runtimeState } from "./state.js";
|
|
5
|
-
import { cleanupDeps, cleanupUntrackedDeps, trackIncrementalSource, } from "./tracking.js";
|
|
5
|
+
import { cleanupDeps, cleanupUntrackedDeps, nextTrackingVersionFor, trackIncrementalSource, } from "./tracking.js";
|
|
6
6
|
const clientDevtoolsDisabled = typeof __MREACT_CLIENT_DEVTOOLS__ !== "undefined" &&
|
|
7
7
|
__MREACT_CLIENT_DEVTOOLS__ === false;
|
|
8
8
|
export function effect(fn) {
|
|
@@ -26,7 +26,7 @@ export function effect(fn) {
|
|
|
26
26
|
cleanup = undefined;
|
|
27
27
|
}
|
|
28
28
|
const previousDepsSize = computation.deps.size;
|
|
29
|
-
const nextTrackingVersion = (computation
|
|
29
|
+
const nextTrackingVersion = nextTrackingVersionFor(computation);
|
|
30
30
|
computation.trackingAddedDeps = [];
|
|
31
31
|
computation.trackingCount = 0;
|
|
32
32
|
computation.trackingTouchedDeps = [];
|
|
@@ -72,6 +72,8 @@ export function effect(fn) {
|
|
|
72
72
|
return;
|
|
73
73
|
}
|
|
74
74
|
computation.disposed = true;
|
|
75
|
+
computation.queued = false;
|
|
76
|
+
runtimeState.pendingComputed.delete(computation);
|
|
75
77
|
cleanupDeps(computation);
|
|
76
78
|
if (cleanup !== undefined) {
|
|
77
79
|
const currentCleanup = cleanup;
|
|
@@ -86,6 +88,8 @@ export function effect(fn) {
|
|
|
86
88
|
}
|
|
87
89
|
catch (error) {
|
|
88
90
|
computation.disposed = true;
|
|
91
|
+
computation.queued = false;
|
|
92
|
+
runtimeState.pendingComputed.delete(computation);
|
|
89
93
|
cleanupDeps(computation);
|
|
90
94
|
if (cleanup !== undefined) {
|
|
91
95
|
const currentCleanup = cleanup;
|
package/dist/effect.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"effect.js","sourceRoot":"","sources":["../src/effect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,YAAY,EAA4B,MAAM,YAAY,CAAC;AACpE,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAIvB,MAAM,sBAAsB,GAC1B,OAAO,0BAA0B,KAAK,WAAW;IACjD,0BAA0B,KAAK,KAAK,CAAC;AAEvC,MAAM,UAAU,MAAM,CAAC,EAA6B;IAClD,IAAI,OAAiC,CAAC;IAEtC,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,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAChC,CAAC;QACD,GAAG;YACD,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;gBACzB,OAAO;YACT,CAAC;YAED,MAAM,eAAe,GAAG,YAAY,CAAC,aAAa,CAAC;YAEnD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,MAAM,cAAc,GAAG,OAAO,CAAC;gBAC/B,cAAc,EAAE,CAAC;gBACjB,OAAO,GAAG,SAAS,CAAC;YACtB,CAAC;YAED,MAAM,gBAAgB,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;YAC/C,MAAM,mBAAmB,GAAG,CAAC,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"effect.js","sourceRoot":"","sources":["../src/effect.ts"],"names":[],"mappings":"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","sourcesContent":["import { queueComputation } from \"./scheduler.js\";\nimport { currentReactiveDevtools } from \"./devtools.js\";\nimport { registerCleanup } from \"./cleanup-scope.js\";\nimport { runtimeState, type ReactiveComputation } from \"./state.js\";\nimport {\n cleanupDeps,\n cleanupUntrackedDeps,\n nextTrackingVersionFor,\n trackIncrementalSource,\n} 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\nexport function effect(fn: () => void | (() => void)): () => void {\n let cleanup: (() => void) | undefined;\n\n const computation: ReactiveComputation = {\n id: runtimeState.nextComputationId,\n deps: new Set(),\n disposed: false,\n queued: false,\n markDirty() {\n queueComputation(computation);\n },\n run() {\n if (computation.disposed) {\n return;\n }\n\n const previousTracker = runtimeState.activeTracker;\n\n if (cleanup !== undefined) {\n const currentCleanup = cleanup;\n currentCleanup();\n cleanup = undefined;\n }\n\n const previousDepsSize = computation.deps.size;\n const nextTrackingVersion = nextTrackingVersionFor(computation);\n\n computation.trackingAddedDeps = [];\n computation.trackingCount = 0;\n computation.trackingTouchedDeps = [];\n computation.trackingVersion = nextTrackingVersion;\n runtimeState.activeTracker = computation;\n\n if (clientDevtoolsDisabled) {\n try {\n const result = fn();\n cleanup = typeof result === \"function\" ? result : undefined;\n } finally {\n finishIncrementalTracking(computation, previousDepsSize, nextTrackingVersion);\n runtimeState.activeTracker = previousTracker;\n }\n return;\n }\n\n const devtools = currentReactiveDevtools();\n const emit = devtools?.emit;\n const startedAt = emit === undefined ? 0 : performanceNow();\n\n try {\n const result = fn();\n cleanup = typeof result === \"function\" ? result : undefined;\n } finally {\n finishIncrementalTracking(computation, previousDepsSize, nextTrackingVersion);\n runtimeState.activeTracker = previousTracker;\n if (typeof emit === \"function\") {\n emit.call(devtools, {\n durationMs: performanceNow() - startedAt,\n id: computation.id,\n package: \"@reckona/mreact-reactive-core\",\n timestamp: Date.now(),\n type: \"reactive:effect:run\",\n });\n }\n }\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\n if (cleanup !== undefined) {\n const currentCleanup = cleanup;\n cleanup = undefined;\n currentCleanup();\n }\n },\n };\n\n runtimeState.nextComputationId += 1;\n\n try {\n computation.run();\n } catch (error) {\n computation.disposed = true;\n computation.queued = false;\n runtimeState.pendingComputed.delete(computation);\n cleanupDeps(computation);\n\n if (cleanup !== undefined) {\n const currentCleanup = cleanup;\n cleanup = undefined;\n currentCleanup();\n }\n\n throw error;\n }\n\n registerCleanup(computation.dispose);\n return computation.dispose;\n}\n\nfunction finishIncrementalTracking(\n computation: ReactiveComputation,\n previousDepsSize: number,\n trackingVersion: number,\n): void {\n const addedDeps = computation.trackingAddedDeps;\n const trackedCount = computation.trackingCount ?? 0;\n\n if (trackedCount !== previousDepsSize || (addedDeps?.length ?? 0) > 0) {\n cleanupUntrackedDeps(computation, trackingVersion);\n }\n\n computation.trackingAddedDeps = undefined;\n computation.trackingCount = undefined;\n computation.trackingTouchedDeps = undefined;\n}\n\nfunction performanceNow(): number {\n return typeof performance === \"undefined\" ? Date.now() : performance.now();\n}\n"]}
|
package/dist/scheduler.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export interface Scheduler {
|
|
|
3
3
|
schedule(flush: () => void): void;
|
|
4
4
|
}
|
|
5
5
|
export declare function setScheduler(nextScheduler: Scheduler): () => void;
|
|
6
|
+
export declare function resetSchedulerStateForTesting(): void;
|
|
6
7
|
export declare function queueComputation(computation: ReactiveComputation): void;
|
|
7
8
|
export declare function schedulePendingFlush(): void;
|
|
8
9
|
export declare function flushQueuedComputations(): void;
|
package/dist/scheduler.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEpE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CACnC;AAqBD,wBAAgB,YAAY,CAAC,aAAa,EAAE,SAAS,GAAG,MAAM,IAAI,CAOjE;AAED,wBAAgB,6BAA6B,IAAI,IAAI,CAQpD;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,mBAAmB,GAAG,IAAI,CAkBvE;AAED,wBAAgB,oBAAoB,IAAI,IAAI,CAiB3C;AAED,wBAAgB,uBAAuB,IAAI,IAAI,CAqC9C"}
|
package/dist/scheduler.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { invalidateDevtoolsWriteCache } from "./cell.js";
|
|
1
2
|
import { runtimeState } from "./state.js";
|
|
2
3
|
const defaultScheduler = {
|
|
3
4
|
schedule(flush) {
|
|
@@ -22,6 +23,14 @@ export function setScheduler(nextScheduler) {
|
|
|
22
23
|
scheduler = previous;
|
|
23
24
|
};
|
|
24
25
|
}
|
|
26
|
+
export function resetSchedulerStateForTesting() {
|
|
27
|
+
for (const computation of queue) {
|
|
28
|
+
computation.queued = false;
|
|
29
|
+
}
|
|
30
|
+
clearQueue();
|
|
31
|
+
scheduled = false;
|
|
32
|
+
flushing = false;
|
|
33
|
+
}
|
|
25
34
|
export function queueComputation(computation) {
|
|
26
35
|
if (computation.disposed || computation.queued) {
|
|
27
36
|
return;
|
|
@@ -58,6 +67,7 @@ export function flushQueuedComputations() {
|
|
|
58
67
|
if (flushing) {
|
|
59
68
|
return;
|
|
60
69
|
}
|
|
70
|
+
invalidateDevtoolsWriteCache();
|
|
61
71
|
scheduled = false;
|
|
62
72
|
flushing = true;
|
|
63
73
|
let firstError;
|
package/dist/scheduler.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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","sourcesContent":["import { runtimeState, type ReactiveComputation } from \"./state.js\";\n\nexport interface Scheduler {\n schedule(flush: () => void): void;\n}\n\nconst defaultScheduler: Scheduler = {\n schedule(flush) {\n if (typeof queueMicrotask === \"function\") {\n queueMicrotask(flush);\n return;\n }\n\n void Promise.resolve().then(flush);\n },\n};\n\nlet scheduler = defaultScheduler;\nlet queue: ReactiveComputation[] = [];\nlet lastQueuedComputationId = -1;\nlet queueRequiresSort = false;\nlet scheduled = false;\nlet flushing = false;\nconst maxFlushIterations = 100;\n\nexport function setScheduler(nextScheduler: Scheduler): () => void {\n const previous = scheduler;\n scheduler = nextScheduler;\n\n return () => {\n scheduler = previous;\n };\n}\n\nexport function queueComputation(computation: ReactiveComputation): void {\n if (computation.disposed || computation.queued) {\n return;\n }\n\n if (computation.id < lastQueuedComputationId) {\n queueRequiresSort = true;\n }\n\n lastQueuedComputationId = computation.id;\n queue.push(computation);\n computation.queued = true;\n\n if (runtimeState.batchDepth > 0) {\n return;\n }\n\n schedulePendingFlush();\n}\n\nexport function schedulePendingFlush(): void {\n if (queue.length === 0 || scheduled || flushing) {\n return;\n }\n\n scheduled = true;\n\n try {\n scheduler.schedule(flushQueuedComputations);\n } catch (error) {\n scheduled = false;\n for (const computation of queue) {\n computation.queued = false;\n }\n clearQueue();\n throw error;\n }\n}\n\nexport function flushQueuedComputations(): void {\n if (flushing) {\n return;\n }\n\n scheduled = false;\n flushing = true;\n let firstError: unknown;\n\n try {\n for (let iteration = 0; queue.length > 0; iteration += 1) {\n if (iteration >= maxFlushIterations) {\n throw new Error(\"Reactive flush limit exceeded\");\n }\n\n const current = takeQueuedComputations();\n\n for (const computation of current) {\n computation.queued = false;\n\n if (!computation.disposed) {\n try {\n computation.run();\n } catch (error) {\n firstError ??= error;\n }\n }\n }\n }\n\n if (firstError !== undefined) {\n throw firstError;\n }\n } finally {\n flushing = false;\n }\n}\n\nfunction clearQueue(): void {\n queue = [];\n lastQueuedComputationId = -1;\n queueRequiresSort = false;\n}\n\nfunction takeQueuedComputations(): ReactiveComputation[] {\n if (queueRequiresSort) {\n const current = queue.sort((a, b) => a.id - b.id);\n clearQueue();\n return current;\n }\n\n const current = queue;\n queue = [];\n lastQueuedComputationId = -1;\n queueRequiresSort = false;\n return current;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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","sourcesContent":["import { invalidateDevtoolsWriteCache } from \"./cell.js\";\nimport { runtimeState, type ReactiveComputation } from \"./state.js\";\n\nexport interface Scheduler {\n schedule(flush: () => void): void;\n}\n\nconst defaultScheduler: Scheduler = {\n schedule(flush) {\n if (typeof queueMicrotask === \"function\") {\n queueMicrotask(flush);\n return;\n }\n\n void Promise.resolve().then(flush);\n },\n};\n\nlet scheduler = defaultScheduler;\nlet queue: ReactiveComputation[] = [];\nlet lastQueuedComputationId = -1;\nlet queueRequiresSort = false;\nlet scheduled = false;\nlet flushing = false;\nconst maxFlushIterations = 100;\n\nexport function setScheduler(nextScheduler: Scheduler): () => void {\n const previous = scheduler;\n scheduler = nextScheduler;\n\n return () => {\n scheduler = previous;\n };\n}\n\nexport function resetSchedulerStateForTesting(): void {\n for (const computation of queue) {\n computation.queued = false;\n }\n\n clearQueue();\n scheduled = false;\n flushing = false;\n}\n\nexport function queueComputation(computation: ReactiveComputation): void {\n if (computation.disposed || computation.queued) {\n return;\n }\n\n if (computation.id < lastQueuedComputationId) {\n queueRequiresSort = true;\n }\n\n lastQueuedComputationId = computation.id;\n queue.push(computation);\n computation.queued = true;\n\n if (runtimeState.batchDepth > 0) {\n return;\n }\n\n schedulePendingFlush();\n}\n\nexport function schedulePendingFlush(): void {\n if (queue.length === 0 || scheduled || flushing) {\n return;\n }\n\n scheduled = true;\n\n try {\n scheduler.schedule(flushQueuedComputations);\n } catch (error) {\n scheduled = false;\n for (const computation of queue) {\n computation.queued = false;\n }\n clearQueue();\n throw error;\n }\n}\n\nexport function flushQueuedComputations(): void {\n if (flushing) {\n return;\n }\n\n invalidateDevtoolsWriteCache();\n scheduled = false;\n flushing = true;\n let firstError: unknown;\n\n try {\n for (let iteration = 0; queue.length > 0; iteration += 1) {\n if (iteration >= maxFlushIterations) {\n throw new Error(\"Reactive flush limit exceeded\");\n }\n\n const current = takeQueuedComputations();\n\n for (const computation of current) {\n computation.queued = false;\n\n if (!computation.disposed) {\n try {\n computation.run();\n } catch (error) {\n firstError ??= error;\n }\n }\n }\n }\n\n if (firstError !== undefined) {\n throw firstError;\n }\n } finally {\n flushing = false;\n }\n}\n\nfunction clearQueue(): void {\n queue = [];\n lastQueuedComputationId = -1;\n queueRequiresSort = false;\n}\n\nfunction takeQueuedComputations(): ReactiveComputation[] {\n if (queueRequiresSort) {\n const current = queue.sort((a, b) => a.id - b.id);\n clearQueue();\n return current;\n }\n\n const current = queue;\n queue = [];\n lastQueuedComputationId = -1;\n queueRequiresSort = false;\n return current;\n}\n"]}
|
package/dist/state.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export interface Source {
|
|
2
|
-
|
|
3
|
-
subscribers: Set<ReactiveComputation>;
|
|
2
|
+
subscribers: ReactiveComputation | Set<ReactiveComputation> | null;
|
|
4
3
|
trackedBy?: ReactiveComputation | undefined;
|
|
5
4
|
trackedVersion?: number | undefined;
|
|
6
5
|
}
|
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;
|
|
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"}
|
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;AA6BjD,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 trackingAddedDeps?: Source[] | undefined;\n trackingCount?: number | 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/testing.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAGA,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAErD;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAIlD;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,IAAI,IAAI,CAAC;IAChB,QAAQ,IAAI,IAAI,CAAC;IACjB,SAAS,IAAI,OAAO,CAAC;IACrB,mBAAmB,IAAI,MAAM,CAAC;CAC/B;AAED,wBAAgB,yBAAyB,IAAI,mBAAmB,
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAGA,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAErD;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAIlD;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,IAAI,IAAI,CAAC;IAChB,QAAQ,IAAI,IAAI,CAAC;IACjB,SAAS,IAAI,OAAO,CAAC;IACrB,mBAAmB,IAAI,MAAM,CAAC;CAC/B;AAED,wBAAgB,yBAAyB,IAAI,mBAAmB,CA2C/D"}
|
package/dist/testing.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { flushQueuedComputations } from "./scheduler.js";
|
|
1
|
+
import { flushQueuedComputations, resetSchedulerStateForTesting } from "./scheduler.js";
|
|
2
2
|
import { setScheduler } from "./scheduler.js";
|
|
3
3
|
export async function flushMicrotasks() {
|
|
4
4
|
await Promise.resolve();
|
|
@@ -29,6 +29,7 @@ export function createReactiveTestRuntime() {
|
|
|
29
29
|
}
|
|
30
30
|
disposed = true;
|
|
31
31
|
scheduled.length = 0;
|
|
32
|
+
resetSchedulerStateForTesting();
|
|
32
33
|
restore();
|
|
33
34
|
},
|
|
34
35
|
flushAll() {
|
package/dist/testing.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AACxF,OAAO,EAAE,YAAY,EAAkB,MAAM,gBAAgB,CAAC;AAE9D,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,uBAAuB,EAAE,CAAC;IAC1B,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;IACxB,uBAAuB,EAAE,CAAC;AAC5B,CAAC;AASD,MAAM,UAAU,yBAAyB;IACvC,MAAM,SAAS,GAAsB,EAAE,CAAC;IACxC,MAAM,SAAS,GAAc;QAC3B,QAAQ,CAAC,KAAK;YACZ,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;KACF,CAAC;IACF,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IACxC,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,MAAM,YAAY,GAAG,GAAG,EAAE;QACxB,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACrE,CAAC;IACH,CAAC,CAAC;IAEF,OAAO;QACL,OAAO;YACL,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO;YACT,CAAC;YACD,QAAQ,GAAG,IAAI,CAAC;YAChB,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;YACrB,6BAA6B,EAAE,CAAC;YAChC,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,QAAQ;YACN,YAAY,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA,CAAC;QAC7B,CAAC;QACD,SAAS;YACP,YAAY,EAAE,CAAC;YACf,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC;YAChC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,OAAO,KAAK,CAAC;YACf,CAAC;YACD,KAAK,EAAE,CAAC;YACR,OAAO,IAAI,CAAC;QACd,CAAC;QACD,mBAAmB;YACjB,OAAO,SAAS,CAAC,MAAM,CAAC;QAC1B,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { flushQueuedComputations, resetSchedulerStateForTesting } from \"./scheduler.js\";\nimport { setScheduler, type Scheduler } from \"./scheduler.js\";\n\nexport async function flushMicrotasks(): Promise<void> {\n await Promise.resolve();\n}\n\nexport async function flushEffects(): Promise<void> {\n flushQueuedComputations();\n await Promise.resolve();\n flushQueuedComputations();\n}\n\nexport interface ReactiveTestRuntime {\n dispose(): void;\n flushAll(): void;\n flushNext(): boolean;\n scheduledFlushCount(): number;\n}\n\nexport function createReactiveTestRuntime(): ReactiveTestRuntime {\n const scheduled: Array<() => void> = [];\n const scheduler: Scheduler = {\n schedule(flush) {\n scheduled.push(flush);\n },\n };\n const restore = setScheduler(scheduler);\n let disposed = false;\n\n const assertActive = () => {\n if (disposed) {\n throw new Error(\"Reactive test runtime has already been disposed\");\n }\n };\n\n return {\n dispose() {\n if (disposed) {\n return;\n }\n disposed = true;\n scheduled.length = 0;\n resetSchedulerStateForTesting();\n restore();\n },\n flushAll() {\n assertActive();\n while (this.flushNext()) {}\n },\n flushNext() {\n assertActive();\n const flush = scheduled.shift();\n if (flush === undefined) {\n return false;\n }\n flush();\n return true;\n },\n scheduledFlushCount() {\n return scheduled.length;\n },\n };\n}\n"]}
|
package/dist/tracking.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { type ReactiveComputation, type Source } from "./state.js";
|
|
2
2
|
export declare function trackSource(source: Source): void;
|
|
3
|
+
export declare function sourceSubscriberCount(source: Source): number;
|
|
3
4
|
export declare function cleanupDeps(computation: ReactiveComputation): void;
|
|
5
|
+
export declare function nextTrackingVersionFor(computation: ReactiveComputation): number;
|
|
4
6
|
export declare function trackIncrementalSource(source: Source, computation: ReactiveComputation): void;
|
|
5
7
|
export declare function preserveIncrementalTracking(computation: ReactiveComputation): void;
|
|
6
8
|
export declare function cleanupUntrackedDeps(computation: ReactiveComputation, trackingVersion: number): void;
|
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,
|
|
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,CAalE;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,CAwBN;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,CAgDtD;AAED,wBAAgB,oBAAoB,IAAI,IAAI,CAmC3C"}
|