@reckona/mreact-reactive-core 0.0.66 → 0.0.68

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/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"}
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"]}
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;AAI/D,MAAM,UAAU,IAAI,CAAI,OAAU;IAChC,IAAI,OAAO,GAAG,OAAO,CAAC;IACtB,MAAM,MAAM,GAAW;QACrB,WAAW,EAAE,IAAI,GAAG,EAAE;KACvB,CAAC;IAEF,OAAO;QACL,GAAG;YACD,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,GAAG,CAAC,IAA0B;YAC5B,MAAM,QAAQ,GAAG,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC,CAAE,IAAuB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAEvF,IAAI,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC;gBACjC,OAAO;YACT,CAAC;YAED,IACE,OAAO,0BAA0B,KAAK,WAAW;gBACjD,0BAA0B,KAAK,KAAK,EACpC,CAAC;gBACD,OAAO,GAAG,QAAQ,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACN,MAAM,QAAQ,GACZ,UAKD,CAAC,gBAAgB,CAAC;gBACnB,MAAM,IAAI,GAAG,QAAQ,EAAE,IAAI,CAAC;gBAE5B,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;oBAC/B,OAAO,GAAG,QAAQ,CAAC;gBACrB,CAAC;qBAAM,CAAC;oBACN,MAAM,QAAQ,GAAG,OAAO,CAAC;oBACzB,OAAO,GAAG,QAAQ,CAAC;oBACnB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;wBAClB,OAAO,EAAE,+BAA+B;wBACxC,QAAQ;wBACR,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI;wBACpC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;wBACrB,IAAI,EAAE,mBAAmB;wBACzB,KAAK,EAAE,QAAQ;qBAChB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,MAAM,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,CAAC;YACjD,IACE,gBAAgB,KAAK,SAAS;gBAC9B,CAAC,gBAAgB,CAAC,QAAQ,IAAI,gBAAgB,CAAC,MAAM,CAAC,EACtD,CAAC;gBACD,OAAO;YACT,CAAC;YACD,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"cell.js","sourceRoot":"","sources":["../src/cell.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAI/D,MAAM,UAAU,IAAI,CAAI,OAAU;IAChC,IAAI,OAAO,GAAG,OAAO,CAAC;IACtB,MAAM,MAAM,GAAW;QACrB,WAAW,EAAE,IAAI,GAAG,EAAE;KACvB,CAAC;IAEF,OAAO;QACL,GAAG;YACD,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,GAAG,CAAC,IAA0B;YAC5B,MAAM,QAAQ,GAAG,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC,CAAE,IAAuB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAEvF,IAAI,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC;gBACjC,OAAO;YACT,CAAC;YAED,IACE,OAAO,0BAA0B,KAAK,WAAW;gBACjD,0BAA0B,KAAK,KAAK,EACpC,CAAC;gBACD,OAAO,GAAG,QAAQ,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACN,MAAM,QAAQ,GACZ,UAKD,CAAC,gBAAgB,CAAC;gBACnB,MAAM,IAAI,GAAG,QAAQ,EAAE,IAAI,CAAC;gBAE5B,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;oBAC/B,OAAO,GAAG,QAAQ,CAAC;gBACrB,CAAC;qBAAM,CAAC;oBACN,MAAM,QAAQ,GAAG,OAAO,CAAC;oBACzB,OAAO,GAAG,QAAQ,CAAC;oBACnB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;wBAClB,OAAO,EAAE,+BAA+B;wBACxC,QAAQ;wBACR,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI;wBACpC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;wBACrB,IAAI,EAAE,mBAAmB;wBACzB,KAAK,EAAE,QAAQ;qBAChB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,MAAM,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,CAAC;YACjD,IACE,gBAAgB,KAAK,SAAS;gBAC9B,CAAC,gBAAgB,CAAC,QAAQ,IAAI,gBAAgB,CAAC,MAAM,CAAC,EACtD,CAAC;gBACD,OAAO;YACT,CAAC;YACD,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { Cell } from \"./types.js\";\nimport type { Source } from \"./state.js\";\nimport { notifySubscribers, trackSource } from \"./tracking.js\";\n\ndeclare const __MREACT_CLIENT_DEVTOOLS__: boolean | undefined;\n\nexport function cell<T>(initial: T): Cell<T> {\n let current = initial;\n const source: Source = {\n subscribers: new Set(),\n };\n\n return {\n get(): T {\n trackSource(source);\n return current;\n },\n set(next: T | ((prev: T) => T)): void {\n const resolved = typeof next === \"function\" ? (next as (prev: T) => T)(current) : next;\n\n if (Object.is(current, resolved)) {\n return;\n }\n\n if (\n typeof __MREACT_CLIENT_DEVTOOLS__ !== \"undefined\" &&\n __MREACT_CLIENT_DEVTOOLS__ === false\n ) {\n current = resolved;\n } else {\n const devtools = (\n globalThis as typeof globalThis & {\n __mreactDevtools?:\n | { emit?: (event: Record<string, unknown>) => void }\n | undefined;\n }\n ).__mreactDevtools;\n const emit = devtools?.emit;\n\n if (typeof emit !== \"function\") {\n current = resolved;\n } else {\n const previous = current;\n current = resolved;\n emit.call(devtools, {\n package: \"@reckona/mreact-reactive-core\",\n previous,\n subscribers: source.subscribers.size,\n timestamp: Date.now(),\n type: \"reactive:cell:set\",\n value: resolved,\n });\n }\n }\n const singleSubscriber = source.singleSubscriber;\n if (\n singleSubscriber !== undefined &&\n (singleSubscriber.disposed || singleSubscriber.queued)\n ) {\n return;\n }\n notifySubscribers(source);\n },\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"cleanup-scope.js","sourceRoot":"","sources":["../src/cleanup-scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,UAAU,gBAAgB,CAC9B,KAAoC,EACpC,GAAY;IAEZ,MAAM,aAAa,GAAG,YAAY,CAAC,YAAY,CAAC;IAChD,YAAY,CAAC,YAAY,GAAG,KAAK,CAAC;IAElC,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC;IACf,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,YAAY,GAAG,aAAa,CAAC;IAC5C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAmB;IACjD,YAAY,CAAC,YAAY,EAAE,CAAC,OAAO,CAAC,CAAC;AACvC,CAAC"}
1
+ {"version":3,"file":"cleanup-scope.js","sourceRoot":"","sources":["../src/cleanup-scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,UAAU,gBAAgB,CAC9B,KAAoC,EACpC,GAAY;IAEZ,MAAM,aAAa,GAAG,YAAY,CAAC,YAAY,CAAC;IAChD,YAAY,CAAC,YAAY,GAAG,KAAK,CAAC;IAElC,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC;IACf,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,YAAY,GAAG,aAAa,CAAC;IAC5C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAmB;IACjD,YAAY,CAAC,YAAY,EAAE,CAAC,OAAO,CAAC,CAAC;AACvC,CAAC","sourcesContent":["import { runtimeState } from \"./state.js\";\n\nexport function withCleanupScope<T>(\n owner: (dispose: () => void) => void,\n run: () => T,\n): T {\n const previousOwner = runtimeState.cleanupOwner;\n runtimeState.cleanupOwner = owner;\n\n try {\n return run();\n } finally {\n runtimeState.cleanupOwner = previousOwner;\n }\n}\n\nexport function registerCleanup(dispose: () => void): void {\n runtimeState.cleanupOwner?.(dispose);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"computed.js","sourceRoot":"","sources":["../src/computed.ts"],"names":[],"mappings":"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"}
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 { cleanupDeps, notifySubscribers, trackSource } 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: new Set(),\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.size === 0 || computation.queued) {\n return;\n }\n }\n\n dirty = true;\n\n if (source.subscribers.size > 0) {\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 trackComputedSource(source, computation);\n },\n dispose() {\n if (computation.disposed) {\n return;\n }\n\n computation.disposed = true;\n cleanupDeps(computation);\n source.subscribers.clear();\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 = (computation.trackingVersion ?? 0) + 1;\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.trackingVersion = undefined;\n runtimeState.activeTracker = previousTracker;\n }\n }\n\n return {\n get(): T {\n trackSource(source);\n return recompute();\n },\n };\n}\n\nfunction trackComputedSource(\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\n if (computation.deps.has(source)) {\n return;\n }\n\n const previousSize = source.subscribers.size;\n source.subscribers.add(computation);\n computation.deps.add(source);\n computation.trackingAddedDeps?.push(source);\n\n if (previousSize === 0) {\n source.singleSubscriber = computation;\n } else if (source.subscribers.size > 1) {\n source.singleSubscriber = undefined;\n }\n}\n\nfunction cleanupUntrackedDeps(\n computation: ReactiveComputation,\n trackingVersion: number,\n): void {\n for (const dep of computation.deps) {\n if (dep.trackedBy === computation && dep.trackedVersion === trackingVersion) {\n continue;\n }\n\n if (!dep.subscribers.delete(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 if (dep.subscribers.size === 0) {\n dep.singleSubscriber = undefined;\n } else if (dep.subscribers.size === 1) {\n dep.singleSubscriber = dep.subscribers.values().next().value;\n }\n }\n}\n\nfunction 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 (!dep.subscribers.delete(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 if (dep.subscribers.size === 0) {\n dep.singleSubscriber = undefined;\n } else if (dep.subscribers.size === 1) {\n dep.singleSubscriber = dep.subscribers.values().next().value;\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"devtools.js","sourceRoot":"","sources":["../src/devtools.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,yBAAyB,CAAC,KAA8B;IACtE,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG,QAAQ,EAAE,IAAI,CAAC;IAE5B,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO;IACT,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;QAClB,OAAO,EAAE,+BAA+B;QACxC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,GAAG,KAAK;KACT,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,0BAA0B;IACxC,OAAO,OAAO,eAAe,EAAE,EAAE,IAAI,KAAK,UAAU,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG,QAAQ,EAAE,IAAI,CAAC;IAE5B,OAAO,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACtE,CAAC;AAED,SAAS,eAAe;IAGtB,MAAM,QAAQ,GACZ,UAGD,CAAC,gBAAgB,CAAC;IAEnB,OAAO,QAAQ,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"devtools.js","sourceRoot":"","sources":["../src/devtools.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,yBAAyB,CAAC,KAA8B;IACtE,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG,QAAQ,EAAE,IAAI,CAAC;IAE5B,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO;IACT,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;QAClB,OAAO,EAAE,+BAA+B;QACxC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,GAAG,KAAK;KACT,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,0BAA0B;IACxC,OAAO,OAAO,eAAe,EAAE,EAAE,IAAI,KAAK,UAAU,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG,QAAQ,EAAE,IAAI,CAAC;IAE5B,OAAO,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACtE,CAAC;AAED,SAAS,eAAe;IAGtB,MAAM,QAAQ,GACZ,UAGD,CAAC,gBAAgB,CAAC;IAEnB,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["type DevtoolsEmitter = (event: Record<string, unknown>) => void;\n\nexport function emitReactiveDevtoolsEvent(event: Record<string, unknown>): void {\n const devtools = currentDevtools();\n const emit = devtools?.emit;\n\n if (typeof emit !== \"function\") {\n return;\n }\n\n emit.call(devtools, {\n package: \"@reckona/mreact-reactive-core\",\n timestamp: Date.now(),\n ...event,\n });\n}\n\nexport function hasReactiveDevtoolsEmitter(): boolean {\n return typeof currentDevtools()?.emit === \"function\";\n}\n\nexport function currentDevtoolsEmitter(): DevtoolsEmitter | undefined {\n const devtools = currentDevtools();\n const emit = devtools?.emit;\n\n return typeof emit === \"function\" ? emit.bind(devtools) : undefined;\n}\n\nfunction currentDevtools():\n | { emit?: DevtoolsEmitter | undefined }\n | undefined {\n const devtools = (\n globalThis as typeof globalThis & {\n __mreactDevtools?: { emit?: DevtoolsEmitter } | undefined;\n }\n ).__mreactDevtools;\n\n return devtools;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"effect.js","sourceRoot":"","sources":["../src/effect.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"effect.js","sourceRoot":"","sources":["../src/effect.ts"],"names":[],"mappings":"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","sourcesContent":["import { queueComputation } from \"./scheduler.js\";\nimport { currentDevtoolsEmitter } from \"./devtools.js\";\nimport { registerCleanup } from \"./cleanup-scope.js\";\nimport { runtimeState, type ReactiveComputation } from \"./state.js\";\nimport { cleanupDeps } from \"./tracking.js\";\n\ndeclare const __MREACT_CLIENT_DEVTOOLS__: boolean | undefined;\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 cleanupDeps(computation);\n runtimeState.activeTracker = computation;\n\n if (\n typeof __MREACT_CLIENT_DEVTOOLS__ !== \"undefined\" &&\n __MREACT_CLIENT_DEVTOOLS__ === false\n ) {\n try {\n const result = fn();\n cleanup = typeof result === \"function\" ? result : undefined;\n } finally {\n runtimeState.activeTracker = previousTracker;\n }\n return;\n }\n\n const emit = currentDevtoolsEmitter();\n const startedAt = emit === undefined ? 0 : performanceNow();\n\n try {\n const result = fn();\n cleanup = typeof result === \"function\" ? result : undefined;\n } finally {\n runtimeState.activeTracker = previousTracker;\n if (emit !== undefined) {\n emit({\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 dispose() {\n if (computation.disposed) {\n return;\n }\n\n computation.disposed = true;\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 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 performanceNow(): number {\n return typeof performance === \"undefined\" ? Date.now() : performance.now();\n}\n"]}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC","sourcesContent":["export type { Cell, ReadonlyCell } from \"./types.js\";\nexport type { ComputedEquality, ComputedOptions } from \"./computed.js\";\nexport { batch, batchAsync } from \"./batch.js\";\nexport { cell } from \"./cell.js\";\nexport { computed } from \"./computed.js\";\nexport { effect } from \"./effect.js\";\nexport { untrack } from \"./untrack.js\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["export type { Scheduler } from \"./scheduler.js\";\nexport { withCleanupScope } from \"./cleanup-scope.js\";\nexport {\n flushQueuedComputations,\n schedulePendingFlush,\n setScheduler,\n} from \"./scheduler.js\";\nexport { getGlobalRuntimeState } from \"./runtime-state.js\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-state-public.js","sourceRoot":"","sources":["../src/runtime-state-public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"runtime-state-public.js","sourceRoot":"","sources":["../src/runtime-state-public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["export { getGlobalRuntimeState } from \"./runtime-state.js\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-state.js","sourceRoot":"","sources":["../src/runtime-state.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,qBAAqB,CACnC,GAAW,EACX,MAAoB;IAEpB,MAAM,MAAM,GAAG,UAA2B,CAAC;IAC3C,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAE7B,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,QAAkB,CAAC;IAC5B,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC;IACvB,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACpB,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"runtime-state.js","sourceRoot":"","sources":["../src/runtime-state.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,qBAAqB,CACnC,GAAW,EACX,MAAoB;IAEpB,MAAM,MAAM,GAAG,UAA2B,CAAC;IAC3C,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAE7B,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,QAAkB,CAAC;IAC5B,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC;IACvB,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACpB,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["type RuntimeGlobal = typeof globalThis & Record<string, unknown>;\n\nexport function getGlobalRuntimeState<TState extends object>(\n key: string,\n create: () => TState,\n): TState {\n const global = globalThis as RuntimeGlobal;\n const existing = global[key];\n\n if (existing !== undefined) {\n return existing as TState;\n }\n\n const state = create();\n global[key] = state;\n return state;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA4B,MAAM,YAAY,CAAC;AAMpE,MAAM,gBAAgB,GAAc;IAClC,QAAQ,CAAC,KAAK;QACZ,IAAI,OAAO,cAAc,KAAK,UAAU,EAAE,CAAC;YACzC,cAAc,CAAC,KAAK,CAAC,CAAC;YACtB,OAAO;QACT,CAAC;QAED,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;CACF,CAAC;AAEF,IAAI,SAAS,GAAG,gBAAgB,CAAC;AACjC,IAAI,KAAK,GAA0B,EAAE,CAAC;AACtC,IAAI,uBAAuB,GAAG,CAAC,CAAC,CAAC;AACjC,IAAI,iBAAiB,GAAG,KAAK,CAAC;AAC9B,IAAI,SAAS,GAAG,KAAK,CAAC;AACtB,IAAI,QAAQ,GAAG,KAAK,CAAC;AACrB,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAE/B,MAAM,UAAU,YAAY,CAAC,aAAwB;IACnD,MAAM,QAAQ,GAAG,SAAS,CAAC;IAC3B,SAAS,GAAG,aAAa,CAAC;IAE1B,OAAO,GAAG,EAAE;QACV,SAAS,GAAG,QAAQ,CAAC;IACvB,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,WAAgC;IAC/D,IAAI,WAAW,CAAC,QAAQ,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;QAC/C,OAAO;IACT,CAAC;IAED,IAAI,WAAW,CAAC,EAAE,GAAG,uBAAuB,EAAE,CAAC;QAC7C,iBAAiB,GAAG,IAAI,CAAC;IAC3B,CAAC;IAED,uBAAuB,GAAG,WAAW,CAAC,EAAE,CAAC;IACzC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACxB,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC;IAE1B,IAAI,YAAY,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;QAChC,OAAO;IACT,CAAC;IAED,oBAAoB,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,IAAI,QAAQ,EAAE,CAAC;QAChD,OAAO;IACT,CAAC;IAED,SAAS,GAAG,IAAI,CAAC;IAEjB,IAAI,CAAC;QACH,SAAS,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,SAAS,GAAG,KAAK,CAAC;QAClB,KAAK,MAAM,WAAW,IAAI,KAAK,EAAE,CAAC;YAChC,WAAW,CAAC,MAAM,GAAG,KAAK,CAAC;QAC7B,CAAC;QACD,UAAU,EAAE,CAAC;QACb,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO;IACT,CAAC;IAED,SAAS,GAAG,KAAK,CAAC;IAClB,QAAQ,GAAG,IAAI,CAAC;IAChB,IAAI,UAAmB,CAAC;IAExB,IAAI,CAAC;QACH,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,SAAS,IAAI,CAAC,EAAE,CAAC;YACzD,IAAI,SAAS,IAAI,kBAAkB,EAAE,CAAC;gBACpC,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;YACnD,CAAC;YAED,MAAM,OAAO,GAAG,sBAAsB,EAAE,CAAC;YAEzC,KAAK,MAAM,WAAW,IAAI,OAAO,EAAE,CAAC;gBAClC,WAAW,CAAC,MAAM,GAAG,KAAK,CAAC;gBAE3B,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;oBAC1B,IAAI,CAAC;wBACH,WAAW,CAAC,GAAG,EAAE,CAAC;oBACpB,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,UAAU,KAAK,KAAK,CAAC;oBACvB,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,UAAU,CAAC;QACnB,CAAC;IACH,CAAC;YAAS,CAAC;QACT,QAAQ,GAAG,KAAK,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,UAAU;IACjB,KAAK,GAAG,EAAE,CAAC;IACX,uBAAuB,GAAG,CAAC,CAAC,CAAC;IAC7B,iBAAiB,GAAG,KAAK,CAAC;AAC5B,CAAC;AAED,SAAS,sBAAsB;IAC7B,IAAI,iBAAiB,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;QAClD,UAAU,EAAE,CAAC;QACb,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC;IACtB,KAAK,GAAG,EAAE,CAAC;IACX,uBAAuB,GAAG,CAAC,CAAC,CAAC;IAC7B,iBAAiB,GAAG,KAAK,CAAC;IAC1B,OAAO,OAAO,CAAC;AACjB,CAAC"}
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"]}
package/dist/state.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAuBA,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"}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAuBA,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":["export 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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,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"}
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,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","sourcesContent":["import { flushQueuedComputations } 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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"tracking.js","sourceRoot":"","sources":["../src/tracking.ts"],"names":[],"mappings":"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"}
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 if (source.singleSubscriber === tracker) {\n tracker.deps.add(source);\n return;\n }\n\n const previousSize = source.subscribers.size;\n source.subscribers.add(tracker);\n tracker.deps.add(source);\n\n if (previousSize === 0) {\n source.singleSubscriber = tracker;\n } else if (source.subscribers.size > 1) {\n source.singleSubscriber = undefined;\n }\n}\n\nexport function cleanupDeps(computation: ReactiveComputation): void {\n for (const dep of computation.deps) {\n if (!dep.subscribers.delete(computation)) {\n continue;\n }\n\n if (dep.trackedBy === computation) {\n dep.trackedBy = undefined;\n dep.trackedVersion = undefined;\n }\n\n if (dep.subscribers.size === 0) {\n dep.singleSubscriber = undefined;\n } else if (dep.subscribers.size === 1) {\n dep.singleSubscriber = dep.subscribers.values().next().value;\n }\n }\n\n computation.deps.clear();\n}\n\nexport function notifySubscribers(source: Source): void {\n if (source.subscribers.size === 0) {\n return;\n }\n\n const cachedSingleSubscriber = source.singleSubscriber;\n if (cachedSingleSubscriber !== undefined) {\n if (cachedSingleSubscriber.disposed || cachedSingleSubscriber.queued) {\n return;\n }\n\n runtimeState.notificationDepth += 1;\n\n try {\n cachedSingleSubscriber.markDirty();\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 source.subscribers.size === 1\n ? source.subscribers.values().next().value\n : undefined;\n\n if (singleSubscriber !== undefined) {\n if (!singleSubscriber.disposed && !singleSubscriber.queued) {\n singleSubscriber.markDirty();\n }\n } else {\n const subscribers = orderedComputations(source.subscribers);\n\n for (const subscriber of 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\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/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["export interface ReadonlyCell<T> {\n get(): T;\n}\n\nexport interface Cell<T> extends ReadonlyCell<T> {\n set(value: T | ((prev: T) => T)): void;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"untrack.js","sourceRoot":"","sources":["../src/untrack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,UAAU,OAAO,CAAI,EAAW;IACpC,MAAM,eAAe,GAAG,YAAY,CAAC,aAAa,CAAC;IACnD,YAAY,CAAC,aAAa,GAAG,IAAI,CAAC;IAElC,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,CAAC;IACd,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,aAAa,GAAG,eAAe,CAAC;IAC/C,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"untrack.js","sourceRoot":"","sources":["../src/untrack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,UAAU,OAAO,CAAI,EAAW;IACpC,MAAM,eAAe,GAAG,YAAY,CAAC,aAAa,CAAC;IACnD,YAAY,CAAC,aAAa,GAAG,IAAI,CAAC;IAElC,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,CAAC;IACd,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,aAAa,GAAG,eAAe,CAAC;IAC/C,CAAC;AACH,CAAC","sourcesContent":["import { runtimeState } from \"./state.js\";\n\nexport function untrack<T>(fn: () => T): T {\n const previousTracker = runtimeState.activeTracker;\n runtimeState.activeTracker = null;\n\n try {\n return fn();\n } finally {\n runtimeState.activeTracker = previousTracker;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reckona/mreact-reactive-core",
3
- "version": "0.0.66",
3
+ "version": "0.0.68",
4
4
  "description": "Fine-grained reactive primitives used across mreact.",
5
5
  "keywords": [
6
6
  "jsx",
@@ -24,7 +24,8 @@
24
24
  "dist/**/*.js",
25
25
  "dist/**/*.js.map",
26
26
  "dist/**/*.d.ts",
27
- "dist/**/*.d.ts.map"
27
+ "dist/**/*.d.ts.map",
28
+ "src/**/*"
28
29
  ],
29
30
  "type": "module",
30
31
  "sideEffects": false,
package/src/batch.ts ADDED
@@ -0,0 +1,33 @@
1
+ import { runtimeState } from "./state.js";
2
+ import { schedulePendingFlush } from "./scheduler.js";
3
+ import { flushPendingComputed } from "./tracking.js";
4
+
5
+ export function batch<T>(fn: () => T): T {
6
+ runtimeState.batchDepth += 1;
7
+
8
+ try {
9
+ return fn();
10
+ } finally {
11
+ runtimeState.batchDepth -= 1;
12
+
13
+ if (runtimeState.batchDepth === 0) {
14
+ flushPendingComputed();
15
+ schedulePendingFlush();
16
+ }
17
+ }
18
+ }
19
+
20
+ export async function batchAsync<T>(fn: () => Promise<T> | T): Promise<T> {
21
+ runtimeState.batchDepth += 1;
22
+
23
+ try {
24
+ return await fn();
25
+ } finally {
26
+ runtimeState.batchDepth -= 1;
27
+
28
+ if (runtimeState.batchDepth === 0) {
29
+ flushPendingComputed();
30
+ schedulePendingFlush();
31
+ }
32
+ }
33
+ }
package/src/cell.ts ADDED
@@ -0,0 +1,65 @@
1
+ import type { Cell } from "./types.js";
2
+ import type { Source } from "./state.js";
3
+ import { notifySubscribers, trackSource } from "./tracking.js";
4
+
5
+ declare const __MREACT_CLIENT_DEVTOOLS__: boolean | undefined;
6
+
7
+ export function cell<T>(initial: T): Cell<T> {
8
+ let current = initial;
9
+ const source: Source = {
10
+ subscribers: new Set(),
11
+ };
12
+
13
+ return {
14
+ get(): T {
15
+ trackSource(source);
16
+ return current;
17
+ },
18
+ set(next: T | ((prev: T) => T)): void {
19
+ const resolved = typeof next === "function" ? (next as (prev: T) => T)(current) : next;
20
+
21
+ if (Object.is(current, resolved)) {
22
+ return;
23
+ }
24
+
25
+ if (
26
+ typeof __MREACT_CLIENT_DEVTOOLS__ !== "undefined" &&
27
+ __MREACT_CLIENT_DEVTOOLS__ === false
28
+ ) {
29
+ current = resolved;
30
+ } else {
31
+ const devtools = (
32
+ globalThis as typeof globalThis & {
33
+ __mreactDevtools?:
34
+ | { emit?: (event: Record<string, unknown>) => void }
35
+ | undefined;
36
+ }
37
+ ).__mreactDevtools;
38
+ const emit = devtools?.emit;
39
+
40
+ if (typeof emit !== "function") {
41
+ current = resolved;
42
+ } else {
43
+ const previous = current;
44
+ current = resolved;
45
+ emit.call(devtools, {
46
+ package: "@reckona/mreact-reactive-core",
47
+ previous,
48
+ subscribers: source.subscribers.size,
49
+ timestamp: Date.now(),
50
+ type: "reactive:cell:set",
51
+ value: resolved,
52
+ });
53
+ }
54
+ }
55
+ const singleSubscriber = source.singleSubscriber;
56
+ if (
57
+ singleSubscriber !== undefined &&
58
+ (singleSubscriber.disposed || singleSubscriber.queued)
59
+ ) {
60
+ return;
61
+ }
62
+ notifySubscribers(source);
63
+ },
64
+ };
65
+ }
@@ -0,0 +1,19 @@
1
+ import { runtimeState } from "./state.js";
2
+
3
+ export function withCleanupScope<T>(
4
+ owner: (dispose: () => void) => void,
5
+ run: () => T,
6
+ ): T {
7
+ const previousOwner = runtimeState.cleanupOwner;
8
+ runtimeState.cleanupOwner = owner;
9
+
10
+ try {
11
+ return run();
12
+ } finally {
13
+ runtimeState.cleanupOwner = previousOwner;
14
+ }
15
+ }
16
+
17
+ export function registerCleanup(dispose: () => void): void {
18
+ runtimeState.cleanupOwner?.(dispose);
19
+ }
@@ -0,0 +1,232 @@
1
+ import type { ReactiveComputation, Source } from "./state.js";
2
+ import { schedulePendingFlush } from "./scheduler.js";
3
+ import { runtimeState } from "./state.js";
4
+ import { cleanupDeps, notifySubscribers, trackSource } from "./tracking.js";
5
+ import type { ReadonlyCell } from "./types.js";
6
+
7
+ export type ComputedEquality<T> = (previous: T, next: T) => boolean;
8
+
9
+ export interface ComputedOptions<T> {
10
+ equals?: ComputedEquality<T> | undefined;
11
+ }
12
+
13
+ export function computed<T>(
14
+ fn: () => T,
15
+ options?: ComputedOptions<T> | ComputedEquality<T>,
16
+ ): ReadonlyCell<T> {
17
+ let hasValue = false;
18
+ let value: T;
19
+ let dirty = true;
20
+ const equals = typeof options === "function" ? options : (options?.equals ?? Object.is);
21
+
22
+ const source: Source = {
23
+ subscribers: new Set(),
24
+ };
25
+
26
+ const computation: ReactiveComputation = {
27
+ id: runtimeState.nextComputationId,
28
+ deps: new Set(),
29
+ disposed: false,
30
+ queued: false,
31
+ markDirty() {
32
+ if (dirty) {
33
+ if (source.subscribers.size === 0 || computation.queued) {
34
+ return;
35
+ }
36
+ }
37
+
38
+ dirty = true;
39
+
40
+ if (source.subscribers.size > 0) {
41
+ if (runtimeState.notificationDepth > 0) {
42
+ computation.queued = true;
43
+ runtimeState.pendingComputed.add(computation);
44
+ return;
45
+ }
46
+
47
+ publishIfChanged();
48
+ }
49
+ },
50
+ run() {
51
+ publishIfChanged();
52
+ },
53
+ trackSource(source) {
54
+ trackComputedSource(source, computation);
55
+ },
56
+ dispose() {
57
+ if (computation.disposed) {
58
+ return;
59
+ }
60
+
61
+ computation.disposed = true;
62
+ cleanupDeps(computation);
63
+ source.subscribers.clear();
64
+ },
65
+ };
66
+
67
+ runtimeState.nextComputationId += 1;
68
+
69
+ function publishIfChanged(): void {
70
+ const previousHasValue = hasValue;
71
+ const previousValue = value;
72
+
73
+ try {
74
+ const nextValue = recompute();
75
+
76
+ if (!previousHasValue || !equals(previousValue, nextValue)) {
77
+ notifySubscribers(source);
78
+ }
79
+ } catch {
80
+ runtimeState.batchDepth += 1;
81
+
82
+ try {
83
+ notifySubscribers(source);
84
+ } finally {
85
+ runtimeState.batchDepth -= 1;
86
+
87
+ if (runtimeState.batchDepth === 0) {
88
+ schedulePendingFlush();
89
+ }
90
+ }
91
+ }
92
+ }
93
+
94
+ function recompute(): T {
95
+ if (!dirty && hasValue) {
96
+ return value;
97
+ }
98
+
99
+ const previousTracker = runtimeState.activeTracker;
100
+ const previousDepsSize = computation.deps.size;
101
+ const nextTrackingVersion = (computation.trackingVersion ?? 0) + 1;
102
+
103
+ computation.trackingAddedDeps = [];
104
+ computation.trackingCount = 0;
105
+ computation.trackingVersion = nextTrackingVersion;
106
+ runtimeState.activeTracker = computation;
107
+
108
+ try {
109
+ const nextValue = fn();
110
+
111
+ const addedDeps = computation.trackingAddedDeps;
112
+ const trackedCount = computation.trackingCount ?? 0;
113
+
114
+ if (trackedCount !== previousDepsSize || (addedDeps?.length ?? 0) > 0) {
115
+ cleanupUntrackedDeps(computation, nextTrackingVersion);
116
+ }
117
+
118
+ value = nextValue;
119
+ hasValue = true;
120
+ dirty = false;
121
+
122
+ return value;
123
+ } catch (error) {
124
+ cleanupAddedDeps(computation);
125
+ dirty = true;
126
+
127
+ throw error;
128
+ } finally {
129
+ computation.trackingAddedDeps = undefined;
130
+ computation.trackingCount = undefined;
131
+ computation.trackingVersion = undefined;
132
+ runtimeState.activeTracker = previousTracker;
133
+ }
134
+ }
135
+
136
+ return {
137
+ get(): T {
138
+ trackSource(source);
139
+ return recompute();
140
+ },
141
+ };
142
+ }
143
+
144
+ function trackComputedSource(
145
+ source: Source,
146
+ computation: ReactiveComputation,
147
+ ): void {
148
+ const trackingVersion = computation.trackingVersion;
149
+
150
+ if (trackingVersion === undefined) {
151
+ trackSource(source);
152
+ return;
153
+ }
154
+
155
+ if (source.trackedBy === computation && source.trackedVersion === trackingVersion) {
156
+ return;
157
+ }
158
+
159
+ source.trackedBy = computation;
160
+ source.trackedVersion = trackingVersion;
161
+ computation.trackingCount = (computation.trackingCount ?? 0) + 1;
162
+
163
+ if (computation.deps.has(source)) {
164
+ return;
165
+ }
166
+
167
+ const previousSize = source.subscribers.size;
168
+ source.subscribers.add(computation);
169
+ computation.deps.add(source);
170
+ computation.trackingAddedDeps?.push(source);
171
+
172
+ if (previousSize === 0) {
173
+ source.singleSubscriber = computation;
174
+ } else if (source.subscribers.size > 1) {
175
+ source.singleSubscriber = undefined;
176
+ }
177
+ }
178
+
179
+ function cleanupUntrackedDeps(
180
+ computation: ReactiveComputation,
181
+ trackingVersion: number,
182
+ ): void {
183
+ for (const dep of computation.deps) {
184
+ if (dep.trackedBy === computation && dep.trackedVersion === trackingVersion) {
185
+ continue;
186
+ }
187
+
188
+ if (!dep.subscribers.delete(computation)) {
189
+ continue;
190
+ }
191
+
192
+ if (dep.trackedBy === computation) {
193
+ dep.trackedBy = undefined;
194
+ dep.trackedVersion = undefined;
195
+ }
196
+
197
+ computation.deps.delete(dep);
198
+
199
+ if (dep.subscribers.size === 0) {
200
+ dep.singleSubscriber = undefined;
201
+ } else if (dep.subscribers.size === 1) {
202
+ dep.singleSubscriber = dep.subscribers.values().next().value;
203
+ }
204
+ }
205
+ }
206
+
207
+ function cleanupAddedDeps(computation: ReactiveComputation): void {
208
+ const addedDeps = computation.trackingAddedDeps;
209
+
210
+ if (addedDeps === undefined) {
211
+ return;
212
+ }
213
+
214
+ for (const dep of addedDeps) {
215
+ if (!dep.subscribers.delete(computation)) {
216
+ continue;
217
+ }
218
+
219
+ if (dep.trackedBy === computation) {
220
+ dep.trackedBy = undefined;
221
+ dep.trackedVersion = undefined;
222
+ }
223
+
224
+ computation.deps.delete(dep);
225
+
226
+ if (dep.subscribers.size === 0) {
227
+ dep.singleSubscriber = undefined;
228
+ } else if (dep.subscribers.size === 1) {
229
+ dep.singleSubscriber = dep.subscribers.values().next().value;
230
+ }
231
+ }
232
+ }
@@ -0,0 +1,39 @@
1
+ type DevtoolsEmitter = (event: Record<string, unknown>) => void;
2
+
3
+ export function emitReactiveDevtoolsEvent(event: Record<string, unknown>): void {
4
+ const devtools = currentDevtools();
5
+ const emit = devtools?.emit;
6
+
7
+ if (typeof emit !== "function") {
8
+ return;
9
+ }
10
+
11
+ emit.call(devtools, {
12
+ package: "@reckona/mreact-reactive-core",
13
+ timestamp: Date.now(),
14
+ ...event,
15
+ });
16
+ }
17
+
18
+ export function hasReactiveDevtoolsEmitter(): boolean {
19
+ return typeof currentDevtools()?.emit === "function";
20
+ }
21
+
22
+ export function currentDevtoolsEmitter(): DevtoolsEmitter | undefined {
23
+ const devtools = currentDevtools();
24
+ const emit = devtools?.emit;
25
+
26
+ return typeof emit === "function" ? emit.bind(devtools) : undefined;
27
+ }
28
+
29
+ function currentDevtools():
30
+ | { emit?: DevtoolsEmitter | undefined }
31
+ | undefined {
32
+ const devtools = (
33
+ globalThis as typeof globalThis & {
34
+ __mreactDevtools?: { emit?: DevtoolsEmitter } | undefined;
35
+ }
36
+ ).__mreactDevtools;
37
+
38
+ return devtools;
39
+ }
package/src/effect.ts ADDED
@@ -0,0 +1,107 @@
1
+ import { queueComputation } from "./scheduler.js";
2
+ import { currentDevtoolsEmitter } from "./devtools.js";
3
+ import { registerCleanup } from "./cleanup-scope.js";
4
+ import { runtimeState, type ReactiveComputation } from "./state.js";
5
+ import { cleanupDeps } from "./tracking.js";
6
+
7
+ declare const __MREACT_CLIENT_DEVTOOLS__: boolean | undefined;
8
+
9
+ export function effect(fn: () => void | (() => void)): () => void {
10
+ let cleanup: (() => void) | undefined;
11
+
12
+ const computation: ReactiveComputation = {
13
+ id: runtimeState.nextComputationId,
14
+ deps: new Set(),
15
+ disposed: false,
16
+ queued: false,
17
+ markDirty() {
18
+ queueComputation(computation);
19
+ },
20
+ run() {
21
+ if (computation.disposed) {
22
+ return;
23
+ }
24
+
25
+ const previousTracker = runtimeState.activeTracker;
26
+
27
+ if (cleanup !== undefined) {
28
+ const currentCleanup = cleanup;
29
+ currentCleanup();
30
+ cleanup = undefined;
31
+ }
32
+
33
+ cleanupDeps(computation);
34
+ runtimeState.activeTracker = computation;
35
+
36
+ if (
37
+ typeof __MREACT_CLIENT_DEVTOOLS__ !== "undefined" &&
38
+ __MREACT_CLIENT_DEVTOOLS__ === false
39
+ ) {
40
+ try {
41
+ const result = fn();
42
+ cleanup = typeof result === "function" ? result : undefined;
43
+ } finally {
44
+ runtimeState.activeTracker = previousTracker;
45
+ }
46
+ return;
47
+ }
48
+
49
+ const emit = currentDevtoolsEmitter();
50
+ const startedAt = emit === undefined ? 0 : performanceNow();
51
+
52
+ try {
53
+ const result = fn();
54
+ cleanup = typeof result === "function" ? result : undefined;
55
+ } finally {
56
+ runtimeState.activeTracker = previousTracker;
57
+ if (emit !== undefined) {
58
+ emit({
59
+ durationMs: performanceNow() - startedAt,
60
+ id: computation.id,
61
+ package: "@reckona/mreact-reactive-core",
62
+ timestamp: Date.now(),
63
+ type: "reactive:effect:run",
64
+ });
65
+ }
66
+ }
67
+ },
68
+ dispose() {
69
+ if (computation.disposed) {
70
+ return;
71
+ }
72
+
73
+ computation.disposed = true;
74
+ cleanupDeps(computation);
75
+
76
+ if (cleanup !== undefined) {
77
+ const currentCleanup = cleanup;
78
+ cleanup = undefined;
79
+ currentCleanup();
80
+ }
81
+ },
82
+ };
83
+
84
+ runtimeState.nextComputationId += 1;
85
+
86
+ try {
87
+ computation.run();
88
+ } catch (error) {
89
+ computation.disposed = true;
90
+ cleanupDeps(computation);
91
+
92
+ if (cleanup !== undefined) {
93
+ const currentCleanup = cleanup;
94
+ cleanup = undefined;
95
+ currentCleanup();
96
+ }
97
+
98
+ throw error;
99
+ }
100
+
101
+ registerCleanup(computation.dispose);
102
+ return computation.dispose;
103
+ }
104
+
105
+ function performanceNow(): number {
106
+ return typeof performance === "undefined" ? Date.now() : performance.now();
107
+ }
package/src/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ export type { Cell, ReadonlyCell } from "./types.js";
2
+ export type { ComputedEquality, ComputedOptions } from "./computed.js";
3
+ export { batch, batchAsync } from "./batch.js";
4
+ export { cell } from "./cell.js";
5
+ export { computed } from "./computed.js";
6
+ export { effect } from "./effect.js";
7
+ export { untrack } from "./untrack.js";
@@ -0,0 +1,8 @@
1
+ export type { Scheduler } from "./scheduler.js";
2
+ export { withCleanupScope } from "./cleanup-scope.js";
3
+ export {
4
+ flushQueuedComputations,
5
+ schedulePendingFlush,
6
+ setScheduler,
7
+ } from "./scheduler.js";
8
+ export { getGlobalRuntimeState } from "./runtime-state.js";
@@ -0,0 +1 @@
1
+ export { getGlobalRuntimeState } from "./runtime-state.js";
@@ -0,0 +1,17 @@
1
+ type RuntimeGlobal = typeof globalThis & Record<string, unknown>;
2
+
3
+ export function getGlobalRuntimeState<TState extends object>(
4
+ key: string,
5
+ create: () => TState,
6
+ ): TState {
7
+ const global = globalThis as RuntimeGlobal;
8
+ const existing = global[key];
9
+
10
+ if (existing !== undefined) {
11
+ return existing as TState;
12
+ }
13
+
14
+ const state = create();
15
+ global[key] = state;
16
+ return state;
17
+ }
@@ -0,0 +1,130 @@
1
+ import { runtimeState, type ReactiveComputation } from "./state.js";
2
+
3
+ export interface Scheduler {
4
+ schedule(flush: () => void): void;
5
+ }
6
+
7
+ const defaultScheduler: Scheduler = {
8
+ schedule(flush) {
9
+ if (typeof queueMicrotask === "function") {
10
+ queueMicrotask(flush);
11
+ return;
12
+ }
13
+
14
+ void Promise.resolve().then(flush);
15
+ },
16
+ };
17
+
18
+ let scheduler = defaultScheduler;
19
+ let queue: ReactiveComputation[] = [];
20
+ let lastQueuedComputationId = -1;
21
+ let queueRequiresSort = false;
22
+ let scheduled = false;
23
+ let flushing = false;
24
+ const maxFlushIterations = 100;
25
+
26
+ export function setScheduler(nextScheduler: Scheduler): () => void {
27
+ const previous = scheduler;
28
+ scheduler = nextScheduler;
29
+
30
+ return () => {
31
+ scheduler = previous;
32
+ };
33
+ }
34
+
35
+ export function queueComputation(computation: ReactiveComputation): void {
36
+ if (computation.disposed || computation.queued) {
37
+ return;
38
+ }
39
+
40
+ if (computation.id < lastQueuedComputationId) {
41
+ queueRequiresSort = true;
42
+ }
43
+
44
+ lastQueuedComputationId = computation.id;
45
+ queue.push(computation);
46
+ computation.queued = true;
47
+
48
+ if (runtimeState.batchDepth > 0) {
49
+ return;
50
+ }
51
+
52
+ schedulePendingFlush();
53
+ }
54
+
55
+ export function schedulePendingFlush(): void {
56
+ if (queue.length === 0 || scheduled || flushing) {
57
+ return;
58
+ }
59
+
60
+ scheduled = true;
61
+
62
+ try {
63
+ scheduler.schedule(flushQueuedComputations);
64
+ } catch (error) {
65
+ scheduled = false;
66
+ for (const computation of queue) {
67
+ computation.queued = false;
68
+ }
69
+ clearQueue();
70
+ throw error;
71
+ }
72
+ }
73
+
74
+ export function flushQueuedComputations(): void {
75
+ if (flushing) {
76
+ return;
77
+ }
78
+
79
+ scheduled = false;
80
+ flushing = true;
81
+ let firstError: unknown;
82
+
83
+ try {
84
+ for (let iteration = 0; queue.length > 0; iteration += 1) {
85
+ if (iteration >= maxFlushIterations) {
86
+ throw new Error("Reactive flush limit exceeded");
87
+ }
88
+
89
+ const current = takeQueuedComputations();
90
+
91
+ for (const computation of current) {
92
+ computation.queued = false;
93
+
94
+ if (!computation.disposed) {
95
+ try {
96
+ computation.run();
97
+ } catch (error) {
98
+ firstError ??= error;
99
+ }
100
+ }
101
+ }
102
+ }
103
+
104
+ if (firstError !== undefined) {
105
+ throw firstError;
106
+ }
107
+ } finally {
108
+ flushing = false;
109
+ }
110
+ }
111
+
112
+ function clearQueue(): void {
113
+ queue = [];
114
+ lastQueuedComputationId = -1;
115
+ queueRequiresSort = false;
116
+ }
117
+
118
+ function takeQueuedComputations(): ReactiveComputation[] {
119
+ if (queueRequiresSort) {
120
+ const current = queue.sort((a, b) => a.id - b.id);
121
+ clearQueue();
122
+ return current;
123
+ }
124
+
125
+ const current = queue;
126
+ queue = [];
127
+ lastQueuedComputationId = -1;
128
+ queueRequiresSort = false;
129
+ return current;
130
+ }
package/src/state.ts ADDED
@@ -0,0 +1,40 @@
1
+ export interface Source {
2
+ singleSubscriber?: ReactiveComputation | undefined;
3
+ subscribers: Set<ReactiveComputation>;
4
+ trackedBy?: ReactiveComputation | undefined;
5
+ trackedVersion?: number | undefined;
6
+ }
7
+
8
+ export interface ReactiveComputation {
9
+ readonly id: number;
10
+ deps: Set<Source>;
11
+ trackingAddedDeps?: Source[] | undefined;
12
+ trackingCount?: number | undefined;
13
+ trackingVersion?: number | undefined;
14
+ disposed: boolean;
15
+ queued: boolean;
16
+ markDirty(): void;
17
+ run(): void;
18
+ dispose(): void;
19
+ trackSource?(source: Source): void;
20
+ }
21
+
22
+ export type Tracker = ReactiveComputation | null;
23
+
24
+ export const runtimeState: {
25
+ activeTracker: Tracker;
26
+ batchDepth: number;
27
+ cleanupOwner: ((dispose: () => void) => void) | undefined;
28
+ flushingComputed: boolean;
29
+ nextComputationId: number;
30
+ notificationDepth: number;
31
+ pendingComputed: Set<ReactiveComputation>;
32
+ } = {
33
+ activeTracker: null,
34
+ batchDepth: 0,
35
+ cleanupOwner: undefined,
36
+ flushingComputed: false,
37
+ nextComputationId: 0,
38
+ notificationDepth: 0,
39
+ pendingComputed: new Set(),
40
+ };
package/src/testing.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { flushQueuedComputations } from "./scheduler.js";
2
+
3
+ export async function flushMicrotasks(): Promise<void> {
4
+ await Promise.resolve();
5
+ }
6
+
7
+ export async function flushEffects(): Promise<void> {
8
+ flushQueuedComputations();
9
+ await Promise.resolve();
10
+ flushQueuedComputations();
11
+ }
@@ -0,0 +1,166 @@
1
+ import { runtimeState, type ReactiveComputation, type Source } from "./state.js";
2
+
3
+ const maxPendingComputedFlushIterations = 100;
4
+
5
+ export function trackSource(source: Source): void {
6
+ const tracker = runtimeState.activeTracker;
7
+
8
+ if (tracker === null || tracker.disposed) {
9
+ return;
10
+ }
11
+
12
+ if (tracker.trackSource !== undefined) {
13
+ tracker.trackSource(source);
14
+ return;
15
+ }
16
+
17
+ if (source.singleSubscriber === tracker) {
18
+ tracker.deps.add(source);
19
+ return;
20
+ }
21
+
22
+ const previousSize = source.subscribers.size;
23
+ source.subscribers.add(tracker);
24
+ tracker.deps.add(source);
25
+
26
+ if (previousSize === 0) {
27
+ source.singleSubscriber = tracker;
28
+ } else if (source.subscribers.size > 1) {
29
+ source.singleSubscriber = undefined;
30
+ }
31
+ }
32
+
33
+ export function cleanupDeps(computation: ReactiveComputation): void {
34
+ for (const dep of computation.deps) {
35
+ if (!dep.subscribers.delete(computation)) {
36
+ continue;
37
+ }
38
+
39
+ if (dep.trackedBy === computation) {
40
+ dep.trackedBy = undefined;
41
+ dep.trackedVersion = undefined;
42
+ }
43
+
44
+ if (dep.subscribers.size === 0) {
45
+ dep.singleSubscriber = undefined;
46
+ } else if (dep.subscribers.size === 1) {
47
+ dep.singleSubscriber = dep.subscribers.values().next().value;
48
+ }
49
+ }
50
+
51
+ computation.deps.clear();
52
+ }
53
+
54
+ export function notifySubscribers(source: Source): void {
55
+ if (source.subscribers.size === 0) {
56
+ return;
57
+ }
58
+
59
+ const cachedSingleSubscriber = source.singleSubscriber;
60
+ if (cachedSingleSubscriber !== undefined) {
61
+ if (cachedSingleSubscriber.disposed || cachedSingleSubscriber.queued) {
62
+ return;
63
+ }
64
+
65
+ runtimeState.notificationDepth += 1;
66
+
67
+ try {
68
+ cachedSingleSubscriber.markDirty();
69
+ } finally {
70
+ runtimeState.notificationDepth -= 1;
71
+
72
+ if (runtimeState.notificationDepth === 0 && runtimeState.batchDepth === 0) {
73
+ flushPendingComputed();
74
+ }
75
+ }
76
+ return;
77
+ }
78
+
79
+ runtimeState.notificationDepth += 1;
80
+
81
+ try {
82
+ const singleSubscriber =
83
+ source.subscribers.size === 1
84
+ ? source.subscribers.values().next().value
85
+ : undefined;
86
+
87
+ if (singleSubscriber !== undefined) {
88
+ if (!singleSubscriber.disposed && !singleSubscriber.queued) {
89
+ singleSubscriber.markDirty();
90
+ }
91
+ } else {
92
+ const subscribers = orderedComputations(source.subscribers);
93
+
94
+ for (const subscriber of subscribers) {
95
+ if (!subscriber.disposed && !subscriber.queued) {
96
+ subscriber.markDirty();
97
+ }
98
+ }
99
+ }
100
+ } finally {
101
+ runtimeState.notificationDepth -= 1;
102
+
103
+ if (runtimeState.notificationDepth === 0 && runtimeState.batchDepth === 0) {
104
+ flushPendingComputed();
105
+ }
106
+ }
107
+ }
108
+
109
+ export function flushPendingComputed(): void {
110
+ if (runtimeState.flushingComputed) {
111
+ return;
112
+ }
113
+
114
+ runtimeState.flushingComputed = true;
115
+
116
+ try {
117
+ for (
118
+ let iteration = 0;
119
+ runtimeState.pendingComputed.size > 0;
120
+ iteration += 1
121
+ ) {
122
+ if (iteration >= maxPendingComputedFlushIterations) {
123
+ runtimeState.pendingComputed.clear();
124
+ throw new Error("Reactive computed flush limit exceeded");
125
+ }
126
+
127
+ const computations =
128
+ runtimeState.pendingComputed.size === 1
129
+ ? [runtimeState.pendingComputed.values().next().value as ReactiveComputation]
130
+ : orderedComputations(runtimeState.pendingComputed);
131
+ runtimeState.pendingComputed.clear();
132
+
133
+ for (const computation of computations) {
134
+ computation.queued = false;
135
+
136
+ if (!computation.disposed) {
137
+ computation.run();
138
+ }
139
+ }
140
+ }
141
+ } finally {
142
+ runtimeState.flushingComputed = false;
143
+ }
144
+ }
145
+
146
+ function orderedComputations(
147
+ computations: ReadonlySet<ReactiveComputation>,
148
+ ): ReactiveComputation[] {
149
+ const ordered: ReactiveComputation[] = [];
150
+ let previousId = -1;
151
+ let monotonic = true;
152
+
153
+ for (const computation of computations) {
154
+ ordered.push(computation);
155
+
156
+ if (computation.id < previousId) {
157
+ monotonic = false;
158
+ }
159
+
160
+ previousId = computation.id;
161
+ }
162
+
163
+ return monotonic || ordered.length < 2
164
+ ? ordered
165
+ : ordered.sort((a, b) => a.id - b.id);
166
+ }
package/src/types.ts ADDED
@@ -0,0 +1,7 @@
1
+ export interface ReadonlyCell<T> {
2
+ get(): T;
3
+ }
4
+
5
+ export interface Cell<T> extends ReadonlyCell<T> {
6
+ set(value: T | ((prev: T) => T)): void;
7
+ }
package/src/untrack.ts ADDED
@@ -0,0 +1,12 @@
1
+ import { runtimeState } from "./state.js";
2
+
3
+ export function untrack<T>(fn: () => T): T {
4
+ const previousTracker = runtimeState.activeTracker;
5
+ runtimeState.activeTracker = null;
6
+
7
+ try {
8
+ return fn();
9
+ } finally {
10
+ runtimeState.activeTracker = previousTracker;
11
+ }
12
+ }