stroid 0.1.1 → 0.1.2
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/CHANGELOG.md +210 -119
- package/README.md +104 -431
- package/dist/async.d.ts +42 -9
- package/dist/async.js +26 -26
- package/dist/async.js.map +1 -1
- package/dist/cache.d.ts +12 -0
- package/dist/computed.d.ts +40 -7
- package/dist/computed.js +11 -11
- package/dist/computed.js.map +1 -1
- package/dist/core.d.ts +5 -15
- package/dist/core.js +14 -15
- package/dist/core.js.map +1 -1
- package/dist/devtools.d.ts +30 -5
- package/dist/devtools.js +1 -1
- package/dist/devtools.js.map +1 -1
- package/dist/feature.d.ts +92 -14
- package/dist/feature.js +1 -1
- package/dist/feature.js.map +1 -1
- package/dist/helpers.d.ts +37 -3
- package/dist/helpers.js +14 -15
- package/dist/helpers.js.map +1 -1
- package/dist/index-internal.d.ts +44 -0
- package/dist/index.d.cts +169 -33
- package/dist/index.d.ts +169 -33
- package/dist/index.js +24 -23
- package/dist/index.js.map +1 -1
- package/dist/install.d.ts +6 -4
- package/dist/install.js +1 -1
- package/dist/install.js.map +1 -1
- package/dist/options.d.ts +295 -0
- package/dist/persist.d.ts +1 -1
- package/dist/persist.js +1 -1
- package/dist/persist.js.map +1 -1
- package/dist/react/index.d.ts +70 -0
- package/dist/react/index.js +38 -0
- package/dist/react/index.js.map +1 -0
- package/dist/registry.d.ts +117 -0
- package/dist/runtime-admin.d.ts +4 -2
- package/dist/runtime-admin.js +1 -1
- package/dist/runtime-admin.js.map +1 -1
- package/dist/runtime-tools.d.ts +66 -9
- package/dist/runtime-tools.js +2 -2
- package/dist/runtime-tools.js.map +1 -1
- package/dist/selectors.d.ts +4 -2
- package/dist/selectors.js +1 -1
- package/dist/selectors.js.map +1 -1
- package/dist/server.d.ts +30 -2
- package/dist/server.js +11 -10
- package/dist/server.js.map +1 -1
- package/dist/store-registry.d.ts +80 -0
- package/dist/sync.d.ts +1 -1
- package/dist/sync.js +1 -1
- package/dist/sync.js.map +1 -1
- package/dist/testing.d.ts +16 -4
- package/dist/testing.js +14 -15
- package/dist/testing.js.map +1 -1
- package/dist/tsdoc-metadata.json +11 -0
- package/dist/types/adapters/options.d.ts +335 -0
- package/dist/types/async/cache.d.ts +39 -0
- package/dist/types/async/clone.d.ts +10 -0
- package/dist/types/async/errors.d.ts +3 -0
- package/dist/types/async/fetch.d.ts +37 -0
- package/dist/types/async/inflight.d.ts +13 -0
- package/dist/types/async/rate.d.ts +5 -0
- package/dist/types/async/registry.d.ts +116 -0
- package/dist/types/async/request.d.ts +11 -0
- package/dist/types/async/retry.d.ts +10 -0
- package/dist/types/async.d.ts +10 -0
- package/dist/types/computed/computed-graph.d.ts +29 -0
- package/dist/types/computed/index.d.ts +16 -0
- package/dist/types/config.d.ts +10 -0
- package/dist/types/core/index.d.ts +11 -0
- package/dist/types/core/lifecycle-hooks.d.ts +16 -0
- package/dist/types/core/store-admin-impl.d.ts +9 -0
- package/dist/types/core/store-admin.d.ts +9 -0
- package/dist/types/core/store-core.d.ts +13 -0
- package/dist/types/core/store-create.d.ts +16 -0
- package/dist/types/core/store-hydrate-impl.d.ts +35 -0
- package/dist/types/core/store-hydrate.d.ts +9 -0
- package/dist/types/core/store-lifecycle/hooks.d.ts +19 -0
- package/dist/types/core/store-lifecycle/identity.d.ts +23 -0
- package/dist/types/core/store-lifecycle/registry.d.ts +53 -0
- package/dist/types/core/store-lifecycle/types.d.ts +67 -0
- package/dist/types/core/store-lifecycle/validation.d.ts +53 -0
- package/dist/types/core/store-name.d.ts +28 -0
- package/dist/types/core/store-notify.d.ts +12 -0
- package/dist/types/core/store-read.d.ts +18 -0
- package/dist/types/core/store-registry.d.ts +108 -0
- package/dist/types/core/store-replace-impl.d.ts +11 -0
- package/dist/types/core/store-replace.d.ts +9 -0
- package/dist/types/core/store-set-impl.d.ts +13 -0
- package/dist/types/core/store-set.d.ts +9 -0
- package/dist/types/core/store-shared/core.d.ts +13 -0
- package/dist/types/core/store-shared/notify.d.ts +12 -0
- package/dist/types/core/store-transaction.d.ts +26 -0
- package/dist/types/core/store-write-shared.d.ts +19 -0
- package/dist/types/core/store-write.d.ts +13 -0
- package/dist/types/features/feature-registry.d.ts +91 -0
- package/dist/types/features/lifecycle.d.ts +40 -0
- package/dist/types/index.d.ts +17 -0
- package/dist/types/integrations/query.d.ts +8 -0
- package/dist/types/internals/computed-order.d.ts +3 -0
- package/dist/types/internals/config.d.ts +116 -0
- package/dist/types/internals/diagnostics.d.ts +21 -0
- package/dist/types/internals/reporting.d.ts +9 -0
- package/dist/types/internals/store-admin.d.ts +7 -0
- package/dist/types/internals/store-ops.d.ts +13 -0
- package/dist/types/internals/test-reset.d.ts +2 -0
- package/dist/types/internals/write-context.d.ts +15 -0
- package/dist/types/notification/delivery.d.ts +3 -0
- package/dist/types/notification/index.d.ts +10 -0
- package/dist/types/notification/metrics.d.ts +12 -0
- package/dist/types/notification/priority.d.ts +9 -0
- package/dist/types/notification/scheduler.d.ts +11 -0
- package/dist/types/notification/snapshot.d.ts +8 -0
- package/dist/types/runtime-admin/index.d.ts +2 -0
- package/dist/types/runtime-tools/index.d.ts +58 -0
- package/dist/types/store.d.ts +16 -0
- package/dist/types/types/utility.d.ts +17 -0
- package/dist/types/utils/clone.d.ts +4 -0
- package/dist/types/utils/devfreeze.d.ts +2 -0
- package/dist/types/utils/hash.d.ts +8 -0
- package/dist/types/utils/path.d.ts +5 -0
- package/dist/types/utils/validation.d.ts +14 -0
- package/dist/types/utils.d.ts +13 -0
- package/dist/types.d.ts +65 -0
- package/dist/utility.d.ts +15 -0
- package/package.json +26 -11
- package/dist/_tsup-dts-rollup.d.cts +0 -2411
- package/dist/_tsup-dts-rollup.d.ts +0 -2411
- package/dist/async.cjs +0 -34
- package/dist/async.cjs.map +0 -1
- package/dist/async.d.cts +0 -9
- package/dist/computed.cjs +0 -13
- package/dist/computed.cjs.map +0 -1
- package/dist/computed.d.cts +0 -7
- package/dist/core.cjs +0 -24
- package/dist/core.cjs.map +0 -1
- package/dist/core.d.cts +0 -15
- package/dist/devtools.cjs +0 -2
- package/dist/devtools.cjs.map +0 -1
- package/dist/devtools.d.cts +0 -5
- package/dist/feature.cjs +0 -2
- package/dist/feature.cjs.map +0 -1
- package/dist/feature.d.cts +0 -14
- package/dist/helpers.cjs +0 -24
- package/dist/helpers.cjs.map +0 -1
- package/dist/helpers.d.cts +0 -3
- package/dist/index.cjs +0 -35
- package/dist/index.cjs.map +0 -1
- package/dist/install.cjs +0 -2
- package/dist/install.cjs.map +0 -1
- package/dist/install.d.cts +0 -4
- package/dist/persist.cjs +0 -2
- package/dist/persist.cjs.map +0 -1
- package/dist/persist.d.cts +0 -1
- package/dist/react.cjs +0 -36
- package/dist/react.cjs.map +0 -1
- package/dist/react.d.cts +0 -7
- package/dist/react.d.ts +0 -7
- package/dist/react.js +0 -36
- package/dist/react.js.map +0 -1
- package/dist/runtime-admin.cjs +0 -2
- package/dist/runtime-admin.cjs.map +0 -1
- package/dist/runtime-admin.d.cts +0 -2
- package/dist/runtime-tools.cjs +0 -4
- package/dist/runtime-tools.cjs.map +0 -1
- package/dist/runtime-tools.d.cts +0 -9
- package/dist/selectors.cjs +0 -2
- package/dist/selectors.cjs.map +0 -1
- package/dist/selectors.d.cts +0 -2
- package/dist/server.cjs +0 -12
- package/dist/server.cjs.map +0 -1
- package/dist/server.d.cts +0 -2
- package/dist/sync.cjs +0 -2
- package/dist/sync.cjs.map +0 -1
- package/dist/sync.d.cts +0 -1
- package/dist/testing.cjs +0 -24
- package/dist/testing.cjs.map +0 -1
- package/dist/testing.d.cts +0 -4
package/dist/sync.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/feature-registry.ts","../src/features/state-helpers.ts","../src/internals/test-reset.ts","../src/async-registry.ts","../src/store-registry.ts","../src/internals/config.ts","../src/internals/diagnostics.ts","../src/features/sync.ts","../src/install.ts","../src/sync.ts"],"names":["_featureFactories","registerStoreFeature","name","factory","normalizeFeatureState","value","sanitize","validate","onSanitizeError","candidate","err","validation","resolveUpdatedAtMs","fallbackMs","onInvalid","parsed","_resetHooks","registerTestResetHook","fn","order","createAsyncRegistry","_registries","_registryOverrideEnv","_registryOverrideRuntime","normalizeStoreRegistryScope","scope","defaultRegistryScope","clearRegistryScopeOverrideForTests","createNotifyState","createStoreRegistry","getStoreRegistry","normalizedScope","existing","created","getActiveStoreRegistry","fallback","defaultLogSink","msg","meta","defaultConfig","cloneConfig","base","configByRegistry","baseConfig","getRegistryConfig","registry","config","getConfig","resetConfig","defaultWarn","warnAlways","_registered","SYNC_PROTOCOL_VERSION","resolveProtocolVersion","insecureSyncWarned","signerVerifyWarned","byteLength","compareSyncOrder","incoming","accepted","localClock","incomingClock","incomingSource","localSource","resolveMetaUpdatedAtMs","isValidSyncMessage","m","requestSyncSnapshot","syncChannels","instanceId","authToken","reportStoreError","channel","payload","bumpSyncClock","syncClocks","absorbSyncClock","closeSyncResources","syncWindowCleanup","syncVersions","cleanupAllSyncResources","dispose","setupSync","syncOption","getMeta","getAcceptedSyncVersion","getStoreValue","hasStoreEntry","notify","warn","setStoreValue","normalizeIncomingState","acceptIncomingSyncVersion","resolveSyncVersion","broadcastSync","hasAuthToken","hasVerify","hasSign","expectedToken","tokenWarned","channelName","event","incomingVersion","verified","resolver","localUpdated","incomingUpdated","resolved","normalizedResolved","resolveUpdatedAt","resolvedUpdatedAt","normalizedIncoming","hostWindow","requestLatest","e","updatedAt","data","hashState","checksumMode","auth","maxPayloadBytes","payloadSize","createSyncFeatureRuntime","recordLocalVersion","ensureLocalClock","ctx","next","message","normalized","updatedAtMs","source","resolvedClock","key","registerSyncFeature","installSync"],"mappings":"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","file":"sync.js","sourcesContent":["/**\r\n * @module feature-registry\r\n *\r\n * LAYER: Module\r\n * OWNS: Module-level behavior and exports for feature-registry.\r\n *\r\n * Consumers: Internal imports and public API.\r\n */\r\nimport type { NormalizedOptions, StoreValue } from \"./adapters/options.js\";\r\n\r\nexport type BuiltInFeatureName = \"persist\" | \"sync\" | \"devtools\";\r\nexport type FeatureName = BuiltInFeatureName | (string & {});\r\n\r\nexport interface FeatureMetrics {\r\n notifyCount: number;\r\n totalNotifyMs: number;\r\n lastNotifyMs: number;\r\n}\r\n\r\nexport interface StoreFeatureMeta {\r\n createdAt: string;\r\n updatedAt: string;\r\n updatedAtMs: number;\r\n updateCount: number;\r\n version: number;\r\n metrics: FeatureMetrics;\r\n options: NormalizedOptions;\r\n}\r\n\r\nexport interface BaseFeatureContext {\r\n name: string;\r\n options: NormalizedOptions;\r\n getMeta: () => StoreFeatureMeta | undefined;\r\n getStoreValue: () => StoreValue;\r\n getAllStores: () => Record<string, StoreValue>;\r\n getInitialState: () => StoreValue;\r\n hasStore: () => boolean;\r\n setStoreValue: (value: StoreValue) => void;\r\n applyFeatureState: (value: StoreValue, updatedAtMs?: number) => void;\r\n notify: () => void;\r\n reportStoreError: (message: string) => void;\r\n warn: (message: string) => void;\r\n log: (message: string) => void;\r\n hashState: (value: unknown) => number;\r\n deepClone: <T>(value: T) => T;\r\n sanitize: (value: unknown) => unknown;\r\n validate: (next: StoreValue) => { ok: boolean; value?: StoreValue };\r\n isDev: () => boolean;\r\n}\r\n\r\nexport interface FeatureCreateContext extends BaseFeatureContext {}\r\n\r\nexport interface FeatureWriteContext extends BaseFeatureContext {\r\n action: string;\r\n prev: StoreValue;\r\n next: StoreValue;\r\n}\r\n\r\nexport interface FeatureDeleteContext extends BaseFeatureContext {\r\n prev: StoreValue;\r\n}\r\n\r\nexport interface DevtoolsFeatureApi {\r\n getHistory?: (name: string, limit?: number) => unknown[];\r\n clearHistory?: (name?: string) => void;\r\n getPersistQueueDepth?: (name: string) => number;\r\n}\r\n\r\nexport interface StoreFeatureRuntime {\r\n onStoreCreate?: (ctx: FeatureCreateContext) => void;\r\n onStoreWrite?: (ctx: FeatureWriteContext) => void;\r\n beforeStoreDelete?: (ctx: FeatureDeleteContext) => void;\r\n afterStoreDelete?: (ctx: FeatureDeleteContext) => void;\r\n resetAll?: () => void;\r\n api?: DevtoolsFeatureApi;\r\n}\r\n\r\nexport type StoreFeatureFactory = () => StoreFeatureRuntime;\r\n\r\nconst _featureFactories = new Map<FeatureName, StoreFeatureFactory>();\r\nlet _onFeatureRegistered: ((name: FeatureName, factory: StoreFeatureFactory) => void) | null = null;\r\n\r\nexport const registerStoreFeature = (name: FeatureName, factory: StoreFeatureFactory): void => {\r\n _featureFactories.set(name, factory);\r\n _onFeatureRegistered?.(name, factory);\r\n};\r\n\r\nexport const hasRegisteredStoreFeature = (name: FeatureName): boolean =>\r\n _featureFactories.has(name);\r\n\r\nexport const getStoreFeatureFactory = (name: FeatureName): StoreFeatureFactory | undefined =>\r\n _featureFactories.get(name);\r\n\r\nexport const getRegisteredFeatureNames = (): FeatureName[] =>\r\n Array.from(_featureFactories.keys());\r\n\r\nexport const setFeatureRegistrationHook = (hook: ((name: FeatureName, factory: StoreFeatureFactory) => void) | null): void => {\r\n _onFeatureRegistered = hook;\r\n};\r\n\r\nexport const resetRegisteredStoreFeaturesForTests = (): void => {\r\n _featureFactories.clear();\r\n _onFeatureRegistered = null;\r\n};\r\n\r\n\r\n","/**\r\n * @module features/state-helpers\r\n *\r\n * LAYER: Feature runtime\r\n * OWNS: Module-level behavior and exports for features/state-helpers.\r\n *\r\n * Consumers: Internal imports and public API.\r\n */\r\nimport type { StoreValue } from \"../adapters/options.js\";\r\n\r\nexport type FeatureValidation = (next: StoreValue) => { ok: boolean; value?: StoreValue };\r\n\r\nexport type NormalizedFeatureState =\r\n | { ok: true; value: StoreValue }\r\n | { ok: false };\r\n\r\nexport const normalizeFeatureState = ({\r\n value,\r\n sanitize,\r\n validate,\r\n onSanitizeError,\r\n}: {\r\n value: unknown;\r\n sanitize?: (value: unknown) => unknown;\r\n validate: FeatureValidation;\r\n onSanitizeError?: (error: unknown) => void;\r\n}): NormalizedFeatureState => {\r\n let candidate: StoreValue;\r\n if (sanitize) {\r\n try {\r\n candidate = sanitize(value) as StoreValue;\r\n } catch (err) {\r\n onSanitizeError?.(err);\r\n return { ok: false };\r\n }\r\n } else {\r\n candidate = value as StoreValue;\r\n }\r\n\r\n const validation = validate(candidate);\r\n if (!validation.ok) return { ok: false };\r\n return { ok: true, value: validation.value ?? candidate };\r\n};\r\n\r\nexport const resolveUpdatedAtMs = ({\r\n value,\r\n fallbackMs = Date.now(),\r\n onInvalid,\r\n}: {\r\n value: unknown;\r\n fallbackMs?: number;\r\n onInvalid?: () => void;\r\n}): number => {\r\n if (typeof value === \"number\") {\r\n if (Number.isFinite(value)) return value;\r\n onInvalid?.();\r\n return fallbackMs;\r\n }\r\n if (typeof value === \"string\") {\r\n const parsed = Date.parse(value);\r\n if (Number.isFinite(parsed)) return parsed;\r\n onInvalid?.();\r\n return fallbackMs;\r\n }\r\n onInvalid?.();\r\n return fallbackMs;\r\n};\r\n\r\n\r\n","/**\r\n * @module internals/test-reset\r\n *\r\n * LAYER: Internal subsystem\r\n * OWNS: Module-level behavior and exports for internals/test-reset.\r\n *\r\n * Consumers: Internal imports and public API.\r\n */\r\ntype TestResetHook = {\r\n name: string;\r\n order: number;\r\n fn: () => void;\r\n};\r\n\r\nconst _resetHooks = new Map<string, TestResetHook>();\r\n\r\nexport const registerTestResetHook = (name: string, fn: () => void, order = 0): void => {\r\n if (!name || typeof fn !== \"function\") return;\r\n _resetHooks.set(name, { name, order, fn });\r\n};\r\n\r\nexport const runTestResets = (): void => {\r\n const ordered = Array.from(_resetHooks.values()).sort((a, b) => {\r\n if (a.order !== b.order) return a.order - b.order;\r\n return a.name.localeCompare(b.name, \"en\");\r\n });\r\n ordered.forEach((hook) => hook.fn());\r\n};\r\n\r\n\r\n","/**\r\n * @module async-registry\r\n *\r\n * LAYER: Module\r\n * OWNS: Module-level behavior and exports for async-registry.\r\n *\r\n * Consumers: Internal imports and public API.\r\n */\r\nexport type AsyncStateSnapshot = {\r\n data?: unknown;\r\n loading: boolean;\r\n error: string | null;\r\n status: \"idle\" | \"loading\" | \"success\" | \"error\" | \"aborted\";\r\n cached?: boolean;\r\n revalidating?: boolean;\r\n};\r\n\r\nexport type AsyncStateAdapter = (ctx: {\r\n name: string;\r\n prev: unknown;\r\n next: AsyncStateSnapshot;\r\n set: (value: unknown | ((draft: any) => void)) => void;\r\n}) => void;\r\n\r\nexport interface FetchOptions {\r\n transform?: (result: unknown) => unknown;\r\n onSuccess?: (data: unknown) => void;\r\n onError?: (message: string) => void;\r\n /**\r\n * Optional adapter to write async state into a custom store shape.\r\n * When provided, default AsyncState writes are skipped.\r\n */\r\n stateAdapter?: AsyncStateAdapter;\r\n method?: string;\r\n headers?: Record<string, string>;\r\n body?: unknown;\r\n ttl?: number;\r\n staleWhileRevalidate?: boolean;\r\n dedupe?: boolean;\r\n retry?: number;\r\n retryDelay?: number;\r\n retryBackoff?: number;\r\n signal?: AbortSignal;\r\n cacheKey?: string;\r\n responseType?: \"auto\" | \"json\" | \"text\" | \"arrayBuffer\" | \"blob\" | \"formData\";\r\n /**\r\n * Auto-create the backing store if missing.\r\n * Defaults to the global config setting (true by default).\r\n */\r\n autoCreate?: boolean;\r\n /**\r\n * Clone strategy for transformed results.\r\n * - \"none\" (default): store by reference.\r\n * - \"shallow\": shallow clone objects/arrays.\r\n * - \"deep\": deep clone objects/arrays.\r\n */\r\n cloneResult?: \"none\" | \"shallow\" | \"deep\";\r\n}\r\n\r\ntype InflightEntry = { promise: Promise<unknown>; raw: Promise<unknown>; transform?: FetchOptions[\"transform\"] };\r\n\r\nexport type AsyncRegistry = {\r\n fetchRegistry: Record<string, { kind: \"url\"; url: string; options: FetchOptions } | { kind: \"factory\"; factory: () => string | Promise<unknown>; options: FetchOptions }>;\r\n inflight: Partial<Record<string, InflightEntry>>;\r\n requestVersion: Record<string, number>;\r\n cacheMeta: Record<string, { timestamp: number; expiresAt: number | null; data: unknown }>;\r\n rateWindowStart: Record<string, number>;\r\n rateCount: Record<string, number>;\r\n ratePruneState: { lastAt: number };\r\n ratePruneTimer: ReturnType<typeof setTimeout> | null;\r\n noSignalWarned: Set<string>;\r\n shapeWarned: Set<string>;\r\n autoCreateWarned: Set<string>;\r\n mutableResultWarned: Set<string>;\r\n cleanupSubs: Record<string, () => void>;\r\n storeCleanupFns: Record<string, Set<() => void>>;\r\n revalidateKeys: Set<string>;\r\n revalidateHandlers: Record<string, () => void>;\r\n asyncMetrics: {\r\n cacheHits: number;\r\n cacheMisses: number;\r\n dedupes: number;\r\n requests: number;\r\n failures: number;\r\n avgMs: number;\r\n lastMs: number;\r\n };\r\n};\r\n\r\nexport const createAsyncRegistry = (): AsyncRegistry => ({\r\n fetchRegistry: Object.create(null),\r\n inflight: Object.create(null),\r\n requestVersion: Object.create(null),\r\n cacheMeta: Object.create(null),\r\n rateWindowStart: Object.create(null),\r\n rateCount: Object.create(null),\r\n ratePruneState: { lastAt: 0 },\r\n ratePruneTimer: null,\r\n noSignalWarned: new Set<string>(),\r\n shapeWarned: new Set<string>(),\r\n autoCreateWarned: new Set<string>(),\r\n mutableResultWarned: new Set<string>(),\r\n cleanupSubs: Object.create(null),\r\n storeCleanupFns: Object.create(null),\r\n revalidateKeys: new Set<string>(),\r\n revalidateHandlers: Object.create(null),\r\n asyncMetrics: {\r\n cacheHits: 0,\r\n cacheMisses: 0,\r\n dedupes: 0,\r\n requests: 0,\r\n failures: 0,\r\n avgMs: 0,\r\n lastMs: 0,\r\n },\r\n});\r\n\r\nexport const resetAsyncRegistry = (registry: AsyncRegistry): void => {\r\n Object.values(registry.revalidateHandlers).forEach((cleanup) => {\r\n try { cleanup(); } catch (_) { /* ignore cleanup errors */ }\r\n });\r\n\r\n Object.values(registry.cleanupSubs).forEach((unsubscribe) => {\r\n try { unsubscribe(); } catch (_) { /* ignore cleanup errors */ }\r\n });\r\n\r\n Object.values(registry.storeCleanupFns).forEach((fns) => {\r\n fns.forEach((fn) => {\r\n try { fn(); } catch (_) { /* ignore cleanup errors */ }\r\n });\r\n });\r\n\r\n Object.keys(registry.fetchRegistry).forEach((key) => delete registry.fetchRegistry[key]);\r\n Object.keys(registry.inflight).forEach((key) => delete registry.inflight[key]);\r\n Object.keys(registry.requestVersion).forEach((key) => delete registry.requestVersion[key]);\r\n Object.keys(registry.cacheMeta).forEach((key) => delete registry.cacheMeta[key]);\r\n Object.keys(registry.rateWindowStart).forEach((key) => delete registry.rateWindowStart[key]);\r\n Object.keys(registry.rateCount).forEach((key) => delete registry.rateCount[key]);\r\n Object.keys(registry.cleanupSubs).forEach((key) => delete registry.cleanupSubs[key]);\r\n Object.keys(registry.storeCleanupFns).forEach((key) => delete registry.storeCleanupFns[key]);\r\n Object.keys(registry.revalidateHandlers).forEach((key) => delete registry.revalidateHandlers[key]);\r\n\r\n registry.revalidateKeys.clear();\r\n registry.noSignalWarned.clear();\r\n registry.shapeWarned.clear();\r\n registry.autoCreateWarned.clear();\r\n registry.mutableResultWarned.clear();\r\n registry.ratePruneState.lastAt = 0;\r\n if (registry.ratePruneTimer) {\r\n clearTimeout(registry.ratePruneTimer);\r\n registry.ratePruneTimer = null;\r\n }\r\n\r\n registry.asyncMetrics.cacheHits = 0;\r\n registry.asyncMetrics.cacheMisses = 0;\r\n registry.asyncMetrics.dedupes = 0;\r\n registry.asyncMetrics.requests = 0;\r\n registry.asyncMetrics.failures = 0;\r\n registry.asyncMetrics.avgMs = 0;\r\n registry.asyncMetrics.lastMs = 0;\r\n};\r\n\r\n\r\n","/**\r\n * @module store-registry\r\n *\r\n * LAYER: Store runtime\r\n * OWNS: Module-level behavior and exports for store-registry.\r\n *\r\n * Consumers: Internal imports and public API.\r\n */\r\nimport type { FeatureName, StoreFeatureMeta, StoreFeatureRuntime } from \"./feature-registry.js\";\r\nimport type { AsyncRegistry } from \"./async-registry.js\";\r\nimport { createAsyncRegistry, resetAsyncRegistry } from \"./async-registry.js\";\r\nimport { registerTestResetHook } from \"./internals/test-reset.js\";\r\n\r\nexport type RegistryStoreValue = unknown;\r\nexport type RegistrySubscriber = (value: RegistryStoreValue | null) => void;\r\nexport type RegistrySnapshotEntry = {\r\n version: number;\r\n snapshot: RegistryStoreValue | null;\r\n};\r\n\r\nexport type TransactionState = {\r\n depth: number;\r\n pending: Array<() => void>;\r\n stagedValues: Map<string, RegistryStoreValue>;\r\n snapshotCache: Map<string, TransactionSnapshotEntry>;\r\n failed: boolean;\r\n error?: Error;\r\n};\r\n\r\ntype TransactionSnapshotMode = \"deep\" | \"shallow\" | \"ref\";\r\ntype TransactionSnapshotEntry = {\r\n source: RegistryStoreValue | null | undefined;\r\n snapshot: RegistryStoreValue | null;\r\n mode: TransactionSnapshotMode;\r\n};\r\n\r\nexport type ComputedEntry = {\r\n deps: string[];\r\n compute: (...args: unknown[]) => unknown;\r\n stale: boolean;\r\n};\r\n\r\nexport type NotifyState = {\r\n pendingNotifications: Set<string>;\r\n pendingBuffer: string[];\r\n orderedNames: string[];\r\n notifyScheduled: boolean;\r\n batchDepth: number;\r\n};\r\n\r\nexport type StoreRegistry = {\r\n stores: Record<string, RegistryStoreValue>;\r\n subscribers: Record<string, Set<RegistrySubscriber>>;\r\n initialStates: Record<string, RegistryStoreValue>;\r\n initialFactories: Record<string, (() => RegistryStoreValue) | undefined>;\r\n metaEntries: Record<string, StoreFeatureMeta>;\r\n snapshotCache: Record<string, RegistrySnapshotEntry>;\r\n featureRuntimes: Map<FeatureName, StoreFeatureRuntime>;\r\n deletingStores: Set<string>;\r\n computedEntries: Record<string, ComputedEntry>;\r\n computedDependents: Record<string, Set<string>>;\r\n computedCleanups: Map<string, () => void>;\r\n transaction: TransactionState;\r\n async: AsyncRegistry;\r\n notify: NotifyState;\r\n};\r\n\r\nconst _registries = new Map<string, StoreRegistry>();\r\n\r\ndeclare const __STROID_REGISTRY_ID__: string | undefined;\r\nconst _registryOverrideEnv =\r\n (typeof __STROID_REGISTRY_ID__ !== \"undefined\" && __STROID_REGISTRY_ID__)\r\n || (typeof process !== \"undefined\" && process.env?.STROID_REGISTRY_ID)\r\n || undefined;\r\n\r\nlet _registryOverrideRuntime: string | undefined;\r\n\r\nexport const normalizeStoreRegistryScope = (scope: string): string => {\r\n const resolved = _registryOverrideRuntime || _registryOverrideEnv || scope;\r\n return resolved.replace(/\\.ts(\\?|$)/, \".js$1\");\r\n};\r\n\r\nexport const defaultRegistryScope = normalizeStoreRegistryScope(new URL(\"./store.js\", import.meta.url).href);\r\nexport const getDefaultStoreRegistry = (): StoreRegistry => getStoreRegistry(defaultRegistryScope);\r\n\r\nexport const setRegistryScope = (scope: string): void => {\r\n _registryOverrideRuntime = scope;\r\n _registries.clear();\r\n};\r\n\r\nexport const clearRegistryScopeOverrideForTests = (): void => {\r\n _registryOverrideRuntime = undefined;\r\n _registries.clear();\r\n};\r\n\r\nregisterTestResetHook(\"registry.scope-override\", clearRegistryScopeOverrideForTests, 110);\r\n\r\nconst createNotifyState = (): NotifyState => ({\r\n pendingNotifications: new Set<string>(),\r\n pendingBuffer: [],\r\n orderedNames: [],\r\n notifyScheduled: false,\r\n batchDepth: 0,\r\n});\r\n\r\nconst resetNotifyState = (notify: NotifyState): void => {\r\n notify.pendingNotifications.clear();\r\n notify.pendingBuffer.length = 0;\r\n notify.orderedNames.length = 0;\r\n notify.notifyScheduled = false;\r\n notify.batchDepth = 0;\r\n};\r\n\r\nexport const createStoreRegistry = (): StoreRegistry => ({\r\n stores: Object.create(null),\r\n subscribers: Object.create(null),\r\n initialStates: Object.create(null),\r\n initialFactories: Object.create(null),\r\n metaEntries: Object.create(null),\r\n snapshotCache: Object.create(null),\r\n featureRuntimes: new Map(),\r\n deletingStores: new Set(),\r\n computedEntries: Object.create(null),\r\n computedDependents: Object.create(null),\r\n computedCleanups: new Map(),\r\n transaction: {\r\n depth: 0,\r\n pending: [],\r\n stagedValues: new Map(),\r\n snapshotCache: new Map(),\r\n failed: false,\r\n error: undefined,\r\n },\r\n async: createAsyncRegistry(),\r\n notify: createNotifyState(),\r\n});\r\n\r\nexport const getStoreRegistry = (scope: string): StoreRegistry => {\r\n const normalizedScope = normalizeStoreRegistryScope(scope);\r\n const existing = _registries.get(normalizedScope);\r\n if (existing) return existing;\r\n const created = createStoreRegistry();\r\n _registries.set(normalizedScope, created);\r\n return created;\r\n};\r\n\r\nexport const hasStoreEntry = (registry: StoreRegistry, name: string): boolean =>\r\n Object.prototype.hasOwnProperty.call(registry.stores, name);\r\n\r\nexport const isStoreDeleting = (registry: StoreRegistry, name: string): boolean =>\r\n registry.deletingStores.has(name);\r\n\r\nexport const clearStoreRegistries = (registry: StoreRegistry): void => {\r\n registry.computedCleanups.forEach((cleanup) => {\r\n try { cleanup(); } catch (_) { /* ignore cleanup errors */ }\r\n });\r\n registry.computedCleanups.clear();\r\n [\r\n registry.stores,\r\n registry.subscribers,\r\n registry.initialStates,\r\n registry.initialFactories,\r\n registry.metaEntries,\r\n registry.snapshotCache,\r\n registry.computedEntries,\r\n registry.computedDependents,\r\n ].forEach((registryPart) => {\r\n Object.keys(registryPart).forEach((key) => {\r\n delete registryPart[key];\r\n });\r\n });\r\n registry.deletingStores.clear();\r\n registry.transaction.depth = 0;\r\n registry.transaction.pending = [];\r\n registry.transaction.stagedValues.clear();\r\n registry.transaction.snapshotCache.clear();\r\n registry.transaction.failed = false;\r\n registry.transaction.error = undefined;\r\n resetNotifyState(registry.notify);\r\n resetAsyncRegistry(registry.async);\r\n};\r\n\r\nexport const resetAllStoreRegistriesForTests = (): void => {\r\n _registries.forEach((registry) => {\r\n registry.computedCleanups.forEach((cleanup) => {\r\n try { cleanup(); } catch (_) { /* ignore cleanup errors */ }\r\n });\r\n registry.computedCleanups.clear();\r\n [\r\n registry.stores,\r\n registry.subscribers,\r\n registry.initialStates,\r\n registry.initialFactories,\r\n registry.metaEntries,\r\n registry.snapshotCache,\r\n registry.computedEntries,\r\n registry.computedDependents,\r\n ].forEach((registryPart) => {\r\n Object.keys(registryPart).forEach((key) => {\r\n delete registryPart[key];\r\n });\r\n });\r\n registry.deletingStores.clear();\r\n registry.transaction.depth = 0;\r\n registry.transaction.pending = [];\r\n registry.transaction.stagedValues.clear();\r\n registry.transaction.snapshotCache.clear();\r\n registry.transaction.failed = false;\r\n registry.transaction.error = undefined;\r\n resetNotifyState(registry.notify);\r\n resetAsyncRegistry(registry.async);\r\n });\r\n _registries.clear();\r\n};\r\n\r\nexport type CarrierContext = Record<string, unknown>;\r\nexport interface CarrierRunner {\r\n run<T>(carrier: CarrierContext, fn: () => T): T;\r\n get(): CarrierContext | null;\r\n}\r\n\r\nlet currentCarrierRunner: CarrierRunner | null = null;\r\n\r\nexport const injectCarrierRunner = (runner: CarrierRunner): void => {\r\n currentCarrierRunner = runner;\r\n};\r\n\r\nexport const getRequestCarrier = (): CarrierContext | null => {\r\n return currentCarrierRunner?.get() || null;\r\n};\r\n\r\nexport interface RegistryRunner {\r\n run<T>(registry: StoreRegistry, fn: () => T): T;\r\n get(): StoreRegistry | null;\r\n enterWith?: (registry: StoreRegistry) => void;\r\n}\r\n\r\nlet currentRegistryRunner: RegistryRunner | null = null;\r\n\r\nexport const injectRegistryRunner = (runner: RegistryRunner): void => {\r\n currentRegistryRunner = runner;\r\n};\r\n\r\nexport const runWithRegistry = <T>(registry: StoreRegistry, fn: () => T): T => {\r\n if (currentRegistryRunner?.run) return currentRegistryRunner.run(registry, fn);\r\n return fn();\r\n};\r\n\r\nexport const getActiveStoreRegistry = (fallback?: StoreRegistry): StoreRegistry => {\r\n return currentRegistryRunner?.get() || fallback || getStoreRegistry(defaultRegistryScope);\r\n};\r\n\r\nexport const enterRegistry = (registry: StoreRegistry): void => {\r\n if (currentRegistryRunner?.enterWith) {\r\n currentRegistryRunner.enterWith(registry);\r\n }\r\n};\r\n\r\n\r\n","/**\r\n * @module internals/config\r\n *\r\n * LAYER: Internal subsystem\r\n * OWNS: Module-level behavior and exports for internals/config.\r\n *\r\n * Consumers: Internal imports and public API.\r\n */\r\nimport type { SnapshotMode, MiddlewareCtx, StoreValue } from \"../adapters/options.js\";\r\nimport { registerTestResetHook } from \"./test-reset.js\";\r\nimport { warnAlways } from \"./diagnostics.js\";\r\nimport { getActiveStoreRegistry, getDefaultStoreRegistry, type StoreRegistry } from \"../store-registry.js\";\r\n\r\nexport type LogSink = {\r\n log?: (msg: string, meta?: Record<string, unknown>) => void;\r\n warn?: (msg: string, meta?: Record<string, unknown>) => void;\r\n critical?: (msg: string, meta?: Record<string, unknown>) => void;\r\n};\r\n\r\nexport type AsyncCloneMode = \"none\" | \"shallow\" | \"deep\";\r\n\r\nexport type FlushConfig = {\r\n chunkSize?: number;\r\n chunkDelayMs?: number;\r\n priorityStores?: string[];\r\n};\r\n\r\nexport type RevalidateOnFocusConfig = {\r\n debounceMs?: number;\r\n maxConcurrent?: number;\r\n staggerMs?: number;\r\n};\r\n\r\nexport type StroidConfig = {\r\n logSink?: LogSink;\r\n flush?: FlushConfig;\r\n revalidateOnFocus?: RevalidateOnFocusConfig;\r\n namespace?: string;\r\n strictMissingFeatures?: boolean;\r\n strictFeatures?: boolean;\r\n assertRuntime?: boolean;\r\n strictMutatorReturns?: boolean;\r\n asyncAutoCreate?: boolean;\r\n asyncCloneResult?: AsyncCloneMode;\r\n defaultSnapshotMode?: SnapshotMode;\r\n /**\r\n * Alias for defaultSnapshotMode.\r\n */\r\n snapshotStrategy?: SnapshotMode;\r\n /**\r\n * Throw on async usage errors instead of returning null.\r\n * Default: false (usage errors return null and call onError).\r\n */\r\n strictAsyncUsageErrors?: boolean;\r\n middleware?: Array<(ctx: MiddlewareCtx) => StoreValue | void>;\r\n /**\r\n * Allow hydrateStores to accept untrusted snapshots without explicit opt-in.\r\n * Default: false (hydration requires an explicit trust opt-in).\r\n */\r\n allowUntrustedHydration?: boolean;\r\n /**\r\n * Optional custom mutator engine (e.g. Immer's produce) to enable structural sharing.\r\n * You can pass the produce function directly or use \"immer\" with a global produce shim.\r\n */\r\n mutatorProduce?: (<T>(base: T, recipe: (draft: T) => void) => T) | \"immer\";\r\n};\r\n\r\ntype ResolvedConfig = {\r\n logSink: LogSink;\r\n flush: Required<FlushConfig>;\r\n revalidateOnFocus: Required<RevalidateOnFocusConfig>;\r\n namespace: string;\r\n strictMissingFeatures: boolean;\r\n assertRuntime: boolean;\r\n strictMutatorReturns: boolean;\r\n asyncAutoCreate: boolean;\r\n asyncCloneResult: AsyncCloneMode;\r\n defaultSnapshotMode: SnapshotMode;\r\n strictAsyncUsageErrors: boolean;\r\n middleware: Array<(ctx: MiddlewareCtx) => StoreValue | void>;\r\n allowUntrustedHydration: boolean;\r\n mutatorProduce?: <T>(base: T, recipe: (draft: T) => void) => T;\r\n};\r\n\r\nconst defaultLogSink: LogSink = {\r\n log: (msg: string, meta?: Record<string, unknown>) => {\r\n if (typeof console !== \"undefined\" && typeof console.log === \"function\") {\r\n if (meta) console.log(`[stroid] ${msg}`, meta);\r\n else console.log(`[stroid] ${msg}`);\r\n }\r\n },\r\n warn: (msg: string, meta?: Record<string, unknown>) => {\r\n if (typeof console !== \"undefined\" && typeof console.warn === \"function\") {\r\n if (meta) console.warn(`[stroid] ${msg}`, meta);\r\n else console.warn(`[stroid] ${msg}`);\r\n }\r\n },\r\n critical: (msg: string, meta?: Record<string, unknown>) => {\r\n if (typeof console !== \"undefined\" && typeof console.error === \"function\") {\r\n if (meta) console.error(`[stroid] ${msg}`, meta);\r\n else console.error(`[stroid] ${msg}`);\r\n }\r\n },\r\n};\r\n\r\nconst defaultConfig: ResolvedConfig = {\r\n logSink: defaultLogSink,\r\n flush: {\r\n chunkSize: Number.POSITIVE_INFINITY,\r\n chunkDelayMs: 0,\r\n priorityStores: [],\r\n },\r\n revalidateOnFocus: {\r\n debounceMs: 0,\r\n maxConcurrent: 3,\r\n staggerMs: 100,\r\n },\r\n namespace: \"\",\r\n strictMissingFeatures: true,\r\n assertRuntime: false,\r\n strictMutatorReturns: true,\r\n asyncAutoCreate: false,\r\n asyncCloneResult: \"none\",\r\n defaultSnapshotMode: \"deep\",\r\n strictAsyncUsageErrors: false,\r\n middleware: [],\r\n allowUntrustedHydration: false,\r\n mutatorProduce: undefined,\r\n};\r\n\r\nconst cloneConfig = (base: ResolvedConfig): ResolvedConfig => ({\r\n logSink: { ...base.logSink },\r\n flush: { ...base.flush },\r\n revalidateOnFocus: { ...base.revalidateOnFocus },\r\n namespace: base.namespace,\r\n strictMissingFeatures: base.strictMissingFeatures,\r\n assertRuntime: base.assertRuntime,\r\n strictMutatorReturns: base.strictMutatorReturns,\r\n asyncAutoCreate: base.asyncAutoCreate,\r\n asyncCloneResult: base.asyncCloneResult,\r\n defaultSnapshotMode: base.defaultSnapshotMode,\r\n strictAsyncUsageErrors: base.strictAsyncUsageErrors,\r\n middleware: [...base.middleware],\r\n allowUntrustedHydration: base.allowUntrustedHydration,\r\n mutatorProduce: base.mutatorProduce,\r\n});\r\n\r\nlet configByRegistry = new WeakMap<StoreRegistry, ResolvedConfig>();\r\nlet baseConfig = cloneConfig(defaultConfig);\r\nconst getRegistryConfig = (registry: StoreRegistry): ResolvedConfig => {\r\n let config = configByRegistry.get(registry);\r\n if (!config) {\r\n config = cloneConfig(baseConfig);\r\n configByRegistry.set(registry, config);\r\n }\r\n return config;\r\n};\r\n\r\nconst IMMER_PRODUCE_KEY = \"__STROID_IMMER_PRODUCE__\";\r\nlet cachedImmerProduce: (<T>(base: T, recipe: (draft: T) => void) => T) | undefined;\r\nlet immerMissingWarned = false;\r\nconst resolveImmerProduce = (): (<T>(base: T, recipe: (draft: T) => void) => T) | undefined => {\r\n if (cachedImmerProduce) return cachedImmerProduce;\r\n const globalAny = globalThis as Record<string, unknown> | undefined;\r\n const candidate = globalAny ? globalAny[IMMER_PRODUCE_KEY] : undefined;\r\n if (typeof candidate === \"function\") {\r\n cachedImmerProduce = candidate as (<T>(base: T, recipe: (draft: T) => void) => T);\r\n return cachedImmerProduce;\r\n }\r\n return undefined;\r\n};\r\n\r\nexport const getConfig = (): ResolvedConfig => getRegistryConfig(getActiveStoreRegistry());\r\n\r\nexport const configureStroid = (next?: StroidConfig): void => {\r\n if (!next) return;\r\n const registry = getActiveStoreRegistry();\r\n let config = getRegistryConfig(registry);\r\n\r\n if (next.logSink) {\r\n config = {\r\n ...config,\r\n logSink: {\r\n log: next.logSink.log ?? config.logSink.log,\r\n warn: next.logSink.warn ?? config.logSink.warn,\r\n critical: next.logSink.critical ?? config.logSink.critical,\r\n },\r\n };\r\n }\r\n\r\n if (next.flush) {\r\n config = {\r\n ...config,\r\n flush: {\r\n chunkSize: Number.isFinite(next.flush.chunkSize ?? config.flush.chunkSize)\r\n ? (next.flush.chunkSize as number)\r\n : config.flush.chunkSize,\r\n chunkDelayMs: Number.isFinite(next.flush.chunkDelayMs ?? config.flush.chunkDelayMs)\r\n ? (next.flush.chunkDelayMs as number)\r\n : config.flush.chunkDelayMs,\r\n priorityStores: Array.isArray(next.flush.priorityStores)\r\n ? next.flush.priorityStores\r\n : config.flush.priorityStores,\r\n },\r\n };\r\n }\r\n\r\n if (next.revalidateOnFocus) {\r\n config = {\r\n ...config,\r\n revalidateOnFocus: {\r\n debounceMs: Number.isFinite(next.revalidateOnFocus.debounceMs ?? config.revalidateOnFocus.debounceMs)\r\n ? (next.revalidateOnFocus.debounceMs as number)\r\n : config.revalidateOnFocus.debounceMs,\r\n maxConcurrent: Number.isFinite(next.revalidateOnFocus.maxConcurrent ?? config.revalidateOnFocus.maxConcurrent)\r\n ? Math.max(1, next.revalidateOnFocus.maxConcurrent as number)\r\n : config.revalidateOnFocus.maxConcurrent,\r\n staggerMs: Number.isFinite(next.revalidateOnFocus.staggerMs ?? config.revalidateOnFocus.staggerMs)\r\n ? Math.max(0, next.revalidateOnFocus.staggerMs as number)\r\n : config.revalidateOnFocus.staggerMs,\r\n },\r\n };\r\n }\r\n\r\n if (typeof next.namespace === \"string\") {\r\n config = {\r\n ...config,\r\n namespace: next.namespace.trim(),\r\n };\r\n }\r\n\r\n if (typeof next.strictMissingFeatures === \"boolean\") {\r\n config = {\r\n ...config,\r\n strictMissingFeatures: next.strictMissingFeatures,\r\n };\r\n }\r\n if (typeof next.strictFeatures === \"boolean\") {\r\n config = {\r\n ...config,\r\n strictMissingFeatures: next.strictFeatures,\r\n };\r\n }\r\n\r\n if (typeof next.assertRuntime === \"boolean\") {\r\n config = {\r\n ...config,\r\n assertRuntime: next.assertRuntime,\r\n };\r\n }\r\n\r\n if (typeof next.strictMutatorReturns === \"boolean\") {\r\n config = {\r\n ...config,\r\n strictMutatorReturns: next.strictMutatorReturns,\r\n };\r\n }\r\n\r\n if (typeof next.asyncAutoCreate === \"boolean\") {\r\n config = {\r\n ...config,\r\n asyncAutoCreate: next.asyncAutoCreate,\r\n };\r\n }\r\n if (typeof next.strictAsyncUsageErrors === \"boolean\") {\r\n config = {\r\n ...config,\r\n strictAsyncUsageErrors: next.strictAsyncUsageErrors,\r\n };\r\n }\r\n\r\n if (next.asyncCloneResult === \"none\" || next.asyncCloneResult === \"shallow\" || next.asyncCloneResult === \"deep\") {\r\n config = {\r\n ...config,\r\n asyncCloneResult: next.asyncCloneResult,\r\n };\r\n }\r\n\r\n if (next.snapshotStrategy === \"shallow\" || next.snapshotStrategy === \"ref\" || next.snapshotStrategy === \"deep\") {\r\n config = {\r\n ...config,\r\n defaultSnapshotMode: next.snapshotStrategy,\r\n };\r\n }\r\n\r\n if (next.defaultSnapshotMode === \"shallow\" || next.defaultSnapshotMode === \"ref\" || next.defaultSnapshotMode === \"deep\") {\r\n config = {\r\n ...config,\r\n defaultSnapshotMode: next.defaultSnapshotMode,\r\n };\r\n }\r\n\r\n if (Array.isArray(next.middleware)) {\r\n config = {\r\n ...config,\r\n middleware: next.middleware,\r\n };\r\n }\r\n\r\n if (typeof next.allowUntrustedHydration === \"boolean\") {\r\n config = {\r\n ...config,\r\n allowUntrustedHydration: next.allowUntrustedHydration,\r\n };\r\n }\r\n\r\n if (typeof next.mutatorProduce === \"function\") {\r\n config = {\r\n ...config,\r\n mutatorProduce: next.mutatorProduce,\r\n };\r\n } else if (next.mutatorProduce === \"immer\") {\r\n const produce = resolveImmerProduce();\r\n if (produce) {\r\n config = {\r\n ...config,\r\n mutatorProduce: produce,\r\n };\r\n } else {\r\n if (!immerMissingWarned) {\r\n immerMissingWarned = true;\r\n warnAlways(\r\n `configureStroid({ mutatorProduce: \"immer\" }) requires Immer's produce function.\\n` +\r\n `Set globalThis.${IMMER_PRODUCE_KEY} = produce or pass mutatorProduce: produce directly.`\r\n );\r\n }\r\n }\r\n }\r\n\r\n configByRegistry.set(registry, config);\r\n if (registry === getDefaultStoreRegistry()) {\r\n baseConfig = cloneConfig(config);\r\n }\r\n};\r\n\r\nexport const resetConfig = (): void => {\r\n configByRegistry = new WeakMap<StoreRegistry, ResolvedConfig>();\r\n baseConfig = cloneConfig(defaultConfig);\r\n cachedImmerProduce = undefined;\r\n immerMissingWarned = false;\r\n};\r\n\r\nregisterTestResetHook(\"config.reset\", resetConfig, 90);\r\n\r\n// Back-compat for tests\r\nexport const _resetConfigForTests = (): void => resetConfig();\r\n\r\nexport const getNamespace = (): string => getConfig().namespace;\r\nexport const setNamespace = (ns: string): void => {\r\n const registry = getActiveStoreRegistry();\r\n const config = getRegistryConfig(registry);\r\n const next = { ...config, namespace: ns.trim() };\r\n configByRegistry.set(registry, next);\r\n if (registry === getDefaultStoreRegistry()) {\r\n baseConfig = cloneConfig(next);\r\n }\r\n};\r\n\r\n\r\n","/**\r\n * @module internals/diagnostics\r\n *\r\n * LAYER: Internal subsystem\r\n * OWNS: Module-level behavior and exports for internals/diagnostics.\r\n *\r\n * Consumers: Internal imports and public API.\r\n */\r\nimport { getConfig } from \"./config.js\";\r\nconst _envFromProcess = typeof process !== \"undefined\" && typeof process.env?.NODE_ENV === \"string\"\r\n ? process.env.NODE_ENV\r\n : undefined;\r\nconst _envFromImportMeta = typeof import.meta !== \"undefined\" && (import.meta as any)?.env?.MODE\r\n ? (import.meta as any).env.MODE\r\n : undefined;\r\nconst _devFlag = typeof globalThis !== \"undefined\" && typeof (globalThis as any).__STROID_DEV__ === \"boolean\"\r\n ? (globalThis as any).__STROID_DEV__\r\n : undefined;\r\nconst _fallbackEnv = \"production\";\r\nconst _resolvedEnv = _envFromProcess ?? _envFromImportMeta ?? _fallbackEnv;\r\n\r\nexport const __DEV__ = typeof _devFlag === \"boolean\"\r\n ? _devFlag\r\n : _resolvedEnv !== \"production\";\r\n\r\nexport const isDev = (): boolean => __DEV__;\r\n\r\nconst defaultWarn = (msg: string, meta?: Record<string, unknown>): void => {\r\n if (typeof console !== \"undefined\" && typeof console.warn === \"function\") {\r\n if (meta) console.warn(`[stroid] ${msg}`, meta);\r\n else console.warn(`[stroid] ${msg}`);\r\n }\r\n};\r\n\r\nconst defaultCritical = (msg: string, meta?: Record<string, unknown>): void => {\r\n if (typeof console !== \"undefined\" && typeof console.error === \"function\") {\r\n if (meta) console.error(`[stroid] ${msg}`, meta);\r\n else console.error(`[stroid] ${msg}`);\r\n }\r\n};\r\n\r\nconst defaultLog = (msg: string, meta?: Record<string, unknown>): void => {\r\n if (typeof console !== \"undefined\" && typeof console.log === \"function\") {\r\n if (meta) console.log(`[stroid] ${msg}`, meta);\r\n else console.log(`[stroid] ${msg}`);\r\n }\r\n};\r\n\r\nexport const critical = (msg: string, meta?: Record<string, unknown>): void => {\r\n const sink = getConfig().logSink.critical ?? defaultCritical;\r\n sink(msg, meta);\r\n if (getConfig().assertRuntime) throw new Error(msg);\r\n};\r\n\r\nexport const warn = (msg: string, meta?: Record<string, unknown>): void => {\r\n if (!__DEV__) return;\r\n const sink = getConfig().logSink.warn ?? defaultWarn;\r\n sink(msg, meta);\r\n if (getConfig().assertRuntime) throw new Error(msg);\r\n};\r\n\r\n// Used for configuration hazards that must surface in production too.\r\nexport const warnAlways = (msg: string, meta?: Record<string, unknown>): void => {\r\n const sink = getConfig().logSink.warn ?? defaultWarn;\r\n sink(msg, meta);\r\n if (getConfig().assertRuntime) throw new Error(msg);\r\n};\r\n\r\nexport const error = (msg: string, meta?: Record<string, unknown>): void => {\r\n if (__DEV__) {\r\n const sink = getConfig().logSink.warn ?? defaultWarn;\r\n sink(msg, meta);\r\n }\r\n critical(msg, meta);\r\n if (getConfig().assertRuntime) throw new Error(msg);\r\n};\r\n\r\nexport const log = (msg: string, meta?: Record<string, unknown>): void => {\r\n if (!__DEV__) return;\r\n const sink = getConfig().logSink.log ?? defaultLog;\r\n sink(msg, meta);\r\n};\r\n\r\nexport const getInvalidFunctionStoreValueMessage = (): string =>\r\n `Functions cannot be stored in stroid.\\n` +\r\n `Store data only - handle functions outside the store.`;\r\n\r\nexport const getMapSetStoreWarningMessage = (): string =>\r\n `Map/Set detected. stroid converts these to plain objects.\\n` +\r\n `Use arrays or plain objects for best results.`;\r\n\r\nexport const getDateStoreWarningMessage = (): string =>\r\n `Date object detected. stroid stores it as ISO string.\\n` +\r\n `Use new Date(value) to convert back when reading.`;\r\n\r\nexport const getSanitizeDateWarningMessage = (): string =>\r\n \"Date detected; stored as ISO string. Use new Date(value) when reading.\";\r\n\r\nexport const getSanitizeMapWarningMessage = (): string =>\r\n \"Map detected; converting to plain object.\";\r\n\r\nexport const getSanitizeSetWarningMessage = (): string =>\r\n \"Set detected; converting to array.\";\r\n\r\nexport const getPathDepthExceededMessage = (depth: number, maxDepth: number, parts: string[]): string =>\r\n `Path depth of ${depth} exceeded maximum of ${maxDepth}.\\n` +\r\n `\"${parts.join(\".\")}\"\\n` +\r\n `This is a data design issue. Split into separate stores:\\n` +\r\n `createStore(\"${parts[0]}\", ...) and createStore(\"${parts[1]}\", ...)`;\r\n\r\nexport const getDeepNestingWarningMessage = (depth: number, parts: string[]): string =>\r\n `Deep nesting detected (${depth} levels): \"${parts.join(\".\")}\"\\n` +\r\n `Consider splitting into separate stores for better readability.`;\r\n\r\nexport const getPathReachedNullMessage = (parts: string[], part: string): string =>\r\n `Path \"${parts.join(\".\")}\" not found - reached null at \"${part}\"`;\r\n\r\nexport const getPathNotObjectMessage = (part: string): string =>\r\n `Cannot go deeper at \"${part}\" - value is not an object`;\r\n\r\nexport const getInvalidStoreNameMessage = (name: string): string =>\r\n `Store name must be a non-empty string. Got: ${JSON.stringify(name)}`;\r\n\r\nexport const getStoreNameContainsSpacesMessage = (name: string): string =>\r\n `Store name \"${name}\" contains spaces.\\n` +\r\n `Use camelCase or kebab-case: \"userName\" or \"user-name\"`;\r\n\r\nexport const getForbiddenStoreNameMessage = (name: string): string =>\r\n `Store name \"${name}\" is not allowed.\\n` +\r\n `Reserved names: \"__proto__\", \"constructor\", \"prototype\".`;\r\n\r\nconst MAX_LEVENSHTEIN_INPUT_LENGTH = 128;\r\n\r\nconst shouldCheckLevenshtein = (a: string, b: string): boolean => {\r\n if (Math.abs(a.length - b.length) > 2) return false;\r\n return Math.max(a.length, b.length) <= MAX_LEVENSHTEIN_INPUT_LENGTH;\r\n};\r\n\r\nconst levenshtein = (a: string, b: string): number => {\r\n if (a === b) return 0;\r\n if (a.length === 0) return b.length;\r\n if (b.length === 0) return a.length;\r\n\r\n let prev = Array.from({ length: a.length + 1 }, (_, i) => i);\r\n let next = new Array<number>(a.length + 1);\r\n\r\n for (let i = 1; i <= b.length; i++) {\r\n next[0] = i;\r\n for (let j = 1; j <= a.length; j++) {\r\n next[j] =\r\n b[i - 1] === a[j - 1]\r\n ? prev[j - 1]\r\n : Math.min(prev[j - 1], next[j - 1], prev[j]) + 1;\r\n }\r\n [prev, next] = [next, prev];\r\n }\r\n return prev[a.length];\r\n};\r\n\r\nexport const suggestStoreName = (name: string, existingNames: string[]): void => {\r\n const similar = existingNames.find((entry) => {\r\n const a = entry.toLowerCase();\r\n const b = name.toLowerCase();\r\n return (\r\n a.includes(b)\r\n || b.includes(a)\r\n || (shouldCheckLevenshtein(a, b) && levenshtein(a, b) <= 2)\r\n );\r\n });\r\n\r\n if (similar) {\r\n warn(`Store \"${name}\" not found. Did you mean \"${similar}\"?`);\r\n return;\r\n }\r\n\r\n error(\r\n `Store \"${name}\" not found.\\n` +\r\n `Available stores: [${existingNames.join(\", \")}]\\n` +\r\n `Call createStore(\"${name}\", data) first.`\r\n );\r\n};\r\n\r\n\r\n","/**\r\n * @module features/sync\r\n *\r\n * LAYER: Feature runtime\r\n * OWNS: Module-level behavior and exports for features/sync.\r\n *\r\n * Consumers: Internal imports and public API.\r\n */\r\nimport type { StoreValue, SyncMessage, SyncOptions } from \"../adapters/options.js\";\r\nimport { registerStoreFeature, type StoreFeatureRuntime } from \"../feature-registry.js\";\r\nimport { normalizeFeatureState, resolveUpdatedAtMs } from \"./state-helpers.js\";\r\nimport { warnAlways } from \"../utils.js\";\r\n\r\nexport type SyncChannels = Record<string, BroadcastChannel>;\r\nexport type SyncClocks = Record<string, number>;\r\nexport type SyncVersion = { clock: number; updatedAt: number; source: string };\r\nexport type SyncVersions = Record<string, SyncVersion>;\r\nexport type SyncWindowCleanup = Record<string, () => void>;\r\n\r\nlet _registered = false;\r\nconst SYNC_PROTOCOL_VERSION = 1;\r\nconst resolveProtocolVersion = (msg: { v?: unknown; protocol?: unknown }): number | undefined =>\r\n typeof msg?.v === \"number\"\r\n ? msg.v as number\r\n : (typeof msg?.protocol === \"number\" ? msg.protocol as number : undefined);\r\n\r\nconst insecureSyncWarned = new Set<string>();\r\nconst signerVerifyWarned = new Set<string>();\r\n\r\ntype SyncMeta = {\r\n updatedAt: string;\r\n updatedAtMs?: number;\r\n updateCount: number;\r\n options: {\r\n sync?: boolean | SyncOptions;\r\n };\r\n};\r\n\r\nconst byteLength = (value: string): number => {\r\n if (typeof TextEncoder !== \"undefined\") {\r\n return new TextEncoder().encode(value).length;\r\n }\r\n if (typeof Buffer !== \"undefined\") {\r\n return Buffer.byteLength(value);\r\n }\r\n return value.length;\r\n};\r\n\r\nconst compareSyncOrder = ({\r\n incoming,\r\n accepted,\r\n}: {\r\n incoming: { clock?: number; source?: string };\r\n accepted?: SyncVersion;\r\n}): number => {\r\n const localClock = accepted?.clock ?? 0;\r\n const incomingClock = typeof incoming.clock === \"number\" ? incoming.clock : 0;\r\n if (incomingClock !== localClock) return incomingClock - localClock;\r\n\r\n const incomingSource = incoming.source ?? \"\";\r\n const localSource = accepted?.source ?? \"\";\r\n if (incomingSource === localSource) return 0;\r\n return incomingSource.localeCompare(localSource, \"en\", { sensitivity: \"variant\" });\r\n};\r\n\r\nconst resolveMetaUpdatedAtMs = (meta?: SyncMeta): number =>\r\n meta?.updatedAtMs ?? resolveUpdatedAtMs({ value: meta?.updatedAt, fallbackMs: 0 });\r\n\r\nconst isValidSyncMessage = (msg: unknown): msg is {\r\n v?: number;\r\n protocol?: number;\r\n type: string;\r\n name: string;\r\n clock: number;\r\n source: string;\r\n data?: unknown;\r\n updatedAt?: number;\r\n auth?: unknown;\r\n token?: unknown;\r\n requestedAt?: number;\r\n} => {\r\n if (typeof msg !== \"object\" || msg === null) return false;\r\n const m = msg as Record<string, unknown>;\r\n const hasVersion = typeof m.v === \"number\" || typeof m.protocol === \"number\";\r\n return (\r\n hasVersion &&\r\n typeof m.type === \"string\" &&\r\n typeof m.name === \"string\" &&\r\n typeof m.clock === \"number\" &&\r\n typeof m.source === \"string\"\r\n );\r\n};\r\n\r\nconst requestSyncSnapshot = ({\r\n name,\r\n syncChannels,\r\n instanceId,\r\n authToken,\r\n reportStoreError,\r\n}: {\r\n name: string;\r\n syncChannels: SyncChannels;\r\n instanceId: string;\r\n authToken?: string;\r\n reportStoreError: (name: string, message: string) => void;\r\n}): void => {\r\n const channel = syncChannels[name];\r\n if (!channel) return;\r\n try {\r\n const payload: SyncMessage = {\r\n v: SYNC_PROTOCOL_VERSION,\r\n protocol: SYNC_PROTOCOL_VERSION,\r\n type: \"sync-request\",\r\n source: instanceId,\r\n name,\r\n clock: 0,\r\n requestedAt: Date.now(),\r\n };\r\n if (authToken) payload.token = authToken;\r\n channel.postMessage(payload);\r\n } catch (err) {\r\n reportStoreError(name, `Failed to request sync snapshot for \"${name}\": ${(err as { message?: string })?.message ?? err}`);\r\n }\r\n};\r\n\r\nexport const bumpSyncClock = (name: string, syncClocks: SyncClocks): number => {\r\n syncClocks[name] = (syncClocks[name] ?? 0) + 1;\r\n return syncClocks[name];\r\n};\r\n\r\nexport const absorbSyncClock = (\r\n name: string,\r\n incomingClock: number,\r\n syncClocks: SyncClocks\r\n): number => {\r\n syncClocks[name] = Math.max(syncClocks[name] ?? 0, incomingClock) + 1;\r\n return syncClocks[name];\r\n};\r\n\r\nexport const closeSyncResources = ({\r\n name,\r\n syncChannels,\r\n syncWindowCleanup,\r\n syncClocks,\r\n syncVersions,\r\n}: {\r\n name: string;\r\n syncChannels: SyncChannels;\r\n syncWindowCleanup: SyncWindowCleanup;\r\n syncClocks: SyncClocks;\r\n syncVersions: SyncVersions;\r\n}): void => {\r\n syncChannels[name]?.close();\r\n delete syncChannels[name];\r\n syncWindowCleanup[name]?.();\r\n delete syncWindowCleanup[name];\r\n delete syncClocks[name];\r\n delete syncVersions[name];\r\n};\r\n\r\nexport const cleanupAllSyncResources = ({\r\n syncChannels,\r\n syncWindowCleanup,\r\n}: {\r\n syncChannels: SyncChannels;\r\n syncWindowCleanup: SyncWindowCleanup;\r\n}): void => {\r\n Object.values(syncWindowCleanup).forEach((dispose) => {\r\n try { dispose(); } catch (_) { /* ignore cleanup errors */ }\r\n });\r\n Object.values(syncChannels).forEach((channel) => {\r\n try { channel.close(); } catch (_) { /* ignore cleanup errors */ }\r\n });\r\n};\r\n\r\nexport const setupSync = ({\r\n name,\r\n syncOption,\r\n syncChannels,\r\n syncClocks,\r\n syncVersions,\r\n syncWindowCleanup,\r\n instanceId,\r\n getMeta,\r\n getAcceptedSyncVersion,\r\n getStoreValue,\r\n hasStoreEntry,\r\n notify,\r\n validate,\r\n reportStoreError,\r\n warn,\r\n setStoreValue,\r\n normalizeIncomingState,\r\n acceptIncomingSyncVersion,\r\n resolveSyncVersion,\r\n broadcastSync,\r\n}: {\r\n name: string;\r\n syncOption?: boolean | SyncOptions;\r\n syncChannels: SyncChannels;\r\n syncClocks: SyncClocks;\r\n syncVersions: SyncVersions;\r\n syncWindowCleanup: SyncWindowCleanup;\r\n instanceId: string;\r\n getMeta: (name: string) => SyncMeta | undefined;\r\n getAcceptedSyncVersion: (name: string) => SyncVersion | undefined;\r\n getStoreValue: (name: string) => StoreValue;\r\n hasStoreEntry: (name: string) => boolean;\r\n notify: (name: string) => void;\r\n validate: (name: string, next: StoreValue) => { ok: boolean; value?: StoreValue };\r\n reportStoreError: (name: string, message: string) => void;\r\n warn: (message: string) => void;\r\n setStoreValue: (name: string, value: StoreValue) => void;\r\n normalizeIncomingState: (name: string, value: StoreValue) => StoreValue | null;\r\n acceptIncomingSyncVersion: (name: string, updatedAtMs: number, incomingClock: number, source: string) => void;\r\n resolveSyncVersion: (name: string, updatedAtMs: number, incomingClock: number) => number;\r\n broadcastSync: (name: string) => void;\r\n}): void => {\r\n if (!syncOption) return;\r\n if (typeof window === \"undefined\" || typeof BroadcastChannel === \"undefined\") {\r\n reportStoreError(name, `Sync enabled for \"${name}\" but BroadcastChannel not available in this environment.`);\r\n return;\r\n }\r\n const hasAuthToken = typeof syncOption === \"object\"\r\n && typeof syncOption.authToken === \"string\"\r\n && syncOption.authToken.length > 0;\r\n const hasVerify = typeof syncOption === \"object\" && typeof syncOption.verify === \"function\";\r\n const hasSign = typeof syncOption === \"object\" && typeof syncOption.sign === \"function\";\r\n\r\n if (!hasAuthToken && !hasVerify && !insecureSyncWarned.has(name)) {\r\n insecureSyncWarned.add(name);\r\n warnAlways(\r\n `Sync for \"${name}\" is unauthenticated. Any same-origin tab can forge sync messages. ` +\r\n `Provide sync.authToken or sync.verify to enforce authentication.`\r\n );\r\n }\r\n\r\n if (hasSign && !hasVerify && !signerVerifyWarned.has(name)) {\r\n signerVerifyWarned.add(name);\r\n warn(\r\n `Sync for \"${name}\" is configured with \"sign\" but no \"verify\". ` +\r\n `\"sign\" has no effect unless incoming messages are verified.`\r\n );\r\n }\r\n const expectedToken = typeof syncOption === \"object\" ? syncOption.authToken : undefined;\r\n let tokenWarned = false;\r\n const channelName = typeof syncOption === \"object\" && syncOption.channel\r\n ? syncOption.channel\r\n : `stroid_sync_${name}`;\r\n try {\r\n const channel = new BroadcastChannel(channelName);\r\n syncChannels[name] = channel;\r\n channel.onmessage = (event: MessageEvent) => {\r\n const msg = event.data as any;\r\n if (!msg || msg.source === instanceId) return;\r\n if (msg.name !== name) return;\r\n if (syncChannels[name] !== channel || !hasStoreEntry(name) || !getMeta(name)) return;\r\n if (!isValidSyncMessage(msg)) {\r\n reportStoreError(name, `Sync message for \"${name}\" is malformed; ignoring.`);\r\n return;\r\n }\r\n if (expectedToken && msg.token !== expectedToken) {\r\n if (!tokenWarned) {\r\n reportStoreError(name, `Sync message for \"${name}\" failed auth token verification; ignoring.`);\r\n tokenWarned = true;\r\n }\r\n return;\r\n }\r\n const incomingVersion = resolveProtocolVersion(msg);\r\n if (incomingVersion !== SYNC_PROTOCOL_VERSION) {\r\n reportStoreError(name, `Sync protocol mismatch for \"${name}\". Expected v${SYNC_PROTOCOL_VERSION} but received ${String(incomingVersion ?? \"unknown\")}. Ignoring message.`);\r\n return;\r\n }\r\n const isSyncState = msg.type === \"sync-state\";\r\n if (isSyncState && (typeof msg.data === \"undefined\" || typeof msg.clock !== \"number\")) {\r\n reportStoreError(name, `Sync message for \"${name}\" is malformed; ignoring.`);\r\n return;\r\n }\r\n if (typeof syncOption === \"object\" && typeof syncOption.verify === \"function\") {\r\n let verified = false;\r\n try {\r\n verified = !!syncOption.verify(msg as SyncMessage);\r\n } catch (err) {\r\n reportStoreError(\r\n name,\r\n `Sync message verification failed for \"${name}\": ${(err as { message?: string })?.message ?? err}`\r\n );\r\n return;\r\n }\r\n if (!verified) {\r\n reportStoreError(name, `Sync message for \"${name}\" failed verification; ignoring.`);\r\n return;\r\n }\r\n }\r\n if (msg.type === \"sync-request\") {\r\n broadcastSync(name);\r\n return;\r\n }\r\n const resolver = typeof syncOption === \"object\" ? syncOption.conflictResolver : null;\r\n const order = compareSyncOrder({\r\n incoming: {\r\n clock: msg.clock,\r\n source: msg.source,\r\n },\r\n accepted: getAcceptedSyncVersion(name),\r\n });\r\n if (order <= 0) {\r\n const localUpdated = resolveMetaUpdatedAtMs(getMeta(name));\r\n const incomingUpdated = typeof msg.updatedAt === \"number\" ? msg.updatedAt : Date.now();\r\n if (resolver) {\r\n const resolved = resolver({\r\n local: getStoreValue(name),\r\n incoming: msg.data,\r\n localUpdated,\r\n incomingUpdated,\r\n });\r\n if (resolved !== undefined) {\r\n const normalizedResolved = normalizeIncomingState(name, resolved);\r\n if (normalizedResolved === null) return;\r\n setStoreValue(name, normalizedResolved);\r\n const resolveUpdatedAt = typeof syncOption === \"object\" ? syncOption.resolveUpdatedAt : null;\r\n const resolvedUpdatedAt = resolveUpdatedAt\r\n ? resolveUpdatedAt({ localUpdated, incomingUpdated, now: Date.now() })\r\n : Math.max(Date.now(), localUpdated, incomingUpdated);\r\n resolveSyncVersion(name, resolvedUpdatedAt, typeof msg.clock === \"number\" ? msg.clock : 0);\r\n notify(name);\r\n broadcastSync(name);\r\n }\r\n }\r\n return;\r\n }\r\n const normalizedIncoming = normalizeIncomingState(name, msg.data);\r\n if (normalizedIncoming === null) return;\r\n setStoreValue(name, normalizedIncoming);\r\n acceptIncomingSyncVersion(\r\n name,\r\n typeof msg.updatedAt === \"number\" ? msg.updatedAt : Date.now(),\r\n typeof msg.clock === \"number\" ? msg.clock : 0,\r\n typeof msg.source === \"string\" ? msg.source : \"\"\r\n );\r\n notify(name);\r\n };\r\n\r\n if (typeof window !== \"undefined\" && typeof window.addEventListener === \"function\") {\r\n syncWindowCleanup[name]?.();\r\n const hostWindow = window;\r\n const requestLatest = () => {\r\n requestSyncSnapshot({\r\n name,\r\n syncChannels,\r\n instanceId,\r\n authToken: expectedToken,\r\n reportStoreError,\r\n });\r\n };\r\n hostWindow.addEventListener(\"focus\", requestLatest);\r\n hostWindow.addEventListener(\"online\", requestLatest);\r\n syncWindowCleanup[name] = () => {\r\n hostWindow.removeEventListener(\"focus\", requestLatest);\r\n hostWindow.removeEventListener(\"online\", requestLatest);\r\n };\r\n }\r\n\r\n queueMicrotask(() => {\r\n requestSyncSnapshot({\r\n name,\r\n syncChannels,\r\n instanceId,\r\n authToken: expectedToken,\r\n reportStoreError,\r\n });\r\n });\r\n } catch (e) {\r\n warn(`Failed to setup sync for \"${name}\": ${(e as { message?: string })?.message || e}`);\r\n }\r\n};\r\n\r\nexport const broadcastSync = ({\r\n name,\r\n syncOption,\r\n syncChannels,\r\n syncClocks,\r\n instanceId,\r\n updatedAt,\r\n data,\r\n hashState,\r\n reportStoreError,\r\n}: {\r\n name: string;\r\n syncOption?: boolean | SyncOptions;\r\n syncChannels: SyncChannels;\r\n syncClocks: SyncClocks;\r\n instanceId: string;\r\n updatedAt: string | number;\r\n data: StoreValue;\r\n hashState: (value: unknown) => number;\r\n reportStoreError: (name: string, message: string) => void;\r\n}): void => {\r\n const channel = syncChannels[name];\r\n if (!channel) return;\r\n try {\r\n const checksumMode = typeof syncOption === \"object\" && syncOption.checksum === \"none\" ? \"none\" : \"hash\";\r\n const payload: SyncMessage = {\r\n v: SYNC_PROTOCOL_VERSION,\r\n protocol: SYNC_PROTOCOL_VERSION,\r\n type: \"sync-state\",\r\n source: instanceId,\r\n name,\r\n clock: syncClocks[name] ?? 0,\r\n updatedAt: resolveUpdatedAtMs({ value: updatedAt, fallbackMs: Date.now() }),\r\n data,\r\n checksum: checksumMode === \"hash\" ? hashState(data) : null,\r\n };\r\n if (typeof syncOption === \"object\" && syncOption.authToken) {\r\n payload.token = syncOption.authToken;\r\n }\r\n if (typeof syncOption === \"object\" && typeof syncOption.sign === \"function\") {\r\n try {\r\n const auth = syncOption.sign(payload);\r\n if (auth && typeof (auth as { then?: unknown }).then === \"function\") {\r\n reportStoreError(\r\n name,\r\n `Sync signer for \"${name}\" returned a Promise. \"sign\" must be synchronous.`\r\n );\r\n return;\r\n }\r\n if (auth !== undefined) payload.auth = auth;\r\n } catch (err) {\r\n reportStoreError(\r\n name,\r\n `Failed to sign sync payload for \"${name}\": ${(err as { message?: string })?.message ?? err}`\r\n );\r\n return;\r\n }\r\n }\r\n const maxPayloadBytes = typeof syncOption === \"object\" && typeof syncOption.maxPayloadBytes === \"number\"\r\n ? syncOption.maxPayloadBytes\r\n : 64 * 1024;\r\n const payloadSize = byteLength(JSON.stringify(payload));\r\n\r\n if (payloadSize > maxPayloadBytes) {\r\n reportStoreError(\r\n name,\r\n `Sync payload for \"${name}\" exceeds ${maxPayloadBytes} bytes (${payloadSize} bytes). Skipping BroadcastChannel sync.`\r\n );\r\n return;\r\n }\r\n\r\n channel.postMessage(payload);\r\n } catch (err) {\r\n reportStoreError(name, `Failed to broadcast sync for \"${name}\": ${(err as { message?: string })?.message ?? err}`);\r\n }\r\n};\r\n\r\nexport const createSyncFeatureRuntime = (): StoreFeatureRuntime => {\r\n const syncChannels: SyncChannels = Object.create(null);\r\n const syncClocks: SyncClocks = Object.create(null);\r\n const syncVersions: SyncVersions = Object.create(null);\r\n const syncWindowCleanup: SyncWindowCleanup = Object.create(null);\r\n const instanceId = `stroid_${Math.random().toString(16).slice(2)}`;\r\n\r\n const recordLocalVersion = (name: string, updatedAt: string | number): void => {\r\n syncVersions[name] = {\r\n clock: syncClocks[name] ?? 0,\r\n updatedAt: resolveUpdatedAtMs({ value: updatedAt, fallbackMs: Date.now() }),\r\n source: instanceId,\r\n };\r\n };\r\n\r\n const ensureLocalClock = (name: string, updatedAt: string | number): void => {\r\n bumpSyncClock(name, syncClocks);\r\n recordLocalVersion(name, updatedAt);\r\n };\r\n\r\n return {\r\n onStoreCreate(ctx) {\r\n if (!ctx.options.sync) return;\r\n\r\n setupSync({\r\n name: ctx.name,\r\n syncOption: ctx.options.sync,\r\n syncChannels,\r\n syncClocks,\r\n syncVersions,\r\n syncWindowCleanup,\r\n instanceId,\r\n getMeta: ctx.getMeta,\r\n getAcceptedSyncVersion: (name) => syncVersions[name],\r\n getStoreValue: (name) => ctx.getStoreValue(),\r\n hasStoreEntry: () => ctx.hasStore(),\r\n notify: () => ctx.notify(),\r\n validate: (name, next) => ctx.validate(next),\r\n reportStoreError: (name, message) => ctx.reportStoreError(message),\r\n warn: ctx.warn,\r\n setStoreValue: (name, value) => ctx.setStoreValue(value),\r\n normalizeIncomingState: (name, value) => {\r\n const normalized = normalizeFeatureState({\r\n value,\r\n sanitize: ctx.sanitize,\r\n validate: ctx.validate,\r\n onSanitizeError: (err) => {\r\n ctx.reportStoreError(\r\n `Sanitize failed for incoming sync \"${name}\": ${(err as { message?: string })?.message ?? err}`\r\n );\r\n },\r\n });\r\n if (!normalized.ok) return null;\r\n return normalized.value;\r\n },\r\n acceptIncomingSyncVersion: (name, updatedAtMs, incomingClock, source) => {\r\n ctx.applyFeatureState(ctx.getStoreValue(), updatedAtMs);\r\n syncClocks[ctx.name] = Math.max(syncClocks[ctx.name] ?? 0, incomingClock);\r\n syncVersions[ctx.name] = {\r\n clock: incomingClock,\r\n updatedAt: updatedAtMs,\r\n source,\r\n };\r\n },\r\n resolveSyncVersion: (name, updatedAtMs, incomingClock) => {\r\n ctx.applyFeatureState(ctx.getStoreValue(), updatedAtMs);\r\n const resolvedClock = absorbSyncClock(ctx.name, incomingClock, syncClocks);\r\n syncVersions[ctx.name] = {\r\n clock: resolvedClock,\r\n updatedAt: updatedAtMs,\r\n source: instanceId,\r\n };\r\n return resolvedClock;\r\n },\r\n broadcastSync: () => {\r\n const meta = ctx.getMeta();\r\n if (!meta) return;\r\n broadcastSync({\r\n name: ctx.name,\r\n syncOption: ctx.options.sync,\r\n syncChannels,\r\n syncClocks,\r\n instanceId,\r\n updatedAt: meta.updatedAtMs ?? meta.updatedAt,\r\n data: ctx.getStoreValue(),\r\n hashState: ctx.hashState,\r\n reportStoreError: (name, message) => ctx.reportStoreError(message),\r\n });\r\n },\r\n });\r\n\r\n if (syncChannels[ctx.name]) {\r\n const meta = ctx.getMeta();\r\n recordLocalVersion(ctx.name, meta?.updatedAtMs ?? meta?.updatedAt ?? new Date().toISOString());\r\n }\r\n },\r\n\r\n onStoreWrite(ctx) {\r\n if (!ctx.options.sync) return;\r\n const meta = ctx.getMeta();\r\n if (!meta) return;\r\n ensureLocalClock(ctx.name, meta.updatedAtMs ?? meta.updatedAt);\r\n broadcastSync({\r\n name: ctx.name,\r\n syncOption: ctx.options.sync,\r\n syncChannels,\r\n syncClocks,\r\n instanceId,\r\n updatedAt: meta.updatedAtMs ?? meta.updatedAt,\r\n data: ctx.next,\r\n hashState: ctx.hashState,\r\n reportStoreError: (name, message) => ctx.reportStoreError(message),\r\n });\r\n },\r\n\r\n beforeStoreDelete(ctx) {\r\n closeSyncResources({\r\n name: ctx.name,\r\n syncChannels,\r\n syncWindowCleanup,\r\n syncClocks,\r\n syncVersions,\r\n });\r\n },\r\n\r\n resetAll() {\r\n cleanupAllSyncResources({\r\n syncChannels,\r\n syncWindowCleanup,\r\n });\r\n Object.keys(syncChannels).forEach((key) => delete syncChannels[key]);\r\n Object.keys(syncClocks).forEach((key) => delete syncClocks[key]);\r\n Object.keys(syncVersions).forEach((key) => delete syncVersions[key]);\r\n Object.keys(syncWindowCleanup).forEach((key) => delete syncWindowCleanup[key]);\r\n insecureSyncWarned.clear();\r\n signerVerifyWarned.clear();\r\n },\r\n };\r\n};\r\n\r\nexport const registerSyncFeature = (): void => {\r\n if (_registered) return;\r\n _registered = true;\r\n registerStoreFeature(\"sync\", createSyncFeatureRuntime);\r\n};\r\n\r\n\r\n","/**\r\n * @module install\r\n *\r\n * LAYER: Module\r\n * OWNS: Module-level behavior and exports for install.\r\n *\r\n * Consumers: Internal imports and public API.\r\n */\r\nimport { registerPersistFeature } from \"./features/persist.js\";\r\nimport { registerSyncFeature } from \"./features/sync.js\";\r\nimport { registerDevtoolsFeature } from \"./features/devtools.js\";\r\n\r\nexport const installPersist = (): void => {\r\n registerPersistFeature();\r\n};\r\n\r\nexport const installSync = (): void => {\r\n registerSyncFeature();\r\n};\r\n\r\nexport const installDevtools = (): void => {\r\n registerDevtoolsFeature();\r\n};\r\n\r\nexport const installAllFeatures = (): void => {\r\n installPersist();\r\n installSync();\r\n installDevtools();\r\n};\r\n\r\n\r\n","/**\r\n * @module sync\r\n *\r\n * LAYER: Public API\r\n * OWNS: Module-level behavior and exports for sync.\r\n *\r\n * Consumers: Internal imports and public API.\r\n */\r\nimport { installSync } from \"./install.js\";\r\n\r\ninstallSync();\r\n\r\nexport { installSync };\r\n\r\n\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/features/feature-registry.ts","../src/features/state-helpers.ts","../src/internals/test-reset.ts","../src/async/registry.ts","../src/core/store-registry.ts","../src/internals/config.ts","../src/internals/diagnostics.ts","../src/features/sync.ts","../src/install.ts","../src/sync.ts"],"names":["_featureFactories","registerStoreFeature","name","factory","getStoreFeatureFactory","getRegisteredFeatureNames","normalizeFeatureState","value","sanitize","validate","onSanitizeError","candidate","err","validation","resolveUpdatedAtMs","fallbackMs","onInvalid","parsed","_resetHooks","registerTestResetHook","fn","order","createWarnedOnce","createAsyncRegistry","_registries","initializedRegistries","initializeRegistryFeatureRuntimes","registry","_registryOverrideEnv","_registryOverrideRuntime","normalizeStoreRegistryScope","scope","defaultRegistryScope","clearRegistryScopeOverrideForTests","createNotifyState","createTransactionState","createStoreRegistry","getStoreRegistry","normalizedScope","existing","created","fallbackRegistryStack","fallbackRegistryRunner","getActiveStoreRegistry","fallback","defaultLogSink","msg","meta","defaultConfig","cloneConfig","base","configByRegistry","baseConfig","getRegistryConfig","config","getConfig","resetConfig","_envFromProcess","_envFromImportMeta","_devFlag","_fallbackEnv","_resolvedEnv","__DEV__","isDev","defaultWarn","warnAlways","_registered","SYNC_PROTOCOL_VERSION","resolveProtocolVersion","insecureSyncWarned","signerVerifyWarned","DEFAULT_LOOP_GUARD_MS","resolveLoopGuardMs","syncOption","guard","ms","byteLength","compareSyncOrder","incoming","accepted","localClock","incomingClock","incomingSource","localSource","resolveMetaUpdatedAtMs","isValidSyncMessage","m","requestSyncSnapshot","syncChannels","instanceId","authToken","reportStoreError","channel","payload","bumpSyncClock","syncClocks","absorbSyncClock","closeSyncResources","syncWindowCleanup","syncVersions","cleanupAllSyncResources","dispose","setupSync","getMeta","getAcceptedSyncVersion","getStoreValue","hasStoreEntry","notify","warn","setStoreValue","normalizeIncomingState","acceptIncomingSyncVersion","resolveSyncVersion","broadcastSync","markLoopGuard","policy","allowInsecure","hasAuthToken","hasVerify","hasSign","strictPolicy","expectedToken","loopGuardMs","tokenWarned","channelName","event","incomingVersion","verified","resolver","localUpdated","incomingUpdated","resolved","normalizedResolved","resolveUpdatedAt","resolvedUpdatedAt","normalizedIncoming","hostWindow","requestLatest","e","updatedAt","data","hashState","checksumMode","auth","maxPayloadBytes","payloadSize","createSyncFeatureRuntime","loopGuardUntil","loopGuardWarned","recordLocalVersion","ensureLocalClock","windowMs","shouldSuppressBroadcast","until","ctx","next","message","normalized","updatedAtMs","source","resolvedClock","key","registerSyncFeature","installSync"],"mappings":"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","file":"sync.js","sourcesContent":["/**\r\n * @module feature-registry\r\n *\r\n * LAYER: Module\r\n * OWNS: Module-level behavior and exports for feature-registry.\r\n *\r\n * Consumers: Internal imports and public API.\r\n */\r\nimport type { NormalizedOptions, StoreValue } from \"../adapters/options.js\";\nimport type { TraceContext } from \"../types/utility.js\";\n\r\nexport type BuiltInFeatureName = \"persist\" | \"sync\" | \"devtools\";\r\nexport type FeatureName = BuiltInFeatureName | (string & {});\r\n\r\nexport interface FeatureMetrics {\n notifyCount: number;\n totalNotifyMs: number;\n lastNotifyMs: number;\n resetCount: number;\n totalResetMs: number;\n lastResetMs: number;\n}\n\r\nexport interface StoreFeatureMeta {\n createdAt: string;\n updatedAt: string;\n updatedAtMs: number;\n updateCount: number;\n version: number;\n metrics: FeatureMetrics;\n options: NormalizedOptions;\n readCount: number;\n lastReadAt: string | null;\n lastReadAtMs: number | null;\n lastCorrelationId: string | null;\n lastCorrelationAt: string | null;\n lastCorrelationAtMs: number | null;\n lastTraceContext: TraceContext | null;\n}\n\r\nexport interface FeatureHookContext {\n name: string;\n options: NormalizedOptions;\n getMeta: () => StoreFeatureMeta | undefined;\n getStoreValue: () => StoreValue;\n getAllStores: () => Record<string, StoreValue>;\n getInitialState: () => StoreValue;\n hasStore: () => boolean;\n setStoreValue: (value: StoreValue) => void;\n applyFeatureState: (value: StoreValue, updatedAtMs?: number) => void;\n notify: () => void;\n reportStoreError: (message: string) => void;\n warn: (message: string) => void;\n warnAlways: (message: string) => void;\n log: (message: string) => void;\n hashState: (value: unknown) => number;\n deepClone: <T>(value: T) => T;\n sanitize: (value: unknown) => unknown;\n validate: (next: StoreValue) => { ok: boolean; value?: StoreValue };\n isDev: () => boolean;\n}\n\n/** @deprecated Use FeatureHookContext instead. */\nexport type BaseFeatureContext = FeatureHookContext;\n\nexport type FeatureCreateContext<Ext extends object = {}> = FeatureHookContext & Ext;\n\nexport type FeatureWriteContext<Ext extends object = {}> = FeatureHookContext & Ext & {\n action: string;\n prev: StoreValue;\n next: StoreValue;\n};\n\nexport type FeatureDeleteContext<Ext extends object = {}> = FeatureHookContext & Ext & {\n prev: StoreValue;\n};\n\r\nexport interface DevtoolsFeatureApi {\r\n getHistory?: (name: string, limit?: number) => unknown[];\r\n clearHistory?: (name?: string) => void;\r\n getPersistQueueDepth?: (name: string) => number;\r\n}\r\n\r\nexport interface StoreFeatureRuntime<Ext extends object = {}> {\n onStoreCreate?: (ctx: FeatureCreateContext<Ext>) => void;\n onStoreWrite?: (ctx: FeatureWriteContext<Ext>) => void;\n beforeStoreDelete?: (ctx: FeatureDeleteContext<Ext>) => void;\n afterStoreDelete?: (ctx: FeatureDeleteContext<Ext>) => void;\n resetAll?: () => void;\n api?: DevtoolsFeatureApi;\n}\n\nexport type StoreFeatureFactory<Ext extends object = {}> = () => StoreFeatureRuntime<Ext>;\n\r\nconst _featureFactories = new Map<FeatureName, StoreFeatureFactory<any>>();\nlet _onFeatureRegistered: ((name: FeatureName, factory: StoreFeatureFactory<any>) => void) | null = null;\n\r\nexport const registerStoreFeature = <Ext extends object = {}>(\n name: FeatureName,\n factory: StoreFeatureFactory<Ext>\n): void => {\n _featureFactories.set(name, factory as StoreFeatureFactory<any>);\n _onFeatureRegistered?.(name, factory as StoreFeatureFactory<any>);\n};\n\r\nexport const hasRegisteredStoreFeature = (name: FeatureName): boolean =>\r\n _featureFactories.has(name);\r\n\r\nexport const getStoreFeatureFactory = (name: FeatureName): StoreFeatureFactory<any> | undefined =>\n _featureFactories.get(name);\n\r\nexport const getRegisteredFeatureNames = (): FeatureName[] =>\r\n Array.from(_featureFactories.keys());\r\n\r\nexport const setFeatureRegistrationHook = (hook: ((name: FeatureName, factory: StoreFeatureFactory<any>) => void) | null): void => {\n _onFeatureRegistered = hook;\n};\n\r\nexport const resetRegisteredStoreFeaturesForTests = (): void => {\r\n _featureFactories.clear();\r\n _onFeatureRegistered = null;\r\n};\r\n\r\n\r\n","/**\r\n * @module features/state-helpers\r\n *\r\n * LAYER: Feature runtime\r\n * OWNS: Module-level behavior and exports for features/state-helpers.\r\n *\r\n * Consumers: Internal imports and public API.\r\n */\r\nimport type { StoreValue } from \"../adapters/options.js\";\r\n\r\nexport type FeatureValidation = (next: StoreValue) => { ok: boolean; value?: StoreValue };\r\n\r\nexport type NormalizedFeatureState =\r\n | { ok: true; value: StoreValue }\r\n | { ok: false };\r\n\r\nexport const normalizeFeatureState = ({\r\n value,\r\n sanitize,\r\n validate,\r\n onSanitizeError,\r\n}: {\r\n value: unknown;\r\n sanitize?: (value: unknown) => unknown;\r\n validate: FeatureValidation;\r\n onSanitizeError?: (error: unknown) => void;\r\n}): NormalizedFeatureState => {\r\n let candidate: StoreValue;\r\n if (sanitize) {\r\n try {\r\n candidate = sanitize(value) as StoreValue;\r\n } catch (err) {\r\n onSanitizeError?.(err);\r\n return { ok: false };\r\n }\r\n } else {\r\n candidate = value as StoreValue;\r\n }\r\n\r\n const validation = validate(candidate);\r\n if (!validation.ok) return { ok: false };\r\n return { ok: true, value: validation.value ?? candidate };\r\n};\r\n\r\nexport const resolveUpdatedAtMs = ({\r\n value,\r\n fallbackMs = Date.now(),\r\n onInvalid,\r\n}: {\r\n value: unknown;\r\n fallbackMs?: number;\r\n onInvalid?: () => void;\r\n}): number => {\r\n if (typeof value === \"number\") {\r\n if (Number.isFinite(value)) return value;\r\n onInvalid?.();\r\n return fallbackMs;\r\n }\r\n if (typeof value === \"string\") {\r\n const parsed = Date.parse(value);\r\n if (Number.isFinite(parsed)) return parsed;\r\n onInvalid?.();\r\n return fallbackMs;\r\n }\r\n onInvalid?.();\r\n return fallbackMs;\r\n};\r\n\r\n\r\n","/**\r\n * @module internals/test-reset\r\n *\r\n * LAYER: Internal subsystem\r\n * OWNS: Module-level behavior and exports for internals/test-reset.\r\n *\r\n * Consumers: Internal imports and public API.\r\n */\r\ntype TestResetHook = {\r\n name: string;\r\n order: number;\r\n fn: () => void;\r\n};\r\n\r\nconst _resetHooks = new Map<string, TestResetHook>();\r\n\r\nexport const registerTestResetHook = (name: string, fn: () => void, order = 0): void => {\r\n if (!name || typeof fn !== \"function\") return;\r\n _resetHooks.set(name, { name, order, fn });\r\n};\r\n\r\nexport const runTestResets = (): void => {\r\n const ordered = Array.from(_resetHooks.values()).sort((a, b) => {\r\n if (a.order !== b.order) return a.order - b.order;\r\n return a.name.localeCompare(b.name, \"en\");\r\n });\r\n ordered.forEach((hook) => hook.fn());\r\n};\r\n\r\n\r\n","/**\n * @module async-registry\n *\r\n * LAYER: Module\r\n * OWNS: Module-level behavior and exports for async-registry.\r\n *\r\n * Consumers: Internal imports and public API.\n */\nimport type { TraceContext } from \"../types/utility.js\";\nexport type AsyncStateSnapshot = {\n data?: unknown;\n loading: boolean;\n error: string | null;\n status: \"idle\" | \"loading\" | \"success\" | \"error\" | \"aborted\";\n cached?: boolean;\n revalidating?: boolean;\n correlationId?: string;\n traceContext?: TraceContext;\n};\n\r\nexport type AsyncStateAdapter = (ctx: {\n name: string;\n prev: unknown;\n next: AsyncStateSnapshot;\n set: (value: unknown | ((draft: any) => void)) => void;\n}) => void;\n\nexport type WarnCategory = \"noSignal\" | \"shape\" | \"autoCreate\" | \"mutableResult\";\nexport type StoreCleanupKind = \"store\" | \"revalidate\";\nexport type StoreCleanupBucket = Partial<Record<StoreCleanupKind, Set<() => void>>>;\n\r\nexport interface FetchOptions {\n transform?: (result: unknown) => unknown;\r\n onSuccess?: (data: unknown) => void;\r\n onError?: (message: string) => void;\r\n /**\r\n * Optional adapter to write async state into a custom store shape.\r\n * When provided, default AsyncState writes are skipped.\r\n */\r\n stateAdapter?: AsyncStateAdapter;\r\n method?: string;\r\n headers?: Record<string, string>;\r\n body?: unknown;\r\n ttl?: number;\r\n staleWhileRevalidate?: boolean;\r\n dedupe?: boolean;\r\n retry?: number;\r\n retryDelay?: number;\r\n retryBackoff?: number;\r\n signal?: AbortSignal;\r\n cacheKey?: string;\n responseType?: \"auto\" | \"json\" | \"text\" | \"arrayBuffer\" | \"blob\" | \"formData\";\n /**\n * Optional correlation ID for tracing async writes.\n * When provided, it is propagated into store metadata and middleware context.\n */\n correlationId?: string;\n /**\n * Optional trace context (e.g. OpenTelemetry).\n */\n traceContext?: TraceContext;\n /**\r\n * Auto-create the backing store if missing.\r\n * Defaults to the global config setting (true by default).\r\n */\r\n autoCreate?: boolean;\r\n /**\r\n * Clone strategy for transformed results.\r\n * - \"none\" (default): store by reference.\r\n * - \"shallow\": shallow clone objects/arrays.\r\n * - \"deep\": deep clone objects/arrays.\r\n */\r\n cloneResult?: \"none\" | \"shallow\" | \"deep\";\r\n}\r\n\r\ntype InflightEntry = { promise: Promise<unknown>; raw: Promise<unknown>; transform?: FetchOptions[\"transform\"] };\r\n\r\nexport type AsyncRegistry = {\n fetchRegistry: Record<string, { kind: \"url\"; url: string; options: FetchOptions } | { kind: \"factory\"; factory: () => string | Promise<unknown>; options: FetchOptions }>;\n inflight: Partial<Record<string, InflightEntry>>;\n requestVersion: Record<string, number>;\n cacheMeta: Record<string, { timestamp: number; expiresAt: number | null; data: unknown }>;\n rateWindowStart: Record<string, number>;\n rateCount: Record<string, number>;\n ratePruneState: { lastAt: number };\n ratePruneTimer: ReturnType<typeof setTimeout> | null;\n warnedOnce: Map<WarnCategory, Set<string>>;\n storeCleanups: Record<string, StoreCleanupBucket>;\n revalidateKeys: Set<string>;\n revalidateHandlers: Record<string, () => void>;\n asyncMetrics: {\n cacheHits: number;\n cacheMisses: number;\n dedupes: number;\n requests: number;\r\n failures: number;\r\n avgMs: number;\r\n lastMs: number;\r\n };\r\n};\n\nconst createWarnedOnce = (): Map<WarnCategory, Set<string>> => new Map([\n [\"noSignal\", new Set<string>()],\n [\"shape\", new Set<string>()],\n [\"autoCreate\", new Set<string>()],\n [\"mutableResult\", new Set<string>()],\n]);\n\nexport const createAsyncRegistry = (): AsyncRegistry => ({\n fetchRegistry: Object.create(null),\n inflight: Object.create(null),\n requestVersion: Object.create(null),\n cacheMeta: Object.create(null),\n rateWindowStart: Object.create(null),\n rateCount: Object.create(null),\n ratePruneState: { lastAt: 0 },\n ratePruneTimer: null,\n warnedOnce: createWarnedOnce(),\n storeCleanups: Object.create(null),\n revalidateKeys: new Set<string>(),\n revalidateHandlers: Object.create(null),\n asyncMetrics: {\n cacheHits: 0,\n cacheMisses: 0,\n dedupes: 0,\r\n requests: 0,\r\n failures: 0,\r\n avgMs: 0,\r\n lastMs: 0,\r\n },\r\n});\r\n\r\nexport const resetAsyncRegistry = (registry: AsyncRegistry): void => {\n Object.values(registry.storeCleanups).forEach((bucket) => {\n Object.values(bucket).forEach((set) => {\n set?.forEach((fn) => {\n try { fn(); } catch (_) { /* ignore cleanup errors */ }\n });\n });\n });\n\r\n Object.keys(registry.fetchRegistry).forEach((key) => delete registry.fetchRegistry[key]);\r\n Object.keys(registry.inflight).forEach((key) => delete registry.inflight[key]);\n Object.keys(registry.requestVersion).forEach((key) => delete registry.requestVersion[key]);\n Object.keys(registry.cacheMeta).forEach((key) => delete registry.cacheMeta[key]);\n Object.keys(registry.rateWindowStart).forEach((key) => delete registry.rateWindowStart[key]);\n Object.keys(registry.rateCount).forEach((key) => delete registry.rateCount[key]);\n Object.keys(registry.storeCleanups).forEach((key) => delete registry.storeCleanups[key]);\n Object.keys(registry.revalidateHandlers).forEach((key) => delete registry.revalidateHandlers[key]);\n\n registry.revalidateKeys.clear();\n registry.warnedOnce.forEach((set) => set.clear());\n registry.warnedOnce.clear();\n createWarnedOnce().forEach((set, key) => {\n registry.warnedOnce.set(key, set);\n });\n registry.ratePruneState.lastAt = 0;\r\n if (registry.ratePruneTimer) {\r\n clearTimeout(registry.ratePruneTimer);\r\n registry.ratePruneTimer = null;\r\n }\r\n\r\n registry.asyncMetrics.cacheHits = 0;\r\n registry.asyncMetrics.cacheMisses = 0;\r\n registry.asyncMetrics.dedupes = 0;\r\n registry.asyncMetrics.requests = 0;\r\n registry.asyncMetrics.failures = 0;\r\n registry.asyncMetrics.avgMs = 0;\r\n registry.asyncMetrics.lastMs = 0;\r\n};\r\n\r\n\r\n","/**\r\n * @module store-registry\r\n *\r\n * LAYER: Store runtime\r\n * OWNS: Module-level behavior and exports for store-registry.\r\n *\r\n * Consumers: Internal imports and public API.\r\n */\r\nimport {\n getRegisteredFeatureNames,\n getStoreFeatureFactory,\n type FeatureName,\n type StoreFeatureMeta,\n type StoreFeatureRuntime,\n} from \"../features/feature-registry.js\";\nimport type { AsyncRegistry } from \"../async/registry.js\";\nimport { createAsyncRegistry, resetAsyncRegistry } from \"../async/registry.js\";\nimport { registerTestResetHook } from \"../internals/test-reset.js\";\n\r\nexport type RegistryStoreValue = unknown;\r\nexport type RegistrySubscriber = (value: RegistryStoreValue | null) => void;\r\nexport type RegistrySnapshotEntry = {\n version: number;\n snapshot: RegistryStoreValue | null;\n source?: RegistryStoreValue | null;\n mode?: \"deep\" | \"shallow\" | \"ref\";\n};\n\nexport type StoreLifecycleEvent =\n | { type: \"created\"; name: string; isGlobal: boolean; isTemp: boolean }\n | { type: \"deleted\"; name: string };\n\nexport type StoreLifecycleListener = (event: StoreLifecycleEvent) => void;\n\nexport type TransactionState = {\n depth: number;\n pending: Array<() => void>;\n stagedValues: Map<string, RegistryStoreValue>;\n snapshotCache: Map<string, TransactionSnapshotEntry>;\n failed: boolean;\n error?: Error;\n};\n\r\ntype TransactionSnapshotMode = \"deep\" | \"shallow\" | \"ref\";\r\ntype TransactionSnapshotEntry = {\r\n source: RegistryStoreValue | null | undefined;\r\n snapshot: RegistryStoreValue | null;\r\n mode: TransactionSnapshotMode;\r\n};\r\n\r\nexport type ComputedEntry = {\r\n deps: string[];\r\n compute: (...args: unknown[]) => unknown;\r\n stale: boolean;\r\n};\r\n\r\nexport type NotifyState = {\n pendingNotifications: Set<string>;\n pendingBuffer: string[];\n orderedNames: string[];\n subscriberBuffer: RegistrySubscriber[];\n notifyScheduled: boolean;\n batchDepth: number;\n flushId: number;\n isFlushing: boolean;\n};\n\r\nexport type RegistryScope = \"default\" | \"request\";\n\nexport type StoreRegistry = {\n scope: RegistryScope;\n stores: Record<string, RegistryStoreValue>;\n subscribers: Record<string, Set<RegistrySubscriber>>;\r\n initialStates: Record<string, RegistryStoreValue>;\r\n initialFactories: Record<string, (() => RegistryStoreValue) | undefined>;\r\n metaEntries: Record<string, StoreFeatureMeta>;\r\n snapshotCache: Record<string, RegistrySnapshotEntry>;\r\n featureRuntimes: Map<FeatureName, StoreFeatureRuntime>;\r\n deletingStores: Set<string>;\r\n computedEntries: Record<string, ComputedEntry>;\r\n computedDependents: Record<string, Set<string>>;\r\n computedCleanups: Map<string, () => void>;\r\n transaction: TransactionState;\n async: AsyncRegistry;\n notify: NotifyState;\n lifecycleListener: StoreLifecycleListener | null;\n};\n\nconst _registries = new Map<string, StoreRegistry>();\nconst initializedRegistries = new WeakSet<StoreRegistry>();\n\nexport const initializeRegistryFeatureRuntimes = (registry: StoreRegistry): void => {\n if (initializedRegistries.has(registry)) return;\n initializedRegistries.add(registry);\n getRegisteredFeatureNames().forEach((name) => {\n if (!registry.featureRuntimes.get(name)) {\n const factory = getStoreFeatureFactory(name);\n if (factory) registry.featureRuntimes.set(name, factory());\n }\n });\n};\n\r\ndeclare const __STROID_REGISTRY_ID__: string | undefined;\r\nconst _registryOverrideEnv =\r\n (typeof __STROID_REGISTRY_ID__ !== \"undefined\" && __STROID_REGISTRY_ID__)\r\n || (typeof process !== \"undefined\" && process.env?.STROID_REGISTRY_ID)\r\n || undefined;\r\n\r\nlet _registryOverrideRuntime: string | undefined;\r\n\r\nexport const normalizeStoreRegistryScope = (scope: string): string => {\r\n const resolved = _registryOverrideRuntime || _registryOverrideEnv || scope;\r\n return resolved.replace(/\\.ts(\\?|$)/, \".js$1\");\r\n};\r\n\r\nexport const defaultRegistryScope = normalizeStoreRegistryScope(new URL(\"../../store.js\", import.meta.url).href);\nexport const getDefaultStoreRegistry = (): StoreRegistry => getStoreRegistry(defaultRegistryScope);\r\n\r\nexport const setRegistryScope = (scope: string): void => {\r\n _registryOverrideRuntime = scope;\r\n _registries.clear();\r\n};\r\n\r\nexport const clearRegistryScopeOverrideForTests = (): void => {\r\n _registryOverrideRuntime = undefined;\r\n _registries.clear();\r\n};\r\n\r\nregisterTestResetHook(\"registry.scope-override\", clearRegistryScopeOverrideForTests, 110);\r\n\r\nconst createNotifyState = (): NotifyState => ({\n pendingNotifications: new Set<string>(),\n pendingBuffer: [],\n orderedNames: [],\n subscriberBuffer: [],\n notifyScheduled: false,\n batchDepth: 0,\n flushId: 0,\n isFlushing: false,\n});\n\r\nconst resetNotifyState = (notify: NotifyState): void => {\n notify.pendingNotifications.clear();\n notify.pendingBuffer.length = 0;\n notify.orderedNames.length = 0;\n notify.subscriberBuffer.length = 0;\n notify.notifyScheduled = false;\n notify.batchDepth = 0;\n notify.flushId = 0;\n notify.isFlushing = false;\n};\n\nexport const createTransactionState = (): TransactionState => ({\n depth: 0,\n pending: [],\n stagedValues: new Map(),\n snapshotCache: new Map(),\n failed: false,\n error: undefined,\n});\n\nexport const createStoreRegistry = (scope: RegistryScope = \"default\"): StoreRegistry => {\n const registry: StoreRegistry = {\n scope,\n stores: Object.create(null),\n subscribers: Object.create(null),\n initialStates: Object.create(null),\n initialFactories: Object.create(null),\n metaEntries: Object.create(null),\n snapshotCache: Object.create(null),\n featureRuntimes: new Map(),\n deletingStores: new Set(),\n computedEntries: Object.create(null),\n computedDependents: Object.create(null),\n computedCleanups: new Map(),\n transaction: createTransactionState(),\n async: createAsyncRegistry(),\n notify: createNotifyState(),\n lifecycleListener: null,\n };\n initializeRegistryFeatureRuntimes(registry);\n return registry;\n};\n\r\nexport const getStoreRegistry = (scope: string): StoreRegistry => {\r\n const normalizedScope = normalizeStoreRegistryScope(scope);\r\n const existing = _registries.get(normalizedScope);\r\n if (existing) return existing;\r\n const created = createStoreRegistry();\r\n _registries.set(normalizedScope, created);\r\n return created;\r\n};\r\n\r\nexport const hasStoreEntry = (registry: StoreRegistry, name: string): boolean =>\r\n Object.prototype.hasOwnProperty.call(registry.stores, name);\r\n\r\nexport const isStoreDeleting = (registry: StoreRegistry, name: string): boolean =>\r\n registry.deletingStores.has(name);\r\n\r\nexport const clearStoreRegistries = (registry: StoreRegistry): void => {\n registry.computedCleanups.forEach((cleanup) => {\r\n try { cleanup(); } catch (_) { /* ignore cleanup errors */ }\r\n });\r\n registry.computedCleanups.clear();\r\n [\r\n registry.stores,\r\n registry.subscribers,\r\n registry.initialStates,\r\n registry.initialFactories,\r\n registry.metaEntries,\r\n registry.snapshotCache,\r\n registry.computedEntries,\r\n registry.computedDependents,\r\n ].forEach((registryPart) => {\r\n Object.keys(registryPart).forEach((key) => {\r\n delete registryPart[key];\r\n });\r\n });\r\n registry.deletingStores.clear();\r\n registry.transaction.depth = 0;\r\n registry.transaction.pending = [];\r\n registry.transaction.stagedValues.clear();\r\n registry.transaction.snapshotCache.clear();\r\n registry.transaction.failed = false;\r\n registry.transaction.error = undefined;\r\n resetNotifyState(registry.notify);\n resetAsyncRegistry(registry.async);\n registry.lifecycleListener = null;\n};\n\nexport const setLifecycleListener = (registry: StoreRegistry, listener: StoreLifecycleListener | null): void => {\n registry.lifecycleListener = listener;\n};\n\nexport const emitLifecycleEvent = (registry: StoreRegistry, event: StoreLifecycleEvent): void => {\n try {\n registry.lifecycleListener?.(event);\n } catch (_) {\n // Listener errors are intentionally ignored to avoid crashing core flows.\n }\n};\n\r\nexport const resetAllStoreRegistriesForTests = (): void => {\r\n _registries.forEach((registry) => {\r\n registry.computedCleanups.forEach((cleanup) => {\r\n try { cleanup(); } catch (_) { /* ignore cleanup errors */ }\r\n });\r\n registry.computedCleanups.clear();\r\n [\r\n registry.stores,\r\n registry.subscribers,\r\n registry.initialStates,\r\n registry.initialFactories,\r\n registry.metaEntries,\r\n registry.snapshotCache,\r\n registry.computedEntries,\r\n registry.computedDependents,\r\n ].forEach((registryPart) => {\r\n Object.keys(registryPart).forEach((key) => {\r\n delete registryPart[key];\r\n });\r\n });\r\n registry.deletingStores.clear();\r\n registry.transaction.depth = 0;\r\n registry.transaction.pending = [];\r\n registry.transaction.stagedValues.clear();\r\n registry.transaction.snapshotCache.clear();\r\n registry.transaction.failed = false;\r\n registry.transaction.error = undefined;\r\n resetNotifyState(registry.notify);\r\n resetAsyncRegistry(registry.async);\r\n });\r\n _registries.clear();\r\n};\r\n\r\nexport type CarrierContext = Record<string, unknown>;\r\nexport interface CarrierRunner {\r\n run<T>(carrier: CarrierContext, fn: () => T): T;\r\n get(): CarrierContext | null;\r\n}\r\n\r\nlet currentCarrierRunner: CarrierRunner | null = null;\r\n\r\nexport const injectCarrierRunner = (runner: CarrierRunner): void => {\r\n currentCarrierRunner = runner;\r\n};\r\n\r\nexport const getRequestCarrier = (): CarrierContext | null => {\r\n return currentCarrierRunner?.get() || null;\r\n};\r\n\r\nexport interface RegistryRunner {\r\n run<T>(registry: StoreRegistry, fn: () => T): T;\r\n get(): StoreRegistry | null;\r\n enterWith?: (registry: StoreRegistry) => void;\r\n}\r\n\r\nlet currentRegistryRunner: RegistryRunner | null = null;\n\nconst fallbackRegistryStack: StoreRegistry[] = [];\nconst fallbackRegistryRunner: RegistryRunner = {\n run: <T>(registry: StoreRegistry, fn: () => T): T => {\n fallbackRegistryStack.push(registry);\n try {\n return fn();\n } finally {\n fallbackRegistryStack.pop();\n }\n },\n get: (): StoreRegistry | null =>\n fallbackRegistryStack.length > 0 ? fallbackRegistryStack[fallbackRegistryStack.length - 1] : null,\n enterWith: (registry: StoreRegistry) => {\n if (fallbackRegistryStack.length > 0) {\n fallbackRegistryStack[fallbackRegistryStack.length - 1] = registry;\n return;\n }\n fallbackRegistryStack.push(registry);\n },\n};\n\nexport const injectRegistryRunner = (runner: RegistryRunner): void => {\n currentRegistryRunner = runner;\n};\n\nexport const runWithRegistry = <T>(registry: StoreRegistry, fn: () => T): T => {\n const runner = currentRegistryRunner ?? fallbackRegistryRunner;\n return runner.run(registry, fn);\n};\n\nexport const getActiveStoreRegistry = (fallback?: StoreRegistry): StoreRegistry => {\n const runner = currentRegistryRunner ?? fallbackRegistryRunner;\n return runner.get() || fallback || getStoreRegistry(defaultRegistryScope);\n};\n\nexport const enterRegistry = (registry: StoreRegistry): void => {\n const runner = currentRegistryRunner ?? fallbackRegistryRunner;\n if (runner.enterWith) {\n runner.enterWith(registry);\n }\n};\n\r\n\r\n","/**\r\n * @module internals/config\r\n *\r\n * LAYER: Internal subsystem\r\n * OWNS: Module-level behavior and exports for internals/config.\r\n *\r\n * Consumers: Internal imports and public API.\r\n */\r\nimport type { SnapshotMode, MiddlewareCtx, StoreValue } from \"../adapters/options.js\";\r\nimport { registerTestResetHook } from \"./test-reset.js\";\r\nimport { warnAlways } from \"./diagnostics.js\";\r\nimport { getActiveStoreRegistry, getDefaultStoreRegistry, type StoreRegistry } from \"../core/store-registry.js\";\n\r\nexport type LogSink = {\r\n log?: (msg: string, meta?: Record<string, unknown>) => void;\r\n warn?: (msg: string, meta?: Record<string, unknown>) => void;\r\n critical?: (msg: string, meta?: Record<string, unknown>) => void;\r\n};\r\n\r\nexport type AsyncCloneMode = \"none\" | \"shallow\" | \"deep\";\r\n\r\nexport type FlushConfig = {\r\n chunkSize?: number;\r\n chunkDelayMs?: number;\r\n priorityStores?: string[];\r\n};\r\n\r\nexport type RevalidateOnFocusConfig = {\r\n debounceMs?: number;\r\n maxConcurrent?: number;\r\n staggerMs?: number;\r\n};\r\n\r\nexport type StroidConfig = {\n logSink?: LogSink;\n flush?: FlushConfig;\n revalidateOnFocus?: RevalidateOnFocusConfig;\n namespace?: string;\n strictMissingFeatures?: boolean;\n strictFeatures?: boolean;\n assertRuntime?: boolean;\n strictMutatorReturns?: boolean;\n asyncAutoCreate?: boolean;\n asyncCloneResult?: AsyncCloneMode;\n /**\n * Automatically generate correlation IDs for async fetch writes.\n * Default: false.\n */\n autoCorrelationIds?: boolean;\n /**\n * Acknowledge loose store name typing and suppress dev warnings.\n * Useful when you intentionally skip StoreStateMap augmentation.\n */\n acknowledgeLooseTypes?: boolean;\n /**\n * Max number of cached path validation verdicts per store.\n * Default: 500.\n */\n pathCacheSize?: number;\n defaultSnapshotMode?: SnapshotMode;\n /**\n * Alias for defaultSnapshotMode.\n */\n snapshotStrategy?: SnapshotMode;\r\n /**\r\n * Throw on async usage errors instead of returning null.\r\n * Default: false (usage errors return null and call onError).\r\n */\r\n strictAsyncUsageErrors?: boolean;\r\n middleware?: Array<(ctx: MiddlewareCtx) => StoreValue | void>;\r\n /**\r\n * Allow hydrateStores to accept trusted snapshots without explicit opt-in.\r\n * Default: false (hydration requires an explicit trust opt-in).\r\n */\r\n allowTrustedHydration?: boolean;\r\n /**\r\n * @deprecated Use allowTrustedHydration instead.\r\n */\r\n allowUntrustedHydration?: boolean;\r\n /**\r\n * Alias for allowTrustedHydration.\r\n */\r\n allowHydration?: boolean;\r\n /**\n * Optional custom mutator engine (e.g. Immer's produce) to enable structural sharing.\n * You can pass the produce function directly or use \"immer\" after calling registerMutatorProduce().\n */\n mutatorProduce?: (<T>(base: T, recipe: (draft: T) => void) => T) | \"immer\";\n /**\n * When true, createSelector clones frozen state before proxy tracking.\n * Default: true (safer for mutation-prone selectors in dev).\n */\n selectorCloneFrozen?: boolean;\n};\n\r\ntype ResolvedConfig = {\n logSink: LogSink;\n flush: Required<FlushConfig>;\n revalidateOnFocus: Required<RevalidateOnFocusConfig>;\n namespace: string;\n strictMissingFeatures: boolean;\n assertRuntime: boolean;\n strictMutatorReturns: boolean;\n asyncAutoCreate: boolean;\n asyncCloneResult: AsyncCloneMode;\n autoCorrelationIds: boolean;\n acknowledgeLooseTypes: boolean;\n pathCacheSize: number;\n defaultSnapshotMode: SnapshotMode;\n strictAsyncUsageErrors: boolean;\n middleware: Array<(ctx: MiddlewareCtx) => StoreValue | void>;\n allowUntrustedHydration: boolean;\n mutatorProduce?: <T>(base: T, recipe: (draft: T) => void) => T;\n selectorCloneFrozen: boolean;\n};\n\r\nconst defaultLogSink: LogSink = {\r\n log: (msg: string, meta?: Record<string, unknown>) => {\r\n if (typeof console !== \"undefined\" && typeof console.log === \"function\") {\r\n if (meta) console.log(`[stroid] ${msg}`, meta);\r\n else console.log(`[stroid] ${msg}`);\r\n }\r\n },\r\n warn: (msg: string, meta?: Record<string, unknown>) => {\r\n if (typeof console !== \"undefined\" && typeof console.warn === \"function\") {\r\n if (meta) console.warn(`[stroid] ${msg}`, meta);\r\n else console.warn(`[stroid] ${msg}`);\r\n }\r\n },\r\n critical: (msg: string, meta?: Record<string, unknown>) => {\r\n if (typeof console !== \"undefined\" && typeof console.error === \"function\") {\r\n if (meta) console.error(`[stroid] ${msg}`, meta);\r\n else console.error(`[stroid] ${msg}`);\r\n }\r\n },\r\n};\r\n\r\nconst defaultConfig: ResolvedConfig = {\n logSink: defaultLogSink,\r\n flush: {\r\n chunkSize: Number.POSITIVE_INFINITY,\r\n chunkDelayMs: 0,\r\n priorityStores: [],\r\n },\r\n revalidateOnFocus: {\r\n debounceMs: 0,\r\n maxConcurrent: 3,\r\n staggerMs: 100,\r\n },\r\n namespace: \"\",\r\n strictMissingFeatures: true,\r\n assertRuntime: false,\r\n strictMutatorReturns: true,\n asyncAutoCreate: false,\n asyncCloneResult: \"none\",\n autoCorrelationIds: false,\n acknowledgeLooseTypes: false,\n pathCacheSize: 500,\n defaultSnapshotMode: \"deep\",\n strictAsyncUsageErrors: false,\n middleware: [],\n allowUntrustedHydration: false,\n mutatorProduce: undefined,\n selectorCloneFrozen: true,\n};\n\r\nconst cloneConfig = (base: ResolvedConfig): ResolvedConfig => ({\n logSink: { ...base.logSink },\r\n flush: { ...base.flush },\r\n revalidateOnFocus: { ...base.revalidateOnFocus },\r\n namespace: base.namespace,\r\n strictMissingFeatures: base.strictMissingFeatures,\r\n assertRuntime: base.assertRuntime,\r\n strictMutatorReturns: base.strictMutatorReturns,\n asyncAutoCreate: base.asyncAutoCreate,\n asyncCloneResult: base.asyncCloneResult,\n autoCorrelationIds: base.autoCorrelationIds,\n acknowledgeLooseTypes: base.acknowledgeLooseTypes,\n pathCacheSize: base.pathCacheSize,\n defaultSnapshotMode: base.defaultSnapshotMode,\n strictAsyncUsageErrors: base.strictAsyncUsageErrors,\n middleware: [...base.middleware],\n allowUntrustedHydration: base.allowUntrustedHydration,\n mutatorProduce: base.mutatorProduce,\n selectorCloneFrozen: base.selectorCloneFrozen,\n});\n\r\nlet configByRegistry = new WeakMap<StoreRegistry, ResolvedConfig>();\r\nlet baseConfig = cloneConfig(defaultConfig);\r\nconst getRegistryConfig = (registry: StoreRegistry): ResolvedConfig => {\r\n let config = configByRegistry.get(registry);\r\n if (!config) {\r\n config = cloneConfig(baseConfig);\r\n configByRegistry.set(registry, config);\r\n }\r\n return config;\r\n};\r\n\r\nlet registeredMutatorProduce: (<T>(base: T, recipe: (draft: T) => void) => T) | undefined;\nlet mutatorProduceLocked = false;\nlet immerMissingWarned = false;\nconst resolveImmerProduce = (): (<T>(base: T, recipe: (draft: T) => void) => T) | undefined =>\n registeredMutatorProduce;\n\r\nexport const getConfig = (): ResolvedConfig => getRegistryConfig(getActiveStoreRegistry());\n\nexport const registerMutatorProduce = (\n produce: (<T>(base: T, recipe: (draft: T) => void) => T),\n options: { force?: boolean } = {}\n): void => {\n if (typeof produce !== \"function\") {\n throw new Error(\"registerMutatorProduce requires a function.\");\n }\n if (mutatorProduceLocked && !options.force) {\n warnAlways(\n \"registerMutatorProduce() called after lock. \" +\n \"Pass { force: true } only if you intentionally replace the producer.\"\n );\n return;\n }\n registeredMutatorProduce = produce;\n mutatorProduceLocked = true;\n configureStroid({ mutatorProduce: produce });\n};\n\nexport const configureStroid = (next?: StroidConfig): void => {\n if (!next) return;\r\n const registry = getActiveStoreRegistry();\r\n let config = getRegistryConfig(registry);\r\n\r\n if (next.logSink) {\r\n config = {\r\n ...config,\r\n logSink: {\r\n log: next.logSink.log ?? config.logSink.log,\r\n warn: next.logSink.warn ?? config.logSink.warn,\r\n critical: next.logSink.critical ?? config.logSink.critical,\r\n },\r\n };\r\n }\r\n\r\n if (next.flush) {\r\n config = {\r\n ...config,\r\n flush: {\r\n chunkSize: Number.isFinite(next.flush.chunkSize ?? config.flush.chunkSize)\r\n ? (next.flush.chunkSize as number)\r\n : config.flush.chunkSize,\r\n chunkDelayMs: Number.isFinite(next.flush.chunkDelayMs ?? config.flush.chunkDelayMs)\r\n ? (next.flush.chunkDelayMs as number)\r\n : config.flush.chunkDelayMs,\r\n priorityStores: Array.isArray(next.flush.priorityStores)\r\n ? next.flush.priorityStores\r\n : config.flush.priorityStores,\r\n },\r\n };\r\n }\r\n\r\n if (next.revalidateOnFocus) {\r\n config = {\r\n ...config,\r\n revalidateOnFocus: {\r\n debounceMs: Number.isFinite(next.revalidateOnFocus.debounceMs ?? config.revalidateOnFocus.debounceMs)\r\n ? (next.revalidateOnFocus.debounceMs as number)\r\n : config.revalidateOnFocus.debounceMs,\r\n maxConcurrent: Number.isFinite(next.revalidateOnFocus.maxConcurrent ?? config.revalidateOnFocus.maxConcurrent)\r\n ? Math.max(1, next.revalidateOnFocus.maxConcurrent as number)\r\n : config.revalidateOnFocus.maxConcurrent,\r\n staggerMs: Number.isFinite(next.revalidateOnFocus.staggerMs ?? config.revalidateOnFocus.staggerMs)\r\n ? Math.max(0, next.revalidateOnFocus.staggerMs as number)\r\n : config.revalidateOnFocus.staggerMs,\r\n },\r\n };\r\n }\r\n\r\n if (typeof next.namespace === \"string\") {\r\n config = {\r\n ...config,\r\n namespace: next.namespace.trim(),\r\n };\r\n }\r\n\r\n if (typeof next.strictMissingFeatures === \"boolean\") {\r\n config = {\r\n ...config,\r\n strictMissingFeatures: next.strictMissingFeatures,\r\n };\r\n }\r\n if (typeof next.strictFeatures === \"boolean\") {\r\n config = {\r\n ...config,\r\n strictMissingFeatures: next.strictFeatures,\r\n };\r\n }\r\n\r\n if (typeof next.assertRuntime === \"boolean\") {\r\n config = {\r\n ...config,\r\n assertRuntime: next.assertRuntime,\r\n };\r\n }\r\n\r\n if (typeof next.strictMutatorReturns === \"boolean\") {\r\n config = {\r\n ...config,\r\n strictMutatorReturns: next.strictMutatorReturns,\r\n };\r\n }\r\n\r\n if (typeof next.asyncAutoCreate === \"boolean\") {\r\n config = {\r\n ...config,\r\n asyncAutoCreate: next.asyncAutoCreate,\r\n };\r\n }\r\n if (typeof next.strictAsyncUsageErrors === \"boolean\") {\n config = {\n ...config,\n strictAsyncUsageErrors: next.strictAsyncUsageErrors,\n };\n }\n\n if (typeof next.autoCorrelationIds === \"boolean\") {\n config = {\n ...config,\n autoCorrelationIds: next.autoCorrelationIds,\n };\n }\n\n if (next.asyncCloneResult === \"none\" || next.asyncCloneResult === \"shallow\" || next.asyncCloneResult === \"deep\") {\n config = {\n ...config,\n asyncCloneResult: next.asyncCloneResult,\n };\n }\n if (typeof next.acknowledgeLooseTypes === \"boolean\") {\n config = {\n ...config,\n acknowledgeLooseTypes: next.acknowledgeLooseTypes,\n };\n }\n if (typeof next.pathCacheSize === \"number\" && Number.isFinite(next.pathCacheSize)) {\n config = {\n ...config,\n pathCacheSize: Math.max(0, Math.floor(next.pathCacheSize)),\n };\n }\n\r\n if (next.snapshotStrategy === \"shallow\" || next.snapshotStrategy === \"ref\" || next.snapshotStrategy === \"deep\") {\r\n config = {\r\n ...config,\r\n defaultSnapshotMode: next.snapshotStrategy,\r\n };\r\n }\r\n\r\n if (next.defaultSnapshotMode === \"shallow\" || next.defaultSnapshotMode === \"ref\" || next.defaultSnapshotMode === \"deep\") {\r\n config = {\r\n ...config,\r\n defaultSnapshotMode: next.defaultSnapshotMode,\r\n };\r\n }\r\n\r\n if (Array.isArray(next.middleware)) {\r\n config = {\r\n ...config,\r\n middleware: next.middleware,\r\n };\r\n }\r\n\r\n if (typeof next.allowUntrustedHydration === \"boolean\") {\r\n config = {\r\n ...config,\r\n allowUntrustedHydration: next.allowUntrustedHydration,\r\n };\r\n }\r\n if (typeof next.allowHydration === \"boolean\") {\r\n config = {\r\n ...config,\r\n allowUntrustedHydration: next.allowHydration,\r\n };\r\n }\r\n if (typeof next.allowTrustedHydration === \"boolean\") {\r\n config = {\r\n ...config,\r\n allowUntrustedHydration: next.allowTrustedHydration,\r\n };\r\n }\r\n\r\n if (typeof next.mutatorProduce === \"function\") {\n config = {\n ...config,\n mutatorProduce: next.mutatorProduce,\n };\n } else if (next.mutatorProduce === \"immer\") {\n const produce = resolveImmerProduce();\n if (produce) {\n config = {\n ...config,\n mutatorProduce: produce,\n };\n } else {\n if (!immerMissingWarned) {\n immerMissingWarned = true;\n warnAlways(\n `configureStroid({ mutatorProduce: \"immer\" }) requires Immer's produce function.\\n` +\n `Call registerMutatorProduce(produce) or pass mutatorProduce: produce directly.`\n );\n }\n }\n }\n\n if (typeof next.selectorCloneFrozen === \"boolean\") {\n config = {\n ...config,\n selectorCloneFrozen: next.selectorCloneFrozen,\n };\n }\n\r\n configByRegistry.set(registry, config);\r\n if (registry === getDefaultStoreRegistry()) {\r\n baseConfig = cloneConfig(config);\r\n }\r\n};\r\n\r\nexport const resetConfig = (): void => {\n configByRegistry = new WeakMap<StoreRegistry, ResolvedConfig>();\n baseConfig = cloneConfig(defaultConfig);\n registeredMutatorProduce = undefined;\n mutatorProduceLocked = false;\n immerMissingWarned = false;\n};\n\r\nregisterTestResetHook(\"config.reset\", resetConfig, 90);\r\n\r\n// Back-compat for tests\r\nexport const _resetConfigForTests = (): void => resetConfig();\r\n\r\nexport const getNamespace = (): string => getConfig().namespace;\r\nexport const setNamespace = (ns: string): void => {\r\n const registry = getActiveStoreRegistry();\r\n const config = getRegistryConfig(registry);\r\n const next = { ...config, namespace: ns.trim() };\r\n configByRegistry.set(registry, next);\r\n if (registry === getDefaultStoreRegistry()) {\r\n baseConfig = cloneConfig(next);\r\n }\r\n};\r\n\r\n\r\n","/**\r\n * @module internals/diagnostics\r\n *\r\n * LAYER: Internal subsystem\r\n * OWNS: Module-level behavior and exports for internals/diagnostics.\r\n *\r\n * Consumers: Internal imports and public API.\r\n */\r\nimport { getConfig } from \"./config.js\";\r\nconst _envFromProcess = typeof process !== \"undefined\" && typeof process.env?.NODE_ENV === \"string\"\r\n ? process.env.NODE_ENV\r\n : undefined;\r\nconst _envFromImportMeta = typeof import.meta !== \"undefined\" && (import.meta as any)?.env?.MODE\r\n ? (import.meta as any).env.MODE\r\n : undefined;\r\nconst _devFlag = typeof globalThis !== \"undefined\" && typeof (globalThis as any).__STROID_DEV__ === \"boolean\"\r\n ? (globalThis as any).__STROID_DEV__\r\n : undefined;\r\nconst _fallbackEnv = \"production\";\r\nconst _resolvedEnv = _envFromProcess ?? _envFromImportMeta ?? _fallbackEnv;\r\n\r\nexport const __DEV__ = typeof _devFlag === \"boolean\"\r\n ? _devFlag\r\n : _resolvedEnv !== \"production\";\r\n\r\nexport const isDev = (): boolean => __DEV__;\r\n\r\nconst defaultWarn = (msg: string, meta?: Record<string, unknown>): void => {\r\n if (typeof console !== \"undefined\" && typeof console.warn === \"function\") {\r\n if (meta) console.warn(`[stroid] ${msg}`, meta);\r\n else console.warn(`[stroid] ${msg}`);\r\n }\r\n};\r\n\r\nconst defaultCritical = (msg: string, meta?: Record<string, unknown>): void => {\r\n if (typeof console !== \"undefined\" && typeof console.error === \"function\") {\r\n if (meta) console.error(`[stroid] ${msg}`, meta);\r\n else console.error(`[stroid] ${msg}`);\r\n }\r\n};\r\n\r\nconst defaultLog = (msg: string, meta?: Record<string, unknown>): void => {\r\n if (typeof console !== \"undefined\" && typeof console.log === \"function\") {\r\n if (meta) console.log(`[stroid] ${msg}`, meta);\r\n else console.log(`[stroid] ${msg}`);\r\n }\r\n};\r\n\r\nexport const critical = (msg: string, meta?: Record<string, unknown>): void => {\r\n const sink = getConfig().logSink.critical ?? defaultCritical;\r\n sink(msg, meta);\r\n if (getConfig().assertRuntime) throw new Error(msg);\r\n};\r\n\r\nexport const warn = (msg: string, meta?: Record<string, unknown>): void => {\r\n if (!__DEV__) return;\r\n const sink = getConfig().logSink.warn ?? defaultWarn;\r\n sink(msg, meta);\r\n if (getConfig().assertRuntime) throw new Error(msg);\r\n};\r\n\r\n// Used for configuration hazards that must surface in production too.\r\nexport const warnAlways = (msg: string, meta?: Record<string, unknown>): void => {\r\n const sink = getConfig().logSink.warn ?? defaultWarn;\r\n sink(msg, meta);\r\n if (getConfig().assertRuntime) throw new Error(msg);\r\n};\r\n\r\nexport const error = (msg: string, meta?: Record<string, unknown>): void => {\r\n if (__DEV__) {\r\n const sink = getConfig().logSink.warn ?? defaultWarn;\r\n sink(msg, meta);\r\n }\r\n critical(msg, meta);\r\n if (getConfig().assertRuntime) throw new Error(msg);\r\n};\r\n\r\nexport const log = (msg: string, meta?: Record<string, unknown>): void => {\r\n if (!__DEV__) return;\r\n const sink = getConfig().logSink.log ?? defaultLog;\r\n sink(msg, meta);\r\n};\r\n\r\nexport const getInvalidFunctionStoreValueMessage = (): string =>\r\n `Functions cannot be stored in stroid.\\n` +\r\n `Store data only - handle functions outside the store.`;\r\n\r\nexport const getMapSetStoreWarningMessage = (): string =>\r\n `Map/Set detected. stroid converts these to plain objects.\\n` +\r\n `Use arrays or plain objects for best results.`;\r\n\r\nexport const getDateStoreWarningMessage = (): string =>\r\n `Date object detected. stroid stores it as ISO string.\\n` +\r\n `Use new Date(value) to convert back when reading.`;\r\n\r\nexport const getSanitizeDateWarningMessage = (): string =>\r\n \"Date detected; stored as ISO string. Use new Date(value) when reading.\";\r\n\r\nexport const getSanitizeMapWarningMessage = (): string =>\r\n \"Map detected; converting to plain object.\";\r\n\r\nexport const getSanitizeSetWarningMessage = (): string =>\r\n \"Set detected; converting to array.\";\r\n\r\nexport const getPathDepthExceededMessage = (depth: number, maxDepth: number, parts: string[]): string =>\r\n `Path depth of ${depth} exceeded maximum of ${maxDepth}.\\n` +\r\n `\"${parts.join(\".\")}\"\\n` +\r\n `This is a data design issue. Split into separate stores:\\n` +\r\n `createStore(\"${parts[0]}\", ...) and createStore(\"${parts[1]}\", ...)`;\r\n\r\nexport const getDeepNestingWarningMessage = (depth: number, parts: string[]): string =>\r\n `Deep nesting detected (${depth} levels): \"${parts.join(\".\")}\"\\n` +\r\n `Consider splitting into separate stores for better readability.`;\r\n\r\nexport const getPathReachedNullMessage = (parts: string[], part: string): string =>\r\n `Path \"${parts.join(\".\")}\" not found - reached null at \"${part}\"`;\r\n\r\nexport const getPathNotObjectMessage = (part: string): string =>\r\n `Cannot go deeper at \"${part}\" - value is not an object`;\r\n\r\nexport const getInvalidStoreNameMessage = (name: string): string =>\r\n `Store name must be a non-empty string. Got: ${JSON.stringify(name)}`;\r\n\r\nexport const getStoreNameContainsSpacesMessage = (name: string): string =>\r\n `Store name \"${name}\" contains spaces.\\n` +\r\n `Use camelCase or kebab-case: \"userName\" or \"user-name\"`;\r\n\r\nexport const getForbiddenStoreNameMessage = (name: string): string =>\r\n `Store name \"${name}\" is not allowed.\\n` +\r\n `Reserved names: \"__proto__\", \"constructor\", \"prototype\".`;\r\n\r\nconst MAX_LEVENSHTEIN_INPUT_LENGTH = 128;\r\n\r\nconst shouldCheckLevenshtein = (a: string, b: string): boolean => {\r\n if (Math.abs(a.length - b.length) > 2) return false;\r\n return Math.max(a.length, b.length) <= MAX_LEVENSHTEIN_INPUT_LENGTH;\r\n};\r\n\r\nconst levenshtein = (a: string, b: string): number => {\r\n if (a === b) return 0;\r\n if (a.length === 0) return b.length;\r\n if (b.length === 0) return a.length;\r\n\r\n let prev = Array.from({ length: a.length + 1 }, (_, i) => i);\r\n let next = new Array<number>(a.length + 1);\r\n\r\n for (let i = 1; i <= b.length; i++) {\r\n next[0] = i;\r\n for (let j = 1; j <= a.length; j++) {\r\n next[j] =\r\n b[i - 1] === a[j - 1]\r\n ? prev[j - 1]\r\n : Math.min(prev[j - 1], next[j - 1], prev[j]) + 1;\r\n }\r\n [prev, next] = [next, prev];\r\n }\r\n return prev[a.length];\r\n};\r\n\r\nexport const suggestStoreName = (name: string, existingNames: string[]): void => {\r\n const similar = existingNames.find((entry) => {\r\n const a = entry.toLowerCase();\r\n const b = name.toLowerCase();\r\n return (\r\n a.includes(b)\r\n || b.includes(a)\r\n || (shouldCheckLevenshtein(a, b) && levenshtein(a, b) <= 2)\r\n );\r\n });\r\n\r\n if (similar) {\r\n warn(`Store \"${name}\" not found. Did you mean \"${similar}\"?`);\r\n return;\r\n }\r\n\r\n error(\r\n `Store \"${name}\" not found.\\n` +\r\n `Available stores: [${existingNames.join(\", \")}]\\n` +\r\n `Call createStore(\"${name}\", data) first.`\r\n );\r\n};\r\n\r\n\r\n","/**\r\n * @module features/sync\r\n *\r\n * LAYER: Feature runtime\r\n * OWNS: Module-level behavior and exports for features/sync.\r\n *\r\n * Consumers: Internal imports and public API.\r\n */\r\nimport type { StoreValue, SyncMessage, SyncOptions } from \"../adapters/options.js\";\r\nimport { registerStoreFeature, type StoreFeatureRuntime } from \"./feature-registry.js\";\r\nimport { normalizeFeatureState, resolveUpdatedAtMs } from \"./state-helpers.js\";\nimport { warnAlways, isDev } from \"../utils.js\";\n\r\nexport type SyncChannels = Record<string, BroadcastChannel>;\r\nexport type SyncClocks = Record<string, number>;\r\nexport type SyncVersion = { clock: number; updatedAt: number; source: string };\r\nexport type SyncVersions = Record<string, SyncVersion>;\r\nexport type SyncWindowCleanup = Record<string, () => void>;\r\n\r\nlet _registered = false;\r\nconst SYNC_PROTOCOL_VERSION = 1;\r\nconst resolveProtocolVersion = (msg: { v?: unknown; protocol?: unknown }): number | undefined =>\r\n typeof msg?.v === \"number\"\r\n ? msg.v as number\r\n : (typeof msg?.protocol === \"number\" ? msg.protocol as number : undefined);\r\n\r\nconst insecureSyncWarned = new Set<string>();\r\nconst signerVerifyWarned = new Set<string>();\r\nconst DEFAULT_LOOP_GUARD_MS = 100;\r\n\r\nconst resolveLoopGuardMs = (syncOption?: boolean | SyncOptions): number | null => {\r\n if (!syncOption) return null;\r\n if (syncOption === true) return DEFAULT_LOOP_GUARD_MS;\r\n if (typeof syncOption !== \"object\") return null;\r\n const guard = syncOption.loopGuard;\r\n if (guard === false) return null;\r\n if (guard === true || guard === undefined) return DEFAULT_LOOP_GUARD_MS;\r\n if (typeof guard === \"object\") {\r\n const ms = guard.windowMs;\r\n if (typeof ms === \"number\" && Number.isFinite(ms) && ms > 0) return ms;\r\n return DEFAULT_LOOP_GUARD_MS;\r\n }\r\n return DEFAULT_LOOP_GUARD_MS;\r\n};\r\n\r\ntype SyncMeta = {\r\n updatedAt: string;\r\n updatedAtMs?: number;\r\n updateCount: number;\r\n options: {\r\n sync?: boolean | SyncOptions;\r\n };\r\n};\r\n\r\nconst byteLength = (value: string): number => {\r\n if (typeof TextEncoder !== \"undefined\") {\r\n return new TextEncoder().encode(value).length;\r\n }\r\n if (typeof Buffer !== \"undefined\") {\r\n return Buffer.byteLength(value);\r\n }\r\n return value.length;\r\n};\r\n\r\nconst compareSyncOrder = ({\r\n incoming,\r\n accepted,\r\n}: {\r\n incoming: { clock?: number; source?: string };\r\n accepted?: SyncVersion;\r\n}): number => {\r\n const localClock = accepted?.clock ?? 0;\r\n const incomingClock = typeof incoming.clock === \"number\" ? incoming.clock : 0;\r\n if (incomingClock !== localClock) return incomingClock - localClock;\r\n\r\n const incomingSource = incoming.source ?? \"\";\r\n const localSource = accepted?.source ?? \"\";\r\n if (incomingSource === localSource) return 0;\r\n return incomingSource.localeCompare(localSource, \"en\", { sensitivity: \"variant\" });\r\n};\r\n\r\nconst resolveMetaUpdatedAtMs = (meta?: SyncMeta): number =>\r\n meta?.updatedAtMs ?? resolveUpdatedAtMs({ value: meta?.updatedAt, fallbackMs: 0 });\r\n\r\nconst isValidSyncMessage = (msg: unknown): msg is {\r\n v?: number;\r\n protocol?: number;\r\n type: string;\r\n name: string;\r\n clock: number;\r\n source: string;\r\n data?: unknown;\r\n updatedAt?: number;\r\n auth?: unknown;\r\n token?: unknown;\r\n requestedAt?: number;\r\n} => {\r\n if (typeof msg !== \"object\" || msg === null) return false;\r\n const m = msg as Record<string, unknown>;\r\n const hasVersion = typeof m.v === \"number\" || typeof m.protocol === \"number\";\r\n return (\r\n hasVersion &&\r\n typeof m.type === \"string\" &&\r\n typeof m.name === \"string\" &&\r\n typeof m.clock === \"number\" &&\r\n typeof m.source === \"string\"\r\n );\r\n};\r\n\r\nconst requestSyncSnapshot = ({\r\n name,\r\n syncChannels,\r\n instanceId,\r\n authToken,\r\n reportStoreError,\r\n}: {\r\n name: string;\r\n syncChannels: SyncChannels;\r\n instanceId: string;\r\n authToken?: string;\r\n reportStoreError: (name: string, message: string) => void;\r\n}): void => {\r\n const channel = syncChannels[name];\r\n if (!channel) return;\r\n try {\r\n const payload: SyncMessage = {\r\n v: SYNC_PROTOCOL_VERSION,\r\n protocol: SYNC_PROTOCOL_VERSION,\r\n type: \"sync-request\",\r\n source: instanceId,\r\n name,\r\n clock: 0,\r\n requestedAt: Date.now(),\r\n };\r\n if (authToken) payload.token = authToken;\r\n channel.postMessage(payload);\r\n } catch (err) {\r\n reportStoreError(name, `Failed to request sync snapshot for \"${name}\": ${(err as { message?: string })?.message ?? err}`);\r\n }\r\n};\r\n\r\nexport const bumpSyncClock = (name: string, syncClocks: SyncClocks): number => {\r\n syncClocks[name] = (syncClocks[name] ?? 0) + 1;\r\n return syncClocks[name];\r\n};\r\n\r\nexport const absorbSyncClock = (\r\n name: string,\r\n incomingClock: number,\r\n syncClocks: SyncClocks\r\n): number => {\r\n syncClocks[name] = Math.max(syncClocks[name] ?? 0, incomingClock) + 1;\r\n return syncClocks[name];\r\n};\r\n\r\nexport const closeSyncResources = ({\r\n name,\r\n syncChannels,\r\n syncWindowCleanup,\r\n syncClocks,\r\n syncVersions,\r\n}: {\r\n name: string;\r\n syncChannels: SyncChannels;\r\n syncWindowCleanup: SyncWindowCleanup;\r\n syncClocks: SyncClocks;\r\n syncVersions: SyncVersions;\r\n}): void => {\r\n syncChannels[name]?.close();\r\n delete syncChannels[name];\r\n syncWindowCleanup[name]?.();\r\n delete syncWindowCleanup[name];\r\n delete syncClocks[name];\r\n delete syncVersions[name];\r\n};\r\n\r\nexport const cleanupAllSyncResources = ({\r\n syncChannels,\r\n syncWindowCleanup,\r\n}: {\r\n syncChannels: SyncChannels;\r\n syncWindowCleanup: SyncWindowCleanup;\r\n}): void => {\r\n Object.values(syncWindowCleanup).forEach((dispose) => {\r\n try { dispose(); } catch (_) { /* ignore cleanup errors */ }\r\n });\r\n Object.values(syncChannels).forEach((channel) => {\r\n try { channel.close(); } catch (_) { /* ignore cleanup errors */ }\r\n });\r\n};\r\n\r\nexport const setupSync = ({\r\n name,\r\n syncOption,\r\n syncChannels,\r\n syncClocks,\r\n syncVersions,\r\n syncWindowCleanup,\r\n instanceId,\r\n getMeta,\r\n getAcceptedSyncVersion,\r\n getStoreValue,\r\n hasStoreEntry,\r\n notify,\r\n validate,\r\n reportStoreError,\r\n warn,\r\n setStoreValue,\r\n normalizeIncomingState,\r\n acceptIncomingSyncVersion,\r\n resolveSyncVersion,\r\n broadcastSync,\r\n markLoopGuard,\r\n}: {\r\n name: string;\r\n syncOption?: boolean | SyncOptions;\r\n syncChannels: SyncChannels;\r\n syncClocks: SyncClocks;\r\n syncVersions: SyncVersions;\r\n syncWindowCleanup: SyncWindowCleanup;\r\n instanceId: string;\r\n getMeta: (name: string) => SyncMeta | undefined;\r\n getAcceptedSyncVersion: (name: string) => SyncVersion | undefined;\r\n getStoreValue: (name: string) => StoreValue;\r\n hasStoreEntry: (name: string) => boolean;\r\n notify: (name: string) => void;\r\n validate: (name: string, next: StoreValue) => { ok: boolean; value?: StoreValue };\r\n reportStoreError: (name: string, message: string) => void;\r\n warn: (message: string) => void;\r\n setStoreValue: (name: string, value: StoreValue) => void;\r\n normalizeIncomingState: (name: string, value: StoreValue) => StoreValue | null;\r\n acceptIncomingSyncVersion: (name: string, updatedAtMs: number, incomingClock: number, source: string) => void;\r\n resolveSyncVersion: (name: string, updatedAtMs: number, incomingClock: number) => number;\r\n broadcastSync: (name: string) => void;\r\n markLoopGuard: (name: string, windowMs: number) => void;\r\n}): void => {\r\n if (!syncOption) return;\r\n if (typeof window === \"undefined\" || typeof BroadcastChannel === \"undefined\") {\r\n reportStoreError(name, `Sync enabled for \"${name}\" but BroadcastChannel not available in this environment.`);\r\n return;\r\n }\r\n const policy = typeof syncOption === \"object\" ? syncOption.policy : undefined;\n const allowInsecure = policy === \"insecure\"\n || (policy !== \"strict\" && typeof syncOption === \"object\" && syncOption.insecure === true);\n const hasAuthToken = typeof syncOption === \"object\"\n && typeof syncOption.authToken === \"string\"\n && syncOption.authToken.length > 0;\n const hasVerify = typeof syncOption === \"object\" && typeof syncOption.verify === \"function\";\n const hasSign = typeof syncOption === \"object\" && typeof syncOption.sign === \"function\";\n\n const strictPolicy = policy === \"strict\" || (!isDev() && policy !== \"insecure\");\n if (strictPolicy && !allowInsecure && !hasAuthToken && !hasVerify) {\n reportStoreError(\n name,\n `Sync for \"${name}\" requires authToken or verify in strict mode. ` +\n `Use sync: { policy: \"insecure\" } to acknowledge the risk.`\n );\n return;\n }\n\n if (!strictPolicy && !allowInsecure && !hasAuthToken && !hasVerify && !insecureSyncWarned.has(name)) {\n insecureSyncWarned.add(name);\n warnAlways(\n `Sync for \"${name}\" is unauthenticated. Any same-origin tab can forge sync messages. ` +\n `Provide sync.authToken or sync.verify to enforce authentication.`\n );\n }\n\r\n if (hasSign && !hasVerify && !signerVerifyWarned.has(name)) {\r\n signerVerifyWarned.add(name);\r\n warn(\r\n `Sync for \"${name}\" is configured with \"sign\" but no \"verify\". ` +\r\n `\"sign\" has no effect unless incoming messages are verified.`\r\n );\r\n }\r\n const expectedToken = typeof syncOption === \"object\" ? syncOption.authToken : undefined;\r\n const loopGuardMs = resolveLoopGuardMs(syncOption);\r\n let tokenWarned = false;\r\n const channelName = typeof syncOption === \"object\" && syncOption.channel\r\n ? syncOption.channel\r\n : `stroid_sync_${name}`;\r\n try {\r\n const channel = new BroadcastChannel(channelName);\r\n syncChannels[name] = channel;\r\n channel.onmessage = (event: MessageEvent) => {\r\n const msg = event.data as any;\r\n if (!msg || msg.source === instanceId) return;\r\n if (msg.name !== name) return;\r\n if (syncChannels[name] !== channel || !hasStoreEntry(name) || !getMeta(name)) return;\r\n if (!isValidSyncMessage(msg)) {\r\n reportStoreError(name, `Sync message for \"${name}\" is malformed; ignoring.`);\r\n return;\r\n }\r\n if (expectedToken && msg.token !== expectedToken) {\r\n if (!tokenWarned) {\r\n reportStoreError(name, `Sync message for \"${name}\" failed auth token verification; ignoring.`);\r\n tokenWarned = true;\r\n }\r\n return;\r\n }\r\n const incomingVersion = resolveProtocolVersion(msg);\r\n if (incomingVersion !== SYNC_PROTOCOL_VERSION) {\r\n reportStoreError(name, `Sync protocol mismatch for \"${name}\". Expected v${SYNC_PROTOCOL_VERSION} but received ${String(incomingVersion ?? \"unknown\")}. Ignoring message.`);\r\n return;\r\n }\r\n const isSyncState = msg.type === \"sync-state\";\r\n if (isSyncState && (typeof msg.data === \"undefined\" || typeof msg.clock !== \"number\")) {\r\n reportStoreError(name, `Sync message for \"${name}\" is malformed; ignoring.`);\r\n return;\r\n }\r\n if (typeof syncOption === \"object\" && typeof syncOption.verify === \"function\") {\r\n let verified = false;\r\n try {\r\n verified = !!syncOption.verify(msg as SyncMessage);\r\n } catch (err) {\r\n reportStoreError(\r\n name,\r\n `Sync message verification failed for \"${name}\": ${(err as { message?: string })?.message ?? err}`\r\n );\r\n return;\r\n }\r\n if (!verified) {\r\n reportStoreError(name, `Sync message for \"${name}\" failed verification; ignoring.`);\r\n return;\r\n }\r\n }\r\n if (msg.type === \"sync-request\") {\r\n broadcastSync(name);\r\n return;\r\n }\r\n const resolver = typeof syncOption === \"object\" ? syncOption.conflictResolver : null;\r\n const order = compareSyncOrder({\r\n incoming: {\r\n clock: msg.clock,\r\n source: msg.source,\r\n },\r\n accepted: getAcceptedSyncVersion(name),\r\n });\r\n if (order <= 0) {\r\n const localUpdated = resolveMetaUpdatedAtMs(getMeta(name));\r\n const incomingUpdated = typeof msg.updatedAt === \"number\" ? msg.updatedAt : Date.now();\r\n if (resolver) {\r\n const resolved = resolver({\r\n local: getStoreValue(name),\r\n incoming: msg.data,\r\n localUpdated,\r\n incomingUpdated,\r\n });\r\n if (resolved !== undefined) {\r\n const normalizedResolved = normalizeIncomingState(name, resolved);\r\n if (normalizedResolved === null) return;\r\n setStoreValue(name, normalizedResolved);\r\n const resolveUpdatedAt = typeof syncOption === \"object\" ? syncOption.resolveUpdatedAt : null;\r\n const resolvedUpdatedAt = resolveUpdatedAt\r\n ? resolveUpdatedAt({ localUpdated, incomingUpdated, now: Date.now() })\r\n : Math.max(Date.now(), localUpdated, incomingUpdated);\r\n resolveSyncVersion(name, resolvedUpdatedAt, typeof msg.clock === \"number\" ? msg.clock : 0);\r\n if (loopGuardMs) markLoopGuard(name, loopGuardMs);\r\n notify(name);\r\n broadcastSync(name);\r\n }\r\n }\r\n return;\r\n }\r\n const normalizedIncoming = normalizeIncomingState(name, msg.data);\r\n if (normalizedIncoming === null) return;\r\n setStoreValue(name, normalizedIncoming);\r\n acceptIncomingSyncVersion(\r\n name,\r\n typeof msg.updatedAt === \"number\" ? msg.updatedAt : Date.now(),\r\n typeof msg.clock === \"number\" ? msg.clock : 0,\r\n typeof msg.source === \"string\" ? msg.source : \"\"\r\n );\r\n if (loopGuardMs) markLoopGuard(name, loopGuardMs);\r\n notify(name);\r\n };\r\n\r\n if (typeof window !== \"undefined\" && typeof window.addEventListener === \"function\") {\r\n syncWindowCleanup[name]?.();\r\n const hostWindow = window;\r\n const requestLatest = () => {\r\n requestSyncSnapshot({\r\n name,\r\n syncChannels,\r\n instanceId,\r\n authToken: expectedToken,\r\n reportStoreError,\r\n });\r\n };\r\n hostWindow.addEventListener(\"focus\", requestLatest);\r\n hostWindow.addEventListener(\"online\", requestLatest);\r\n syncWindowCleanup[name] = () => {\r\n hostWindow.removeEventListener(\"focus\", requestLatest);\r\n hostWindow.removeEventListener(\"online\", requestLatest);\r\n };\r\n }\r\n\r\n queueMicrotask(() => {\r\n requestSyncSnapshot({\r\n name,\r\n syncChannels,\r\n instanceId,\r\n authToken: expectedToken,\r\n reportStoreError,\r\n });\r\n });\r\n } catch (e) {\r\n warn(`Failed to setup sync for \"${name}\": ${(e as { message?: string })?.message || e}`);\r\n }\r\n};\r\n\r\nexport const broadcastSync = ({\r\n name,\r\n syncOption,\r\n syncChannels,\r\n syncClocks,\r\n instanceId,\r\n updatedAt,\r\n data,\r\n hashState,\r\n reportStoreError,\r\n}: {\r\n name: string;\r\n syncOption?: boolean | SyncOptions;\r\n syncChannels: SyncChannels;\r\n syncClocks: SyncClocks;\r\n instanceId: string;\r\n updatedAt: string | number;\r\n data: StoreValue;\r\n hashState: (value: unknown) => number;\r\n reportStoreError: (name: string, message: string) => void;\r\n}): void => {\r\n const channel = syncChannels[name];\r\n if (!channel) return;\r\n try {\r\n const checksumMode = typeof syncOption === \"object\" && syncOption.checksum === \"none\" ? \"none\" : \"hash\";\r\n const payload: SyncMessage = {\r\n v: SYNC_PROTOCOL_VERSION,\r\n protocol: SYNC_PROTOCOL_VERSION,\r\n type: \"sync-state\",\r\n source: instanceId,\r\n name,\r\n clock: syncClocks[name] ?? 0,\r\n updatedAt: resolveUpdatedAtMs({ value: updatedAt, fallbackMs: Date.now() }),\r\n data,\r\n checksum: checksumMode === \"hash\" ? hashState(data) : null,\r\n };\r\n if (typeof syncOption === \"object\" && syncOption.authToken) {\r\n payload.token = syncOption.authToken;\r\n }\r\n if (typeof syncOption === \"object\" && typeof syncOption.sign === \"function\") {\r\n try {\r\n const auth = syncOption.sign(payload);\r\n if (auth && typeof (auth as { then?: unknown }).then === \"function\") {\r\n reportStoreError(\r\n name,\r\n `Sync signer for \"${name}\" returned a Promise. \"sign\" must be synchronous.`\r\n );\r\n return;\r\n }\r\n if (auth !== undefined) payload.auth = auth;\r\n } catch (err) {\r\n reportStoreError(\r\n name,\r\n `Failed to sign sync payload for \"${name}\": ${(err as { message?: string })?.message ?? err}`\r\n );\r\n return;\r\n }\r\n }\r\n const maxPayloadBytes = typeof syncOption === \"object\" && typeof syncOption.maxPayloadBytes === \"number\"\r\n ? syncOption.maxPayloadBytes\r\n : 64 * 1024;\r\n const payloadSize = byteLength(JSON.stringify(payload));\r\n\r\n if (payloadSize > maxPayloadBytes) {\r\n reportStoreError(\r\n name,\r\n `Sync payload for \"${name}\" exceeds ${maxPayloadBytes} bytes (${payloadSize} bytes). Skipping BroadcastChannel sync.`\r\n );\r\n return;\r\n }\r\n\r\n try {\r\n channel.postMessage(payload);\r\n } catch (err) {\r\n if (err && typeof err === \"object\" && (err as { name?: string }).name === \"DataCloneError\") {\r\n reportStoreError(\r\n name,\r\n `Sync payload for \"${name}\" could not be cloned (DataCloneError). ` +\r\n `Remove non-serializable values or provide a custom serializer. ` +\r\n `Payload size ~${payloadSize} bytes.`\r\n );\r\n return;\r\n }\r\n throw err;\r\n }\r\n } catch (err) {\r\n reportStoreError(name, `Failed to broadcast sync for \"${name}\": ${(err as { message?: string })?.message ?? err}`);\r\n }\r\n};\r\n\r\nexport const createSyncFeatureRuntime = (): StoreFeatureRuntime => {\r\n const syncChannels: SyncChannels = Object.create(null);\r\n const syncClocks: SyncClocks = Object.create(null);\r\n const syncVersions: SyncVersions = Object.create(null);\r\n const syncWindowCleanup: SyncWindowCleanup = Object.create(null);\r\n const loopGuardUntil: Record<string, number> = Object.create(null);\r\n const loopGuardWarned = new Set<string>();\r\n const instanceId = `stroid_${Math.random().toString(16).slice(2)}`;\r\n\r\n const recordLocalVersion = (name: string, updatedAt: string | number): void => {\r\n syncVersions[name] = {\r\n clock: syncClocks[name] ?? 0,\r\n updatedAt: resolveUpdatedAtMs({ value: updatedAt, fallbackMs: Date.now() }),\r\n source: instanceId,\r\n };\r\n };\r\n\r\n const ensureLocalClock = (name: string, updatedAt: string | number): void => {\r\n bumpSyncClock(name, syncClocks);\r\n recordLocalVersion(name, updatedAt);\r\n };\r\n\r\n const markLoopGuard = (name: string, windowMs: number): void => {\r\n if (!windowMs || !Number.isFinite(windowMs)) return;\r\n loopGuardUntil[name] = Date.now() + windowMs;\r\n };\r\n\r\n const shouldSuppressBroadcast = (name: string, windowMs: number | null): boolean => {\r\n if (!windowMs) return false;\r\n const until = loopGuardUntil[name];\r\n if (!until) return false;\r\n if (Date.now() >= until) {\r\n delete loopGuardUntil[name];\r\n return false;\r\n }\r\n return true;\r\n };\r\n\r\n return {\r\n onStoreCreate(ctx) {\n if (!ctx.options.sync) return;\n const syncOption = ctx.options.sync;\n const policy = typeof syncOption === \"object\" ? syncOption.policy : undefined;\n const allowInsecure = policy === \"insecure\"\n || (policy !== \"strict\" && typeof syncOption === \"object\" && syncOption.insecure === true);\n const hasAuthToken = typeof syncOption === \"object\"\n && typeof syncOption.authToken === \"string\"\n && syncOption.authToken.length > 0;\n const hasVerify = typeof syncOption === \"object\" && typeof syncOption.verify === \"function\";\n const strictPolicy = policy === \"strict\" || (!ctx.isDev() && policy !== \"insecure\");\n if (strictPolicy && syncOption && !allowInsecure && !hasAuthToken && !hasVerify) {\n ctx.reportStoreError(\n `Sync for \"${ctx.name}\" requires authToken or verify in strict mode. ` +\n `Use sync: { policy: \"insecure\" } to acknowledge the risk.`\n );\n ctx.options.sync = false;\n return;\n }\n\r\n setupSync({\r\n name: ctx.name,\r\n syncOption,\r\n syncChannels,\r\n syncClocks,\r\n syncVersions,\r\n syncWindowCleanup,\r\n instanceId,\r\n getMeta: ctx.getMeta,\r\n getAcceptedSyncVersion: (name) => syncVersions[name],\r\n getStoreValue: (name) => ctx.getStoreValue(),\r\n hasStoreEntry: () => ctx.hasStore(),\r\n notify: () => ctx.notify(),\r\n validate: (name, next) => ctx.validate(next),\r\n reportStoreError: (name, message) => ctx.reportStoreError(message),\r\n warn: ctx.warn,\r\n setStoreValue: (name, value) => ctx.setStoreValue(value),\r\n normalizeIncomingState: (name, value) => {\r\n const normalized = normalizeFeatureState({\r\n value,\r\n sanitize: ctx.sanitize,\r\n validate: ctx.validate,\r\n onSanitizeError: (err) => {\r\n ctx.reportStoreError(\r\n `Sanitize failed for incoming sync \"${name}\": ${(err as { message?: string })?.message ?? err}`\r\n );\r\n },\r\n });\r\n if (!normalized.ok) return null;\r\n return normalized.value;\r\n },\r\n acceptIncomingSyncVersion: (name, updatedAtMs, incomingClock, source) => {\r\n ctx.applyFeatureState(ctx.getStoreValue(), updatedAtMs);\r\n syncClocks[ctx.name] = Math.max(syncClocks[ctx.name] ?? 0, incomingClock);\r\n syncVersions[ctx.name] = {\r\n clock: incomingClock,\r\n updatedAt: updatedAtMs,\r\n source,\r\n };\r\n },\r\n resolveSyncVersion: (name, updatedAtMs, incomingClock) => {\r\n ctx.applyFeatureState(ctx.getStoreValue(), updatedAtMs);\r\n const resolvedClock = absorbSyncClock(ctx.name, incomingClock, syncClocks);\r\n syncVersions[ctx.name] = {\r\n clock: resolvedClock,\r\n updatedAt: updatedAtMs,\r\n source: instanceId,\r\n };\r\n return resolvedClock;\r\n },\r\n broadcastSync: () => {\r\n const meta = ctx.getMeta();\r\n if (!meta) return;\r\n broadcastSync({\r\n name: ctx.name,\r\n syncOption: ctx.options.sync,\r\n syncChannels,\r\n syncClocks,\r\n instanceId,\r\n updatedAt: meta.updatedAtMs ?? meta.updatedAt,\r\n data: ctx.getStoreValue(),\r\n hashState: ctx.hashState,\r\n reportStoreError: (name, message) => ctx.reportStoreError(message),\r\n });\r\n },\r\n markLoopGuard,\r\n });\r\n\r\n if (syncChannels[ctx.name]) {\r\n const meta = ctx.getMeta();\r\n recordLocalVersion(ctx.name, meta?.updatedAtMs ?? meta?.updatedAt ?? new Date().toISOString());\r\n }\r\n },\r\n\r\n onStoreWrite(ctx) {\r\n if (!ctx.options.sync) return;\r\n const meta = ctx.getMeta();\r\n if (!meta) return;\r\n const loopGuardMs = resolveLoopGuardMs(ctx.options.sync);\r\n if (shouldSuppressBroadcast(ctx.name, loopGuardMs)) {\r\n ensureLocalClock(ctx.name, meta.updatedAtMs ?? meta.updatedAt);\r\n if (!loopGuardWarned.has(ctx.name)) {\r\n loopGuardWarned.add(ctx.name);\r\n ctx.warn(\r\n `Sync broadcast for \"${ctx.name}\" suppressed by loopGuard to prevent feedback loops.`\r\n );\r\n }\r\n return;\r\n }\r\n ensureLocalClock(ctx.name, meta.updatedAtMs ?? meta.updatedAt);\r\n broadcastSync({\r\n name: ctx.name,\r\n syncOption: ctx.options.sync,\r\n syncChannels,\r\n syncClocks,\r\n instanceId,\r\n updatedAt: meta.updatedAtMs ?? meta.updatedAt,\r\n data: ctx.next,\r\n hashState: ctx.hashState,\r\n reportStoreError: (name, message) => ctx.reportStoreError(message),\r\n });\r\n },\r\n\r\n beforeStoreDelete(ctx) {\r\n closeSyncResources({\r\n name: ctx.name,\r\n syncChannels,\r\n syncWindowCleanup,\r\n syncClocks,\r\n syncVersions,\r\n });\r\n delete loopGuardUntil[ctx.name];\r\n loopGuardWarned.delete(ctx.name);\r\n },\r\n\r\n resetAll() {\r\n cleanupAllSyncResources({\r\n syncChannels,\r\n syncWindowCleanup,\r\n });\r\n Object.keys(syncChannels).forEach((key) => delete syncChannels[key]);\r\n Object.keys(syncClocks).forEach((key) => delete syncClocks[key]);\r\n Object.keys(syncVersions).forEach((key) => delete syncVersions[key]);\r\n Object.keys(syncWindowCleanup).forEach((key) => delete syncWindowCleanup[key]);\r\n Object.keys(loopGuardUntil).forEach((key) => delete loopGuardUntil[key]);\r\n insecureSyncWarned.clear();\r\n signerVerifyWarned.clear();\r\n loopGuardWarned.clear();\r\n },\r\n };\r\n};\r\n\r\nexport const registerSyncFeature = (): void => {\r\n if (_registered) return;\r\n _registered = true;\r\n registerStoreFeature(\"sync\", createSyncFeatureRuntime);\r\n};\r\n\r\n\r\n","/**\r\n * @module install\r\n *\r\n * LAYER: Module\r\n * OWNS: Module-level behavior and exports for install.\r\n *\r\n * Consumers: Internal imports and public API.\r\n */\r\nimport { registerPersistFeature } from \"./features/persist.js\";\r\nimport { registerSyncFeature } from \"./features/sync.js\";\r\nimport { registerDevtoolsFeature } from \"./features/devtools.js\";\r\n\r\nexport const installPersist = (): void => {\r\n registerPersistFeature();\r\n};\r\n\r\nexport const installSync = (): void => {\r\n registerSyncFeature();\r\n};\r\n\r\nexport const installDevtools = (): void => {\r\n registerDevtoolsFeature();\r\n};\r\n\r\nexport const installAllFeatures = (): void => {\r\n installPersist();\r\n installSync();\r\n installDevtools();\r\n};\r\n\r\n\r\n","/**\r\n * @module sync\r\n *\r\n * LAYER: Public API\r\n * OWNS: Module-level behavior and exports for sync.\r\n *\r\n * Consumers: Internal imports and public API.\r\n */\r\nimport { installSync } from \"./install.js\";\r\n\r\ninstallSync();\r\n\r\nexport { installSync };\r\n\r\n\r\n"]}
|
package/dist/testing.d.ts
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { a as StoreDefinition, b as StoreKey, P as PartialDeep, W as WriteResult } from './types.js';
|
|
2
|
+
|
|
3
|
+
declare const createMockStore: <Name extends string, State extends Record<string, unknown> = Record<string, unknown>>(name?: Name, initial?: State) => {
|
|
4
|
+
set: (update: PartialDeep<State> | ((draft: State) => void)) => WriteResult;
|
|
5
|
+
reset: () => WriteResult;
|
|
6
|
+
use: () => StoreDefinition<Name, State>;
|
|
7
|
+
};
|
|
8
|
+
declare const withMockedTime: <T>(nowMs: number, fn: () => T) => T;
|
|
9
|
+
declare const resetAllStoresForTest: () => void;
|
|
10
|
+
declare const benchmarkStoreSet: <Name extends string, State extends Record<string, unknown>>(name: StoreDefinition<Name, State> | StoreKey<Name, State>, iterations?: number, makeUpdate?: (i: number) => PartialDeep<State>) => {
|
|
11
|
+
iterations: number;
|
|
12
|
+
totalMs: number;
|
|
13
|
+
avgMs: number;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export { benchmarkStoreSet, createMockStore, resetAllStoresForTest, withMockedTime };
|