@directive-run/core 0.1.1
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/LICENSE +21 -0
- package/README.md +57 -0
- package/dist/adapter-utils.cjs +2 -0
- package/dist/adapter-utils.cjs.map +1 -0
- package/dist/adapter-utils.d.cts +230 -0
- package/dist/adapter-utils.d.ts +230 -0
- package/dist/adapter-utils.js +2 -0
- package/dist/adapter-utils.js.map +1 -0
- package/dist/index.cjs +35 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2016 -0
- package/dist/index.d.ts +2016 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/migration.cjs +25 -0
- package/dist/migration.cjs.map +1 -0
- package/dist/migration.d.cts +109 -0
- package/dist/migration.d.ts +109 -0
- package/dist/migration.js +25 -0
- package/dist/migration.js.map +1 -0
- package/dist/plugins/index.cjs +3 -0
- package/dist/plugins/index.cjs.map +1 -0
- package/dist/plugins/index.d.cts +697 -0
- package/dist/plugins/index.d.ts +697 -0
- package/dist/plugins/index.js +3 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins-CcwEXXMS.d.cts +1876 -0
- package/dist/plugins-CcwEXXMS.d.ts +1876 -0
- package/dist/testing.cjs +12 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +235 -0
- package/dist/testing.d.ts +235 -0
- package/dist/testing.js +12 -0
- package/dist/testing.js.map +1 -0
- package/dist/utils-4JrY5fk9.d.cts +198 -0
- package/dist/utils-4JrY5fk9.d.ts +198 -0
- package/dist/worker.cjs +12 -0
- package/dist/worker.cjs.map +1 -0
- package/dist/worker.d.cts +241 -0
- package/dist/worker.d.ts +241 -0
- package/dist/worker.js +12 -0
- package/dist/worker.js.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function f(){let t=new Set;return {get isTracking(){return true},track(e){t.add(e);},getDependencies(){return t}}}function d(t){let e=f();try{return {value:t(),deps:e.getDependencies()}}finally{}}function g(t,e,r){t[e]=r;}function m(t,e){return t[e]}function p(t,e){return {name:t,onRequirementCreated:e.onRequirementCreated?r=>e.onRequirementCreated(r.requirement):void 0,onRequirementMet:e.onRequirementResolved?r=>e.onRequirementResolved(r.requirement):void 0,onError:e.onError}}function h(t){return e=>e.type===t}function y(t){let e=new Set(t);return r=>e.has(r.type)}function x(t,e){if(t===e)return true;if(!t||!e)return false;let r=Object.keys(t),n=Object.keys(e);if(r.length!==n.length)return false;for(let o of r)if(t[o]!==e[o])return false;return true}function w(t){let e=t.inspect();return {isSettled:t.isSettled,unmet:e.unmet,inflight:e.inflight,isWorking:e.unmet.length>0||e.inflight.length>0,hasUnmet:e.unmet.length>0,hasInflight:e.inflight.length>0}}function b(t,e){let r=null,n=null,o=0;return {throttled:((...s)=>{let i=Date.now(),c=i-o;c>=e?(o=i,t(...s)):(n=s,r||(r=setTimeout(()=>{r=null,o=Date.now(),n&&(t(...n),n=null);},e-c)));}),cleanup:()=>{r&&(clearTimeout(r),r=null),n=null;}}}function q(t,e){if(process.env.NODE_ENV!=="production"&&e==null)throw new Error(`[Directive] ${t}() requires a system instance as the first argument. Received ${e}.`)}function v(t,e){return Object.is(t,e)}function A(t){let e=t.debug;if(!e)return null;let r=e.snapshots.map(n=>({id:n.id,timestamp:n.timestamp,trigger:n.trigger}));return {canUndo:e.currentIndex>0,canRedo:e.currentIndex<e.snapshots.length-1,undo:()=>e.goBack(),redo:()=>e.goForward(),currentIndex:e.currentIndex,totalSnapshots:e.snapshots.length,snapshots:r,getSnapshotFacts:n=>{let o=e.snapshots.find(a=>a.id===n);return o?o.facts:null},goTo:n=>e.goTo(n),goBack:n=>e.goBack(n),goForward:n=>e.goForward(n),replay:()=>e.replay(),exportSession:()=>e.export(),importSession:n=>e.import(n),beginChangeset:n=>e.beginChangeset(n),endChangeset:()=>e.endChangeset(),isPaused:e.isPaused,pause:()=>e.pause(),resume:()=>e.resume()}}function C(t,e){let r={};for(let n of e)r[n]=t.facts.$store.get(n);return r}function D(t,e,r){let n=[],o=new Proxy({},{get(s,i){if(typeof i=="string")return e.has(i)?(n.push(i),t.read(i)):t.facts.$store.get(i)},has(s,i){return typeof i!="string"?false:e.has(i)||t.facts.$store.has(i)},ownKeys(){let s=Object.keys(t.facts.$store.toObject()),i=new Set(s);for(let c of e)i.add(c);return [...i]},getOwnPropertyDescriptor(){return {configurable:true,enumerable:true,writable:true}}}),{value:a,deps:u}=d(()=>r(o));return {value:a,factKeys:Array.from(u),deriveKeys:n}}function E(t,e,r,n){let o=e.length!==t.length||e.some((u,s)=>u!==t[s]),a=n.length!==r.length||n.some((u,s)=>u!==r[s]);return o||a}export{q as assertSystem,A as buildTimeTravelState,w as computeInspectState,p as createCallbackPlugin,b as createThrottle,v as defaultEquality,E as depsChanged,m as getBridgeFact,C as pickFacts,h as requirementGuard,y as requirementGuardMultiple,D as runTrackedSelector,g as setBridgeFact,x as shallowEqual};//# sourceMappingURL=adapter-utils.js.map
|
|
2
|
+
//# sourceMappingURL=adapter-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/tracking.ts","../src/core/types/adapter-utils.ts","../src/utils/utils.ts","../src/adapter-utils.ts"],"names":["createTrackingContext","dependencies","key","withTracking","fn","context","setBridgeFact","facts","value","getBridgeFact","createCallbackPlugin","name","callbacks","req","requirementGuard","type","requirementGuardMultiple","types","typeSet","shallowEqual","a","b","keysA","keysB","computeInspectState","system","inspection","createThrottle","callback","ms","timeoutId","lastArgs","lastCallTime","args","now","timeSinceLastCall","assertSystem","hookName","defaultEquality","buildTimeTravelState","debug","snapshots","s","id","snap","snapshotId","steps","json","label","pickFacts","keys","result","runTrackedSelector","deriveKeySet","selector","accessedDeriveKeys","stateProxy","_","prop","factKeys","combined","k","deps","depsChanged","prevFacts","newFacts","prevDerived","newDerived","factsChanged","i","derivedChanged"],"mappings":"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","file":"adapter-utils.js","sourcesContent":["/**\n * Dependency tracking context for auto-tracking derivations\n *\n * Uses a stack-based approach to handle nested derivation computations.\n * When a derivation accesses a fact, the tracking context records it.\n */\n\nimport type { TrackingContext } from \"./types.js\";\n\n/** Stack of active tracking contexts */\nconst trackingStack: TrackingContext[] = [];\n\n/** Create a new tracking context */\nfunction createTrackingContext(): TrackingContext {\n\tconst dependencies = new Set<string>();\n\n\treturn {\n\t\tget isTracking() {\n\t\t\treturn true;\n\t\t},\n\t\ttrack(key: string) {\n\t\t\tdependencies.add(key);\n\t\t},\n\t\tgetDependencies() {\n\t\t\treturn dependencies;\n\t\t},\n\t};\n}\n\n/** Null tracking context when not tracking */\nconst nullContext: TrackingContext = {\n\tisTracking: false,\n\ttrack() {},\n\tgetDependencies() {\n\t\treturn new Set();\n\t},\n};\n\n/**\n * Get the current tracking context.\n * Returns null context if no tracking is active.\n */\nexport function getCurrentTracker(): TrackingContext {\n\treturn trackingStack[trackingStack.length - 1] ?? nullContext;\n}\n\n/**\n * Check if we're currently tracking dependencies.\n */\nexport function isTracking(): boolean {\n\treturn trackingStack.length > 0;\n}\n\n/**\n * Run a function with dependency tracking.\n * Returns the computed value and the set of dependencies accessed.\n */\nexport function withTracking<T>(fn: () => T): { value: T; deps: Set<string> } {\n\tconst context = createTrackingContext();\n\ttrackingStack.push(context);\n\n\ttry {\n\t\tconst value = fn();\n\t\treturn { value, deps: context.getDependencies() };\n\t} finally {\n\t\ttrackingStack.pop();\n\t}\n}\n\n/**\n * Run a function without tracking.\n * Useful for reading facts without creating dependencies.\n */\nexport function withoutTracking<T>(fn: () => T): T {\n\t// Temporarily clear the stack\n\tconst saved = trackingStack.splice(0, trackingStack.length);\n\n\ttry {\n\t\treturn fn();\n\t} finally {\n\t\t// Restore the stack\n\t\ttrackingStack.push(...saved);\n\t}\n}\n\n/**\n * Track a specific key in the current context.\n * No-op if not currently tracking.\n */\nexport function trackAccess(key: string): void {\n\tgetCurrentTracker().track(key);\n}\n","/**\n * Adapter Type Utilities - Shared types and helpers for framework adapters\n *\n * These utilities reduce type assertions in adapters by providing:\n * - Schema composition types\n * - Constraint/resolver converters\n * - Plugin factory helpers\n */\n\nimport type { Schema, InferSchema } from \"./schema.js\";\nimport type { Facts } from \"./facts.js\";\nimport type { Requirement, ConstraintDef } from \"./requirements.js\";\nimport type { ResolverDef, ResolverContext } from \"./resolvers.js\";\nimport type { Plugin } from \"./plugins.js\";\n\n// ============================================================================\n// Schema Composition Types\n// ============================================================================\n\n/**\n * Merge two schemas into one.\n * Useful for adapters that add bridge-specific facts to user schemas.\n *\n * @example\n * ```typescript\n * type BridgeFields = { __state: SchemaType<Record<string, unknown>> };\n * type Combined = MergedSchema<UserSchema, BridgeFields>;\n * ```\n */\nexport type MergedSchema<\n\tBase extends Schema,\n\tExtra extends Schema,\n> = Base & Extra;\n\n/**\n * Create a schema type from a fields definition.\n * Helper for defining adapter bridge schemas.\n *\n * @example\n * ```typescript\n * type AdapterBridgeSchema = BridgeSchema<{\n * __adapterState: SchemaType<Record<string, unknown>>;\n * }>;\n * ```\n */\nexport type BridgeSchema<Fields extends Schema> = Fields;\n\n// ============================================================================\n// Bridge Schema Helper\n// ============================================================================\n\n/**\n * Create a bridge schema definition for adapters.\n * Returns a schema object compatible with createModule().\n *\n * @example\n * ```typescript\n * const bridgeSchema = createBridgeSchema({\n * __state: t.object<Record<string, unknown>>(),\n * });\n * ```\n */\nexport function createBridgeSchema<S extends Schema>(schema: S): S {\n\treturn schema;\n}\n\n// ============================================================================\n// Type-Safe Fact Mutation\n// ============================================================================\n\n/**\n * Type-safe fact setter for known schema keys.\n * Use when you have a typed schema and want to set a specific fact.\n *\n * @example\n * ```typescript\n * setFact(facts, \"count\", 10); // Type-checked\n * ```\n */\nexport function setFact<S extends Schema, K extends keyof InferSchema<S>>(\n\tfacts: Facts<S>,\n\tkey: K,\n\tvalue: InferSchema<S>[K],\n): void {\n\t(facts as Record<string, unknown>)[key as string] = value;\n}\n\n/**\n * Set a bridge fact without strict typing.\n * Use for adapter-internal bridge fields like `__adapterState`.\n *\n * @example\n * ```typescript\n * setBridgeFact(facts, \"__adapterState\", currentState);\n * ```\n */\nexport function setBridgeFact<V>(\n\tfacts: Facts<Schema>,\n\tkey: string,\n\tvalue: V,\n): void {\n\t(facts as Record<string, unknown>)[key] = value;\n}\n\n/**\n * Get a bridge fact without strict typing.\n * Use for adapter-internal bridge fields.\n *\n * @example\n * ```typescript\n * const state = getBridgeFact<MyState>(facts, \"__adapterState\");\n * ```\n */\nexport function getBridgeFact<V>(\n\tfacts: Facts<Schema>,\n\tkey: string,\n): V {\n\treturn (facts as Record<string, unknown>)[key] as V;\n}\n\n// ============================================================================\n// Constraint Converters\n// ============================================================================\n\n/**\n * Adapter constraint definition (generic form used by adapters).\n */\nexport interface AdapterConstraint<TState> {\n\twhen: (state: TState) => boolean | Promise<boolean>;\n\trequire: Requirement | ((state: TState) => Requirement | null);\n\tpriority?: number;\n}\n\n/**\n * Convert adapter-style constraints to Directive format.\n * Maps adapter constraints that work with external state (TState) to\n * Directive constraints that work with Facts<Schema>.\n *\n * @param constraints - Adapter constraints keyed by name\n * @param extractState - Function to extract adapter state from facts\n *\n * @example\n * ```typescript\n * const directiveConstraints = convertConstraints<MyState, BridgeSchema>(\n * adapterConstraints,\n * (facts) => getBridgeFact<MyState>(facts, \"__state\"),\n * );\n * ```\n */\nexport function convertConstraints<TState, S extends Schema>(\n\tconstraints: Record<string, AdapterConstraint<TState>>,\n\textractState: (facts: Facts<S>) => TState,\n): Record<string, ConstraintDef<S, Requirement>> {\n\tconst result: Record<string, ConstraintDef<S, Requirement>> = {};\n\n\tfor (const [id, constraint] of Object.entries(constraints)) {\n\t\tresult[id] = {\n\t\t\tpriority: constraint.priority ?? 0,\n\t\t\twhen: (facts) => constraint.when(extractState(facts)),\n\t\t\trequire: (facts) => {\n\t\t\t\tconst req = typeof constraint.require === \"function\"\n\t\t\t\t\t? constraint.require(extractState(facts))\n\t\t\t\t\t: constraint.require;\n\t\t\t\treturn req;\n\t\t\t},\n\t\t};\n\t}\n\n\treturn result;\n}\n\n// ============================================================================\n// Resolver Converters\n// ============================================================================\n\n/**\n * Adapter resolver context (generic form used by adapters).\n */\nexport interface AdapterResolverContext<TContext> {\n\tcontext: TContext;\n\tsignal: AbortSignal;\n}\n\n/**\n * Adapter resolver definition (generic form used by adapters).\n */\nexport interface AdapterResolver<TContext, R extends Requirement = Requirement> {\n\trequirement: (req: Requirement) => req is R;\n\tkey?: (req: R) => string;\n\tresolve: (req: R, ctx: AdapterResolverContext<TContext>) => void | Promise<void>;\n}\n\n/**\n * Convert adapter-style resolvers to Directive format.\n * Maps adapter resolvers that work with external context (TContext) to\n * Directive resolvers that work with ResolverContext<Schema>.\n *\n * @param resolvers - Adapter resolvers keyed by name\n * @param createContext - Function to create adapter context from Directive context\n *\n * @example\n * ```typescript\n * const directiveResolvers = convertResolvers<MyContext, BridgeSchema>(\n * adapterResolvers,\n * (ctx) => ({\n * getState: () => getBridgeFact<MyState>(ctx.facts, \"__state\"),\n * setState: (update) => setBridgeFact(ctx.facts, \"__state\", update),\n * signal: ctx.signal,\n * }),\n * );\n * ```\n */\nexport function convertResolvers<TContext, S extends Schema>(\n\tresolvers: Record<string, AdapterResolver<TContext, Requirement>>,\n\tcreateContext: (ctx: ResolverContext<S>) => TContext,\n): Record<string, ResolverDef<S, Requirement>> {\n\tconst result: Record<string, ResolverDef<S, Requirement>> = {};\n\n\tfor (const [id, resolver] of Object.entries(resolvers)) {\n\t\tresult[id] = {\n\t\t\trequirement: resolver.requirement,\n\t\t\tkey: resolver.key,\n\t\t\tresolve: async (req, ctx) => {\n\t\t\t\tconst adapterCtx = createContext(ctx);\n\t\t\t\tawait resolver.resolve(req, { context: adapterCtx, signal: ctx.signal });\n\t\t\t},\n\t\t};\n\t}\n\n\treturn result;\n}\n\n// ============================================================================\n// Plugin Factory\n// ============================================================================\n\n/**\n * Callback definitions for adapter plugins.\n */\nexport interface AdapterCallbacks {\n\tonRequirementCreated?: (req: Requirement) => void;\n\tonRequirementResolved?: (req: Requirement) => void;\n\tonError?: (error: Error) => void;\n}\n\n/**\n * Create a callback plugin for adapter events.\n * Wraps adapter callbacks in a Directive plugin.\n *\n * @param name - Plugin name (for debugging)\n * @param callbacks - Callback functions to invoke\n *\n * @example\n * ```typescript\n * const callbackPlugin = createCallbackPlugin(\"adapter-callbacks\", {\n * onRequirementCreated: (req) => console.log(\"Created:\", req),\n * onRequirementResolved: (req) => console.log(\"Resolved:\", req),\n * });\n * ```\n */\n// biome-ignore lint/suspicious/noExplicitAny: Plugins work with any schema type\nexport function createCallbackPlugin(\n\tname: string,\n\tcallbacks: AdapterCallbacks,\n): Plugin<any> {\n\treturn {\n\t\tname,\n\t\tonRequirementCreated: callbacks.onRequirementCreated\n\t\t\t? (req) => callbacks.onRequirementCreated!(req.requirement)\n\t\t\t: undefined,\n\t\tonRequirementMet: callbacks.onRequirementResolved\n\t\t\t? (req) => callbacks.onRequirementResolved!(req.requirement)\n\t\t\t: undefined,\n\t\tonError: callbacks.onError,\n\t};\n}\n\n// ============================================================================\n// Module Config Helpers\n// ============================================================================\n\n/**\n * Cast constraints to the correct type for createModule.\n * Use this when TypeScript can't infer the constraint types correctly.\n */\nexport function asConstraints<S extends Schema>(\n\tconstraints: Record<string, ConstraintDef<S, Requirement>>,\n): Record<string, ConstraintDef<S, Requirement>> {\n\treturn constraints;\n}\n\n/**\n * Cast resolvers to the correct type for createModule.\n * Use this when TypeScript can't infer the resolver types correctly.\n */\nexport function asResolvers<S extends Schema>(\n\tresolvers: Record<string, ResolverDef<S, Requirement>>,\n): Record<string, ResolverDef<S, Requirement>> {\n\treturn resolvers;\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Create a type guard for a specific requirement type.\n * Simplifies the common pattern of checking req.type.\n *\n * @example\n * ```typescript\n * const isResetReq = requirementGuard<ResetReq>(\"RESET\");\n * // Use in resolver:\n * { requirement: isResetReq, resolve: ... }\n * ```\n */\nexport function requirementGuard<R extends Requirement>(\n\ttype: R[\"type\"],\n): (req: Requirement) => req is R {\n\treturn (req): req is R => req.type === type;\n}\n\n/**\n * Create a type guard that matches multiple requirement types.\n *\n * @example\n * ```typescript\n * const isDataReq = requirementGuardMultiple<FetchReq | RefreshReq>([\"FETCH\", \"REFRESH\"]);\n * ```\n */\nexport function requirementGuardMultiple<R extends Requirement>(\n\ttypes: Array<R[\"type\"]>,\n): (req: Requirement) => req is R {\n\tconst typeSet = new Set(types);\n\treturn (req): req is R => typeSet.has(req.type);\n}\n","/**\n * Shared utilities for Directive\n */\n\n/**\n * Execute a promise with a timeout, properly cleaning up the timer.\n * Used by both constraints and resolvers for timeout handling.\n *\n * @param promise - The promise to wrap with a timeout\n * @param ms - Timeout duration in milliseconds\n * @param errorMessage - Error message if timeout occurs\n * @returns The promise result\n * @throws Error if timeout is exceeded\n */\nexport async function withTimeout<T>(\n\tpromise: Promise<T>,\n\tms: number,\n\terrorMessage: string,\n): Promise<T> {\n\tlet timeoutId: ReturnType<typeof setTimeout>;\n\n\tconst timeoutPromise = new Promise<never>((_, reject) => {\n\t\ttimeoutId = setTimeout(() => reject(new Error(errorMessage)), ms);\n\t});\n\n\ttry {\n\t\treturn await Promise.race([promise, timeoutPromise]);\n\t} finally {\n\t\tclearTimeout(timeoutId!);\n\t}\n}\n\n/**\n * Normalize an error to an Error instance.\n * Ensures consistent error handling throughout the library.\n *\n * @param error - The error to normalize (can be anything)\n * @returns An Error instance\n */\nexport function normalizeError(error: unknown): Error {\n\tif (error instanceof Error) {\n\t\treturn error;\n\t}\n\treturn new Error(String(error));\n}\n\n/**\n * Create a stable JSON string with sorted keys.\n * Handles circular references and deeply nested objects safely.\n *\n * @param value - The value to stringify\n * @param maxDepth - Maximum nesting depth (default: 50)\n * @returns A stable JSON string\n */\nexport function stableStringify(value: unknown, maxDepth = 50): string {\n\tconst seen = new WeakSet();\n\n\tfunction stringify(val: unknown, depth: number): string {\n\t\tif (depth > maxDepth) {\n\t\t\treturn '\"[max depth exceeded]\"';\n\t\t}\n\n\t\tif (val === null) return \"null\";\n\t\tif (val === undefined) return \"undefined\";\n\n\t\tconst type = typeof val;\n\n\t\tif (type === \"string\") return JSON.stringify(val);\n\t\tif (type === \"number\" || type === \"boolean\") return String(val);\n\t\tif (type === \"function\") return '\"[function]\"';\n\t\tif (type === \"symbol\") return '\"[symbol]\"';\n\n\t\tif (Array.isArray(val)) {\n\t\t\t// Check for circular reference\n\t\t\tif (seen.has(val)) {\n\t\t\t\treturn '\"[circular]\"';\n\t\t\t}\n\t\t\tseen.add(val);\n\t\t\tconst result = `[${val.map((v) => stringify(v, depth + 1)).join(\",\")}]`;\n\t\t\tseen.delete(val);\n\t\t\treturn result;\n\t\t}\n\n\t\tif (type === \"object\") {\n\t\t\tconst obj = val as Record<string, unknown>;\n\t\t\t// Check for circular reference\n\t\t\tif (seen.has(obj)) {\n\t\t\t\treturn '\"[circular]\"';\n\t\t\t}\n\t\t\tseen.add(obj);\n\t\t\tconst keys = Object.keys(obj).sort();\n\t\t\tconst pairs = keys.map((k) => `${JSON.stringify(k)}:${stringify(obj[k], depth + 1)}`);\n\t\t\tconst result = `{${pairs.join(\",\")}}`;\n\t\t\tseen.delete(obj);\n\t\t\treturn result;\n\t\t}\n\n\t\treturn '\"[unknown]\"';\n\t}\n\n\treturn stringify(value, 0);\n}\n\n/**\n * Check for prototype pollution in an object, including nested objects.\n * Returns true if the object is safe, false if dangerous keys are found.\n *\n * @param obj - The object to check\n * @param maxDepth - Maximum nesting depth to check (default: 50)\n * @returns True if safe, false if dangerous keys found\n */\nexport function isPrototypeSafe(obj: unknown, maxDepth = 50): boolean {\n\tconst dangerousKeys = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\tconst seen = new WeakSet();\n\n\tfunction check(val: unknown, depth: number): boolean {\n\t\tif (depth > maxDepth) return false; // Fail safe at max depth - don't assume safety\n\t\tif (val === null || val === undefined) return true;\n\t\tif (typeof val !== \"object\") return true;\n\n\t\tconst objVal = val as Record<string, unknown>;\n\n\t\t// Check for circular reference\n\t\tif (seen.has(objVal)) return true;\n\t\tseen.add(objVal);\n\n\t\t// Check array elements\n\t\tif (Array.isArray(objVal)) {\n\t\t\tfor (const item of objVal) {\n\t\t\t\tif (!check(item, depth + 1)) {\n\t\t\t\t\tseen.delete(objVal);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tseen.delete(objVal);\n\t\t\treturn true;\n\t\t}\n\n\t\t// Check object keys and values\n\t\tfor (const key of Object.keys(objVal)) {\n\t\t\tif (dangerousKeys.has(key)) {\n\t\t\t\tseen.delete(objVal);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!check(objVal[key], depth + 1)) {\n\t\t\t\tseen.delete(objVal);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tseen.delete(objVal);\n\t\treturn true;\n\t}\n\n\treturn check(obj, 0);\n}\n\n/**\n * Shallow equality comparison for objects.\n * Used by React hooks to avoid unnecessary re-renders.\n *\n * @param a - First object\n * @param b - Second object\n * @returns True if objects are shallowly equal\n */\nexport function shallowEqual<T extends Record<string, unknown>>(a: T, b: T): boolean {\n\tif (a === b) return true;\n\tif (!a || !b) return false;\n\n\tconst keysA = Object.keys(a);\n\tconst keysB = Object.keys(b);\n\n\tif (keysA.length !== keysB.length) return false;\n\n\tfor (const key of keysA) {\n\t\tif (a[key] !== b[key]) return false;\n\t}\n\n\treturn true;\n}\n\n/**\n * Generate a simple hash string from an object.\n * Uses djb2 algorithm on the stable stringified value.\n *\n * **Limitations:**\n * - 32-bit hash output means collision probability increases with data set size\n * (birthday paradox: ~50% collision chance at ~77,000 distinct values)\n * - Suitable for: cache invalidation, change detection, deduplication of small sets\n * - NOT suitable for: cryptographic use, security-sensitive operations, large-scale deduplication\n *\n * For security-sensitive use cases requiring stronger collision resistance,\n * consider using a cryptographic hash like SHA-256.\n *\n * @param value - The value to hash\n * @returns A hex hash string (8 characters, 32 bits)\n */\nexport function hashObject(value: unknown): string {\n\tconst str = stableStringify(value);\n\tlet hash = 5381;\n\tfor (let i = 0; i < str.length; i++) {\n\t\thash = ((hash << 5) + hash) ^ str.charCodeAt(i);\n\t}\n\t// Convert to unsigned 32-bit and then to hex\n\treturn (hash >>> 0).toString(16);\n}\n\n// ============================================================================\n// Distributable Snapshot Utilities\n// ============================================================================\n\n/**\n * Distributable snapshot type for type-safe helper functions.\n */\nexport interface DistributableSnapshotLike<T = Record<string, unknown>> {\n\tdata: T;\n\tcreatedAt: number;\n\texpiresAt?: number;\n\tversion?: string;\n\tmetadata?: Record<string, unknown>;\n}\n\n/**\n * Check if a distributable snapshot has expired.\n * Returns false if the snapshot has no expiresAt field.\n *\n * @example\n * ```typescript\n * const snapshot = system.getDistributableSnapshot({ ttlSeconds: 3600 });\n * // ... later ...\n * if (isSnapshotExpired(snapshot)) {\n * // Refresh the snapshot\n * }\n * ```\n *\n * @param snapshot - The snapshot to check\n * @param now - Optional current timestamp (defaults to Date.now())\n * @returns True if the snapshot has expired, false otherwise\n */\nexport function isSnapshotExpired<T>(\n\tsnapshot: DistributableSnapshotLike<T>,\n\tnow: number = Date.now(),\n): boolean {\n\treturn snapshot.expiresAt !== undefined && now > snapshot.expiresAt;\n}\n\n/**\n * Validate a distributable snapshot and return its data.\n * Throws if the snapshot is malformed or has expired.\n *\n * @example\n * ```typescript\n * const cached = JSON.parse(await redis.get(`entitlements:${userId}`));\n * try {\n * const data = validateSnapshot(cached);\n * // Use data.canUseFeature, etc.\n * } catch (e) {\n * // Snapshot invalid or expired, refresh it\n * }\n * ```\n *\n * @example Using custom timestamp for testing\n * ```typescript\n * const snapshot = { data: { test: true }, createdAt: 1000, expiresAt: 2000 };\n * validateSnapshot(snapshot, 1500); // Returns { test: true }\n * validateSnapshot(snapshot, 2500); // Throws: Snapshot expired\n * ```\n *\n * @param snapshot - The snapshot to validate\n * @param now - Optional current timestamp (defaults to Date.now())\n * @returns The snapshot data if valid\n * @throws Error if the snapshot is malformed or has expired\n */\nexport function validateSnapshot<T>(\n\tsnapshot: DistributableSnapshotLike<T>,\n\tnow: number = Date.now(),\n): T {\n\t// Structural validation\n\tif (!snapshot || typeof snapshot !== \"object\") {\n\t\tthrow new Error(\n\t\t\t\"[Directive] Invalid snapshot: expected an object with 'data' and 'createdAt' properties.\",\n\t\t);\n\t}\n\tif (!(\"data\" in snapshot)) {\n\t\tthrow new Error(\n\t\t\t\"[Directive] Invalid snapshot: missing required 'data' property.\",\n\t\t);\n\t}\n\tif (!(\"createdAt\" in snapshot) || typeof snapshot.createdAt !== \"number\") {\n\t\tthrow new Error(\n\t\t\t\"[Directive] Invalid snapshot: missing or invalid 'createdAt' property (expected number).\",\n\t\t);\n\t}\n\n\t// Expiration validation\n\tif (isSnapshotExpired(snapshot, now)) {\n\t\tconst expiredAt = new Date(snapshot.expiresAt!).toISOString();\n\t\tthrow new Error(\n\t\t\t`[Directive] Snapshot expired at ${expiredAt}. Obtain a fresh snapshot from the source.`,\n\t\t);\n\t}\n\treturn snapshot.data;\n}\n\n/**\n * Diff result for a single changed value.\n */\nexport interface SnapshotDiffEntry {\n\t/** The key path that changed (e.g., \"canUseApi\" or \"limits.apiCalls\") */\n\tpath: string;\n\t/** The value in the old snapshot */\n\toldValue: unknown;\n\t/** The value in the new snapshot */\n\tnewValue: unknown;\n\t/** Type of change: \"added\", \"removed\", or \"changed\" */\n\ttype: \"added\" | \"removed\" | \"changed\";\n}\n\n/**\n * Result of diffing two snapshots.\n */\nexport interface SnapshotDiff {\n\t/** Whether the snapshots are identical */\n\tidentical: boolean;\n\t/** List of changes between snapshots */\n\tchanges: SnapshotDiffEntry[];\n\t/** Whether the version changed (if both have versions) */\n\tversionChanged: boolean;\n\t/** Old version (if available) */\n\toldVersion?: string;\n\t/** New version (if available) */\n\tnewVersion?: string;\n}\n\n/**\n * Compare two distributable snapshots and return the differences.\n * Useful for debugging, audit logs, and webhook payloads.\n *\n * @example\n * ```typescript\n * const oldSnapshot = system.getDistributableSnapshot({ includeVersion: true });\n * system.dispatch({ type: \"upgradePlan\", plan: \"pro\" });\n * const newSnapshot = system.getDistributableSnapshot({ includeVersion: true });\n *\n * const diff = diffSnapshots(oldSnapshot, newSnapshot);\n * if (!diff.identical) {\n * console.log(\"Changes:\", diff.changes);\n * // [{ path: \"canUseApi\", oldValue: false, newValue: true, type: \"changed\" }]\n * }\n * ```\n *\n * @param oldSnapshot - The previous snapshot\n * @param newSnapshot - The new snapshot\n * @returns A diff result with all changes\n */\nexport function diffSnapshots<T = Record<string, unknown>>(\n\toldSnapshot: DistributableSnapshotLike<T>,\n\tnewSnapshot: DistributableSnapshotLike<T>,\n): SnapshotDiff {\n\tconst changes: SnapshotDiffEntry[] = [];\n\n\t// Deep compare function\n\tfunction compare(\n\t\toldObj: unknown,\n\t\tnewObj: unknown,\n\t\tpath: string,\n\t): void {\n\t\t// Handle null/undefined\n\t\tif (oldObj === null || oldObj === undefined) {\n\t\t\tif (newObj !== null && newObj !== undefined) {\n\t\t\t\tchanges.push({ path, oldValue: oldObj, newValue: newObj, type: \"added\" });\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (newObj === null || newObj === undefined) {\n\t\t\tchanges.push({ path, oldValue: oldObj, newValue: newObj, type: \"removed\" });\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle primitives\n\t\tif (typeof oldObj !== \"object\" || typeof newObj !== \"object\") {\n\t\t\tif (!Object.is(oldObj, newObj)) {\n\t\t\t\tchanges.push({ path, oldValue: oldObj, newValue: newObj, type: \"changed\" });\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle arrays\n\t\tif (Array.isArray(oldObj) && Array.isArray(newObj)) {\n\t\t\tif (oldObj.length !== newObj.length) {\n\t\t\t\tchanges.push({ path, oldValue: oldObj, newValue: newObj, type: \"changed\" });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (let i = 0; i < oldObj.length; i++) {\n\t\t\t\tcompare(oldObj[i], newObj[i], `${path}[${i}]`);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle objects\n\t\tconst oldRecord = oldObj as Record<string, unknown>;\n\t\tconst newRecord = newObj as Record<string, unknown>;\n\t\tconst allKeys = new Set([...Object.keys(oldRecord), ...Object.keys(newRecord)]);\n\n\t\tfor (const key of allKeys) {\n\t\t\tconst childPath = path ? `${path}.${key}` : key;\n\t\t\tif (!(key in oldRecord)) {\n\t\t\t\tchanges.push({ path: childPath, oldValue: undefined, newValue: newRecord[key], type: \"added\" });\n\t\t\t} else if (!(key in newRecord)) {\n\t\t\t\tchanges.push({ path: childPath, oldValue: oldRecord[key], newValue: undefined, type: \"removed\" });\n\t\t\t} else {\n\t\t\t\tcompare(oldRecord[key], newRecord[key], childPath);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compare data\n\tcompare(oldSnapshot.data, newSnapshot.data, \"\");\n\n\t// Check version change\n\tconst versionChanged = oldSnapshot.version !== newSnapshot.version &&\n\t\t(oldSnapshot.version !== undefined || newSnapshot.version !== undefined);\n\n\treturn {\n\t\tidentical: changes.length === 0,\n\t\tchanges,\n\t\tversionChanged,\n\t\toldVersion: oldSnapshot.version,\n\t\tnewVersion: newSnapshot.version,\n\t};\n}\n\n// ============================================================================\n// Snapshot Signing (HMAC)\n// ============================================================================\n\n/**\n * A signed distributable snapshot.\n * Contains the original snapshot plus a cryptographic signature.\n */\nexport interface SignedSnapshot<T = Record<string, unknown>>\n\textends DistributableSnapshotLike<T> {\n\t/** HMAC-SHA256 signature in hex format */\n\tsignature: string;\n\t/** Signing algorithm used */\n\talgorithm: \"hmac-sha256\";\n}\n\n/**\n * Check if a snapshot is signed.\n *\n * @param snapshot - The snapshot to check\n * @returns True if the snapshot has a signature\n */\nexport function isSignedSnapshot<T>(\n\tsnapshot: DistributableSnapshotLike<T> | SignedSnapshot<T>,\n): snapshot is SignedSnapshot<T> {\n\treturn \"signature\" in snapshot && typeof snapshot.signature === \"string\";\n}\n\n/**\n * Sign a distributable snapshot using HMAC-SHA256.\n * Creates a tamper-proof signature that can be verified later.\n *\n * **Security Notes:**\n * - Use a cryptographically random secret of at least 32 bytes\n * - Store the secret securely (environment variable, secrets manager)\n * - Never expose the secret to clients\n * - The signature covers all snapshot fields for integrity\n *\n * @example\n * ```typescript\n * const snapshot = system.getDistributableSnapshot({\n * includeDerivations: ['canUseFeature', 'limits'],\n * ttlSeconds: 3600,\n * });\n *\n * // Sign the snapshot (server-side only)\n * const signed = await signSnapshot(snapshot, process.env.SNAPSHOT_SECRET);\n *\n * // Store in JWT, Redis, or send to client\n * const jwt = createJWT({ snapshot: signed });\n *\n * // Later, verify the signature\n * const isValid = await verifySnapshotSignature(signed, process.env.SNAPSHOT_SECRET);\n * if (!isValid) {\n * throw new Error('Snapshot has been tampered with');\n * }\n * ```\n *\n * @param snapshot - The snapshot to sign\n * @param secret - The HMAC secret (string or Uint8Array)\n * @returns A signed snapshot with the signature attached\n */\nexport async function signSnapshot<T>(\n\tsnapshot: DistributableSnapshotLike<T>,\n\tsecret: string | Uint8Array,\n): Promise<SignedSnapshot<T>> {\n\t// Create a canonical representation for signing\n\tconst payload = stableStringify({\n\t\tdata: snapshot.data,\n\t\tcreatedAt: snapshot.createdAt,\n\t\texpiresAt: snapshot.expiresAt,\n\t\tversion: snapshot.version,\n\t\tmetadata: snapshot.metadata,\n\t});\n\n\tconst signature = await hmacSha256(payload, secret);\n\n\treturn {\n\t\t...snapshot,\n\t\tsignature,\n\t\talgorithm: \"hmac-sha256\",\n\t};\n}\n\n/**\n * Verify the signature of a signed snapshot.\n * Returns true if the signature is valid, false otherwise.\n *\n * **Important:** Always verify signatures before trusting snapshot data,\n * especially if the snapshot was received from an untrusted source (client, cache).\n *\n * @example\n * ```typescript\n * // Receive signed snapshot from client or cache\n * const snapshot = JSON.parse(cachedData);\n *\n * // Verify before using\n * const isValid = await verifySnapshotSignature(snapshot, process.env.SNAPSHOT_SECRET);\n * if (!isValid) {\n * throw new Error('Invalid snapshot signature - possible tampering');\n * }\n *\n * // Now safe to use snapshot.data\n * if (snapshot.data.canUseFeature.api) {\n * // Grant access\n * }\n * ```\n *\n * @param signedSnapshot - The signed snapshot to verify\n * @param secret - The HMAC secret (must match the signing secret)\n * @returns True if signature is valid, false otherwise\n */\nexport async function verifySnapshotSignature<T>(\n\tsignedSnapshot: SignedSnapshot<T>,\n\tsecret: string | Uint8Array,\n): Promise<boolean> {\n\tif (!signedSnapshot.signature || signedSnapshot.algorithm !== \"hmac-sha256\") {\n\t\treturn false;\n\t}\n\n\t// Recreate the canonical payload (same as signing)\n\tconst payload = stableStringify({\n\t\tdata: signedSnapshot.data,\n\t\tcreatedAt: signedSnapshot.createdAt,\n\t\texpiresAt: signedSnapshot.expiresAt,\n\t\tversion: signedSnapshot.version,\n\t\tmetadata: signedSnapshot.metadata,\n\t});\n\n\tconst expectedSignature = await hmacSha256(payload, secret);\n\n\t// Use timing-safe comparison\n\treturn timingSafeEqual(signedSnapshot.signature, expectedSignature);\n}\n\n/**\n * Create HMAC-SHA256 signature of a message.\n * Uses Web Crypto API for cross-platform support (Node.js, browsers, Deno, Bun).\n */\nasync function hmacSha256(\n\tmessage: string,\n\tsecret: string | Uint8Array,\n): Promise<string> {\n\t// Convert secret to Uint8Array if string\n\tconst secretBytes: Uint8Array =\n\t\ttypeof secret === \"string\" ? new TextEncoder().encode(secret) : secret;\n\n\t// Import key for HMAC\n\tconst algorithm: HmacImportParams = { name: \"HMAC\", hash: { name: \"SHA-256\" } };\n\tconst key = await crypto.subtle.importKey(\n\t\t\"raw\",\n\t\tsecretBytes as unknown as ArrayBuffer,\n\t\talgorithm,\n\t\tfalse,\n\t\t[\"sign\"],\n\t);\n\n\t// Sign the message\n\tconst messageBytes = new TextEncoder().encode(message);\n\tconst signature = await crypto.subtle.sign(\"HMAC\", key, messageBytes);\n\n\t// Convert to hex string\n\treturn Array.from(new Uint8Array(signature))\n\t\t.map((b) => b.toString(16).padStart(2, \"0\"))\n\t\t.join(\"\");\n}\n\n/**\n * Timing-safe string comparison to prevent timing attacks.\n * Both strings should be the same length (hex signatures from same algorithm).\n */\nfunction timingSafeEqual(a: string, b: string): boolean {\n\tif (a.length !== b.length) {\n\t\treturn false;\n\t}\n\n\tlet result = 0;\n\tfor (let i = 0; i < a.length; i++) {\n\t\tresult |= a.charCodeAt(i) ^ b.charCodeAt(i);\n\t}\n\treturn result === 0;\n}\n","/**\n * Shared Adapter Utilities\n *\n * Common types and helper functions used across all framework adapters.\n * @internal\n */\n\nimport type { TimeTravelState, TimeTravelAPI, SystemInspection, SnapshotMeta } from \"./core/types.js\";\nimport { withTracking } from \"./core/tracking.js\";\n\n// ============================================================================\n// SystemLike — structural type satisfied by both System and SingleModuleSystem\n// ============================================================================\n\n/**\n * Minimal structural type for shared adapter helpers.\n * Both `System<any>` and `SingleModuleSystem<any>` satisfy this interface,\n * eliminating the need for `as unknown as System<any>` casts in adapters.\n * @internal\n */\nexport interface SystemLike {\n\treadonly isSettled: boolean;\n\treadonly debug: TimeTravelAPI | null;\n\treadonly facts: {\n\t\t$store: {\n\t\t\tget(key: string): unknown;\n\t\t\thas(key: string): boolean;\n\t\t\ttoObject(): Record<string, unknown>;\n\t\t};\n\t};\n\treadonly derive?: Record<string, unknown>;\n\tread(key: string): unknown;\n\tinspect(): SystemInspection;\n}\n\n// ============================================================================\n// Requirements State\n// ============================================================================\n\n/**\n * Requirements state returned by useRequirements hooks.\n * Provides a focused view of just requirements without full inspection overhead.\n */\nexport interface RequirementsState {\n\t/** Array of unmet requirements waiting to be resolved */\n\tunmet: Array<{\n\t\tid: string;\n\t\trequirement: { type: string; [key: string]: unknown };\n\t\tfromConstraint: string;\n\t}>;\n\t/** Array of requirements currently being resolved */\n\tinflight: Array<{ id: string; resolverId: string; startedAt: number }>;\n\t/** Whether there are any unmet requirements */\n\thasUnmet: boolean;\n\t/** Whether there are any inflight requirements */\n\thasInflight: boolean;\n\t/** Whether the system is actively working (has unmet or inflight requirements) */\n\tisWorking: boolean;\n}\n\n// ============================================================================\n// Inspect State (shared across all adapters)\n// ============================================================================\n\n/**\n * Consolidated inspection state returned by useInspect hooks.\n * Identical shape across React, Vue, Svelte, Solid, and Lit adapters.\n */\nexport interface InspectState {\n\t/** Whether the system has settled (no pending operations) */\n\tisSettled: boolean;\n\t/** Array of unmet requirements */\n\tunmet: RequirementsState[\"unmet\"];\n\t/** Array of inflight requirements */\n\tinflight: RequirementsState[\"inflight\"];\n\t/** Whether the system is actively working */\n\tisWorking: boolean;\n\t/** Whether there are any unmet requirements */\n\thasUnmet: boolean;\n\t/** Whether there are any inflight requirements */\n\thasInflight: boolean;\n}\n\n/**\n * Information about a single constraint.\n */\nexport interface ConstraintInfo {\n\tid: string;\n\tactive: boolean;\n\tpriority: number;\n}\n\n/**\n * Compute InspectState from a system instance.\n * Centralizes the logic currently duplicated across adapters.\n * @internal\n */\nexport function computeInspectState(system: SystemLike): InspectState {\n\tconst inspection = system.inspect();\n\treturn {\n\t\tisSettled: system.isSettled,\n\t\tunmet: inspection.unmet,\n\t\tinflight: inspection.inflight,\n\t\tisWorking: inspection.unmet.length > 0 || inspection.inflight.length > 0,\n\t\thasUnmet: inspection.unmet.length > 0,\n\t\thasInflight: inspection.inflight.length > 0,\n\t};\n}\n\n// ============================================================================\n// Throttled Hook Options\n// ============================================================================\n\n/**\n * Options for throttled hooks.\n * Used by useInspectThrottled, useRequirementsThrottled, etc.\n */\nexport interface ThrottledHookOptions {\n\t/**\n\t * Minimum time between updates in milliseconds.\n\t * @default 100\n\t */\n\tthrottleMs?: number;\n}\n\n// ============================================================================\n// Throttle Utility\n// ============================================================================\n\n/**\n * Create a throttled version of a callback function.\n * Uses trailing-edge throttling: the callback will be called at most once per interval,\n * with the latest arguments from the most recent call.\n *\n * @param callback - The function to throttle\n * @param ms - The minimum time between calls in milliseconds\n * @returns A throttled version of the callback and a cleanup function\n * @internal\n */\nexport function createThrottle<T extends (...args: unknown[]) => void>(\n\tcallback: T,\n\tms: number,\n): { throttled: T; cleanup: () => void } {\n\tlet timeoutId: ReturnType<typeof setTimeout> | null = null;\n\tlet lastArgs: Parameters<T> | null = null;\n\tlet lastCallTime = 0;\n\n\tconst throttled = ((...args: Parameters<T>) => {\n\t\tconst now = Date.now();\n\t\tconst timeSinceLastCall = now - lastCallTime;\n\n\t\tif (timeSinceLastCall >= ms) {\n\t\t\t// Enough time has passed, call immediately\n\t\t\tlastCallTime = now;\n\t\t\tcallback(...args);\n\t\t} else {\n\t\t\t// Schedule for later, keeping latest args\n\t\t\tlastArgs = args;\n\t\t\tif (!timeoutId) {\n\t\t\t\ttimeoutId = setTimeout(() => {\n\t\t\t\t\ttimeoutId = null;\n\t\t\t\t\tlastCallTime = Date.now();\n\t\t\t\t\tif (lastArgs) {\n\t\t\t\t\t\tcallback(...lastArgs);\n\t\t\t\t\t\tlastArgs = null;\n\t\t\t\t\t}\n\t\t\t\t}, ms - timeSinceLastCall);\n\t\t\t}\n\t\t}\n\t}) as T;\n\n\tconst cleanup = () => {\n\t\tif (timeoutId) {\n\t\t\tclearTimeout(timeoutId);\n\t\t\ttimeoutId = null;\n\t\t}\n\t\tlastArgs = null;\n\t};\n\n\treturn { throttled, cleanup };\n}\n\n// ============================================================================\n// Shared Adapter Helpers\n// ============================================================================\n\n/**\n * Dev-mode assertion that the system parameter is non-null.\n * Tree-shaken in production builds.\n * @internal\n */\nexport function assertSystem(hookName: string, system: unknown): void {\n\tif (process.env.NODE_ENV !== \"production\" && system == null) {\n\t\tthrow new Error(\n\t\t\t`[Directive] ${hookName}() requires a system instance as the first argument. Received ${system}.`,\n\t\t);\n\t}\n}\n\n/** Default equality function using Object.is */\nexport function defaultEquality<T>(a: T, b: T): boolean {\n\treturn Object.is(a, b);\n}\n\n/**\n * Build a TimeTravelState object from a system's debug instance.\n * Returns null when time-travel is disabled.\n * @internal\n */\nexport function buildTimeTravelState(system: SystemLike): TimeTravelState | null {\n\tconst debug = system.debug;\n\tif (!debug) return null;\n\n\t// Build lightweight metadata array (no facts data)\n\tconst snapshots: SnapshotMeta[] = debug.snapshots.map((s) => ({\n\t\tid: s.id,\n\t\ttimestamp: s.timestamp,\n\t\ttrigger: s.trigger,\n\t}));\n\n\treturn {\n\t\t// Existing\n\t\tcanUndo: debug.currentIndex > 0,\n\t\tcanRedo: debug.currentIndex < debug.snapshots.length - 1,\n\t\tundo: () => debug.goBack(),\n\t\tredo: () => debug.goForward(),\n\t\tcurrentIndex: debug.currentIndex,\n\t\ttotalSnapshots: debug.snapshots.length,\n\n\t\t// Snapshot access\n\t\tsnapshots,\n\t\tgetSnapshotFacts: (id: number): Record<string, unknown> | null => {\n\t\t\tconst snap = debug.snapshots.find((s) => s.id === id);\n\t\t\treturn snap ? snap.facts : null;\n\t\t},\n\n\t\t// Navigation\n\t\tgoTo: (snapshotId: number) => debug.goTo(snapshotId),\n\t\tgoBack: (steps: number) => debug.goBack(steps),\n\t\tgoForward: (steps: number) => debug.goForward(steps),\n\t\treplay: () => debug.replay(),\n\n\t\t// Session persistence\n\t\texportSession: () => debug.export(),\n\t\timportSession: (json: string) => debug.import(json),\n\n\t\t// Changesets\n\t\tbeginChangeset: (label: string) => debug.beginChangeset(label),\n\t\tendChangeset: () => debug.endChangeset(),\n\n\t\t// Recording control\n\t\tisPaused: debug.isPaused,\n\t\tpause: () => debug.pause(),\n\t\tresume: () => debug.resume(),\n\t};\n}\n\n/**\n * Pick specific fact values from a system's store.\n * @internal\n */\nexport function pickFacts(system: SystemLike, keys: string[]): Record<string, unknown> {\n\tconst result: Record<string, unknown> = {};\n\tfor (const key of keys) {\n\t\tresult[key] = system.facts.$store.get(key);\n\t}\n\treturn result;\n}\n\n// ============================================================================\n// Tracked Selector\n// ============================================================================\n\n/** Result of running a selector with tracking. @internal */\nexport interface TrackedSelectorResult<R> {\n\tvalue: R;\n\tfactKeys: string[];\n\tderiveKeys: string[];\n}\n\n/**\n * Run a selector against a system with automatic dependency tracking.\n * Creates a Proxy that intercepts property access to distinguish between\n * fact reads (tracked via withTracking) and derivation reads (tracked manually).\n *\n * Used by useSelector in all framework adapters.\n * @internal\n */\nexport function runTrackedSelector<R>(\n\tsystem: SystemLike,\n\tderiveKeySet: Set<string>,\n\tselector: (state: Record<string, unknown>) => R,\n): TrackedSelectorResult<R> {\n\tconst accessedDeriveKeys: string[] = [];\n\n\tconst stateProxy = new Proxy(\n\t\t{},\n\t\t{\n\t\t\tget(_, prop: string | symbol) {\n\t\t\t\tif (typeof prop !== \"string\") return undefined;\n\t\t\t\tif (deriveKeySet.has(prop)) {\n\t\t\t\t\taccessedDeriveKeys.push(prop);\n\t\t\t\t\treturn system.read(prop);\n\t\t\t\t}\n\t\t\t\treturn system.facts.$store.get(prop);\n\t\t\t},\n\t\t\thas(_, prop: string | symbol) {\n\t\t\t\tif (typeof prop !== \"string\") return false;\n\t\t\t\treturn deriveKeySet.has(prop) || system.facts.$store.has(prop);\n\t\t\t},\n\t\t\townKeys() {\n\t\t\t\tconst factKeys = Object.keys(system.facts.$store.toObject());\n\t\t\t\tconst combined = new Set(factKeys);\n\t\t\t\tfor (const k of deriveKeySet) combined.add(k);\n\t\t\t\treturn [...combined];\n\t\t\t},\n\t\t\tgetOwnPropertyDescriptor() {\n\t\t\t\treturn { configurable: true, enumerable: true, writable: true };\n\t\t\t},\n\t\t},\n\t);\n\n\tconst { value, deps } = withTracking(() => selector(stateProxy as Record<string, unknown>));\n\treturn { value, factKeys: Array.from(deps) as string[], deriveKeys: accessedDeriveKeys };\n}\n\n/**\n * Check if tracked dependency keys have changed.\n * @internal\n */\nexport function depsChanged(\n\tprevFacts: string[],\n\tnewFacts: string[],\n\tprevDerived: string[],\n\tnewDerived: string[],\n): boolean {\n\tconst factsChanged =\n\t\tnewFacts.length !== prevFacts.length ||\n\t\tnewFacts.some((k, i) => k !== prevFacts[i]);\n\tconst derivedChanged =\n\t\tnewDerived.length !== prevDerived.length ||\n\t\tnewDerived.some((k, i) => k !== prevDerived[i]);\n\treturn factsChanged || derivedChanged;\n}\n\n// ============================================================================\n// Re-exports from core/types/adapter-utils and utils/utils\n// ============================================================================\n\nexport {\n\tsetBridgeFact,\n\tgetBridgeFact,\n\tcreateCallbackPlugin,\n\trequirementGuard,\n\trequirementGuardMultiple,\n} from \"./core/types/adapter-utils.js\";\n\n\nexport { shallowEqual } from \"./utils/utils.js\";\n"]}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use strict';var le=class extends Error{constructor(o,c,i,n,u=true){super(o);this.source=c;this.sourceId=i;this.context=n;this.recoverable=u;this.name="DirectiveError";}};function Pe(){return {create(e){return e}}}function Ae(){return {create(e){return e}}}function je(e){return e}function Fe(e){return e}function st(e){return e._mode==="single"}function ot(e){return e._mode==="namespaced"}var oe=[];function it(){let e=new Set;return {get isTracking(){return true},track(t){e.add(t);},getDependencies(){return e}}}var at={isTracking:false,track(){},getDependencies(){return new Set}};function _e(){return oe[oe.length-1]??at}function ct(){return oe.length>0}function ie(e){let t=it();oe.push(t);try{return {value:e(),deps:t.getDependencies()}}finally{oe.pop();}}function Se(e){let t=oe.splice(0,oe.length);try{return e()}finally{oe.push(...t);}}function fe(e){_e().track(e);}function ut(e,t=100){try{return JSON.stringify(e)?.slice(0,t)??String(e)}catch{return "[circular or non-serializable]"}}var Be=new Set;function he(e=[],t,o,c,i,n){return {_type:void 0,_validators:e,_typeName:t,_default:o,_transform:c,_description:i,_refinements:n,validate(u){return he([...e,u],t,o,c,i,n)}}}function X(e,t,o,c,i,n){return {...he(e,t,o,c,i,n),default(d){return X(e,t,d,c,i,n)},transform(d){return X([],t,void 0,s=>{let m=c?c(s):s;return d(m)},i)},brand(){return X(e,`Branded<${t}>`,o,c,i,n)},describe(d){return X(e,t,o,c,d,n)},refine(d,a){let s=[...n??[],{predicate:d,message:a}];return X([...e,d],t,o,c,i,s)},nullable(){return X([d=>d===null||e.every(a=>a(d))],`${t} | null`,o,c,i)},optional(){return X([d=>d===void 0||e.every(a=>a(d))],`${t} | undefined`,o,c,i)}}}var dt={string(){return X([e=>typeof e=="string"],"string")},number(){let e=(t,o,c,i,n)=>({...X(t,"number",o,c,i,n),min(d){return e([...t,a=>a>=d],o,c,i,n)},max(d){return e([...t,a=>a<=d],o,c,i,n)},default(d){return e(t,d,c,i,n)},describe(d){return e(t,o,c,d,n)},refine(d,a){let s=[...n??[],{predicate:d,message:a}];return e([...t,d],o,c,i,s)}});return e([t=>typeof t=="number"])},boolean(){return X([e=>typeof e=="boolean"],"boolean")},array(){let e=(t,o,c,i,n)=>{let u=X(t,"array",c,void 0,i),d=n??{value:-1};return {...u,get _lastFailedIndex(){return d.value},set _lastFailedIndex(s){d.value=s;},of(s){let m={value:-1};return e([...t,p=>{for(let q=0;q<p.length;q++){let T=p[q];if(!s._validators.every(A=>A(T)))return m.value=q,false}return true}],s,c,i,m)},nonEmpty(){return e([...t,s=>s.length>0],o,c,i,d)},maxLength(s){return e([...t,m=>m.length<=s],o,c,i,d)},minLength(s){return e([...t,m=>m.length>=s],o,c,i,d)},default(s){return e(t,o,s,i,d)},describe(s){return e(t,o,c,s,d)}}};return e([t=>Array.isArray(t)])},object(){let e=(t,o,c)=>({...X(t,"object",o,void 0,c),shape(n){return e([...t,u=>{for(let[d,a]of Object.entries(n)){let s=u[d],m=a;if(m&&!m._validators.every(p=>p(s)))return false}return true}],o,c)},nonNull(){return e([...t,n=>n!=null],o,c)},hasKeys(...n){return e([...t,u=>n.every(d=>d in u)],o,c)},default(n){return e(t,n,c)},describe(n){return e(t,o,n)}});return e([t=>typeof t=="object"&&t!==null&&!Array.isArray(t)])},any(){return process.env.NODE_ENV!=="production"&&!Be.has("any")&&(Be.add("any"),console.warn("[Directive] t.any() bypasses runtime validation. Consider using t.object<T>(), t.union(), or a Zod schema for type safety.")),he([],"any")},enum(...e){process.env.NODE_ENV!=="production"&&e.length===0&&console.warn("[Directive] t.enum() called with no values - this will reject all strings");let t=new Set(e);return X([o=>typeof o=="string"&&t.has(o)],`enum(${e.join("|")})`)},literal(e){return X([t=>t===e],`literal(${String(e)})`)},nullable(e){let t=e._typeName??"unknown";return he([o=>o===null?true:e._validators.every(c=>c(o))],`${t} | null`)},optional(e){let t=e._typeName??"unknown";return he([o=>o===void 0?true:e._validators.every(c=>c(o))],`${t} | undefined`)},union(...e){process.env.NODE_ENV!=="production"&&e.length===0&&console.warn("[Directive] t.union() called with no types - this will reject all values");let t=e.map(o=>o._typeName??"unknown");return X([o=>e.some(c=>c._validators.every(i=>i(o)))],t.join(" | "))},record(e){let t=e._typeName??"unknown";return X([o=>typeof o!="object"||o===null||Array.isArray(o)?false:Object.values(o).every(c=>e._validators.every(i=>i(c)))],`Record<string, ${t}>`)},tuple(...e){process.env.NODE_ENV!=="production"&&e.length===0&&console.warn("[Directive] t.tuple() called with no types - this will only accept empty arrays");let t=e.map(o=>o._typeName??"unknown");return X([o=>!Array.isArray(o)||o.length!==e.length?false:e.every((c,i)=>c._validators.every(n=>n(o[i])))],`[${t.join(", ")}]`)},date(){return X([e=>e instanceof Date&&!isNaN(e.getTime())],"Date")},uuid(){let e=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;return X([t=>typeof t=="string"&&e.test(t)],"uuid")},email(){let e=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;return X([t=>typeof t=="string"&&e.test(t)],"email")},url(){return X([e=>{if(typeof e!="string")return false;try{return new URL(e),!0}catch{return false}}],"url")},bigint(){return X([e=>typeof e=="bigint"],"bigint")}};function Ne(e){let{schema:t,onChange:o,onBatch:c}=e,n=Object.keys(t).length===0,u=e.validate??process.env.NODE_ENV!=="production",d=e.strictKeys??(process.env.NODE_ENV!=="production"&&!n),a=e.redactErrors??false,s=new Map,m=new Set,p=new Map,q=new Set,T=0,A=[],B=new Set,K=false,C=[],P=100;function W(g){return g!==null&&typeof g=="object"&&"safeParse"in g&&typeof g.safeParse=="function"&&"_def"in g&&"parse"in g&&typeof g.parse=="function"}function f(g){let D=g;if(D._typeName)return D._typeName;if(W(g)){let j=g._def;if(j?.typeName)return j.typeName.replace(/^Zod/,"").toLowerCase()}return "unknown"}function b(g){return a?"[redacted]":ut(g)}function k(g,D){if(!u)return;let j=t[g];if(!j){if(d)throw new Error(`[Directive] Unknown fact key: "${g}". Key not defined in schema.`);console.warn(`[Directive] Unknown fact key: "${g}"`);return}if(W(j)){let y=j.safeParse(D);if(!y.success){let S=D===null?"null":Array.isArray(D)?"array":typeof D,x=b(D),l=y.error?.message??y.error?.issues?.[0]?.message??"Validation failed",h=f(j);throw new Error(`[Directive] Validation failed for "${g}": expected ${h}, got ${S} ${x}. ${l}`)}return}let F=j,V=F._validators;if(!V||!Array.isArray(V)||V.length===0)return;let r=F._typeName??"unknown";for(let y=0;y<V.length;y++){let S=V[y];if(typeof S=="function"&&!S(D)){let x=D===null?"null":Array.isArray(D)?"array":typeof D,l=b(D),h="";typeof F._lastFailedIndex=="number"&&F._lastFailedIndex>=0&&(h=` (element at index ${F._lastFailedIndex} failed)`,F._lastFailedIndex=-1);let w=y===0?"":` (validator ${y+1} failed)`;throw new Error(`[Directive] Validation failed for "${g}": expected ${r}, got ${x} ${l}${w}${h}`)}}}function O(g){p.get(g)?.forEach(D=>D());}function M(){q.forEach(g=>g());}function I(g,D,j){if(K){C.push({key:g,value:D,prev:j});return}K=true;try{o?.(g,D,j),O(g),M();let F=0;for(;C.length>0;){if(++F>P)throw C.length=0,new Error(`[Directive] Infinite notification loop detected after ${P} iterations. A listener is repeatedly mutating facts that re-trigger notifications.`);let V=[...C];C.length=0;for(let r of V)o?.(r.key,r.value,r.prev),O(r.key);M();}}finally{K=false;}}function R(){if(!(T>0)){if(c&&A.length>0&&c([...A]),B.size>0){K=true;try{for(let D of B)O(D);M();let g=0;for(;C.length>0;){if(++g>P)throw C.length=0,new Error(`[Directive] Infinite notification loop detected during flush after ${P} iterations.`);let D=[...C];C.length=0;for(let j of D)o?.(j.key,j.value,j.prev),O(j.key);M();}}finally{K=false;}}A.length=0,B.clear();}}let v={get(g){return fe(g),s.get(g)},has(g){return fe(g),s.has(g)},set(g,D){k(g,D);let j=s.get(g);Object.is(j,D)||(s.set(g,D),m.add(g),T>0?(A.push({key:g,value:D,prev:j,type:"set"}),B.add(g)):I(g,D,j));},delete(g){let D=s.get(g);s.delete(g),m.delete(g),T>0?(A.push({key:g,value:void 0,prev:D,type:"delete"}),B.add(g)):I(g,void 0,D);},batch(g){T++;try{g();}finally{T--,R();}},subscribe(g,D){for(let j of g){let F=j;p.has(F)||p.set(F,new Set),p.get(F).add(D);}return ()=>{for(let j of g){let F=p.get(j);F&&(F.delete(D),F.size===0&&p.delete(j));}}},subscribeAll(g){return q.add(g),()=>q.delete(g)},toObject(){let g={};for(let D of m)s.has(D)&&(g[D]=s.get(D));return g}};return v.registerKeys=g=>{for(let D of Object.keys(g))pe.has(D)||(t[D]=g[D],m.add(D));},v}var pe=Object.freeze(new Set(["__proto__","constructor","prototype"]));function Ke(e,t){let o=()=>({get:i=>Se(()=>e.get(i)),has:i=>Se(()=>e.has(i))});return new Proxy({},{get(i,n){if(n==="$store")return e;if(n==="$snapshot")return o;if(typeof n!="symbol"&&!pe.has(n))return e.get(n)},set(i,n,u){return typeof n=="symbol"||n==="$store"||n==="$snapshot"||pe.has(n)?false:(e.set(n,u),true)},deleteProperty(i,n){return typeof n=="symbol"||n==="$store"||n==="$snapshot"||pe.has(n)?false:(e.delete(n),true)},has(i,n){return n==="$store"||n==="$snapshot"?true:typeof n=="symbol"||pe.has(n)?false:e.has(n)},ownKeys(){return Object.keys(t)},getOwnPropertyDescriptor(i,n){return n==="$store"||n==="$snapshot"?{configurable:true,enumerable:false,writable:false}:{configurable:true,enumerable:true,writable:true}}})}function we(e){let t=Ne(e),o=Ke(t,e.schema);return {store:t,facts:o}}function We(e,t){if(process.env.NODE_ENV!=="production"){!e||typeof e!="string"?console.warn("[Directive] Module ID must be a non-empty string"):/^[a-z][a-z0-9-]*$/i.test(e)||console.warn(`[Directive] Module ID "${e}" should follow kebab-case convention (e.g., "my-module")`),t.schema?t.schema.facts||console.warn("[Directive] Module schema.facts is required"):console.warn("[Directive] Module schema is required");let c=t.schema?.derivations??{},i=t.derive??{},n=new Set(Object.keys(c)),u=new Set(Object.keys(i));for(let p of u)n.has(p)||console.warn(`[Directive] Derivation "${p}" not declared in schema.derivations`);for(let p of n)u.has(p)||console.warn(`[Directive] schema.derivations["${p}"] has no matching implementation in derive`);let d=t.schema?.events??{},a=t.events??{},s=new Set(Object.keys(d)),m=new Set(Object.keys(a));for(let p of m)s.has(p)||console.warn(`[Directive] Event "${p}" not declared in schema.events`);for(let p of s)m.has(p)||console.warn(`[Directive] schema.events["${p}"] has no matching handler in events`);if(t.resolvers&&t.schema?.requirements){let p=new Set(Object.keys(t.schema.requirements));for(let[q,T]of Object.entries(t.resolvers)){let A=T;typeof A.requirement=="string"&&!p.has(A.requirement)&&console.warn(`[Directive] Resolver "${q}" references unknown requirement type "${A.requirement}". Available types: ${[...p].join(", ")||"(none)"}`);}}}let o="crossModuleDeps"in t?t.crossModuleDeps:void 0;return {id:e,schema:t.schema,init:t.init,derive:t.derive??{},events:t.events??{},effects:t.effects,constraints:t.constraints,resolvers:t.resolvers,hooks:t.hooks,crossModuleDeps:o}}function lt(e){return t=>We(t,e)}async function ge(e,t,o){let c,i=new Promise((n,u)=>{c=setTimeout(()=>u(new Error(o)),t);});try{return await Promise.race([e,i])}finally{clearTimeout(c);}}function ve(e,t=50){let o=new WeakSet;function c(i,n){if(n>t)return '"[max depth exceeded]"';if(i===null)return "null";if(i===void 0)return "undefined";let u=typeof i;if(u==="string")return JSON.stringify(i);if(u==="number"||u==="boolean")return String(i);if(u==="function")return '"[function]"';if(u==="symbol")return '"[symbol]"';if(Array.isArray(i)){if(o.has(i))return '"[circular]"';o.add(i);let d=`[${i.map(a=>c(a,n+1)).join(",")}]`;return o.delete(i),d}if(u==="object"){let d=i;if(o.has(d))return '"[circular]"';o.add(d);let m=`{${Object.keys(d).sort().map(p=>`${JSON.stringify(p)}:${c(d[p],n+1)}`).join(",")}}`;return o.delete(d),m}return '"[unknown]"'}return c(e,0)}function ae(e,t=50){let o=new Set(["__proto__","constructor","prototype"]),c=new WeakSet;function i(n,u){if(u>t)return false;if(n==null||typeof n!="object")return true;let d=n;if(c.has(d))return true;if(c.add(d),Array.isArray(d)){for(let a of d)if(!i(a,u+1))return c.delete(d),false;return c.delete(d),true}for(let a of Object.keys(d))if(o.has(a)||!i(d[a],u+1))return c.delete(d),false;return c.delete(d),true}return i(e,0)}function ft(e,t){if(e===t)return true;if(!e||!t)return false;let o=Object.keys(e),c=Object.keys(t);if(o.length!==c.length)return false;for(let i of o)if(e[i]!==t[i])return false;return true}function Ve(e){let t=ve(e),o=5381;for(let c=0;c<t.length;c++)o=(o<<5)+o^t.charCodeAt(c);return (o>>>0).toString(16)}function ze(e,t=Date.now()){return e.expiresAt!==void 0&&t>e.expiresAt}function gt(e,t=Date.now()){if(!e||typeof e!="object")throw new Error("[Directive] Invalid snapshot: expected an object with 'data' and 'createdAt' properties.");if(!("data"in e))throw new Error("[Directive] Invalid snapshot: missing required 'data' property.");if(!("createdAt"in e)||typeof e.createdAt!="number")throw new Error("[Directive] Invalid snapshot: missing or invalid 'createdAt' property (expected number).");if(ze(e,t)){let o=new Date(e.expiresAt).toISOString();throw new Error(`[Directive] Snapshot expired at ${o}. Obtain a fresh snapshot from the source.`)}return e.data}function mt(e,t){let o=[];function c(n,u,d){if(n==null){u!=null&&o.push({path:d,oldValue:n,newValue:u,type:"added"});return}if(u==null){o.push({path:d,oldValue:n,newValue:u,type:"removed"});return}if(typeof n!="object"||typeof u!="object"){Object.is(n,u)||o.push({path:d,oldValue:n,newValue:u,type:"changed"});return}if(Array.isArray(n)&&Array.isArray(u)){if(n.length!==u.length){o.push({path:d,oldValue:n,newValue:u,type:"changed"});return}for(let p=0;p<n.length;p++)c(n[p],u[p],`${d}[${p}]`);return}let a=n,s=u,m=new Set([...Object.keys(a),...Object.keys(s)]);for(let p of m){let q=d?`${d}.${p}`:p;p in a?p in s?c(a[p],s[p],q):o.push({path:q,oldValue:a[p],newValue:void 0,type:"removed"}):o.push({path:q,oldValue:void 0,newValue:s[p],type:"added"});}}c(e.data,t.data,"");let i=e.version!==t.version&&(e.version!==void 0||t.version!==void 0);return {identical:o.length===0,changes:o,versionChanged:i,oldVersion:e.version,newVersion:t.version}}function yt(e){return "signature"in e&&typeof e.signature=="string"}async function pt(e,t){let o=ve({data:e.data,createdAt:e.createdAt,expiresAt:e.expiresAt,version:e.version,metadata:e.metadata}),c=await Le(o,t);return {...e,signature:c,algorithm:"hmac-sha256"}}async function ht(e,t){if(!e.signature||e.algorithm!=="hmac-sha256")return false;let o=ve({data:e.data,createdAt:e.createdAt,expiresAt:e.expiresAt,version:e.version,metadata:e.metadata}),c=await Le(o,t);return vt(e.signature,c)}async function Le(e,t){let o=typeof t=="string"?new TextEncoder().encode(t):t,c={name:"HMAC",hash:{name:"SHA-256"}},i=await crypto.subtle.importKey("raw",o,c,false,["sign"]),n=new TextEncoder().encode(e),u=await crypto.subtle.sign("HMAC",i,n);return Array.from(new Uint8Array(u)).map(d=>d.toString(16).padStart(2,"0")).join("")}function vt(e,t){if(e.length!==t.length)return false;let o=0;for(let c=0;c<e.length;c++)o|=e.charCodeAt(c)^t.charCodeAt(c);return o===0}function Ue(e,t){if(t)return t(e);let{type:o,...c}=e,i=ve(c);return `${o}:${i}`}function He(e,t,o){return {requirement:e,id:Ue(e,o),fromConstraint:t}}function St(e){return t=>({type:e,...t})}function bt(e,t){return e.type===t}function wt(e){return t=>t.type===e}var ce=class e{map=new Map;add(t){this.map.has(t.id)||this.map.set(t.id,t);}remove(t){return this.map.delete(t)}has(t){return this.map.has(t)}get(t){return this.map.get(t)}all(){return [...this.map.values()]}ids(){return [...this.map.keys()]}get size(){return this.map.size}clear(){this.map.clear();}clone(){let t=new e;for(let o of this.map.values())t.add(o);return t}diff(t){let o=[],c=[],i=[];for(let n of this.map.values())t.has(n.id)?i.push(n):o.push(n);for(let n of t.map.values())this.map.has(n.id)||c.push(n);return {added:o,removed:c,unchanged:i}}};var Rt=5e3;function Re(e){let{definitions:t,facts:o,requirementKeys:c={},defaultTimeout:i=Rt,onEvaluate:n,onError:u}=e,d=new Map,a=new Set,s=new Set,m=new Map,p=new Map,q=new Set,T=new Map,A=new Map,B=false,K=new Set,C=new Set,P=new Map,W=[],f=new Map;function b(){for(let[l,h]of Object.entries(t))if(h.after)for(let w of h.after)t[w]&&(P.has(w)||P.set(w,new Set),P.get(w).add(l));}function k(){let l=new Set,h=new Set,w=[];function $(E,z){if(l.has(E))return;if(h.has(E)){let U=z.indexOf(E),_=[...z.slice(U),E].join(" \u2192 ");throw new Error(`[Directive] Constraint cycle detected: ${_}. Remove one of the \`after\` dependencies to break the cycle.`)}h.add(E),z.push(E);let L=t[E];if(L?.after)for(let U of L.after)t[U]&&$(U,z);z.pop(),h.delete(E),l.add(E),w.push(E);}for(let E of Object.keys(t))$(E,[]);W=w,f=new Map(W.map((E,z)=>[E,z]));}if(k(),b(),process.env.NODE_ENV!=="production"){for(let[l,h]of Object.entries(t))if(h.after)for(let w of h.after)t[w]||console.warn(`[Directive] Constraint "${l}" references unknown constraint "${w}" in \`after\`. This dependency will be ignored. Check for typos or ensure the constraint exists.`);}function O(l,h){return h.async!==void 0?h.async:!!s.has(l)}function M(l){let h=t[l];if(!h)throw new Error(`[Directive] Unknown constraint: ${l}`);let w=O(l,h);w&&s.add(l);let $={id:l,priority:h.priority??0,isAsync:w,lastResult:null,isEvaluating:false,error:null,lastResolvedAt:null,after:h.after??[]};return d.set(l,$),$}function I(l){return d.get(l)??M(l)}function R(l,h){let w=m.get(l)??new Set;for(let $ of w){let E=p.get($);E?.delete(l),E&&E.size===0&&p.delete($);}for(let $ of h)p.has($)||p.set($,new Set),p.get($).add(l);m.set(l,h);}function v(l){let h=t[l];if(!h)return false;let w=I(l);w.isEvaluating=true,w.error=null;try{let $;if(h.deps)$=h.when(o),T.set(l,new Set(h.deps));else {let E=ie(()=>h.when(o));$=E.value,T.set(l,E.deps);}return $ instanceof Promise?(s.add(l),w.isAsync=!0,process.env.NODE_ENV!=="production"&&console.warn(`[Directive] Constraint "${l}" returned a Promise but was not marked as async. Add \`async: true\` to the constraint definition to avoid this warning and improve performance.`),$.then(E=>(w.lastResult=E,w.isEvaluating=!1,n?.(l,E),E)).catch(E=>(w.error=E instanceof Error?E:new Error(String(E)),w.lastResult=!1,w.isEvaluating=!1,u?.(l,E),!1))):(w.lastResult=$,w.isEvaluating=!1,n?.(l,$),$)}catch($){return w.error=$ instanceof Error?$:new Error(String($)),w.lastResult=false,w.isEvaluating=false,u?.(l,$),false}}async function g(l){let h=t[l];if(!h)return false;let w=I(l),$=h.timeout??i;if(w.isEvaluating=true,w.error=null,h.deps?.length){let E=new Set(h.deps);R(l,E),T.set(l,E);}try{let E=h.when(o),z=await ge(E,$,`Constraint "${l}" timed out after ${$}ms`);return w.lastResult=z,w.isEvaluating=!1,n?.(l,z),z}catch(E){return w.error=E instanceof Error?E:new Error(String(E)),w.lastResult=false,w.isEvaluating=false,u?.(l,E),false}}let D=10;function j(l,h){if(l==null)return [];if(Array.isArray(l)){let w=l.filter($=>$!=null);return process.env.NODE_ENV!=="production"&&w.length>D&&h&&console.warn(`[Directive] Constraint "${h}" produced ${w.length} requirements. Consider splitting into multiple constraints for better performance.`),w}return [l]}function F(l){let h=t[l];if(!h)return {requirements:[],deps:new Set};let w=h.require;if(typeof w=="function"){let{value:E,deps:z}=ie(()=>w(o));return {requirements:j(E,l),deps:z}}return {requirements:j(w,l),deps:new Set}}function V(l,h){if(h.size===0)return;let w=m.get(l)??new Set;for(let $ of h)w.add($),p.has($)||p.set($,new Set),p.get($).add(l);m.set(l,w);}let r=null;function y(){return r||(r=Object.keys(t).sort((l,h)=>{let w=I(l),E=I(h).priority-w.priority;if(E!==0)return E;let z=f.get(l)??0,L=f.get(h)??0;return z-L})),r}for(let l of Object.keys(t))M(l);if(process.env.NODE_ENV!=="production")for(let[l,h]of Object.entries(t))h.async&&!h.deps&&console.warn(`[Directive] Async constraint "${l}" has no \`deps\` declared. Auto-tracking cannot work across async boundaries. Add \`deps: ["key1", "key2"]\` to enable dependency tracking.`);function S(l){let h=d.get(l);if(!h||h.after.length===0)return true;for(let w of h.after)if(t[w]&&!a.has(w)&&!C.has(w)&&!K.has(w))return false;return true}return {async evaluate(l){let h=new ce;C.clear();let w=y().filter(_=>!a.has(_)),$;if(!B||!l||l.size===0)$=w,B=true;else {let _=new Set;for(let H of l){let J=p.get(H);if(J)for(let ee of J)a.has(ee)||_.add(ee);}for(let H of q)a.has(H)||_.add(H);q.clear(),$=[..._];for(let H of w)if(!_.has(H)){let J=A.get(H);if(J)for(let ee of J)h.add(ee);}}function E(_,H){if(a.has(_))return;let J=T.get(_);if(!H){J!==void 0&&R(_,J),C.add(_),A.set(_,[]);return}C.delete(_);let ee,ue;try{let te=F(_);ee=te.requirements,ue=te.deps;}catch(te){u?.(_,te),J!==void 0&&R(_,J),A.set(_,[]);return}if(J!==void 0){let te=new Set(J);for(let Z of ue)te.add(Z);R(_,te);}else V(_,ue);if(ee.length>0){let te=c[_],Z=ee.map(Y=>He(Y,_,te));for(let Y of Z)h.add(Y);A.set(_,Z);}else A.set(_,[]);}async function z(_){let H=[],J=[];for(let Z of _)if(S(Z))J.push(Z);else {H.push(Z);let Y=A.get(Z);if(Y)for(let de of Y)h.add(de);}if(J.length===0)return H;let ee=[],ue=[];for(let Z of J)I(Z).isAsync?ue.push(Z):ee.push(Z);let te=[];for(let Z of ee){let Y=v(Z);if(Y instanceof Promise){te.push({id:Z,promise:Y});continue}E(Z,Y);}if(te.length>0){let Z=await Promise.all(te.map(async({id:Y,promise:de})=>({id:Y,active:await de})));for(let{id:Y,active:de}of Z)E(Y,de);}if(ue.length>0){let Z=await Promise.all(ue.map(async Y=>({id:Y,active:await g(Y)})));for(let{id:Y,active:de}of Z)E(Y,de);}return H}let L=$,U=$.length+1;for(;L.length>0&&U>0;){let _=L.length;if(L=await z(L),L.length===_)break;U--;}return h.all()},getState(l){return d.get(l)},getAllStates(){return [...d.values()]},disable(l){a.add(l),r=null,A.delete(l);let h=m.get(l);if(h){for(let w of h){let $=p.get(w);$&&($.delete(l),$.size===0&&p.delete(w));}m.delete(l);}T.delete(l);},enable(l){a.delete(l),r=null,q.add(l);},invalidate(l){let h=p.get(l);if(h)for(let w of h)q.add(w);},markResolved(l){K.add(l);let h=d.get(l);h&&(h.lastResolvedAt=Date.now());let w=P.get(l);if(w)for(let $ of w)q.add($);},isResolved(l){return K.has(l)},registerDefinitions(l){for(let[h,w]of Object.entries(l))t[h]=w,M(h),q.add(h);r=null,k(),b();}}}function ke(e){let{definitions:t,facts:o,store:c,onCompute:i,onInvalidate:n,onError:u}=e,d=new Map,a=new Map,s=new Map,m=new Map,p=new Set(["__proto__","constructor","prototype"]),q=0,T=new Set,A=false,B=100,K;function C(M){if(!t[M])throw new Error(`[Directive] Unknown derivation: ${M}`);let R={id:M,compute:()=>W(M),cachedValue:void 0,dependencies:new Set,isStale:true,isComputing:false};return d.set(M,R),R}function P(M){return d.get(M)??C(M)}function W(M){let I=P(M),R=t[M];if(!R)throw new Error(`[Directive] Unknown derivation: ${M}`);if(I.isComputing)throw new Error(`[Directive] Circular dependency detected in derivation: ${M}`);I.isComputing=true;try{let{value:v,deps:g}=ie(()=>R(o,K));return I.cachedValue=v,I.isStale=!1,f(M,g),i?.(M,v,[...g]),v}catch(v){throw u?.(M,v),v}finally{I.isComputing=false;}}function f(M,I){let R=P(M),v=R.dependencies;for(let g of v)if(d.has(g)){let D=m.get(g);D?.delete(M),D&&D.size===0&&m.delete(g);}else {let D=s.get(g);D?.delete(M),D&&D.size===0&&s.delete(g);}for(let g of I)t[g]?(m.has(g)||m.set(g,new Set),m.get(g).add(M)):(s.has(g)||s.set(g,new Set),s.get(g).add(M));R.dependencies=I;}function b(){if(!(q>0||A)){A=true;try{let M=0;for(;T.size>0;){if(++M>B){let R=[...T];throw T.clear(),new Error(`[Directive] Infinite derivation notification loop detected after ${B} iterations. Remaining: ${R.join(", ")}. This usually means a derivation listener is mutating facts that re-trigger the same derivation.`)}let I=[...T];T.clear();for(let R of I)a.get(R)?.forEach(v=>v());}}finally{A=false;}}}function k(M,I=new Set){if(I.has(M))return;I.add(M);let R=d.get(M);if(!R||R.isStale)return;R.isStale=true,n?.(M),T.add(M);let v=m.get(M);if(v)for(let g of v)k(g,I);}return K=new Proxy({},{get(M,I){if(typeof I=="symbol"||p.has(I))return;fe(I);let R=P(I);return R.isStale&&W(I),R.cachedValue}}),{get(M){let I=P(M);return I.isStale&&W(M),I.cachedValue},isStale(M){return d.get(M)?.isStale??true},invalidate(M){let I=s.get(M);if(I){q++;try{for(let R of I)k(R);}finally{q--,b();}}},invalidateMany(M){q++;try{for(let I of M){let R=s.get(I);if(R)for(let v of R)k(v);}}finally{q--,b();}},invalidateAll(){q++;try{for(let M of d.values())M.isStale||(M.isStale=!0,T.add(M.id));}finally{q--,b();}},subscribe(M,I){for(let R of M){let v=R;a.has(v)||a.set(v,new Set),a.get(v).add(I);}return ()=>{for(let R of M){let v=R,g=a.get(v);g?.delete(I),g&&g.size===0&&a.delete(v);}}},getProxy(){return K},getDependencies(M){return P(M).dependencies},registerDefinitions(M){for(let[I,R]of Object.entries(M))t[I]=R,C(I);}}}function Me(e){let{definitions:t,facts:o,store:c,onRun:i,onError:n}=e,u=new Map,d=null,a=false;function s(C){let P=t[C];if(!P)throw new Error(`[Directive] Unknown effect: ${C}`);let W={id:C,enabled:true,hasExplicitDeps:!!P.deps,dependencies:P.deps?new Set(P.deps):null,lastSnapshot:null,cleanup:null};return u.set(C,W),W}function m(C){return u.get(C)??s(C)}function p(){return o.$snapshot()}function q(C,P){let W=m(C);if(!W.enabled)return false;if(W.dependencies){for(let f of W.dependencies)if(P.has(f))return true;return false}return true}function T(C){if(C.cleanup){try{C.cleanup();}catch(P){n?.(C.id,P),console.error(`[Directive] Effect "${C.id}" cleanup threw an error:`,P);}C.cleanup=null;}}function A(C,P){if(typeof P=="function")if(a)try{P();}catch(W){n?.(C.id,W),console.error(`[Directive] Effect "${C.id}" cleanup threw an error:`,W);}else C.cleanup=P;}async function B(C){let P=m(C),W=t[C];if(!(!P.enabled||!W)){T(P),i?.(C);try{if(P.hasExplicitDeps){let f;if(c.batch(()=>{f=W.run(o,d);}),f instanceof Promise){let b=await f;A(P,b);}else A(P,f);}else {let f=null,b,k=ie(()=>(c.batch(()=>{b=W.run(o,d);}),b));f=k.deps;let O=k.value;O instanceof Promise&&(O=await O),A(P,O),P.dependencies=f.size>0?f:null;}}catch(f){n?.(C,f),console.error(`[Directive] Effect "${C}" threw an error:`,f);}}}for(let C of Object.keys(t))s(C);return {async runEffects(C){let P=[];for(let W of Object.keys(t))q(W,C)&&P.push(W);await Promise.all(P.map(B)),d=p();},async runAll(){let C=Object.keys(t);await Promise.all(C.map(P=>m(P).enabled?B(P):Promise.resolve())),d=p();},disable(C){let P=m(C);P.enabled=false;},enable(C){let P=m(C);P.enabled=true;},isEnabled(C){return m(C).enabled},cleanupAll(){a=true;for(let C of u.values())T(C);},registerDefinitions(C){for(let[P,W]of Object.entries(C))t[P]=W,s(P);}}}function Je(e={}){let{delayMs:t=1e3,maxRetries:o=3,backoffMultiplier:c=2,maxDelayMs:i=3e4}=e,n=new Map;function u(d){let a=t*Math.pow(c,d-1);return Math.min(a,i)}return {scheduleRetry(d,a,s,m,p){if(m>o)return null;let q=u(m),T={source:d,sourceId:a,context:s,attempt:m,nextRetryTime:Date.now()+q,callback:p};return n.set(a,T),T},getPendingRetries(){return Array.from(n.values())},processDueRetries(){let d=Date.now(),a=[];for(let[s,m]of n)m.nextRetryTime<=d&&(a.push(m),n.delete(s));return a},cancelRetry(d){n.delete(d);},clearAll(){n.clear();}}}var kt={constraint:"skip",resolver:"skip",effect:"skip",derivation:"skip",system:"throw"};function De(e={}){let{config:t={},onError:o,onRecovery:c}=e,i=[],n=100,u=Je(t.retryLater),d=new Map;function a(p,q,T,A){if(T instanceof le)return T;let B=T instanceof Error?T.message:String(T),K=p!=="system";return new le(B,p,q,A,K)}function s(p,q,T){let A=(()=>{switch(p){case "constraint":return t.onConstraintError;case "resolver":return t.onResolverError;case "effect":return t.onEffectError;case "derivation":return t.onDerivationError;default:return}})();if(typeof A=="function"){try{A(T,q);}catch(B){console.error("[Directive] Error in error handler callback:",B);}return "skip"}return typeof A=="string"?A:kt[p]}return {handleError(p,q,T,A){let B=a(p,q,T,A);i.push(B),i.length>n&&i.shift();try{o?.(B);}catch(C){console.error("[Directive] Error in onError callback:",C);}try{t.onError?.(B);}catch(C){console.error("[Directive] Error in config.onError callback:",C);}let K=s(p,q,T instanceof Error?T:new Error(String(T)));if(K==="retry-later"){let C=(d.get(q)??0)+1;d.set(q,C),u.scheduleRetry(p,q,A,C)||(K="skip",d.delete(q),typeof process<"u"&&process.env?.NODE_ENV!=="production"&&console.warn(`[Directive] ${p} "${q}" exceeded max retry-later attempts. Skipping.`));}try{c?.(B,K);}catch(C){console.error("[Directive] Error in onRecovery callback:",C);}if(K==="throw")throw B;return K},getLastError(){return i[i.length-1]??null},getAllErrors(){return [...i]},clearErrors(){i.length=0;},getRetryLaterManager(){return u},processDueRetries(){return u.processDueRetries()},clearRetryAttempts(p){d.delete(p),u.cancelRetry(p);}}}function xe(){let e=[];function t(i){if(i)try{return i()}catch(n){console.error("[Directive] Plugin error:",n);return}}async function o(i){if(i)try{return await i()}catch(n){console.error("[Directive] Plugin error:",n);return}}return {register(i){e.some(n=>n.name===i.name)&&(console.warn(`[Directive] Plugin "${i.name}" is already registered, replacing...`),this.unregister(i.name)),e.push(i);},unregister(i){let n=e.findIndex(u=>u.name===i);n!==-1&&e.splice(n,1);},getPlugins(){return [...e]},async emitInit(i){for(let n of e)await o(()=>n.onInit?.(i));},emitStart(i){for(let n of e)t(()=>n.onStart?.(i));},emitStop(i){for(let n of e)t(()=>n.onStop?.(i));},emitDestroy(i){for(let n of e)t(()=>n.onDestroy?.(i));},emitFactSet(i,n,u){for(let d of e)t(()=>d.onFactSet?.(i,n,u));},emitFactDelete(i,n){for(let u of e)t(()=>u.onFactDelete?.(i,n));},emitFactsBatch(i){for(let n of e)t(()=>n.onFactsBatch?.(i));},emitDerivationCompute(i,n,u){for(let d of e)t(()=>d.onDerivationCompute?.(i,n,u));},emitDerivationInvalidate(i){for(let n of e)t(()=>n.onDerivationInvalidate?.(i));},emitReconcileStart(i){for(let n of e)t(()=>n.onReconcileStart?.(i));},emitReconcileEnd(i){for(let n of e)t(()=>n.onReconcileEnd?.(i));},emitConstraintEvaluate(i,n){for(let u of e)t(()=>u.onConstraintEvaluate?.(i,n));},emitConstraintError(i,n){for(let u of e)t(()=>u.onConstraintError?.(i,n));},emitRequirementCreated(i){for(let n of e)t(()=>n.onRequirementCreated?.(i));},emitRequirementMet(i,n){for(let u of e)t(()=>u.onRequirementMet?.(i,n));},emitRequirementCanceled(i){for(let n of e)t(()=>n.onRequirementCanceled?.(i));},emitResolverStart(i,n){for(let u of e)t(()=>u.onResolverStart?.(i,n));},emitResolverComplete(i,n,u){for(let d of e)t(()=>d.onResolverComplete?.(i,n,u));},emitResolverError(i,n,u){for(let d of e)t(()=>d.onResolverError?.(i,n,u));},emitResolverRetry(i,n,u){for(let d of e)t(()=>d.onResolverRetry?.(i,n,u));},emitResolverCancel(i,n){for(let u of e)t(()=>u.onResolverCancel?.(i,n));},emitEffectRun(i){for(let n of e)t(()=>n.onEffectRun?.(i));},emitEffectError(i,n){for(let u of e)t(()=>u.onEffectError?.(i,n));},emitSnapshot(i){for(let n of e)t(()=>n.onSnapshot?.(i));},emitTimeTravel(i,n){for(let u of e)t(()=>u.onTimeTravel?.(i,n));},emitError(i){for(let n of e)t(()=>n.onError?.(i));},emitErrorRecovery(i,n){for(let u of e)t(()=>u.onErrorRecovery?.(i,n));}}}var Xe={attempts:1,backoff:"none",initialDelay:100,maxDelay:3e4},Ze={enabled:false,windowMs:50};function Ge(e,t){let{backoff:o,initialDelay:c=100,maxDelay:i=3e4}=e,n;switch(o){case "none":n=c;break;case "linear":n=c*t;break;case "exponential":n=c*Math.pow(2,t-1);break;default:n=c;}return Math.max(1,Math.min(n,i))}function Te(e){let{definitions:t,facts:o,store:c,onStart:i,onComplete:n,onError:u,onRetry:d,onCancel:a,onResolutionComplete:s}=e;if(process.env.NODE_ENV!=="production")for(let[v,g]of Object.entries(t)){if(!g.resolve&&!g.resolveBatch)throw new Error(`[Directive] Resolver "${v}" must define either resolve() or resolveBatch(). Add one of these methods to handle requirements.`);if(g.batch?.enabled&&!g.resolveBatch)throw new Error(`[Directive] Resolver "${v}" has batch.enabled=true but no resolveBatch() method. Add resolveBatch() to handle batched requirements.`)}let m=new Map,p=new Map,q=1e3,T=new Map,A=new Map,B=1e3;function K(){if(p.size>q){let v=p.size-q,g=p.keys();for(let D=0;D<v;D++){let j=g.next().value;j&&p.delete(j);}}}function C(v){return typeof v=="object"&&v!==null&&"requirement"in v&&typeof v.requirement=="string"}function P(v){return typeof v=="object"&&v!==null&&"requirement"in v&&typeof v.requirement=="function"}function W(v,g){return C(v)?g.type===v.requirement:P(v)?v.requirement(g):false}function f(v){let g=v.type,D=A.get(g);if(D)for(let j of D){let F=t[j];if(F&&W(F,v))return j}for(let[j,F]of Object.entries(t))if(W(F,v)){if(!A.has(g)){if(A.size>=B){let r=A.keys().next().value;r!==void 0&&A.delete(r);}A.set(g,[]);}let V=A.get(g);return V.includes(j)||V.push(j),j}return null}function b(v){return {facts:o,signal:v,snapshot:()=>o.$snapshot()}}async function k(v,g,D){let j=t[v];if(!j)return;let F={...Xe,...j.retry},V=null;for(let r=1;r<=F.attempts;r++){if(D.signal.aborted)return;let y=m.get(g.id);y&&(y.attempt=r,y.status={state:"running",requirementId:g.id,startedAt:y.startedAt,attempt:r});try{let S=b(D.signal);if(j.resolve){let l;c.batch(()=>{l=j.resolve(g.requirement,S);});let h=j.timeout;h&&h>0?await ge(l,h,`Resolver "${v}" timed out after ${h}ms`):await l;}let x=Date.now()-(y?.startedAt??Date.now());p.set(g.id,{state:"success",requirementId:g.id,completedAt:Date.now(),duration:x}),K(),n?.(v,g,x);return}catch(S){if(V=S instanceof Error?S:new Error(String(S)),D.signal.aborted)return;if(F.shouldRetry&&!F.shouldRetry(V,r))break;if(r<F.attempts){if(D.signal.aborted)return;let x=Ge(F,r);if(d?.(v,g,r+1),await new Promise(l=>{let h=setTimeout(l,x),w=()=>{clearTimeout(h),l();};D.signal.addEventListener("abort",w,{once:true});}),D.signal.aborted)return}}}p.set(g.id,{state:"error",requirementId:g.id,error:V,failedAt:Date.now(),attempts:F.attempts}),K(),u?.(v,g,V);}async function O(v,g){let D=t[v];if(!D)return;if(!D.resolveBatch&&!D.resolveBatchWithResults){await Promise.all(g.map(x=>{let l=new AbortController;return k(v,x,l)}));return}let j={...Xe,...D.retry},F={...Ze,...D.batch},V=new AbortController,r=Date.now(),y=null,S=F.timeoutMs??D.timeout;for(let x=1;x<=j.attempts;x++){if(V.signal.aborted)return;try{let l=b(V.signal),h=g.map(w=>w.requirement);if(D.resolveBatchWithResults){let w,$;if(c.batch(()=>{$=D.resolveBatchWithResults(h,l);}),S&&S>0?w=await ge($,S,`Batch resolver "${v}" timed out after ${S}ms`):w=await $,w.length!==g.length)throw new Error(`[Directive] Batch resolver "${v}" returned ${w.length} results but expected ${g.length}. Results array must match input order.`);let E=Date.now()-r,z=!1;for(let L=0;L<g.length;L++){let U=g[L],_=w[L];if(_.success)p.set(U.id,{state:"success",requirementId:U.id,completedAt:Date.now(),duration:E}),n?.(v,U,E);else {z=!0;let H=_.error??new Error("Batch item failed");p.set(U.id,{state:"error",requirementId:U.id,error:H,failedAt:Date.now(),attempts:x}),u?.(v,U,H);}}if(!z||g.some((L,U)=>w[U]?.success))return}else {let w;c.batch(()=>{w=D.resolveBatch(h,l);}),S&&S>0?await ge(w,S,`Batch resolver "${v}" timed out after ${S}ms`):await w;let $=Date.now()-r;for(let E of g)p.set(E.id,{state:"success",requirementId:E.id,completedAt:Date.now(),duration:$}),n?.(v,E,$);return}}catch(l){if(y=l instanceof Error?l:new Error(String(l)),V.signal.aborted)return;if(j.shouldRetry&&!j.shouldRetry(y,x))break;if(x<j.attempts){let h=Ge(j,x);for(let w of g)d?.(v,w,x+1);if(await new Promise(w=>{let $=setTimeout(w,h),E=()=>{clearTimeout($),w();};V.signal.addEventListener("abort",E,{once:true});}),V.signal.aborted)return}}}for(let x of g)p.set(x.id,{state:"error",requirementId:x.id,error:y,failedAt:Date.now(),attempts:j.attempts}),u?.(v,x,y);K();}function M(v,g){let D=t[v];if(!D)return;let j={...Ze,...D.batch};T.has(v)||T.set(v,{resolverId:v,requirements:[],timer:null});let F=T.get(v);F.requirements.push(g),F.timer&&clearTimeout(F.timer),F.timer=setTimeout(()=>{I(v);},j.windowMs);}function I(v){let g=T.get(v);if(!g||g.requirements.length===0)return;let D=[...g.requirements];g.requirements=[],g.timer=null,O(v,D).then(()=>{s?.();});}return {resolve(v){if(m.has(v.id))return;let g=f(v.requirement);if(!g){console.warn(`[Directive] No resolver found for requirement: ${v.id}`);return}let D=t[g];if(!D)return;if(D.batch?.enabled){M(g,v);return}let j=new AbortController,F=Date.now(),V={requirementId:v.id,resolverId:g,controller:j,startedAt:F,attempt:1,status:{state:"pending",requirementId:v.id,startedAt:F},originalRequirement:v};m.set(v.id,V),i?.(g,v),k(g,v,j).finally(()=>{m.delete(v.id)&&s?.();});},cancel(v){let g=m.get(v);g&&(g.controller.abort(),m.delete(v),p.set(v,{state:"canceled",requirementId:v,canceledAt:Date.now()}),K(),a?.(g.resolverId,g.originalRequirement));},cancelAll(){for(let[v]of m)this.cancel(v);for(let v of T.values())v.timer&&clearTimeout(v.timer);T.clear();},getStatus(v){let g=m.get(v);if(g)return g.status;let D=p.get(v);return D||{state:"idle"}},getInflight(){return [...m.keys()]},getInflightInfo(){return [...m.values()].map(v=>({id:v.requirementId,resolverId:v.resolverId,startedAt:v.startedAt}))},isResolving(v){return m.has(v)},processBatches(){for(let v of T.keys())I(v);},registerDefinitions(v){for(let[g,D]of Object.entries(v))t[g]=D;A.clear();}}}function Ee(e){let{config:t,facts:o,store:c,onSnapshot:i,onTimeTravel:n}=e,u=t.timeTravel??false,d=t.maxSnapshots??100,a=[],s=-1,m=1,p=false,q=false,T=[],A=null,B=-1;function K(){return c.toObject()}function C(){let f=K();return structuredClone(f)}function P(f){if(!ae(f)){console.error("[Directive] Potential prototype pollution detected in snapshot data, skipping restore");return}c.batch(()=>{for(let[b,k]of Object.entries(f)){if(b==="__proto__"||b==="constructor"||b==="prototype"){console.warn(`[Directive] Skipping dangerous key "${b}" during fact restoration`);continue}o[b]=k;}});}return {get isEnabled(){return u},get isRestoring(){return q},get isPaused(){return p},get snapshots(){return [...a]},get currentIndex(){return s},takeSnapshot(f){if(!u||p)return {id:-1,timestamp:Date.now(),facts:{},trigger:f};let b={id:m++,timestamp:Date.now(),facts:C(),trigger:f};for(s<a.length-1&&a.splice(s+1),a.push(b),s=a.length-1;a.length>d;)a.shift(),s--;return i?.(b),b},restore(f){if(u){p=true,q=true;try{P(f.facts);}finally{p=false,q=false;}}},goBack(f=1){if(!u||a.length===0)return;let b=s,k=s,O=T.find(I=>s>I.startIndex&&s<=I.endIndex);if(O)k=O.startIndex;else if(T.find(R=>s===R.startIndex)){let R=T.find(v=>v.endIndex<s&&s-v.endIndex<=f);k=R?R.startIndex:Math.max(0,s-f);}else k=Math.max(0,s-f);if(b===k)return;s=k;let M=a[s];M&&(this.restore(M),n?.(b,k));},goForward(f=1){if(!u||a.length===0)return;let b=s,k=s,O=T.find(I=>s>=I.startIndex&&s<I.endIndex);if(O?k=O.endIndex:k=Math.min(a.length-1,s+f),b===k)return;s=k;let M=a[s];M&&(this.restore(M),n?.(b,k));},goTo(f){if(!u)return;let b=a.findIndex(M=>M.id===f);if(b===-1){console.warn(`[Directive] Snapshot ${f} not found`);return}let k=s;s=b;let O=a[s];O&&(this.restore(O),n?.(k,b));},replay(){if(!u||a.length===0)return;s=0;let f=a[0];f&&this.restore(f);},export(){return JSON.stringify({version:1,snapshots:a,currentIndex:s})},import(f){if(u)try{let b=JSON.parse(f);if(typeof b!="object"||b===null)throw new Error("Invalid time-travel data: expected object");if(b.version!==1)throw new Error(`Unsupported time-travel export version: ${b.version}`);if(!Array.isArray(b.snapshots))throw new Error("Invalid time-travel data: snapshots must be an array");if(typeof b.currentIndex!="number")throw new Error("Invalid time-travel data: currentIndex must be a number");for(let O of b.snapshots){if(typeof O!="object"||O===null)throw new Error("Invalid snapshot: expected object");if(typeof O.id!="number"||typeof O.timestamp!="number"||typeof O.trigger!="string"||typeof O.facts!="object")throw new Error("Invalid snapshot structure");if(!ae(O.facts))throw new Error("Invalid fact data: potential prototype pollution detected in nested objects")}a.length=0,a.push(...b.snapshots),s=b.currentIndex;let k=a[s];k&&this.restore(k);}catch(b){console.error("[Directive] Failed to import time-travel data:",b);}},beginChangeset(f){u&&(A=f,B=s);},endChangeset(){!u||A===null||(s>B&&T.push({label:A,startIndex:B,endIndex:s}),A=null,B=-1);},pause(){p=true;},resume(){p=false;}}}function Ce(){let e={id:-1,timestamp:0,facts:{},trigger:""};return {isEnabled:false,isRestoring:false,isPaused:false,snapshots:[],currentIndex:-1,takeSnapshot:()=>e,restore:()=>{},goBack:()=>{},goForward:()=>{},goTo:()=>{},replay:()=>{},export:()=>"{}",import:()=>{},beginChangeset:()=>{},endChangeset:()=>{},pause:()=>{},resume:()=>{}}}var ne=new Set(["__proto__","constructor","prototype"]);function be(e){let t=Object.create(null),o=Object.create(null),c=Object.create(null),i=Object.create(null),n=Object.create(null),u=Object.create(null),d=new Map;for(let r of e.modules){let y=(S,x)=>{if(S){for(let l of Object.keys(S))if(ne.has(l))throw new Error(`[Directive] Security: Module "${r.id}" has dangerous key "${l}" in ${x}. This could indicate a prototype pollution attempt.`)}};if(y(r.schema,"schema"),y(r.events,"events"),y(r.derive,"derive"),y(r.effects,"effects"),y(r.constraints,"constraints"),y(r.resolvers,"resolvers"),process.env.NODE_ENV!=="production")for(let S of Object.keys(r.schema)){let x=d.get(S);if(x)throw new Error(`[Directive] Schema collision: Fact "${S}" is defined in both module "${x}" and "${r.id}". Use namespacing (e.g., "${r.id}::${S}") or merge into one module.`);d.set(S,r.id);}Object.assign(t,r.schema),r.events&&Object.assign(o,r.events),r.derive&&Object.assign(c,r.derive),r.effects&&Object.assign(i,r.effects),r.constraints&&Object.assign(n,r.constraints),r.resolvers&&Object.assign(u,r.resolvers);}if(process.env.NODE_ENV!=="production"){let r=new Set(Object.keys(c));for(let y of Object.keys(t))r.has(y)&&console.warn(`[Directive] "${y}" exists as both a fact and a derivation. This may cause unexpected dependency tracking behavior.`);}let a=xe();for(let r of e.plugins??[])a.register(r);let s=De({config:e.errorBoundary,onError:r=>a.emitError(r),onRecovery:(r,y)=>a.emitErrorRecovery(r,y)}),m=()=>{},p=()=>{},q=null,{store:T,facts:A}=we({schema:t,onChange:(r,y,S)=>{a.emitFactSet(r,y,S),m(r),!q?.isRestoring&&(R.changedKeys.add(r),v());},onBatch:r=>{a.emitFactsBatch(r);let y=[];for(let S of r)y.push(S.key);if(p(y),!q?.isRestoring){for(let S of r)R.changedKeys.add(S.key);v();}}}),B=ke({definitions:c,facts:A,store:T,onCompute:(r,y,S)=>a.emitDerivationCompute(r,y,S),onInvalidate:r=>a.emitDerivationInvalidate(r),onError:(r,y)=>{s.handleError("derivation",r,y);}});m=r=>B.invalidate(r),p=r=>B.invalidateMany(r);let K=Me({definitions:i,facts:A,store:T,onRun:r=>a.emitEffectRun(r),onError:(r,y)=>{s.handleError("effect",r,y),a.emitEffectError(r,y);}}),C=Re({definitions:n,facts:A,onEvaluate:(r,y)=>a.emitConstraintEvaluate(r,y),onError:(r,y)=>{s.handleError("constraint",r,y),a.emitConstraintError(r,y);}}),P=Te({definitions:u,facts:A,store:T,onStart:(r,y)=>a.emitResolverStart(r,y),onComplete:(r,y,S)=>{a.emitResolverComplete(r,y,S),a.emitRequirementMet(y,r),C.markResolved(y.fromConstraint);},onError:(r,y,S)=>{s.handleError("resolver",r,S,y),a.emitResolverError(r,y,S);},onRetry:(r,y,S)=>a.emitResolverRetry(r,y,S),onCancel:(r,y)=>{a.emitResolverCancel(r,y),a.emitRequirementCanceled(y);},onResolutionComplete:()=>{O(),v();}}),W=new Set;function f(){for(let r of W)r();}let b=e.debug?.timeTravel?Ee({config:e.debug,facts:A,store:T,onSnapshot:r=>{a.emitSnapshot(r),f();},onTimeTravel:(r,y)=>{a.emitTimeTravel(r,y),f();}}):Ce();q=b;let k=new Set;function O(){for(let r of k)r();}let M=50,I=0,R={isRunning:false,isReconciling:false,reconcileScheduled:false,isInitializing:false,isInitialized:false,isReady:false,isDestroyed:false,changedKeys:new Set,previousRequirements:new ce,readyPromise:null,readyResolve:null};function v(){!R.isRunning||R.reconcileScheduled||R.isInitializing||(R.reconcileScheduled=true,O(),queueMicrotask(()=>{R.reconcileScheduled=false,R.isRunning&&!R.isInitializing&&g().catch(r=>{process.env.NODE_ENV!=="production"&&console.error("[Directive] Unexpected error in reconcile:",r);});}));}async function g(){if(!R.isReconciling){if(I++,I>M){process.env.NODE_ENV!=="production"&&console.warn(`[Directive] Reconcile loop exceeded ${M} iterations. This usually means resolvers are creating circular requirement chains. Check that resolvers aren't mutating facts that re-trigger their own constraints.`),I=0;return}R.isReconciling=true,O();try{R.changedKeys.size>0&&b.takeSnapshot(`facts-changed:${[...R.changedKeys].join(",")}`);let r=A.$snapshot();a.emitReconcileStart(r),await K.runEffects(R.changedKeys);let y=new Set(R.changedKeys);R.changedKeys.clear();let S=await C.evaluate(y),x=new ce;for(let E of S)x.add(E),a.emitRequirementCreated(E);let{added:l,removed:h}=x.diff(R.previousRequirements);for(let E of h)P.cancel(E.id);for(let E of l)P.resolve(E);R.previousRequirements=x;let w=P.getInflightInfo(),$={unmet:S.filter(E=>!P.isResolving(E.id)),inflight:w,completed:[],canceled:h.map(E=>({id:E.id,resolverId:w.find(z=>z.id===E.id)?.resolverId??"unknown"}))};a.emitReconcileEnd($),R.isReady||(R.isReady=!0,R.readyResolve&&(R.readyResolve(),R.readyResolve=null));}finally{R.isReconciling=false,R.changedKeys.size>0?v():R.reconcileScheduled||(I=0),O();}}}let D=new Proxy({},{get(r,y){if(typeof y!="symbol"&&!ne.has(y))return B.get(y)},has(r,y){return typeof y=="symbol"||ne.has(y)?false:y in c},ownKeys(){return Object.keys(c)},getOwnPropertyDescriptor(r,y){if(typeof y!="symbol"&&!ne.has(y)&&y in c)return {configurable:true,enumerable:true}}}),j=new Proxy({},{get(r,y){if(typeof y!="symbol"&&!ne.has(y))return S=>{let x=o[y];x?T.batch(()=>{x(A,{type:y,...S});}):process.env.NODE_ENV!=="production"&&console.warn(`[Directive] Unknown event type "${y}". No handler is registered for this event. Available events: ${Object.keys(o).join(", ")||"(none)"}`);}},has(r,y){return typeof y=="symbol"||ne.has(y)?false:y in o},ownKeys(){return Object.keys(o)},getOwnPropertyDescriptor(r,y){if(typeof y!="symbol"&&!ne.has(y)&&y in o)return {configurable:true,enumerable:true}}}),F={facts:A,debug:b.isEnabled?b:null,derive:D,events:j,constraints:{disable:r=>C.disable(r),enable:r=>C.enable(r)},effects:{disable:r=>K.disable(r),enable:r=>K.enable(r),isEnabled:r=>K.isEnabled(r)},start(){if(!R.isRunning){R.isRunning=true,R.isInitializing=true;for(let r of e.modules)r.init&&T.batch(()=>{r.init(A);}),r.hooks?.onStart?.(F);e.onAfterModuleInit&&T.batch(()=>{e.onAfterModuleInit();}),R.isInitializing=false,R.isInitialized=true,a.emitStart(F),v();}},stop(){if(R.isRunning){R.isRunning=false,P.cancelAll(),K.cleanupAll();for(let r of e.modules)r.hooks?.onStop?.(F);a.emitStop(F);}},destroy(){this.stop(),R.isDestroyed=true,k.clear(),W.clear(),a.emitDestroy(F);},dispatch(r){if(ne.has(r.type))return;let y=o[r.type];y?T.batch(()=>{y(A,r);}):process.env.NODE_ENV!=="production"&&console.warn(`[Directive] Unknown event type "${r.type}". No handler is registered for this event. Available events: ${Object.keys(o).join(", ")||"(none)"}`);},read(r){return B.get(r)},subscribe(r,y){let S=[],x=[];for(let h of r)h in c?S.push(h):h in t?x.push(h):process.env.NODE_ENV!=="production"&&console.warn(`[Directive] subscribe: unknown key "${h}"`);let l=[];return S.length>0&&l.push(B.subscribe(S,y)),x.length>0&&l.push(T.subscribe(x,y)),()=>{for(let h of l)h();}},watch(r,y,S){let x=S?.equalityFn?(h,w)=>S.equalityFn(h,w):(h,w)=>Object.is(h,w);if(r in c){let h=B.get(r);return B.subscribe([r],()=>{let w=B.get(r);if(!x(w,h)){let $=h;h=w,y(w,$);}})}process.env.NODE_ENV!=="production"&&(r in t||console.warn(`[Directive] watch: unknown key "${r}"`));let l=T.get(r);return T.subscribe([r],()=>{let h=T.get(r);if(!x(h,l)){let w=l;l=h,y(h,w);}})},when(r,y){return new Promise((S,x)=>{let l=T.toObject();if(r(l)){S();return}let h,w,$=()=>{h?.(),w!==void 0&&clearTimeout(w);};h=T.subscribeAll(()=>{let E=T.toObject();r(E)&&($(),S());}),y?.timeout!==void 0&&y.timeout>0&&(w=setTimeout(()=>{$(),x(new Error(`[Directive] when: timed out after ${y.timeout}ms`));},y.timeout));})},inspect(){return {unmet:R.previousRequirements.all(),inflight:P.getInflightInfo(),constraints:C.getAllStates().map(r=>({id:r.id,active:r.lastResult??false,priority:r.priority})),resolvers:Object.fromEntries(P.getInflight().map(r=>[r,P.getStatus(r)]))}},explain(r){let S=R.previousRequirements.all().find(L=>L.id===r);if(!S)return null;let x=C.getState(S.fromConstraint),l=P.getStatus(r),h={},w=T.toObject();for(let[L,U]of Object.entries(w))h[L]=U;let $=[`Requirement "${S.requirement.type}" (id: ${S.id})`,`\u251C\u2500 Produced by constraint: ${S.fromConstraint}`,`\u251C\u2500 Constraint priority: ${x?.priority??0}`,`\u251C\u2500 Constraint active: ${x?.lastResult??"unknown"}`,`\u251C\u2500 Resolver status: ${l.state}`],E=Object.entries(S.requirement).filter(([L])=>L!=="type").map(([L,U])=>`${L}=${JSON.stringify(U)}`).join(", ");E&&$.push(`\u251C\u2500 Requirement payload: { ${E} }`);let z=Object.entries(h).slice(0,10);return z.length>0&&($.push("\u2514\u2500 Relevant facts:"),z.forEach(([L,U],_)=>{let H=_===z.length-1?" \u2514\u2500":" \u251C\u2500",J=typeof U=="object"?JSON.stringify(U):String(U);$.push(`${H} ${L} = ${J.slice(0,50)}${J.length>50?"...":""}`);})),$.join(`
|
|
2
|
+
`)},async settle(r=5e3){let y=Date.now();for(;;){await new Promise(l=>setTimeout(l,0));let S=this.inspect();if(S.inflight.length===0&&!R.isReconciling&&!R.reconcileScheduled)return;if(Date.now()-y>r){let l=[];S.inflight.length>0&&l.push(`${S.inflight.length} resolvers inflight: ${S.inflight.map(w=>w.resolverId).join(", ")}`),R.isReconciling&&l.push("reconciliation in progress"),R.reconcileScheduled&&l.push("reconcile scheduled");let h=R.previousRequirements.all();throw h.length>0&&l.push(`${h.length} unmet requirements: ${h.map(w=>w.requirement.type).join(", ")}`),new Error(`[Directive] settle() timed out after ${r}ms. ${l.join("; ")}`)}await new Promise(l=>setTimeout(l,10));}},getSnapshot(){return {facts:T.toObject(),version:1}},getDistributableSnapshot(r={}){let{includeDerivations:y,excludeDerivations:S,includeFacts:x,ttlSeconds:l,metadata:h,includeVersion:w}=r,$={},E=Object.keys(c),z;if(y){if(z=y.filter(_=>E.includes(_)),process.env.NODE_ENV!=="production"){let _=y.filter(H=>!E.includes(H));_.length>0&&console.warn(`[Directive] getDistributableSnapshot: Unknown derivation keys ignored: ${_.join(", ")}. Available: ${E.join(", ")||"(none)"}`);}}else z=E;if(S){let _=new Set(S);z=z.filter(H=>!_.has(H));}for(let _ of z)try{$[_]=B.get(_);}catch(H){process.env.NODE_ENV!=="production"&&console.warn(`[Directive] getDistributableSnapshot: Skipping derivation "${_}" due to error:`,H);}if(x&&x.length>0){let _=T.toObject(),H=Object.keys(_);if(process.env.NODE_ENV!=="production"){let J=x.filter(ee=>!(ee in _));J.length>0&&console.warn(`[Directive] getDistributableSnapshot: Unknown fact keys ignored: ${J.join(", ")}. Available: ${H.join(", ")||"(none)"}`);}for(let J of x)J in _&&($[J]=_[J]);}let L=Date.now(),U={data:$,createdAt:L};return l!==void 0&&l>0&&(U.expiresAt=L+l*1e3),w&&(U.version=Ve($)),h&&(U.metadata=h),U},watchDistributableSnapshot(r,y){let{includeDerivations:S,excludeDerivations:x}=r,l=Object.keys(c),h;if(S?h=S.filter(E=>l.includes(E)):h=l,x){let E=new Set(x);h=h.filter(z=>!E.has(z));}if(h.length===0)return process.env.NODE_ENV!=="production"&&console.warn("[Directive] watchDistributableSnapshot: No derivations to watch. Callback will never be called."),()=>{};let $=this.getDistributableSnapshot({...r,includeVersion:true}).version;return B.subscribe(h,()=>{let E=this.getDistributableSnapshot({...r,includeVersion:true});E.version!==$&&($=E.version,y(E));})},restore(r){if(!r||typeof r!="object")throw new Error("[Directive] restore() requires a valid snapshot object");if(!r.facts||typeof r.facts!="object")throw new Error("[Directive] restore() snapshot must have a facts object");if(!ae(r))throw new Error("[Directive] restore() rejected: snapshot contains potentially dangerous keys (__proto__, constructor, or prototype). This may indicate a prototype pollution attack.");T.batch(()=>{for(let[y,S]of Object.entries(r.facts))ne.has(y)||T.set(y,S);});},onSettledChange(r){return k.add(r),()=>{k.delete(r);}},onTimeTravelChange(r){return W.add(r),()=>{W.delete(r);}},batch(r){T.batch(r);},get isSettled(){return this.inspect().inflight.length===0&&!R.isReconciling&&!R.reconcileScheduled},get isRunning(){return R.isRunning},get isInitialized(){return R.isInitialized},get isReady(){return R.isReady},whenReady(){return R.isReady?Promise.resolve():R.isRunning?(R.readyPromise||(R.readyPromise=new Promise(r=>{R.readyResolve=r;})),R.readyPromise):Promise.reject(new Error("[Directive] whenReady() called before start(). Call system.start() first, then await system.whenReady()."))}};function V(r){if(R.isReconciling)throw new Error(`[Directive] Cannot register module "${r.id}" during reconciliation. Wait for the current reconciliation cycle to complete.`);if(R.isDestroyed)throw new Error(`[Directive] Cannot register module "${r.id}" on a destroyed system.`);let y=(S,x)=>{if(S){for(let l of Object.keys(S))if(ne.has(l))throw new Error(`[Directive] Security: Module "${r.id}" has dangerous key "${l}" in ${x}.`)}};y(r.schema,"schema"),y(r.events,"events"),y(r.derive,"derive"),y(r.effects,"effects"),y(r.constraints,"constraints"),y(r.resolvers,"resolvers");for(let S of Object.keys(r.schema))if(S in t)throw new Error(`[Directive] Schema collision: Fact "${S}" already exists. Cannot register module "${r.id}".`);if(process.env.NODE_ENV!=="production"&&r.derive){let S=new Set(Object.keys(t));for(let x of Object.keys(r.derive))S.has(x)&&console.warn(`[Directive] "${x}" exists as both a fact and a derivation after registering module "${r.id}".`);}Object.assign(t,r.schema),r.events&&Object.assign(o,r.events),r.derive&&(Object.assign(c,r.derive),B.registerDefinitions(r.derive)),r.effects&&(Object.assign(i,r.effects),K.registerDefinitions(r.effects)),r.constraints&&(Object.assign(n,r.constraints),C.registerDefinitions(r.constraints)),r.resolvers&&(Object.assign(u,r.resolvers),P.registerDefinitions(r.resolvers)),T.registerKeys(r.schema),e.modules.push(r),r.init&&T.batch(()=>{r.init(A);}),r.hooks?.onInit?.(F),R.isRunning&&(r.hooks?.onStart?.(F),v());}F.registerModule=V,a.emitInit(F);for(let r of e.modules)r.hooks?.onInit?.(F);return F}var G=Object.freeze(new Set(["__proto__","constructor","prototype"])),N="::";function Mt(e){let t=Object.keys(e),o=new Set,c=new Set,i=[],n=[];function u(d){if(o.has(d))return;if(c.has(d)){let s=n.indexOf(d),m=[...n.slice(s),d].join(" \u2192 ");throw new Error(`[Directive] Circular dependency detected: ${m}. Modules cannot have circular crossModuleDeps. Break the cycle by removing one of the cross-module references.`)}c.add(d),n.push(d);let a=e[d];if(a?.crossModuleDeps)for(let s of Object.keys(a.crossModuleDeps))t.includes(s)&&u(s);n.pop(),c.delete(d),o.add(d),i.push(d);}for(let d of t)u(d);return i}var Ye=new WeakMap,Qe=new WeakMap,et=new WeakMap,tt=new WeakMap;function me(e){if("module"in e){if(!e.module)throw new Error("[Directive] createSystem requires a module. Got: "+typeof e.module);return Et(e)}let t=e;if(Array.isArray(t.modules))throw new Error(`[Directive] createSystem expects modules as an object, not an array.
|
|
3
|
+
|
|
4
|
+
Instead of:
|
|
5
|
+
createSystem({ modules: [authModule, dataModule] })
|
|
6
|
+
|
|
7
|
+
Use:
|
|
8
|
+
createSystem({ modules: { auth: authModule, data: dataModule } })
|
|
9
|
+
|
|
10
|
+
Or for a single module:
|
|
11
|
+
createSystem({ module: counterModule })`);return Dt(t)}function Dt(e){let t=e.modules,o=new Set(Object.keys(t));if(e.tickMs!==void 0&&e.tickMs<=0)throw new Error("[Directive] tickMs must be a positive number");if(process.env.NODE_ENV!=="production"){for(let[f,b]of Object.entries(t))if(b.crossModuleDeps)for(let k of Object.keys(b.crossModuleDeps))k===f?console.warn(`[Directive] Module "${f}" references itself in crossModuleDeps. Use "facts.self" to access own module's facts instead.`):o.has(k)||console.warn(`[Directive] Module "${f}" declares crossModuleDeps.${k}, but no module with namespace "${k}" exists in the system. Available modules: ${[...o].join(", ")}`);}let c,i=e.initOrder??"auto";if(Array.isArray(i)){let f=i,b=Object.keys(t).filter(k=>!f.includes(k));if(b.length>0)throw new Error(`[Directive] initOrder is missing modules: ${b.join(", ")}. All modules must be included in the explicit order.`);c=f;}else i==="declaration"?c=Object.keys(t):c=Mt(t);let n=e.debug,u=e.errorBoundary;e.zeroConfig&&(n={timeTravel:process.env.NODE_ENV!=="production",maxSnapshots:100,...e.debug},u={onConstraintError:"skip",onResolverError:"skip",onEffectError:"skip",onDerivationError:"skip",...e.errorBoundary});for(let f of Object.keys(t)){if(f.includes(N))throw new Error(`[Directive] Module name "${f}" contains the reserved separator "${N}". Module names cannot contain "${N}".`);let b=t[f];if(b){for(let k of Object.keys(b.schema.facts))if(k.includes(N))throw new Error(`[Directive] Schema key "${k}" in module "${f}" contains the reserved separator "${N}". Schema keys cannot contain "${N}".`)}}let d=[];for(let f of c){let b=t[f];if(!b)continue;let k=b.crossModuleDeps&&Object.keys(b.crossModuleDeps).length>0,O=k?Object.keys(b.crossModuleDeps):[],M={};for(let[r,y]of Object.entries(b.schema.facts))M[`${f}${N}${r}`]=y;let I={};if(b.schema.derivations)for(let[r,y]of Object.entries(b.schema.derivations))I[`${f}${N}${r}`]=y;let R={};if(b.schema.events)for(let[r,y]of Object.entries(b.schema.events))R[`${f}${N}${r}`]=y;let v=b.init?r=>{let y=Q(r,f);b.init(y);}:void 0,g={};if(b.derive)for(let[r,y]of Object.entries(b.derive))g[`${f}${N}${r}`]=(S,x)=>{let l=k?re(S,f,O):Q(S,f),h=$e(x,f);return y(l,h)};let D={};if(b.events)for(let[r,y]of Object.entries(b.events))D[`${f}${N}${r}`]=(S,x)=>{let l=Q(S,f);y(l,x);};let j={};if(b.constraints)for(let[r,y]of Object.entries(b.constraints)){let S=y;j[`${f}${N}${r}`]={...S,deps:S.deps?.map(x=>`${f}${N}${x}`),when:x=>{let l=k?re(x,f,O):Q(x,f);return S.when(l)},require:typeof S.require=="function"?x=>{let l=k?re(x,f,O):Q(x,f);return S.require(l)}:S.require};}let F={};if(b.resolvers)for(let[r,y]of Object.entries(b.resolvers)){let S=y;F[`${f}${N}${r}`]={...S,resolve:async(x,l)=>{let h=qe(l.facts,t,()=>Object.keys(t));await S.resolve(x,{facts:h[f],signal:l.signal});}};}let V={};if(b.effects)for(let[r,y]of Object.entries(b.effects)){let S=y;V[`${f}${N}${r}`]={...S,run:(x,l)=>{let h=k?re(x,f,O):Q(x,f),w=l?k?re(l,f,O):Q(l,f):void 0;return S.run(h,w)},deps:S.deps?.map(x=>`${f}${N}${x}`)};}d.push({id:b.id,schema:{facts:M,derivations:I,events:R,requirements:b.schema.requirements??{}},init:v,derive:g,events:D,effects:V,constraints:j,resolvers:F,hooks:b.hooks});}process.env.NODE_ENV!=="production"&&e.tickMs&&e.tickMs>0&&(d.some(b=>b.events&&Object.keys(b.events).some(k=>k.endsWith(`${N}tick`)))||console.warn(`[Directive] tickMs is set to ${e.tickMs}ms but no module defines a "tick" event handler.`));let a=null,s=null;function m(f){for(let[b,k]of Object.entries(f)){if(G.has(b)){process.env.NODE_ENV!=="production"&&console.warn(`[Directive] initialFacts/hydrate contains blocked namespace "${b}". Skipping.`);continue}if(!o.has(b)){process.env.NODE_ENV!=="production"&&console.warn(`[Directive] initialFacts/hydrate contains unknown namespace "${b}". Available modules: ${[...o].join(", ")}`);continue}if(k&&typeof k=="object"&&!ae(k))throw new Error(`[Directive] initialFacts/hydrate for namespace "${b}" contains potentially dangerous keys (__proto__, constructor, or prototype). This may indicate a prototype pollution attack.`);for(let[O,M]of Object.entries(k))G.has(O)||(s.facts[`${b}${N}${O}`]=M);}}s=be({modules:d.map(f=>({id:f.id,schema:f.schema.facts,requirements:f.schema.requirements,init:f.init,derive:f.derive,events:f.events,effects:f.effects,constraints:f.constraints,resolvers:f.resolvers,hooks:f.hooks})),plugins:e.plugins,debug:n,errorBoundary:u,tickMs:e.tickMs,onAfterModuleInit:()=>{e.initialFacts&&m(e.initialFacts),a&&(m(a),a=null);}});let p=new Map;for(let f of Object.keys(t)){let b=t[f];if(!b)continue;let k=[];for(let O of Object.keys(b.schema.facts))k.push(`${f}${N}${O}`);if(b.schema.derivations)for(let O of Object.keys(b.schema.derivations))k.push(`${f}${N}${O}`);p.set(f,k);}let q={names:null};function T(){return q.names===null&&(q.names=Object.keys(t)),q.names}let A=qe(s.facts,t,T),B=xt(s.derive,t,T),K=Tt(s,t,T),C=null,P=e.tickMs;return {_mode:"namespaced",facts:A,debug:s.debug,derive:B,events:K,constraints:s.constraints,effects:s.effects,get isRunning(){return s.isRunning},get isSettled(){return s.isSettled},get isInitialized(){return s.isInitialized},get isReady(){return s.isReady},whenReady:s.whenReady.bind(s),async hydrate(f){if(s.isRunning)throw new Error("[Directive] hydrate() must be called before start(). The system is already running.");let b=await f();b&&typeof b=="object"&&(a=b);},start(){if(s.start(),P&&P>0){let f=Object.keys(d[0]?.events??{}).find(b=>b.endsWith(`${N}tick`));f&&(C=setInterval(()=>{s.dispatch({type:f});},P));}},stop(){C&&(clearInterval(C),C=null),s.stop();},destroy(){this.stop(),s.destroy();},dispatch(f){s.dispatch(f);},batch:s.batch.bind(s),read(f){return s.read(se(f))},subscribe(f,b){let k=[];for(let O of f)if(O.endsWith(".*")){let M=O.slice(0,-2),I=p.get(M);I?k.push(...I):process.env.NODE_ENV!=="production"&&console.warn(`[Directive] subscribe wildcard "${O}" \u2014 namespace "${M}" not found.`);}else k.push(se(O));return s.subscribe(k,b)},subscribeModule(f,b){let k=p.get(f);return !k||k.length===0?(process.env.NODE_ENV!=="production"&&console.warn(`[Directive] subscribeModule("${f}") \u2014 namespace not found. Available: ${[...p.keys()].join(", ")}`),()=>{}):s.subscribe(k,b)},watch(f,b,k){return s.watch(se(f),b,k)},when(f,b){return s.when(()=>f(A),b)},onSettledChange:s.onSettledChange.bind(s),onTimeTravelChange:s.onTimeTravelChange.bind(s),inspect:s.inspect.bind(s),settle:s.settle.bind(s),explain:s.explain.bind(s),getSnapshot:s.getSnapshot.bind(s),restore:s.restore.bind(s),getDistributableSnapshot(f){let b={...f,includeDerivations:f?.includeDerivations?.map(se),excludeDerivations:f?.excludeDerivations?.map(se),includeFacts:f?.includeFacts?.map(se)},k=s.getDistributableSnapshot(b),O={};for(let[M,I]of Object.entries(k.data)){let R=M.indexOf(N);if(R>0){let v=M.slice(0,R),g=M.slice(R+N.length);O[v]||(O[v]={}),O[v][g]=I;}else O._root||(O._root={}),O._root[M]=I;}return {...k,data:O}},watchDistributableSnapshot(f,b){let k={...f,includeDerivations:f?.includeDerivations?.map(se),excludeDerivations:f?.excludeDerivations?.map(se),includeFacts:f?.includeFacts?.map(se)};return s.watchDistributableSnapshot(k,O=>{let M={};for(let[I,R]of Object.entries(O.data)){let v=I.indexOf(N);if(v>0){let g=I.slice(0,v),D=I.slice(v+N.length);M[g]||(M[g]={}),M[g][D]=R;}else M._root||(M._root={}),M._root[I]=R;}b({...O,data:M});})},registerModule(f,b){if(o.has(f))throw new Error(`[Directive] Module namespace "${f}" already exists. Cannot register a duplicate namespace.`);if(f.includes(N))throw new Error(`[Directive] Module name "${f}" contains the reserved separator "${N}".`);if(G.has(f))throw new Error(`[Directive] Module name "${f}" is a blocked property.`);for(let r of Object.keys(b.schema.facts))if(r.includes(N))throw new Error(`[Directive] Schema key "${r}" in module "${f}" contains the reserved separator "${N}".`);let k=b,O=k.crossModuleDeps&&Object.keys(k.crossModuleDeps).length>0,M=O?Object.keys(k.crossModuleDeps):[],I={};for(let[r,y]of Object.entries(k.schema.facts))I[`${f}${N}${r}`]=y;let R=k.init?r=>{let y=Q(r,f);k.init(y);}:void 0,v={};if(k.derive)for(let[r,y]of Object.entries(k.derive))v[`${f}${N}${r}`]=(S,x)=>{let l=O?re(S,f,M):Q(S,f),h=$e(x,f);return y(l,h)};let g={};if(k.events)for(let[r,y]of Object.entries(k.events))g[`${f}${N}${r}`]=(S,x)=>{let l=Q(S,f);y(l,x);};let D={};if(k.constraints)for(let[r,y]of Object.entries(k.constraints)){let S=y;D[`${f}${N}${r}`]={...S,deps:S.deps?.map(x=>`${f}${N}${x}`),when:x=>{let l=O?re(x,f,M):Q(x,f);return S.when(l)},require:typeof S.require=="function"?x=>{let l=O?re(x,f,M):Q(x,f);return S.require(l)}:S.require};}let j={};if(k.resolvers)for(let[r,y]of Object.entries(k.resolvers)){let S=y;j[`${f}${N}${r}`]={...S,resolve:async(x,l)=>{let h=qe(l.facts,t,T);await S.resolve(x,{facts:h[f],signal:l.signal});}};}let F={};if(k.effects)for(let[r,y]of Object.entries(k.effects)){let S=y;F[`${f}${N}${r}`]={...S,run:(x,l)=>{let h=O?re(x,f,M):Q(x,f),w=l?O?re(l,f,M):Q(l,f):void 0;return S.run(h,w)},deps:S.deps?.map(x=>`${f}${N}${x}`)};}o.add(f),t[f]=k,q.names=null;let V=[];for(let r of Object.keys(k.schema.facts))V.push(`${f}${N}${r}`);if(k.schema.derivations)for(let r of Object.keys(k.schema.derivations))V.push(`${f}${N}${r}`);p.set(f,V),s.registerModule({id:k.id,schema:I,requirements:k.schema.requirements??{},init:R,derive:Object.keys(v).length>0?v:void 0,events:Object.keys(g).length>0?g:void 0,effects:Object.keys(F).length>0?F:void 0,constraints:Object.keys(D).length>0?D:void 0,resolvers:Object.keys(j).length>0?j:void 0,hooks:k.hooks});}}}function se(e){if(e.includes(".")){let[t,...o]=e.split(".");return `${t}${N}${o.join(N)}`}return e}function Q(e,t){let o=Ye.get(e);if(o){let i=o.get(t);if(i)return i}else o=new Map,Ye.set(e,o);let c=new Proxy({},{get(i,n){if(typeof n!="symbol"&&!G.has(n))return n==="$store"||n==="$snapshot"?e[n]:e[`${t}${N}${n}`]},set(i,n,u){return typeof n=="symbol"||G.has(n)?false:(e[`${t}${N}${n}`]=u,true)},has(i,n){return typeof n=="symbol"||G.has(n)?false:`${t}${N}${n}`in e},deleteProperty(i,n){return typeof n=="symbol"||G.has(n)?false:(delete e[`${t}${N}${n}`],true)}});return o.set(t,c),c}function qe(e,t,o){let c=Qe.get(e);if(c)return c;let i=new Proxy({},{get(n,u){if(typeof u!="symbol"&&!G.has(u)&&Object.hasOwn(t,u))return Q(e,u)},has(n,u){return typeof u=="symbol"||G.has(u)?false:Object.hasOwn(t,u)},ownKeys(){return o()},getOwnPropertyDescriptor(n,u){if(typeof u!="symbol"&&Object.hasOwn(t,u))return {configurable:true,enumerable:true}}});return Qe.set(e,i),i}var nt=new WeakMap;function re(e,t,o){let c=`${t}:${JSON.stringify([...o].sort())}`,i=nt.get(e);if(i){let a=i.get(c);if(a)return a}else i=new Map,nt.set(e,i);let n=new Set(o),u=["self",...o],d=new Proxy({},{get(a,s){if(typeof s!="symbol"&&!G.has(s)){if(s==="self")return Q(e,t);if(n.has(s))return Q(e,s);process.env.NODE_ENV!=="production"&&typeof s=="string"&&console.warn(`[Directive] Module "${t}" accessed undeclared cross-module property "${s}". Add it to crossModuleDeps or use "facts.self.${s}" for own module facts.`);}},has(a,s){return typeof s=="symbol"||G.has(s)?false:s==="self"||n.has(s)},ownKeys(){return u},getOwnPropertyDescriptor(a,s){if(typeof s!="symbol"&&(s==="self"||n.has(s)))return {configurable:true,enumerable:true}}});return i.set(c,d),d}function $e(e,t){let o=tt.get(e);if(o){let i=o.get(t);if(i)return i}else o=new Map,tt.set(e,o);let c=new Proxy({},{get(i,n){if(typeof n!="symbol"&&!G.has(n))return e[`${t}${N}${n}`]},has(i,n){return typeof n=="symbol"||G.has(n)?false:`${t}${N}${n}`in e}});return o.set(t,c),c}function xt(e,t,o){let c=et.get(e);if(c)return c;let i=new Proxy({},{get(n,u){if(typeof u!="symbol"&&!G.has(u)&&Object.hasOwn(t,u))return $e(e,u)},has(n,u){return typeof u=="symbol"||G.has(u)?false:Object.hasOwn(t,u)},ownKeys(){return o()},getOwnPropertyDescriptor(n,u){if(typeof u!="symbol"&&Object.hasOwn(t,u))return {configurable:true,enumerable:true}}});return et.set(e,i),i}var rt=new WeakMap;function Tt(e,t,o){let c=rt.get(e);return c||(c=new Map,rt.set(e,c)),new Proxy({},{get(i,n){if(typeof n=="symbol"||G.has(n)||!Object.hasOwn(t,n))return;let u=c.get(n);if(u)return u;let d=new Proxy({},{get(a,s){if(typeof s!="symbol"&&!G.has(s))return m=>{e.dispatch({type:`${n}${N}${s}`,...m});}}});return c.set(n,d),d},has(i,n){return typeof n=="symbol"||G.has(n)?false:Object.hasOwn(t,n)},ownKeys(){return o()},getOwnPropertyDescriptor(i,n){if(typeof n!="symbol"&&Object.hasOwn(t,n))return {configurable:true,enumerable:true}}})}function Et(e){let t=e.module;if(!t)throw new Error("[Directive] createSystem requires a module. Got: "+typeof t);if(e.tickMs!==void 0&&e.tickMs<=0)throw new Error("[Directive] tickMs must be a positive number");if(e.initialFacts&&!ae(e.initialFacts))throw new Error("[Directive] initialFacts contains potentially dangerous keys (__proto__, constructor, or prototype). This may indicate a prototype pollution attack.");process.env.NODE_ENV!=="production"&&(t.crossModuleDeps&&Object.keys(t.crossModuleDeps).length>0&&console.warn("[Directive] Single module mode ignores crossModuleDeps. Use multiple modules if cross-module access is needed: createSystem({ modules: { ... } })"),e.tickMs&&e.tickMs>0&&(t.events&&"tick"in t.events||console.warn(`[Directive] tickMs is set to ${e.tickMs}ms but module has no "tick" event handler.`)));let o=e.debug,c=e.errorBoundary;e.zeroConfig&&(o={timeTravel:process.env.NODE_ENV!=="production",maxSnapshots:100,...e.debug},c={onConstraintError:"skip",onResolverError:"skip",onEffectError:"skip",onDerivationError:"skip",...e.errorBoundary});let i=null,n=null;n=be({modules:[{id:t.id,schema:t.schema.facts,requirements:t.schema.requirements,init:t.init,derive:t.derive,events:t.events,effects:t.effects,constraints:t.constraints,resolvers:t.resolvers,hooks:t.hooks}],plugins:e.plugins,debug:o,errorBoundary:c,tickMs:e.tickMs,onAfterModuleInit:()=>{if(e.initialFacts)for(let[m,p]of Object.entries(e.initialFacts))G.has(m)||(n.facts[m]=p);if(i){for(let[m,p]of Object.entries(i))G.has(m)||(n.facts[m]=p);i=null;}}});let u=new Proxy({},{get(m,p){if(typeof p!="symbol"&&!G.has(p))return q=>{n.dispatch({type:p,...q});}}}),d=null,a=e.tickMs;return {_mode:"single",facts:n.facts,debug:n.debug,derive:n.derive,events:u,constraints:n.constraints,effects:n.effects,get isRunning(){return n.isRunning},get isSettled(){return n.isSettled},get isInitialized(){return n.isInitialized},get isReady(){return n.isReady},whenReady:n.whenReady.bind(n),async hydrate(m){if(n.isRunning)throw new Error("[Directive] hydrate() must be called before start(). The system is already running.");let p=await m();p&&typeof p=="object"&&(i=p);},start(){n.start(),a&&a>0&&t.events&&"tick"in t.events&&(d=setInterval(()=>{n.dispatch({type:"tick"});},a));},stop(){d&&(clearInterval(d),d=null),n.stop();},destroy(){this.stop(),n.destroy();},dispatch(m){n.dispatch(m);},batch:n.batch.bind(n),read(m){return n.read(m)},subscribe(m,p){return n.subscribe(m,p)},watch(m,p,q){return n.watch(m,p,q)},when(m,p){return n.when(m,p)},onSettledChange:n.onSettledChange.bind(n),onTimeTravelChange:n.onTimeTravelChange.bind(n),inspect:n.inspect.bind(n),settle:n.settle.bind(n),explain:n.explain.bind(n),getSnapshot:n.getSnapshot.bind(n),restore:n.restore.bind(n),getDistributableSnapshot:n.getDistributableSnapshot.bind(n),watchDistributableSnapshot:n.watchDistributableSnapshot.bind(n),registerModule(m){n.registerModule({id:m.id,schema:m.schema.facts,requirements:m.schema.requirements,init:m.init,derive:m.derive,events:m.events,effects:m.effects,constraints:m.constraints,resolvers:m.resolvers,hooks:m.hooks});}}}function Ct(e){let t={facts:{},derivations:{},events:{},requirements:{}},o,c,i,n,u,d,a,s={schema(m){return t=m,s},init(m){return o=m,s},derive(m){return i=m,s},events(m){return c=m,s},effects(m){return n=m,s},constraints(m){return u=m,s},resolvers(m){return d=m,s},hooks(m){return a=m,s},build(){if(!t||!t.facts)throw new Error(`[Directive] Module "${e}" requires a schema with at least facts defined. Call .schema({ facts: { ... } }) before .build().`);let m=Object.keys(t.derivations??{}),p=Object.keys(i??{}),q=m.filter(K=>!p.includes(K));if(q.length>0)throw new Error(`[Directive] Module "${e}" is missing derivation implementations: ${q.join(", ")}. All derivations declared in schema.derivations must have implementations in .derive().`);let T=Object.keys(t.events??{}),A=Object.keys(c??{}),B=T.filter(K=>!A.includes(K));if(B.length>0)throw new Error(`[Directive] Module "${e}" is missing event handler implementations: ${B.join(", ")}. All events declared in schema.events must have implementations in .events().`);return {id:e,schema:t,init:o,events:c,derive:i,effects:n,constraints:u,resolvers:d,hooks:a}}};return s}function qt(){return {when(e){return {require(t){let o,c,i,n,u,d={priority(a){return o=a,d},after(...a){return c=c?[...c,...a]:[...a],d},deps(...a){return i=i?[...i,...a]:[...a],d},timeout(a){return n=a,d},async(a){return u=a,d},build(){let a={when:e,require:t};return o!==void 0&&(a.priority=o),c!==void 0&&(a.after=c),i!==void 0&&(a.deps=i),n!==void 0&&(a.timeout=n),u!==void 0&&(a.async=u),a}};return d}}}}}function ye(e){let t={...e};return t.withPriority=o=>ye({...e,priority:o}),t.withAfter=(...o)=>ye({...e,after:e.after?[...e.after,...o]:[...o]}),t.withDeps=(...o)=>ye({...e,deps:e.deps?[...e.deps,...o]:[...o]}),t.withTimeout=o=>ye({...e,timeout:o}),t.withAsync=o=>ye({...e,async:o}),t}function $t(e){return {require(t){return ye({when:e,require:t})}}}function It(){return {module(e){return Ot(e)},modules(e){return Pt(e)}}}function Ot(e){let t,o,c,i,n,u,d={plugins(a){return t=a,d},debug(a){return o=a,d},errorBoundary(a){return c=a,d},tickMs(a){return i=a,d},zeroConfig(a=true){return n=a,d},initialFacts(a){return u=a,d},build(){return me({module:e,plugins:t,debug:o,errorBoundary:c,tickMs:i,zeroConfig:n,initialFacts:u})}};return d}function Pt(e){let t,o,c,i,n,u,d,a={plugins(s){return t=s,a},debug(s){return o=s,a},errorBoundary(s){return c=s,a},tickMs(s){return i=s,a},zeroConfig(s=true){return n=s,a},initialFacts(s){return u=s,a},initOrder(s){return d=s,a},build(){return me({modules:e,plugins:t,debug:o,errorBoundary:c,tickMs:i,zeroConfig:n,initialFacts:u,initOrder:d})}};return a}function Ie(){let e={pending:new Map,inflight:new Map,failed:new Map,errors:new Map,listeners:new Set};function t(){for(let a of e.listeners)a();}function o(a,s){let m=a.get(s);return m||(m=new Set,a.set(s,m)),m}function c(a){let s=e.pending.get(a)??new Set,m=e.inflight.get(a)??new Set,p=e.failed.get(a)??new Set,q=e.errors.get(a)??null;return {pending:s.size,inflight:m.size,failed:p.size,isLoading:s.size>0||m.size>0,hasError:p.size>0,lastError:q}}function i(){let a=new Set([...e.pending.keys(),...e.inflight.keys(),...e.failed.keys()]),s=new Map;for(let m of a)s.set(m,c(m));return s}function n(a){return e.listeners.add(a),()=>e.listeners.delete(a)}function u(){e.pending.clear(),e.inflight.clear(),e.failed.clear(),e.errors.clear(),t();}return {plugin:{name:"requirement-status",onRequirementCreated(a){let s=a.requirement.type;o(e.pending,s).add(a.id),e.failed.get(s)?.delete(a.id),t();},onResolverStart(a,s){let m=s.requirement.type;e.pending.get(m)?.delete(s.id),o(e.inflight,m).add(s.id),t();},onResolverComplete(a,s){let m=s.requirement.type;e.inflight.get(m)?.delete(s.id),e.pending.get(m)?.delete(s.id),t();},onResolverError(a,s,m){let p=s.requirement.type;e.inflight.get(p)?.delete(s.id),o(e.failed,p).add(s.id),e.errors.set(p,m instanceof Error?m:new Error(String(m))),t();},onResolverCancel(a,s){let m=s.requirement.type;e.pending.get(m)?.delete(s.id),e.inflight.get(m)?.delete(s.id),t();},onRequirementMet(a){let s=a.requirement.type;e.pending.get(s)?.delete(a.id),e.inflight.get(s)?.delete(a.id),t();}},getStatus:c,getAllStatus:i,subscribe:n,reset:u}}function At(e){return t=>e.getStatus(t)}function jt(e){let t=Ie(),c=[...e.plugins??[],t.plugin];return {system:me({module:e.module,plugins:c,debug:e.debug,errorBoundary:e.errorBoundary,tickMs:e.tickMs,zeroConfig:e.zeroConfig,initialFacts:e.initialFacts}),statusPlugin:t}}function Ft(e){let t={},o={},c={};for(let[u,d]of Object.entries(e.initialState))t[u]=Oe(d);for(let u of Object.keys(e.reducers))u.includes("By")||u.includes("Set")||u.includes("With")?(o[u]={payload:"t.any()"},c[u]=`(facts, { payload }) => {
|
|
12
|
+
// TODO: Implement ${u}
|
|
13
|
+
}`):(o[u]={},c[u]=`(facts) => {
|
|
14
|
+
// TODO: Implement ${u}
|
|
15
|
+
}`);let n=`(facts) => {
|
|
16
|
+
${Object.entries(e.initialState).map(([u,d])=>` facts.${u} = ${JSON.stringify(d)};`).join(`
|
|
17
|
+
`)}
|
|
18
|
+
}`;return {name:e.name,facts:t,derivations:{},events:o,requirements:{},initCode:n,deriveCode:{},eventsCode:c}}function _t(e){let t={},o={},c={};for(let[u,d]of Object.entries(e.state))t[u]=Oe(d);for(let u of Object.keys(e.actions))o[u]={},c[u]=`(facts) => {
|
|
19
|
+
// TODO: Implement ${u}
|
|
20
|
+
}`;let n=`(facts) => {
|
|
21
|
+
${Object.entries(e.state).map(([u,d])=>` facts.${u} = ${JSON.stringify(d)};`).join(`
|
|
22
|
+
`)}
|
|
23
|
+
}`;return {name:"store",facts:t,derivations:{},events:o,requirements:{},initCode:n,deriveCode:{},eventsCode:c}}function Bt(e){let t={state:`t.string<${Object.keys(e.states).map(s=>`'${s}'`).join(" | ")}>()`},o={},c={},i={},n={};if(e.context)for(let[s,m]of Object.entries(e.context))t[s]=Oe(m);for(let s of Object.keys(e.states)){let m=`is${Kt(s)}`;o[m]="t.boolean()",c[m]=`(facts) => facts.state === '${s}'`;}let u=new Map;for(let[s,m]of Object.entries(e.states))if(m.on)for(let[p,q]of Object.entries(m.on)){u.has(p)||u.set(p,new Map);let T=typeof q=="string"?q:q.target;u.get(p).set(s,T);}for(let[s,m]of u)if(i[s]={},m.size===1){let p=[...m.entries()][0],q=p?p[1]:"unknown";n[s]=`(facts) => {
|
|
24
|
+
facts.state = '${q}';
|
|
25
|
+
}`;}else {let p=[...m.entries()].map(([q,T])=>` case '${q}': facts.state = '${T}'; break;`).join(`
|
|
26
|
+
`);n[s]=`(facts) => {
|
|
27
|
+
switch (facts.state) {
|
|
28
|
+
${p}
|
|
29
|
+
}
|
|
30
|
+
}`;}let d=[` facts.state = '${e.initial}';`];if(e.context)for(let[s,m]of Object.entries(e.context))d.push(` facts.${s} = ${JSON.stringify(m)};`);let a=`(facts) => {
|
|
31
|
+
${d.join(`
|
|
32
|
+
`)}
|
|
33
|
+
}`;return {name:e.id,facts:t,derivations:o,events:i,requirements:{},initCode:a,deriveCode:c,eventsCode:n}}function Nt(e){let t=["import { createModule, t } from '@directive-run/core';","",`const ${e.name}Module = createModule('${e.name}', {`," schema: {"," facts: {"];for(let[o,c]of Object.entries(e.facts))t.push(` ${o}: ${c},`);t.push(" },"),t.push(" derivations: {");for(let[o,c]of Object.entries(e.derivations))t.push(` ${o}: ${c},`);t.push(" },"),t.push(" events: {");for(let[o,c]of Object.entries(e.events)){let i=Object.entries(c).map(([n,u])=>`${n}: ${u}`).join(", ");t.push(` ${o}: { ${i} },`);}if(t.push(" },"),t.push(" requirements: {},"),t.push(" },"),t.push(` init: ${e.initCode},`),Object.keys(e.deriveCode).length>0){t.push(" derive: {");for(let[o,c]of Object.entries(e.deriveCode))t.push(` ${o}: ${c},`);t.push(" },");}t.push(" events: {");for(let[o,c]of Object.entries(e.eventsCode))t.push(` ${o}: ${c},`);return t.push(" },"),t.push("});"),t.push(""),t.push(`export { ${e.name}Module };`),t.join(`
|
|
34
|
+
`)}function Oe(e){if(e===null)return "t.any().nullable()";if(e===void 0)return "t.any().optional()";switch(typeof e){case "number":return "t.number()";case "string":return "t.string()";case "boolean":return "t.boolean()";case "object":return Array.isArray(e)?"t.array(t.any())":"t.object()";default:return "t.any()"}}function Kt(e){return e.charAt(0).toUpperCase()+e.slice(1)}function Wt(e){let t=["[ ] Install directive: pnpm add directive","[ ] Create module file(s) for your state","[ ] Define schema with facts, derivations, events","[ ] Implement init function for initial state","[ ] Implement event handlers","[ ] Update imports in consuming code","[ ] Test the new implementation","[ ] Remove old state management code"];return [...{redux:["[ ] Convert reducers to event handlers","[ ] Convert selectors to derivations","[ ] Convert thunks to constraints + resolvers","[ ] Update useSelector to useDerived","[ ] Update useDispatch to system.dispatch"],zustand:["[ ] Convert store state to facts","[ ] Convert store actions to events","[ ] Convert computed getters to derivations","[ ] Update useStore hooks to useDirective hooks"],xstate:["[ ] Convert machine states to a 'state' fact","[ ] Convert state checks to derivations (isActive, etc.)","[ ] Convert events to Directive events","[ ] Convert guards to constraint 'when' conditions","[ ] Convert services/actors to constraints + resolvers","[ ] Update useMachine to useDirective hooks"]}[e]??[],...t]}var Kn={None:"none",Linear:"linear",Exponential:"exponential"};exports.Backoff=Kn;exports.DirectiveError=le;exports.RequirementSet=ce;exports.analyzeReduxSlice=Ft;exports.analyzeXStateMachine=Bt;exports.analyzeZustandStore=_t;exports.constraint=qt;exports.constraintFactory=Pe;exports.createConstraintsManager=Re;exports.createDerivationsManager=ke;exports.createDisabledTimeTravel=Ce;exports.createEffectsManager=Me;exports.createEngine=be;exports.createErrorBoundaryManager=De;exports.createFacts=we;exports.createFactsProxy=Ke;exports.createFactsStore=Ne;exports.createModule=We;exports.createModuleFactory=lt;exports.createPluginManager=xe;exports.createRequirementStatusPlugin=Ie;exports.createResolversManager=Te;exports.createRetryLaterManager=Je;exports.createStatusHook=At;exports.createSystem=me;exports.createSystemWithStatus=jt;exports.createTimeTravelManager=Ee;exports.diffSnapshots=mt;exports.forType=wt;exports.generateMigrationChecklist=Wt;exports.generateModuleCode=Nt;exports.generateRequirementId=Ue;exports.getCurrentTracker=_e;exports.isNamespacedSystem=ot;exports.isRequirementType=bt;exports.isSignedSnapshot=yt;exports.isSingleModuleSystem=st;exports.isSnapshotExpired=ze;exports.isTracking=ct;exports.module=Ct;exports.req=St;exports.resolverFactory=Ae;exports.shallowEqual=ft;exports.signSnapshot=pt;exports.system=It;exports.t=dt;exports.trackAccess=fe;exports.typedConstraint=je;exports.typedResolver=Fe;exports.validateSnapshot=gt;exports.verifySnapshotSignature=ht;exports.when=$t;exports.withTracking=ie;exports.withoutTracking=Se;//# sourceMappingURL=index.cjs.map
|
|
35
|
+
//# sourceMappingURL=index.cjs.map
|