@onereach/state-machine-core 1.0.0-framework.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # @onereach/state-machine-core
2
+
3
+ This package defines the persisted format for State Machine templates and instances.
@@ -0,0 +1,221 @@
1
+ import { z } from "zod";
2
+ //#region src/schemas/functions.d.ts
3
+ declare const FunctionKindSchema: z.ZodEnum<{
4
+ query: "query";
5
+ mutation: "mutation";
6
+ }>;
7
+ type FunctionKind = z.infer<typeof FunctionKindSchema>;
8
+ declare const FunctionImplementationSchema: z.ZodObject<{
9
+ runtime: z.ZodLiteral<"javascript">;
10
+ abi: z.ZodLiteral<"state-machine-function-v1">;
11
+ format: z.ZodLiteral<"async-function-body">;
12
+ code: z.ZodString;
13
+ capabilities: z.ZodDefault<z.ZodArray<z.ZodString>>;
14
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
15
+ }, z.core.$strip>;
16
+ declare const StateMachineFunctionDefinitionSchema: z.ZodObject<{
17
+ name: z.ZodString;
18
+ description: z.ZodOptional<z.ZodString>;
19
+ kind: z.ZodEnum<{
20
+ query: "query";
21
+ mutation: "mutation";
22
+ }>;
23
+ inputSchema: z.ZodObject<{
24
+ type: z.ZodLiteral<"object">;
25
+ }, z.core.$loose>;
26
+ outputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
27
+ implementation: z.ZodObject<{
28
+ runtime: z.ZodLiteral<"javascript">;
29
+ abi: z.ZodLiteral<"state-machine-function-v1">;
30
+ format: z.ZodLiteral<"async-function-body">;
31
+ code: z.ZodString;
32
+ capabilities: z.ZodDefault<z.ZodArray<z.ZodString>>;
33
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
34
+ }, z.core.$strip>;
35
+ annotations: z.ZodOptional<z.ZodObject<{
36
+ idempotent: z.ZodOptional<z.ZodBoolean>;
37
+ destructive: z.ZodOptional<z.ZodBoolean>;
38
+ deprecated: z.ZodOptional<z.ZodBoolean>;
39
+ }, z.core.$strip>>;
40
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
41
+ }, z.core.$strip>;
42
+ type StateMachineFunctionDefinition = z.infer<typeof StateMachineFunctionDefinitionSchema>;
43
+ //#endregion
44
+ //#region src/schemas/json-schema.d.ts
45
+ declare const JsonSchemaSchema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
46
+ type JsonSchema = z.infer<typeof JsonSchemaSchema>;
47
+ declare const ObjectJsonSchemaSchema: z.ZodObject<{
48
+ type: z.ZodLiteral<"object">;
49
+ }, z.core.$loose>;
50
+ type ObjectJsonSchema = z.infer<typeof ObjectJsonSchemaSchema>;
51
+ //#endregion
52
+ //#region src/schemas/state-instance.d.ts
53
+ declare const StateTemplateBindingSchema: z.ZodObject<{
54
+ id: z.ZodString;
55
+ version: z.ZodOptional<z.ZodString>;
56
+ revision: z.ZodString;
57
+ }, z.core.$strip>;
58
+ type StateTemplateBinding = z.infer<typeof StateTemplateBindingSchema>;
59
+ declare const StateMachineInstanceSchema: z.ZodObject<{
60
+ schemaVersion: z.ZodLiteral<1>;
61
+ id: z.ZodString;
62
+ template: z.ZodObject<{
63
+ id: z.ZodString;
64
+ version: z.ZodOptional<z.ZodString>;
65
+ revision: z.ZodString;
66
+ }, z.core.$strip>;
67
+ state: z.ZodRecord<z.ZodString, z.ZodUnknown>;
68
+ sequence: z.ZodNumber;
69
+ createdAt: z.ZodISODateTime;
70
+ updatedAt: z.ZodISODateTime;
71
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
72
+ }, z.core.$strip>;
73
+ type StateMachineInstance = z.infer<typeof StateMachineInstanceSchema>;
74
+ //#endregion
75
+ //#region src/schemas/state-template.d.ts
76
+ declare const StateTemplateSchema: z.ZodObject<{
77
+ schemaVersion: z.ZodLiteral<1>;
78
+ id: z.ZodString;
79
+ version: z.ZodOptional<z.ZodString>;
80
+ description: z.ZodOptional<z.ZodString>;
81
+ stateSchema: z.ZodObject<{
82
+ type: z.ZodLiteral<"object">;
83
+ }, z.core.$loose>;
84
+ initialState: z.ZodRecord<z.ZodString, z.ZodUnknown>;
85
+ functions: z.ZodArray<z.ZodObject<{
86
+ name: z.ZodString;
87
+ description: z.ZodOptional<z.ZodString>;
88
+ kind: z.ZodEnum<{
89
+ query: "query";
90
+ mutation: "mutation";
91
+ }>;
92
+ inputSchema: z.ZodObject<{
93
+ type: z.ZodLiteral<"object">;
94
+ }, z.core.$loose>;
95
+ outputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
96
+ implementation: z.ZodObject<{
97
+ runtime: z.ZodLiteral<"javascript">;
98
+ abi: z.ZodLiteral<"state-machine-function-v1">;
99
+ format: z.ZodLiteral<"async-function-body">;
100
+ code: z.ZodString;
101
+ capabilities: z.ZodDefault<z.ZodArray<z.ZodString>>;
102
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
103
+ }, z.core.$strip>;
104
+ annotations: z.ZodOptional<z.ZodObject<{
105
+ idempotent: z.ZodOptional<z.ZodBoolean>;
106
+ destructive: z.ZodOptional<z.ZodBoolean>;
107
+ deprecated: z.ZodOptional<z.ZodBoolean>;
108
+ }, z.core.$strip>>;
109
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
110
+ }, z.core.$strip>>;
111
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
112
+ }, z.core.$strip>;
113
+ type StateTemplateDefinition = z.infer<typeof StateTemplateSchema>;
114
+ //#endregion
115
+ //#region src/validation/types.d.ts
116
+ interface SchemaValidationIssue {
117
+ /**
118
+ * JSON pointer / instance path.
119
+ *
120
+ * Example:
121
+ * /customer/id
122
+ */
123
+ path: string;
124
+ message?: string;
125
+ keyword?: string;
126
+ schemaPath?: string;
127
+ params?: unknown;
128
+ }
129
+ interface SchemaValidator<T = unknown> {
130
+ validate(value: unknown): value is T;
131
+ /**
132
+ * Issues from the most recent validate() call.
133
+ */
134
+ readonly issues: readonly SchemaValidationIssue[];
135
+ }
136
+ /**
137
+ * Lowest-level adapter interface.
138
+ *
139
+ * AJV, Zod, Valibot, or anything else only has to implement this.
140
+ */
141
+ interface JsonSchemaValidatorCompiler {
142
+ compile<T = unknown>(schema: JsonSchema): SchemaValidator<T>;
143
+ }
144
+ interface CompiledFunctionValidators {
145
+ readonly input: SchemaValidator<Record<string, unknown>>;
146
+ readonly output?: SchemaValidator;
147
+ }
148
+ interface CompiledStateTemplateValidators {
149
+ readonly state: SchemaValidator<Record<string, unknown>>;
150
+ readonly functions: ReadonlyMap<string, CompiledFunctionValidators>;
151
+ }
152
+ type SchemaValidationTarget = 'initial-state' | 'input' | 'output' | 'state-before' | 'state-after';
153
+ //#endregion
154
+ //#region src/validation/compiler.d.ts
155
+ declare class StateTemplateValidatorCompiler {
156
+ /**
157
+ * Same JSON Schema JS object -> same validator.
158
+ */
159
+ private readonly schemaCache;
160
+ /**
161
+ * Same parsed StateTemplate object -> same complete
162
+ * validator collection.
163
+ */
164
+ private readonly templateCache;
165
+ /**
166
+ * Immutable storage revision -> validator collection.
167
+ *
168
+ * This handles loading the same persisted template again,
169
+ * even though parsing produces a new JS object.
170
+ */
171
+ private readonly revisionCache;
172
+ /**
173
+ * Low-level schema compiler.
174
+ */
175
+ private readonly schemaCompiler;
176
+ constructor(schemaCompiler: JsonSchemaValidatorCompiler);
177
+ private compileSchema;
178
+ /**
179
+ * Get already-prepared validators by persistent revision key.
180
+ */
181
+ get(cacheKey: string): CompiledStateTemplateValidators | undefined;
182
+ /**
183
+ * Prepare validators for a template.
184
+ *
185
+ * Order:
186
+ *
187
+ * 1. revision cache
188
+ * 2. template object cache
189
+ * 3. actual schema compilation
190
+ */
191
+ compile(definition: StateTemplateDefinition, cacheKey?: string): CompiledStateTemplateValidators;
192
+ /**
193
+ * Associate validators that were already compiled with a
194
+ * persistent template revision.
195
+ *
196
+ * Critically, this performs NO compilation.
197
+ *
198
+ * This is primarily used by StateTemplateStore.save():
199
+ *
200
+ * compile definition
201
+ * → save definition
202
+ * → receive revision
203
+ * → bind revision to existing compiled validators
204
+ */
205
+ bind(cacheKey: string, validators: CompiledStateTemplateValidators): void;
206
+ invalidate(cacheKey: string): void;
207
+ clearRevisionCache(): void;
208
+ }
209
+ //#endregion
210
+ //#region src/validation/errors.d.ts
211
+ declare class SchemaValidationError extends Error {
212
+ readonly target: SchemaValidationTarget;
213
+ readonly errors: SchemaValidationIssue[] | null | undefined;
214
+ constructor(target: SchemaValidationTarget, errors: SchemaValidationIssue[] | null | undefined);
215
+ }
216
+ //#endregion
217
+ //#region src/validation/validation.d.ts
218
+ declare function assertSchema<T>(validator: SchemaValidator<T>, value: unknown, target: SchemaValidationTarget): asserts value is T;
219
+ //#endregion
220
+ export { type CompiledFunctionValidators, type CompiledStateTemplateValidators, FunctionImplementationSchema, FunctionKind, FunctionKindSchema, JsonSchema, JsonSchemaSchema, type JsonSchemaValidatorCompiler, ObjectJsonSchema, ObjectJsonSchemaSchema, SchemaValidationError, type SchemaValidationIssue, type SchemaValidationTarget, type SchemaValidator, StateMachineFunctionDefinition, StateMachineFunctionDefinitionSchema, StateMachineInstance, StateMachineInstanceSchema, StateTemplateBinding, StateTemplateBindingSchema, StateTemplateDefinition, StateTemplateSchema, StateTemplateValidatorCompiler, assertSchema };
221
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/schemas/functions.ts","../src/schemas/json-schema.ts","../src/schemas/state-instance.ts","../src/schemas/state-template.ts","../src/validation/types.ts","../src/validation/compiler.ts","../src/validation/errors.ts","../src/validation/validation.ts"],"mappings":";;cAIa,oBAAkB,EAAA;;;;KAEnB,eAAe,EAAE,aAAa;cAE7B,8BAA4B,EAAA;;;;;;;GAsCvC,EAAA,KAAA;cAEW,sCAAoC,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;GA8B/C,EAAA,KAAA;KAEU,iCAAiC,EAAE,aAAa;;;cC9E/C,kBAAgB,EAAA,UAAA,EAAA,WAAA,EAAA;KAEjB,aAAa,EAAE,aAAa;cAE3B,wBAAsB,EAAA;;GAEjC,EAAA,KAAA;KAEU,mBAAmB,EAAE,aAAa;;;cCRjC,4BAA0B,EAAA;;;;GAsBrC,EAAA,KAAA;KAEU,uBAAuB,EAAE,aAAa;cAErC,4BAA0B,EAAA;;;;;;;;;;;;;GA0CrC,EAAA,KAAA;KAEU,uBAAuB,EAAE,aAAa;;;cCnErC,qBAAmB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6C5B,EAAA,KAAA;KAEQ,0BAA0B,EAAE,aAAa;;;UClDpC;;;;;;;EAOf;EAEA;EAEA;EAEA;EAEA;;UAGe,gBAAgB;EAC/B,SAAS,iBAAiB,SAAS;;;;WAK1B,iBAAiB;;;;;;;UAQX;EACf,QAAQ,aAAa,QAAQ,aAAa,gBAAgB;;UAa3C;WACN,OAAO,gBAAgB;WAEvB,SAAS;;UAGH;WACN,OAAO,gBAAgB;WAEvB,WAAW,oBAAoB;;KAa9B;;;cCzDC;;;;mBAIM;;;;;mBAMA;;;;;;;mBAQA;;;;mBAKA;EAEL,YAAA,gBAAgB;UAIpB;;;;EAgBD,IAAI,mBAAmB;;;;;;;;;;EAavB,QAAQ,YAAY,yBAAyB,oBAAoB;;;;;;;;;;;;;;EA8DjE,KAAK,kBAAkB,YAAY;EAInC,WAAW;EAIX;;;;cC3II,8BAA8B;WACzB,QAAQ;WACR,QAAQ;EAEZ,YAAA,QAAQ,wBAAwB,QAAQ;;;;iBCOtC,aAAa,GAC3B,WAAW,gBAAgB,IAC3B,gBACA,QAAQ,iCACC,SAAS"}
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import{z as e}from"zod";const t=e.record(e.string(),e.unknown()),n=e.looseObject({type:e.literal(`object`)}),r=e.enum([`query`,`mutation`]),i=e.object({runtime:e.literal(`javascript`),abi:e.literal(`state-machine-function-v1`),format:e.literal(`async-function-body`),code:e.string().min(1),capabilities:e.array(e.string()).default([]),timeoutMs:e.number().int().positive().optional()}),a=e.object({name:e.string().min(1),description:e.string().optional(),kind:r,inputSchema:n,outputSchema:t.optional(),implementation:i,annotations:e.object({idempotent:e.boolean().optional(),destructive:e.boolean().optional(),deprecated:e.boolean().optional()}).optional(),metadata:e.record(e.string(),e.unknown()).optional()}),o=e.object({id:e.string().min(1),version:e.string().optional(),revision:e.string().min(1)}),s=e.object({schemaVersion:e.literal(1),id:e.string().min(1),template:o,state:e.record(e.string(),e.unknown()),sequence:e.number().int().nonnegative(),createdAt:e.iso.datetime(),updatedAt:e.iso.datetime(),metadata:e.record(e.string(),e.unknown()).optional()}),c=e.object({schemaVersion:e.literal(1),id:e.string().min(1),version:e.string().optional(),description:e.string().optional(),stateSchema:n,initialState:e.record(e.string(),e.unknown()),functions:e.array(a),metadata:e.record(e.string(),e.unknown()).optional()}).superRefine((e,t)=>{let n=new Set;for(let[r,i]of e.functions.entries())n.has(i.name)&&t.addIssue({code:`custom`,path:[`functions`,r,`name`],message:`Duplicate function name: ${i.name}`}),n.add(i.name)});var l=class extends Error{target;errors;constructor(e,t){super(`Schema validation failed: ${e}`),this.name=`SchemaValidationError`,this.target=e,this.errors=t}};function u(e,t,n){if(!e.validate(t))throw new l(n,[...e.issues])}var d=class{schemaCache=new WeakMap;templateCache=new WeakMap;revisionCache=new Map;schemaCompiler;constructor(e){this.schemaCompiler=e}compileSchema(e){let t=e,n=this.schemaCache.get(t);if(n)return n;let r=this.schemaCompiler.compile(e);return this.schemaCache.set(t,r),r}get(e){return this.revisionCache.get(e)}compile(e,t){if(t){let e=this.revisionCache.get(t);if(e)return e}let n=this.templateCache.get(e);if(n)return t&&this.bind(t,n),n;let r=this.compileSchema(e.stateSchema);u(r,e.initialState,`initial-state`);let i=new Map;for(let t of e.functions)i.set(t.name,{input:this.compileSchema(t.inputSchema),output:t.outputSchema?this.compileSchema(t.outputSchema):void 0});let a={state:r,functions:i};return this.templateCache.set(e,a),t&&this.bind(t,a),a}bind(e,t){this.revisionCache.set(e,t)}invalidate(e){this.revisionCache.delete(e)}clearRevisionCache(){this.revisionCache.clear()}};export{i as FunctionImplementationSchema,r as FunctionKindSchema,t as JsonSchemaSchema,n as ObjectJsonSchemaSchema,l as SchemaValidationError,a as StateMachineFunctionDefinitionSchema,s as StateMachineInstanceSchema,o as StateTemplateBindingSchema,c as StateTemplateSchema,d as StateTemplateValidatorCompiler,u as assertSchema};
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/schemas/json-schema.ts","../src/schemas/functions.ts","../src/schemas/state-instance.ts","../src/schemas/state-template.ts","../src/validation/errors.ts","../src/validation/validation.ts","../src/validation/compiler.ts"],"sourcesContent":["import { z } from 'zod';\n\nexport const JsonSchemaSchema = z.record(z.string(), z.unknown());\n\nexport type JsonSchema = z.infer<typeof JsonSchemaSchema>;\n\nexport const ObjectJsonSchemaSchema = z.looseObject({\n type: z.literal('object'),\n});\n\nexport type ObjectJsonSchema = z.infer<typeof ObjectJsonSchemaSchema>;\n","import { z } from 'zod';\n\nimport { JsonSchemaSchema, ObjectJsonSchemaSchema } from './json-schema.ts';\n\nexport const FunctionKindSchema = z.enum(['query', 'mutation']);\n\nexport type FunctionKind = z.infer<typeof FunctionKindSchema>;\n\nexport const FunctionImplementationSchema = z.object({\n runtime: z.literal('javascript'),\n\n /**\n * ABI v1 means:\n *\n * ```javascript\n * async function(input, state, ctx) {\n * // implementation.code\n * }\n * ```\n */\n abi: z.literal('state-machine-function-v1'),\n\n format: z.literal('async-function-body'),\n\n /**\n * JavaScript function BODY.\n *\n * Not:\n *\n * ```javascript\n * async function(...) {}\n * ```\n *\n * But:\n *\n * ```javascript\n * const x = await ctx.foo(...)\n * state.foo = x\n * return x\n * ```\n */\n code: z.string().min(1),\n\n capabilities: z.array(z.string()).default([]),\n\n timeoutMs: z.number().int().positive().optional(),\n});\n\nexport const StateMachineFunctionDefinitionSchema = z.object({\n name: z.string().min(1),\n\n description: z.string().optional(),\n\n kind: FunctionKindSchema,\n\n /**\n * Argument #1.\n */\n inputSchema: ObjectJsonSchemaSchema,\n\n /**\n * Return value.\n */\n outputSchema: JsonSchemaSchema.optional(),\n\n implementation: FunctionImplementationSchema,\n\n annotations: z\n .object({\n idempotent: z.boolean().optional(),\n\n destructive: z.boolean().optional(),\n\n deprecated: z.boolean().optional(),\n })\n .optional(),\n\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type StateMachineFunctionDefinition = z.infer<typeof StateMachineFunctionDefinitionSchema>;\n","import { z } from 'zod';\n\nexport const StateTemplateBindingSchema = z.object({\n /**\n * The unique identifier of the template.\n */\n id: z.string().min(1),\n\n /**\n * The version of the template.\n *\n * Optional because the template may not have a version.\n */\n version: z.string().optional(),\n\n /**\n * Driver-level revision of the template that this\n * instance was created against.\n *\n * This prevents an instance silently starting to\n * execute a different template after the template\n * file/object changes.\n */\n revision: z.string().min(1),\n});\n\nexport type StateTemplateBinding = z.infer<typeof StateTemplateBindingSchema>;\n\nexport const StateMachineInstanceSchema = z.object({\n /**\n * The schema version of the instance.\n */\n schemaVersion: z.literal(1),\n\n /**\n * The unique identifier of the instance.\n */\n id: z.string().min(1),\n\n /**\n * The template binding of the instance.\n */\n template: StateTemplateBindingSchema,\n\n /**\n * The state of the instance.\n */\n state: z.record(z.string(), z.unknown()),\n\n /**\n * Logical instance version.\n *\n * Increased for every successful persisted update.\n */\n sequence: z.number().int().nonnegative(),\n\n /**\n * The date and time the instance was created.\n */\n createdAt: z.iso.datetime(),\n\n /**\n * The date and time the instance was last updated.\n */\n updatedAt: z.iso.datetime(),\n\n /**\n * Additional metadata about the instance.\n */\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type StateMachineInstance = z.infer<typeof StateMachineInstanceSchema>;\n","import { z } from 'zod';\n\nimport { StateMachineFunctionDefinitionSchema } from './functions.ts';\nimport { ObjectJsonSchemaSchema } from './json-schema.ts';\n\nexport const StateTemplateSchema = z\n .object({\n schemaVersion: z.literal(1),\n\n id: z.string().min(1),\n\n /**\n * Logical/app version.\n *\n * This is different from a storage-driver revision.\n */\n version: z.string().optional(),\n\n description: z.string().optional(),\n\n /**\n * Schema shared by every function in this machine.\n */\n stateSchema: ObjectJsonSchemaSchema,\n\n /**\n * Used when creating a new state-machine instance.\n */\n initialState: z.record(z.string(), z.unknown()),\n\n functions: z.array(StateMachineFunctionDefinitionSchema),\n\n metadata: z.record(z.string(), z.unknown()).optional(),\n })\n .superRefine((template, context) => {\n const names = new Set<string>();\n\n for (const [index, function_] of template.functions.entries()) {\n if (names.has(function_.name)) {\n context.addIssue({\n code: 'custom',\n\n path: ['functions', index, 'name'],\n\n message: `Duplicate function name: ${function_.name}`,\n });\n }\n\n names.add(function_.name);\n }\n });\n\nexport type StateTemplateDefinition = z.infer<typeof StateTemplateSchema>;\n","import type { SchemaValidationIssue, SchemaValidationTarget } from './types.ts';\n\nexport class SchemaValidationError extends Error {\n public readonly target: SchemaValidationTarget;\n public readonly errors: SchemaValidationIssue[] | null | undefined;\n\n constructor(target: SchemaValidationTarget, errors: SchemaValidationIssue[] | null | undefined) {\n super(`Schema validation failed: ${target}`);\n\n this.name = 'SchemaValidationError';\n this.target = target;\n this.errors = errors;\n }\n}\n","import { SchemaValidationError } from './errors.ts';\nimport type { SchemaValidationTarget, SchemaValidator } from './types.ts';\n\n/*\n--------------------------------------------------------------------------\n*/\n/*\nGeneric validator\n*/\n/*\n--------------------------------------------------------------------------\n*/\n\nexport function assertSchema<T>(\n validator: SchemaValidator<T>,\n value: unknown,\n target: SchemaValidationTarget,\n): asserts value is T {\n if (validator.validate(value)) return;\n\n throw new SchemaValidationError(target, [...validator.issues]);\n}\n","// state-machine-core/src/validation/compiler.ts\n\nimport type { JsonSchema } from '../schemas/json-schema.ts';\nimport type { StateTemplateDefinition } from '../schemas/state-template.ts';\n\nimport type {\n JsonSchemaValidatorCompiler,\n SchemaValidator,\n CompiledFunctionValidators,\n CompiledStateTemplateValidators,\n} from './types.js';\nimport { assertSchema } from './validation.ts';\n\nexport class StateTemplateValidatorCompiler {\n /**\n * Same JSON Schema JS object -> same validator.\n */\n private readonly schemaCache = new WeakMap<object, SchemaValidator>();\n\n /**\n * Same parsed StateTemplate object -> same complete\n * validator collection.\n */\n private readonly templateCache = new WeakMap<StateTemplateDefinition, CompiledStateTemplateValidators>();\n\n /**\n * Immutable storage revision -> validator collection.\n *\n * This handles loading the same persisted template again,\n * even though parsing produces a new JS object.\n */\n private readonly revisionCache = new Map<string, CompiledStateTemplateValidators>();\n\n /**\n * Low-level schema compiler.\n */\n private readonly schemaCompiler: JsonSchemaValidatorCompiler;\n\n constructor(schemaCompiler: JsonSchemaValidatorCompiler) {\n this.schemaCompiler = schemaCompiler;\n }\n\n private compileSchema<T>(schema: JsonSchema): SchemaValidator<T> {\n const object = schema as object;\n const cached = this.schemaCache.get(object);\n\n if (cached) return cached as SchemaValidator<T>;\n\n const validator = this.schemaCompiler.compile<T>(schema);\n\n this.schemaCache.set(object, validator);\n\n return validator;\n }\n\n /**\n * Get already-prepared validators by persistent revision key.\n */\n public get(cacheKey: string): CompiledStateTemplateValidators | undefined {\n return this.revisionCache.get(cacheKey);\n }\n\n /**\n * Prepare validators for a template.\n *\n * Order:\n *\n * 1. revision cache\n * 2. template object cache\n * 3. actual schema compilation\n */\n public compile(definition: StateTemplateDefinition, cacheKey?: string): CompiledStateTemplateValidators {\n /*\n * Same persisted template revision.\n */\n if (cacheKey) {\n const cached = this.revisionCache.get(cacheKey);\n if (cached) return cached;\n }\n\n /*\n * Same parsed template object.\n */\n const objectCached = this.templateCache.get(definition);\n\n if (objectCached) {\n if (cacheKey) this.bind(cacheKey, objectCached);\n return objectCached;\n }\n\n const state = this.compileSchema<Record<string, unknown>>(definition.stateSchema);\n\n /*\n * initialState is part of template validity, so reject\n * the template immediately rather than waiting for an\n * instance to be created.\n */\n assertSchema(state, definition.initialState, 'initial-state');\n\n const functions = new Map<string, CompiledFunctionValidators>();\n\n for (const function_ of definition.functions) {\n functions.set(function_.name, {\n input: this.compileSchema<Record<string, unknown>>(function_.inputSchema),\n output: function_.outputSchema ? this.compileSchema(function_.outputSchema) : undefined,\n });\n }\n\n const compiled: CompiledStateTemplateValidators = {\n state,\n functions,\n };\n\n this.templateCache.set(definition, compiled);\n\n if (cacheKey) this.bind(cacheKey, compiled);\n\n return compiled;\n }\n\n /**\n * Associate validators that were already compiled with a\n * persistent template revision.\n *\n * Critically, this performs NO compilation.\n *\n * This is primarily used by StateTemplateStore.save():\n *\n * compile definition\n * → save definition\n * → receive revision\n * → bind revision to existing compiled validators\n */\n public bind(cacheKey: string, validators: CompiledStateTemplateValidators): void {\n this.revisionCache.set(cacheKey, validators);\n }\n\n public invalidate(cacheKey: string): void {\n this.revisionCache.delete(cacheKey);\n }\n\n public clearRevisionCache(): void {\n this.revisionCache.clear();\n }\n}\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@onereach/state-machine-core",
3
+ "version": "1.0.0-framework.2",
4
+ "description": "State Machine persisted format specification",
5
+ "keywords": [
6
+ "onereach",
7
+ "toolkit",
8
+ "state-machine"
9
+ ],
10
+ "author": "OneReach Development Team <dev.team@onereach.ai>",
11
+ "license": "Apache-2.0",
12
+ "type": "module",
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "!dist/metafile*.json"
19
+ ],
20
+ "devDependencies": {
21
+ "@arethetypeswrong/core": "^0.18.5",
22
+ "@types/source-map-support": "^0.5.10",
23
+ "publint": "^0.3.24",
24
+ "rollup-plugin-visualizer": "^7.1.1",
25
+ "tsdown": "^0.22.14",
26
+ "typescript": "^6.0.3"
27
+ },
28
+ "dependencies": {
29
+ "zod": "^4.5.4"
30
+ },
31
+ "exports": {
32
+ ".": "./dist/index.mjs",
33
+ "./package.json": "./package.json"
34
+ },
35
+ "scripts": {
36
+ "build": "tsdown --config tsdown.config.mts",
37
+ "build:visualize": "VISUALIZE=1 pnpm build",
38
+ "typecheck": "tsc --noEmit",
39
+ "preversion_": "pnpm build && pnpm test",
40
+ "publish:rc": "pnpm version prerelease --preid rc && pnpm publish --tag rc",
41
+ "test": "pnpm run unit",
42
+ "unit": "vitest run",
43
+ "preversion": "pnpm build"
44
+ }
45
+ }