@reckona/mreact-reactive-core 0.0.136 → 0.0.138
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 +14 -0
- package/dist/duplicate-guard.d.ts +10 -0
- package/dist/duplicate-guard.d.ts.map +1 -0
- package/dist/duplicate-guard.js +37 -0
- package/dist/duplicate-guard.js.map +1 -0
- package/dist/internal.d.ts +1 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -0
- package/dist/internal.js.map +1 -1
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +5 -0
- package/dist/state.js.map +1 -1
- package/package.json +1 -1
- package/src/duplicate-guard.ts +51 -0
- package/src/internal.ts +1 -0
- package/src/state.ts +7 -0
package/README.md
CHANGED
|
@@ -38,6 +38,20 @@ dispose();
|
|
|
38
38
|
- `batchAsync()` groups updates across `await` points into one flush. Use it only around intentionally scoped async work because reactive flushes are deferred until the callback settles.
|
|
39
39
|
- `untrack()` reads values without subscribing.
|
|
40
40
|
|
|
41
|
+
## Update Scheduling
|
|
42
|
+
|
|
43
|
+
`cell.set()` updates the stored value immediately and propagates `computed` invalidation synchronously, but effects (including the DOM bindings emitted by the compiler) run in a single microtask scheduled at the first update. Reads through `.get()` always observe the latest value even before that flush runs.
|
|
44
|
+
|
|
45
|
+
Because browsers drain the microtask queue before any rendering steps, this scheduling is compatible with `document.startViewTransition()`: a `cell.set()` made inside the update callback is committed to the DOM before the browser captures the new-state snapshot, so no `flushSync` wrapper is required.
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
document.startViewTransition(() => {
|
|
49
|
+
selectedMediaId.set(mediaId);
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
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
|
+
|
|
41
55
|
## Testing
|
|
42
56
|
|
|
43
57
|
`@reckona/mreact-reactive-core/testing` exports `flushMicrotasks()` and
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Warns when a second copy of reactive-core evaluates in the same browser
|
|
3
|
+
* page. Cells and computeds from one copy are invisible to the other, so
|
|
4
|
+
* cross-package reactivity silently breaks (for example when a bundler
|
|
5
|
+
* prebundles one mreact package while serving another as source). Server and
|
|
6
|
+
* test realms stay untouched: module runners and `vi.resetModules` legitimately
|
|
7
|
+
* re-evaluate modules there, and the duplication failure mode is browser-only.
|
|
8
|
+
*/
|
|
9
|
+
export declare function warnOnDuplicateReactiveCoreCopy(moduleUrl: string): void;
|
|
10
|
+
//# sourceMappingURL=duplicate-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duplicate-guard.d.ts","sourceRoot":"","sources":["../src/duplicate-guard.ts"],"names":[],"mappings":"AAmBA;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAuBvE"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const duplicateCopyStateKey = "__mreactReactiveCoreCopies";
|
|
2
|
+
function modulePathname(moduleUrl) {
|
|
3
|
+
try {
|
|
4
|
+
return new URL(moduleUrl).pathname;
|
|
5
|
+
}
|
|
6
|
+
catch {
|
|
7
|
+
return moduleUrl;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Warns when a second copy of reactive-core evaluates in the same browser
|
|
12
|
+
* page. Cells and computeds from one copy are invisible to the other, so
|
|
13
|
+
* cross-package reactivity silently breaks (for example when a bundler
|
|
14
|
+
* prebundles one mreact package while serving another as source). Server and
|
|
15
|
+
* test realms stay untouched: module runners and `vi.resetModules` legitimately
|
|
16
|
+
* re-evaluate modules there, and the duplication failure mode is browser-only.
|
|
17
|
+
*/
|
|
18
|
+
export function warnOnDuplicateReactiveCoreCopy(moduleUrl) {
|
|
19
|
+
if (typeof document === "undefined" || typeof console === "undefined") {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const global = globalThis;
|
|
23
|
+
const pathname = modulePathname(moduleUrl);
|
|
24
|
+
const state = (global[duplicateCopyStateKey] ??= { first: pathname, seen: new Set() });
|
|
25
|
+
if (state.seen.has(pathname) || pathname === state.first) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
state.seen.add(pathname);
|
|
29
|
+
console.warn(`[mreact] Multiple copies of @reckona/mreact-reactive-core are loaded in this page.\n` +
|
|
30
|
+
` first copy: ${state.first}\n` +
|
|
31
|
+
` duplicate copy: ${pathname}\n` +
|
|
32
|
+
`Cells created by one copy are invisible to computeds and effects in the other, ` +
|
|
33
|
+
`so cross-package reactivity silently breaks. In Vite dev this usually means an ` +
|
|
34
|
+
`mreact package was prebundled; keep every @reckona/mreact* package listed in ` +
|
|
35
|
+
`optimizeDeps.exclude (the @reckona/mreact-router Vite plugin applies the full list automatically).`);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=duplicate-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duplicate-guard.js","sourceRoot":"","sources":["../src/duplicate-guard.ts"],"names":[],"mappings":"AAKA,MAAM,qBAAqB,GAAG,4BAA4B,CAAC;AAM3D,SAAS,cAAc,CAAC,SAAiB;IACvC,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,+BAA+B,CAAC,SAAiB;IAC/D,IAAI,OAAO,QAAQ,KAAK,WAAW,IAAI,OAAO,OAAO,KAAK,WAAW,EAAE,CAAC;QACtE,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,UAAiC,CAAC;IACjD,MAAM,QAAQ,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,qBAAqB,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;IAEvF,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC;QACzD,OAAO;IACT,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACzB,OAAO,CAAC,IAAI,CACV,sFAAsF;QACpF,iBAAiB,KAAK,CAAC,KAAK,IAAI;QAChC,qBAAqB,QAAQ,IAAI;QACjC,iFAAiF;QACjF,iFAAiF;QACjF,+EAA+E;QAC/E,oGAAoG,CACvG,CAAC;AACJ,CAAC","sourcesContent":["interface DuplicateCopyState {\n first: string;\n seen: Set<string>;\n}\n\nconst duplicateCopyStateKey = \"__mreactReactiveCoreCopies\";\n\ntype DuplicateCopyGlobal = typeof globalThis & {\n [duplicateCopyStateKey]?: DuplicateCopyState;\n};\n\nfunction modulePathname(moduleUrl: string): string {\n try {\n return new URL(moduleUrl).pathname;\n } catch {\n return moduleUrl;\n }\n}\n\n/**\n * Warns when a second copy of reactive-core evaluates in the same browser\n * page. Cells and computeds from one copy are invisible to the other, so\n * cross-package reactivity silently breaks (for example when a bundler\n * prebundles one mreact package while serving another as source). Server and\n * test realms stay untouched: module runners and `vi.resetModules` legitimately\n * re-evaluate modules there, and the duplication failure mode is browser-only.\n */\nexport function warnOnDuplicateReactiveCoreCopy(moduleUrl: string): void {\n if (typeof document === \"undefined\" || typeof console === \"undefined\") {\n return;\n }\n\n const global = globalThis as DuplicateCopyGlobal;\n const pathname = modulePathname(moduleUrl);\n const state = (global[duplicateCopyStateKey] ??= { first: pathname, seen: new Set() });\n\n if (state.seen.has(pathname) || pathname === state.first) {\n return;\n }\n\n state.seen.add(pathname);\n console.warn(\n `[mreact] Multiple copies of @reckona/mreact-reactive-core are loaded in this page.\\n` +\n ` first copy: ${state.first}\\n` +\n ` duplicate copy: ${pathname}\\n` +\n `Cells created by one copy are invisible to computeds and effects in the other, ` +\n `so cross-package reactivity silently breaks. In Vite dev this usually means an ` +\n `mreact package was prebundled; keep every @reckona/mreact* package listed in ` +\n `optimizeDeps.exclude (the @reckona/mreact-router Vite plugin applies the full list automatically).`,\n );\n}\n"]}
|
package/dist/internal.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type { Scheduler } from "./scheduler.js";
|
|
2
2
|
export { registerCleanup, withCleanupScope } from "./cleanup-scope.js";
|
|
3
3
|
export { flushQueuedComputations, schedulePendingFlush, setScheduler } from "./scheduler.js";
|
|
4
|
+
export { flushPendingComputed } from "./tracking.js";
|
|
4
5
|
export { getGlobalRuntimeState } from "./runtime-state.js";
|
|
5
6
|
//# 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,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/internal.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { registerCleanup, withCleanupScope } from "./cleanup-scope.js";
|
|
2
2
|
export { flushQueuedComputations, schedulePendingFlush, setScheduler } from "./scheduler.js";
|
|
3
|
+
export { flushPendingComputed } from "./tracking.js";
|
|
3
4
|
export { getGlobalRuntimeState } from "./runtime-state.js";
|
|
4
5
|
//# 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":"AACA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["export type { Scheduler } from \"./scheduler.js\";\nexport { registerCleanup, withCleanupScope } from \"./cleanup-scope.js\";\nexport { flushQueuedComputations, schedulePendingFlush, setScheduler } from \"./scheduler.js\";\nexport { getGlobalRuntimeState } from \"./runtime-state.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["export type { Scheduler } from \"./scheduler.js\";\nexport { registerCleanup, withCleanupScope } from \"./cleanup-scope.js\";\nexport { flushQueuedComputations, schedulePendingFlush, setScheduler } from \"./scheduler.js\";\nexport { flushPendingComputed } from \"./tracking.js\";\nexport { getGlobalRuntimeState } from \"./runtime-state.js\";\n"]}
|
package/dist/state.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,MAAM;IACrB,gBAAgB,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;IACnD,WAAW,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACtC,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,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
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import { warnOnDuplicateReactiveCoreCopy } from "./duplicate-guard.js";
|
|
2
|
+
// This module holds the per-copy reactive runtime identity, so a second
|
|
3
|
+
// evaluation in the same browser page is exactly the duplication that breaks
|
|
4
|
+
// cross-package cell tracking.
|
|
5
|
+
warnOnDuplicateReactiveCoreCopy(import.meta.url);
|
|
1
6
|
export const runtimeState = {
|
|
2
7
|
activeTracker: null,
|
|
3
8
|
batchDepth: 0,
|
package/dist/state.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"
|
|
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;AAyBjD,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 singleSubscriber?: ReactiveComputation | undefined;\n subscribers: Set<ReactiveComputation>;\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 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/package.json
CHANGED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
interface DuplicateCopyState {
|
|
2
|
+
first: string;
|
|
3
|
+
seen: Set<string>;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const duplicateCopyStateKey = "__mreactReactiveCoreCopies";
|
|
7
|
+
|
|
8
|
+
type DuplicateCopyGlobal = typeof globalThis & {
|
|
9
|
+
[duplicateCopyStateKey]?: DuplicateCopyState;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
function modulePathname(moduleUrl: string): string {
|
|
13
|
+
try {
|
|
14
|
+
return new URL(moduleUrl).pathname;
|
|
15
|
+
} catch {
|
|
16
|
+
return moduleUrl;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Warns when a second copy of reactive-core evaluates in the same browser
|
|
22
|
+
* page. Cells and computeds from one copy are invisible to the other, so
|
|
23
|
+
* cross-package reactivity silently breaks (for example when a bundler
|
|
24
|
+
* prebundles one mreact package while serving another as source). Server and
|
|
25
|
+
* test realms stay untouched: module runners and `vi.resetModules` legitimately
|
|
26
|
+
* re-evaluate modules there, and the duplication failure mode is browser-only.
|
|
27
|
+
*/
|
|
28
|
+
export function warnOnDuplicateReactiveCoreCopy(moduleUrl: string): void {
|
|
29
|
+
if (typeof document === "undefined" || typeof console === "undefined") {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const global = globalThis as DuplicateCopyGlobal;
|
|
34
|
+
const pathname = modulePathname(moduleUrl);
|
|
35
|
+
const state = (global[duplicateCopyStateKey] ??= { first: pathname, seen: new Set() });
|
|
36
|
+
|
|
37
|
+
if (state.seen.has(pathname) || pathname === state.first) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
state.seen.add(pathname);
|
|
42
|
+
console.warn(
|
|
43
|
+
`[mreact] Multiple copies of @reckona/mreact-reactive-core are loaded in this page.\n` +
|
|
44
|
+
` first copy: ${state.first}\n` +
|
|
45
|
+
` duplicate copy: ${pathname}\n` +
|
|
46
|
+
`Cells created by one copy are invisible to computeds and effects in the other, ` +
|
|
47
|
+
`so cross-package reactivity silently breaks. In Vite dev this usually means an ` +
|
|
48
|
+
`mreact package was prebundled; keep every @reckona/mreact* package listed in ` +
|
|
49
|
+
`optimizeDeps.exclude (the @reckona/mreact-router Vite plugin applies the full list automatically).`,
|
|
50
|
+
);
|
|
51
|
+
}
|
package/src/internal.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type { Scheduler } from "./scheduler.js";
|
|
2
2
|
export { registerCleanup, withCleanupScope } from "./cleanup-scope.js";
|
|
3
3
|
export { flushQueuedComputations, schedulePendingFlush, setScheduler } from "./scheduler.js";
|
|
4
|
+
export { flushPendingComputed } from "./tracking.js";
|
|
4
5
|
export { getGlobalRuntimeState } from "./runtime-state.js";
|
package/src/state.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import { warnOnDuplicateReactiveCoreCopy } from "./duplicate-guard.js";
|
|
2
|
+
|
|
3
|
+
// This module holds the per-copy reactive runtime identity, so a second
|
|
4
|
+
// evaluation in the same browser page is exactly the duplication that breaks
|
|
5
|
+
// cross-package cell tracking.
|
|
6
|
+
warnOnDuplicateReactiveCoreCopy(import.meta.url);
|
|
7
|
+
|
|
1
8
|
export interface Source {
|
|
2
9
|
singleSubscriber?: ReactiveComputation | undefined;
|
|
3
10
|
subscribers: Set<ReactiveComputation>;
|