@json-eval-rs/webcore 0.0.42 → 0.0.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +520 -0
- package/dist/index.js +487 -0
- package/package.json +8 -5
- package/index.d.ts +0 -379
- package/index.js +0 -733
package/index.js
DELETED
|
@@ -1,733 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @json-eval-rs/webcore
|
|
3
|
-
* High-level JavaScript API for JSON Eval RS WASM bindings
|
|
4
|
-
*
|
|
5
|
-
* This package provides a clean, ergonomic API that works with any WASM target:
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Get the library version from the WASM module
|
|
10
|
-
* @param {any} wasmModule - WASM module
|
|
11
|
-
* @returns {string} Version string
|
|
12
|
-
*/
|
|
13
|
-
export function getVersion(wasmModule) {
|
|
14
|
-
if (wasmModule && typeof wasmModule.getVersion === 'function') {
|
|
15
|
-
return wasmModule.getVersion();
|
|
16
|
-
}
|
|
17
|
-
return 'unknown';
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* JSONEval - High-level JavaScript API for JSON Eval RS
|
|
22
|
-
*
|
|
23
|
-
* This is an internal abstraction layer. Use specific packages instead:
|
|
24
|
-
* - @json-eval-rs/bundler (for bundlers like Webpack, Vite, Next.js)
|
|
25
|
-
* - @json-eval-rs/vanilla (for direct browser usage)
|
|
26
|
-
* - @json-eval-rs/node (for Node.js/SSR)
|
|
27
|
-
*
|
|
28
|
-
* @example
|
|
29
|
-
* ```js
|
|
30
|
-
* import { JSONEval } from '@json-eval-rs/webcore';
|
|
31
|
-
*
|
|
32
|
-
* const evaluator = new JSONEval({
|
|
33
|
-
* schema: { type: 'object', properties: { ... } }
|
|
34
|
-
* });
|
|
35
|
-
*
|
|
36
|
-
* await evaluator.init();
|
|
37
|
-
* const result = await evaluator.validate({ data: { name: 'John' } });
|
|
38
|
-
* ```
|
|
39
|
-
*/
|
|
40
|
-
export class JSONEvalCore {
|
|
41
|
-
/**
|
|
42
|
-
* @param {any} wasmModule - WASM module (injected by wrapper package)
|
|
43
|
-
* @param {object} options
|
|
44
|
-
* @param {object|Uint8Array|string} options.schema - JSON schema, MessagePack bytes, or cache key
|
|
45
|
-
* @param {object} [options.context] - Optional context data
|
|
46
|
-
* @param {object} [options.data] - Optional initial data
|
|
47
|
-
* @param {boolean} [options.fromCache] - If true, schema is treated as a cache key
|
|
48
|
-
*/
|
|
49
|
-
constructor(wasmModule, { schema, context, data, fromCache = false }) {
|
|
50
|
-
this._schema = schema;
|
|
51
|
-
this._wasmModule = wasmModule;
|
|
52
|
-
this._context = context;
|
|
53
|
-
this._data = data;
|
|
54
|
-
this._instance = null;
|
|
55
|
-
this._ready = false;
|
|
56
|
-
this._isMsgpackSchema = schema instanceof Uint8Array;
|
|
57
|
-
this._isFromCache = fromCache;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Initialize the WASM instance
|
|
62
|
-
* Call this before using other methods, or use the async methods which call it automatically
|
|
63
|
-
*/
|
|
64
|
-
async init() {
|
|
65
|
-
if (this._ready) return;
|
|
66
|
-
|
|
67
|
-
// If WASM module not provided, throw error - user must provide it or install peer dependency
|
|
68
|
-
if (!this._wasmModule) {
|
|
69
|
-
throw new Error(
|
|
70
|
-
'No WASM module provided. Please either:\n' +
|
|
71
|
-
'1. Pass wasmModule in constructor: new JSONEval({ schema, wasmModule: await import("@json-eval-rs/bundler") })\n' +
|
|
72
|
-
'2. Or install a peer dependency: yarn install @json-eval-rs/bundler (or @json-eval-rs/vanilla or @json-eval-rs/node)'
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
const { JSONEvalWasm } = this._wasmModule;
|
|
78
|
-
|
|
79
|
-
// Create instance from cache, MessagePack, or JSON
|
|
80
|
-
if (this._isFromCache) {
|
|
81
|
-
this._instance = JSONEvalWasm.newFromCache(
|
|
82
|
-
this._schema, // cache key
|
|
83
|
-
this._context ? JSON.stringify(this._context) : null,
|
|
84
|
-
this._data ? JSON.stringify(this._data) : null
|
|
85
|
-
);
|
|
86
|
-
} else if (this._isMsgpackSchema) {
|
|
87
|
-
this._instance = JSONEvalWasm.newFromMsgpack(
|
|
88
|
-
this._schema,
|
|
89
|
-
this._context ? JSON.stringify(this._context) : null,
|
|
90
|
-
this._data ? JSON.stringify(this._data) : null
|
|
91
|
-
);
|
|
92
|
-
} else {
|
|
93
|
-
this._instance = new JSONEvalWasm(
|
|
94
|
-
JSON.stringify(this._schema),
|
|
95
|
-
this._context ? JSON.stringify(this._context) : null,
|
|
96
|
-
this._data ? JSON.stringify(this._data) : null
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
this._ready = true;
|
|
100
|
-
} catch (error) {
|
|
101
|
-
throw new Error(`Failed to create JSONEval instance: ${error.message || error}`);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Create a new JSONEval instance from a cached ParsedSchema
|
|
107
|
-
* Static factory method for convenience
|
|
108
|
-
*
|
|
109
|
-
* @param {any} wasmModule - WASM module
|
|
110
|
-
* @param {string} cacheKey - Cache key to lookup in ParsedSchemaCache
|
|
111
|
-
* @param {object} [context] - Optional context data
|
|
112
|
-
* @param {object} [data] - Optional initial data
|
|
113
|
-
* @returns {JSONEvalCore} New instance
|
|
114
|
-
*/
|
|
115
|
-
static fromCache(wasmModule, cacheKey, context, data) {
|
|
116
|
-
return new JSONEvalCore(wasmModule, {
|
|
117
|
-
schema: cacheKey,
|
|
118
|
-
context,
|
|
119
|
-
data,
|
|
120
|
-
fromCache: true
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Validate data against schema (returns parsed JavaScript object)
|
|
126
|
-
* Uses validateJS for Worker-safe serialization
|
|
127
|
-
* @param {object} options
|
|
128
|
-
* @param {object} options.data - Data to validate
|
|
129
|
-
* @param {object} [options.context] - Optional context
|
|
130
|
-
* @returns {Promise<{has_error: boolean, errors: Array<{path: string, rule_type: string, message: string}>}>}
|
|
131
|
-
*/
|
|
132
|
-
async validate({ data, context }) {
|
|
133
|
-
await this.init();
|
|
134
|
-
try {
|
|
135
|
-
// Use validateJS for proper serialization (Worker-safe)
|
|
136
|
-
return this._instance.validateJS(
|
|
137
|
-
JSON.stringify(data),
|
|
138
|
-
context ? JSON.stringify(context) : null
|
|
139
|
-
);
|
|
140
|
-
} catch (error) {
|
|
141
|
-
throw new Error(`Validation failed: ${error.message || error}`);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Evaluate schema with data (returns parsed JavaScript object)
|
|
147
|
-
* @param {object} options
|
|
148
|
-
* @param {object} options.data - Data to evaluate
|
|
149
|
-
* @param {object} [options.context] - Optional context
|
|
150
|
-
* @param {string[]} [options.paths] - Optional array of paths for selective evaluation
|
|
151
|
-
* @returns {Promise<any>}
|
|
152
|
-
*/
|
|
153
|
-
async evaluate({ data, context, paths }) {
|
|
154
|
-
await this.init();
|
|
155
|
-
try {
|
|
156
|
-
return this._instance.evaluateJS(
|
|
157
|
-
JSON.stringify(data),
|
|
158
|
-
context ? JSON.stringify(context) : null,
|
|
159
|
-
paths || null
|
|
160
|
-
);
|
|
161
|
-
} catch (error) {
|
|
162
|
-
throw new Error(`Evaluation failed: ${error.message || error}`);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Evaluate dependent fields (returns parsed JavaScript object, processes transitively)
|
|
168
|
-
* @param {object} options
|
|
169
|
-
* @param {string[]} options.changedPaths - Array of changed field paths (e.g., ["#/illustration/properties/field1", "field2"])
|
|
170
|
-
* @param {object} [options.data] - Optional updated data (null to use existing)
|
|
171
|
-
* @param {object} [options.context] - Optional context
|
|
172
|
-
* @param {boolean} [options.reEvaluate] - If true, performs full evaluation after processing dependents
|
|
173
|
-
* @returns {Promise<Array>} Array of dependent change objects
|
|
174
|
-
*/
|
|
175
|
-
async evaluateDependents({ changedPaths, data, context, reEvaluate = false }) {
|
|
176
|
-
await this.init();
|
|
177
|
-
try {
|
|
178
|
-
return this._instance.evaluateDependentsJS(
|
|
179
|
-
JSON.stringify(changedPaths),
|
|
180
|
-
data ? JSON.stringify(data) : null,
|
|
181
|
-
context ? JSON.stringify(context) : null,
|
|
182
|
-
reEvaluate
|
|
183
|
-
);
|
|
184
|
-
} catch (error) {
|
|
185
|
-
throw new Error(`Dependent evaluation failed: ${error.message || error}`);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Get evaluated schema
|
|
191
|
-
* @param {object} [options]
|
|
192
|
-
* @param {boolean} [options.skipLayout=false] - Skip layout resolution
|
|
193
|
-
* @returns {Promise<any>}
|
|
194
|
-
*/
|
|
195
|
-
async getEvaluatedSchema({ skipLayout = false } = {}) {
|
|
196
|
-
await this.init();
|
|
197
|
-
return this._instance.getEvaluatedSchemaJS(skipLayout);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Get evaluated schema as MessagePack binary data
|
|
202
|
-
* @param {object} [options]
|
|
203
|
-
* @param {boolean} [options.skipLayout=false] - Skip layout resolution
|
|
204
|
-
* @returns {Promise<Uint8Array>} MessagePack-encoded schema bytes
|
|
205
|
-
*/
|
|
206
|
-
async getEvaluatedSchemaMsgpack({ skipLayout = false } = {}) {
|
|
207
|
-
await this.init();
|
|
208
|
-
return this._instance.getEvaluatedSchemaMsgpack(skipLayout);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Get schema values (evaluations ending with .value)
|
|
213
|
-
* @returns {Promise<object>}
|
|
214
|
-
*/
|
|
215
|
-
async getSchemaValue() {
|
|
216
|
-
await this.init();
|
|
217
|
-
return this._instance.getSchemaValue();
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Get evaluated schema without $params field
|
|
222
|
-
* @param {object} [options]
|
|
223
|
-
* @param {boolean} [options.skipLayout=false] - Skip layout resolution
|
|
224
|
-
* @returns {Promise<any>}
|
|
225
|
-
*/
|
|
226
|
-
async getEvaluatedSchemaWithoutParams({ skipLayout = false } = {}) {
|
|
227
|
-
await this.init();
|
|
228
|
-
return this._instance.getEvaluatedSchemaWithoutParamsJS(skipLayout);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Get a value from the evaluated schema using dotted path notation
|
|
233
|
-
* @param {object} options
|
|
234
|
-
* @param {string} options.path - Dotted path to the value (e.g., "properties.field.value")
|
|
235
|
-
* @param {boolean} [options.skipLayout=false] - Skip layout resolution
|
|
236
|
-
* @returns {Promise<any|null>} Value at the path, or null if not found
|
|
237
|
-
*/
|
|
238
|
-
async getEvaluatedSchemaByPath({ path, skipLayout = false }) {
|
|
239
|
-
await this.init();
|
|
240
|
-
return this._instance.getEvaluatedSchemaByPathJS(path, skipLayout);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Get values from the evaluated schema using multiple dotted path notations
|
|
245
|
-
* Returns data in the specified format (skips paths that are not found)
|
|
246
|
-
* @param {object} options
|
|
247
|
-
* @param {string[]} options.paths - Array of dotted paths to retrieve
|
|
248
|
-
* @param {boolean} [options.skipLayout=false] - Skip layout resolution
|
|
249
|
-
* @param {number} [options.format=0] - Return format (0=Nested, 1=Flat, 2=Array)
|
|
250
|
-
* @returns {Promise<any>} Data in specified format
|
|
251
|
-
*/
|
|
252
|
-
async getEvaluatedSchemaByPaths({ paths, skipLayout = false, format = 0 }) {
|
|
253
|
-
await this.init();
|
|
254
|
-
return this._instance.getEvaluatedSchemaByPathsJS(JSON.stringify(paths), skipLayout, format);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Get a value from the schema using dotted path notation
|
|
259
|
-
* @param {object} options
|
|
260
|
-
* @param {string} options.path - Dotted path to the value (e.g., "properties.field.value")
|
|
261
|
-
* @returns {Promise<any|null>} Value at the path, or null if not found
|
|
262
|
-
*/
|
|
263
|
-
async getSchemaByPath({ path }) {
|
|
264
|
-
await this.init();
|
|
265
|
-
return this._instance.getSchemaByPathJS(path);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* Get values from the schema using multiple dotted path notations
|
|
270
|
-
* Returns data in the specified format (skips paths that are not found)
|
|
271
|
-
* @param {object} options
|
|
272
|
-
* @param {string[]} options.paths - Array of dotted paths to retrieve
|
|
273
|
-
* @param {number} [options.format=0] - Return format (0=Nested, 1=Flat, 2=Array)
|
|
274
|
-
* @returns {Promise<any>} Data in specified format
|
|
275
|
-
*/
|
|
276
|
-
async getSchemaByPaths({ paths, format = 0 }) {
|
|
277
|
-
await this.init();
|
|
278
|
-
return this._instance.getSchemaByPathsJS(JSON.stringify(paths), format);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Reload schema with new data
|
|
283
|
-
* @param {object} options
|
|
284
|
-
* @param {object} options.schema - New JSON schema
|
|
285
|
-
* @param {object} [options.context] - Optional new context
|
|
286
|
-
* @param {object} [options.data] - Optional new data
|
|
287
|
-
* @returns {Promise<void>}
|
|
288
|
-
*/
|
|
289
|
-
async reloadSchema({ schema, context, data }) {
|
|
290
|
-
if (!this._instance) {
|
|
291
|
-
throw new Error('Instance not initialized. Call init() first.');
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
try {
|
|
295
|
-
await this._instance.reloadSchema(
|
|
296
|
-
JSON.stringify(schema),
|
|
297
|
-
context ? JSON.stringify(context) : null,
|
|
298
|
-
data ? JSON.stringify(data) : null
|
|
299
|
-
);
|
|
300
|
-
|
|
301
|
-
// Update internal state
|
|
302
|
-
this._schema = schema;
|
|
303
|
-
this._context = context;
|
|
304
|
-
this._data = data;
|
|
305
|
-
} catch (error) {
|
|
306
|
-
throw new Error(`Failed to reload schema: ${error.message || error}`);
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* Reload schema from MessagePack bytes
|
|
312
|
-
* @param {Uint8Array} schemaMsgpack - MessagePack-encoded schema bytes
|
|
313
|
-
* @param {object} [context] - Optional new context
|
|
314
|
-
* @param {object} [data] - Optional new data
|
|
315
|
-
* @returns {Promise<void>}
|
|
316
|
-
*/
|
|
317
|
-
async reloadSchemaMsgpack(schemaMsgpack, context, data) {
|
|
318
|
-
if (!this._instance) {
|
|
319
|
-
throw new Error('Instance not initialized. Call init() first.');
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
if (!(schemaMsgpack instanceof Uint8Array)) {
|
|
323
|
-
throw new Error('schemaMsgpack must be a Uint8Array');
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
try {
|
|
327
|
-
await this._instance.reloadSchemaMsgpack(
|
|
328
|
-
schemaMsgpack,
|
|
329
|
-
context ? JSON.stringify(context) : null,
|
|
330
|
-
data ? JSON.stringify(data) : null
|
|
331
|
-
);
|
|
332
|
-
|
|
333
|
-
// Update internal state
|
|
334
|
-
this._schema = schemaMsgpack;
|
|
335
|
-
this._context = context;
|
|
336
|
-
this._data = data;
|
|
337
|
-
this._isMsgpackSchema = true;
|
|
338
|
-
} catch (error) {
|
|
339
|
-
throw new Error(`Failed to reload schema from MessagePack: ${error.message || error}`);
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
/**
|
|
344
|
-
* Reload schema from ParsedSchemaCache using a cache key
|
|
345
|
-
* @param {string} cacheKey - Cache key to lookup in the global ParsedSchemaCache
|
|
346
|
-
* @param {object} [context] - Optional new context
|
|
347
|
-
* @param {object} [data] - Optional new data
|
|
348
|
-
* @returns {Promise<void>}
|
|
349
|
-
*/
|
|
350
|
-
async reloadSchemaFromCache(cacheKey, context, data) {
|
|
351
|
-
if (!this._instance) {
|
|
352
|
-
throw new Error('Instance not initialized. Call init() first.');
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
if (typeof cacheKey !== 'string' || !cacheKey) {
|
|
356
|
-
throw new Error('cacheKey must be a non-empty string');
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
try {
|
|
360
|
-
await this._instance.reloadSchemaFromCache(
|
|
361
|
-
cacheKey,
|
|
362
|
-
context ? JSON.stringify(context) : null,
|
|
363
|
-
data ? JSON.stringify(data) : null
|
|
364
|
-
);
|
|
365
|
-
|
|
366
|
-
// Update internal state
|
|
367
|
-
this._context = context;
|
|
368
|
-
this._data = data;
|
|
369
|
-
// Note: schema is not updated as we don't have access to it from the cache key
|
|
370
|
-
} catch (error) {
|
|
371
|
-
throw new Error(`Failed to reload schema from cache: ${error.message || error}`);
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
/**
|
|
376
|
-
* Get cache statistics
|
|
377
|
-
* @returns {Promise<{hits: number, misses: number, entries: number}>}
|
|
378
|
-
*/
|
|
379
|
-
async cacheStats() {
|
|
380
|
-
await this.init();
|
|
381
|
-
return this._instance.cacheStats();
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
/**
|
|
385
|
-
* Clear the evaluation cache
|
|
386
|
-
* @returns {Promise<void>}
|
|
387
|
-
*/
|
|
388
|
-
async clearCache() {
|
|
389
|
-
await this.init();
|
|
390
|
-
this._instance.clearCache();
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
/**
|
|
394
|
-
* Get the number of cached entries
|
|
395
|
-
* @returns {Promise<number>}
|
|
396
|
-
*/
|
|
397
|
-
async cacheLen() {
|
|
398
|
-
await this.init();
|
|
399
|
-
return this._instance.cacheLen();
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
/**
|
|
403
|
-
* Enable evaluation caching
|
|
404
|
-
* Useful for reusing JSONEval instances with different data
|
|
405
|
-
* @returns {Promise<void>}
|
|
406
|
-
*/
|
|
407
|
-
async enableCache() {
|
|
408
|
-
await this.init();
|
|
409
|
-
this._instance.enableCache();
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* Disable evaluation caching
|
|
414
|
-
* Useful for web API usage where each request creates a new JSONEval instance
|
|
415
|
-
* Improves performance by skipping cache operations that have no benefit for single-use instances
|
|
416
|
-
* @returns {Promise<void>}
|
|
417
|
-
*/
|
|
418
|
-
async disableCache() {
|
|
419
|
-
await this.init();
|
|
420
|
-
this._instance.disableCache();
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
/**
|
|
424
|
-
* Check if evaluation caching is enabled
|
|
425
|
-
* @returns {boolean}
|
|
426
|
-
*/
|
|
427
|
-
isCacheEnabled() {
|
|
428
|
-
if (!this._instance) return true; // Default is enabled
|
|
429
|
-
return this._instance.isCacheEnabled();
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
/**
|
|
433
|
-
* Resolve layout with optional evaluation
|
|
434
|
-
* @param {object} [options]
|
|
435
|
-
* @param {boolean} [options.evaluate=false] - If true, runs evaluation before resolving layout
|
|
436
|
-
* @returns {Promise<void>}
|
|
437
|
-
*/
|
|
438
|
-
async resolveLayout({ evaluate = false } = {}) {
|
|
439
|
-
await this.init();
|
|
440
|
-
return this._instance.resolveLayout(evaluate);
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
/**
|
|
444
|
-
* Set timezone offset for datetime operations (TODAY, NOW)
|
|
445
|
-
* @param {number|null|undefined} offsetMinutes - Timezone offset in minutes from UTC
|
|
446
|
-
* (e.g., 420 for UTC+7, -300 for UTC-5)
|
|
447
|
-
* Pass null or undefined to reset to UTC
|
|
448
|
-
* @returns {void}
|
|
449
|
-
*/
|
|
450
|
-
setTimezoneOffset(offsetMinutes) {
|
|
451
|
-
if (!this._instance) {
|
|
452
|
-
throw new Error('Instance not initialized. Call init() first.');
|
|
453
|
-
}
|
|
454
|
-
this._instance.set_timezone_offset(offsetMinutes);
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
/**
|
|
458
|
-
* Compile and run JSON logic from a JSON logic string
|
|
459
|
-
* @param {object} options - Options for compile and run logic
|
|
460
|
-
* @param {string|object} options.logicStr - JSON logic expression as a string or object
|
|
461
|
-
* @param {object} [options.data] - Optional data to evaluate against (uses existing data if not provided)
|
|
462
|
-
* @param {object} [options.context] - Optional context to use (uses existing context if not provided)
|
|
463
|
-
* @returns {Promise<any>} Result of the evaluation
|
|
464
|
-
*/
|
|
465
|
-
async compileAndRunLogic({ logicStr, data, context }) {
|
|
466
|
-
await this.init();
|
|
467
|
-
const logic = typeof logicStr === 'string' ? logicStr : JSON.stringify(logicStr);
|
|
468
|
-
const result = await this._instance.compileAndRunLogic(
|
|
469
|
-
logic,
|
|
470
|
-
data ? JSON.stringify(data) : null,
|
|
471
|
-
context ? JSON.stringify(context) : null
|
|
472
|
-
);
|
|
473
|
-
// Parse result if it's a string
|
|
474
|
-
return typeof result === 'string' ? JSON.parse(result) : result;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
/**
|
|
478
|
-
* Compile JSON logic and return a global ID
|
|
479
|
-
* @param {string|object} logicStr - JSON logic expression as a string or object
|
|
480
|
-
* @returns {Promise<number>} Compiled logic ID
|
|
481
|
-
*/
|
|
482
|
-
async compileLogic(logicStr) {
|
|
483
|
-
await this.init();
|
|
484
|
-
const logic = typeof logicStr === 'string' ? logicStr : JSON.stringify(logicStr);
|
|
485
|
-
return this._instance.compileLogic(logic);
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
/**
|
|
489
|
-
* Run pre-compiled logic by ID
|
|
490
|
-
* @param {number} logicId - Compiled logic ID from compileLogic
|
|
491
|
-
* @param {object} [data] - Optional data to evaluate against (uses existing data if not provided)
|
|
492
|
-
* @param {object} [context] - Optional context to use (uses existing context if not provided)
|
|
493
|
-
* @returns {Promise<any>} Result of the evaluation
|
|
494
|
-
*/
|
|
495
|
-
async runLogic(logicId, data, context) {
|
|
496
|
-
await this.init();
|
|
497
|
-
const result = await this._instance.runLogic(
|
|
498
|
-
logicId,
|
|
499
|
-
data ? JSON.stringify(data) : null,
|
|
500
|
-
context ? JSON.stringify(context) : null
|
|
501
|
-
);
|
|
502
|
-
// Parse result if it's a string
|
|
503
|
-
return typeof result === 'string' ? JSON.parse(result) : result;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
/**
|
|
507
|
-
* Validate data against schema rules with optional path filtering
|
|
508
|
-
* @param {object} options
|
|
509
|
-
* @param {object} options.data - Data to validate
|
|
510
|
-
* @param {object} [options.context] - Optional context
|
|
511
|
-
* @param {Array<string>} [options.paths] - Optional array of paths to validate (null for all)
|
|
512
|
-
* @returns {Promise<{has_error: boolean, errors: Array<{path: string, rule_type: string, message: string}>}>}
|
|
513
|
-
*/
|
|
514
|
-
async validatePaths({ data, context, paths }) {
|
|
515
|
-
await this.init();
|
|
516
|
-
try {
|
|
517
|
-
// Use validatePathsJS for proper serialization (Worker-safe)
|
|
518
|
-
return this._instance.validatePathsJS(
|
|
519
|
-
JSON.stringify(data),
|
|
520
|
-
context ? JSON.stringify(context) : null,
|
|
521
|
-
paths || null
|
|
522
|
-
);
|
|
523
|
-
} catch (error) {
|
|
524
|
-
throw new Error(`Validation failed: ${error.message || error}`);
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
// ============================================================================
|
|
529
|
-
// Subform Methods
|
|
530
|
-
// ============================================================================
|
|
531
|
-
|
|
532
|
-
/**
|
|
533
|
-
* Evaluate a subform with data
|
|
534
|
-
* @param {object} options
|
|
535
|
-
* @param {string} options.subformPath - Path to the subform (e.g., "#/riders")
|
|
536
|
-
* @param {object} options.data - Data for the subform
|
|
537
|
-
* @param {object} [options.context] - Optional context
|
|
538
|
-
* @param {Array<string>} [options.paths] - Optional array of paths to evaluate
|
|
539
|
-
* @returns {Promise<void>}
|
|
540
|
-
*/
|
|
541
|
-
async evaluateSubform({ subformPath, data, context, paths }) {
|
|
542
|
-
await this.init();
|
|
543
|
-
return this._instance.evaluateSubform(
|
|
544
|
-
subformPath,
|
|
545
|
-
JSON.stringify(data),
|
|
546
|
-
context ? JSON.stringify(context) : null,
|
|
547
|
-
paths || null
|
|
548
|
-
);
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
/**
|
|
552
|
-
* Validate subform data against its schema rules
|
|
553
|
-
* @param {object} options
|
|
554
|
-
* @param {string} options.subformPath - Path to the subform
|
|
555
|
-
* @param {object} options.data - Data for the subform
|
|
556
|
-
* @param {object} [options.context] - Optional context
|
|
557
|
-
* @returns {Promise<{has_error: boolean, errors: Array}>}
|
|
558
|
-
*/
|
|
559
|
-
async validateSubform({ subformPath, data, context }) {
|
|
560
|
-
await this.init();
|
|
561
|
-
return this._instance.validateSubform(
|
|
562
|
-
subformPath,
|
|
563
|
-
JSON.stringify(data),
|
|
564
|
-
context ? JSON.stringify(context) : null
|
|
565
|
-
);
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
/**
|
|
569
|
-
* Evaluate dependent fields in subform
|
|
570
|
-
* @param {object} options
|
|
571
|
-
* @param {string} options.subformPath - Path to the subform
|
|
572
|
-
* @param {string[]} options.changedPaths - Array of field paths that changed
|
|
573
|
-
* @param {object} [options.data] - Optional updated data
|
|
574
|
-
* @param {object} [options.context] - Optional context
|
|
575
|
-
* @param {boolean} [options.reEvaluate=false] - If true, performs full evaluation after processing dependents
|
|
576
|
-
* @returns {Promise<any>}
|
|
577
|
-
*/
|
|
578
|
-
async evaluateDependentsSubform({ subformPath, changedPaths, data, context, reEvaluate = false }) {
|
|
579
|
-
await this.init();
|
|
580
|
-
|
|
581
|
-
// For backward compatibility, accept single changedPath too
|
|
582
|
-
const paths = Array.isArray(changedPaths) ? changedPaths : [changedPaths];
|
|
583
|
-
|
|
584
|
-
return this._instance.evaluateDependentsSubformJS(
|
|
585
|
-
subformPath,
|
|
586
|
-
paths[0], // WASM still expects single path (wraps internally)
|
|
587
|
-
data ? JSON.stringify(data) : null,
|
|
588
|
-
context ? JSON.stringify(context) : null
|
|
589
|
-
);
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
/**
|
|
593
|
-
* Resolve layout for subform
|
|
594
|
-
* @param {object} options
|
|
595
|
-
* @param {string} options.subformPath - Path to the subform
|
|
596
|
-
* @param {boolean} [options.evaluate=false] - If true, runs evaluation before resolving layout
|
|
597
|
-
* @returns {Promise<void>}
|
|
598
|
-
*/
|
|
599
|
-
async resolveLayoutSubform({ subformPath, evaluate = false }) {
|
|
600
|
-
await this.init();
|
|
601
|
-
return this._instance.resolveLayoutSubform(subformPath, evaluate);
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
/**
|
|
605
|
-
* Get evaluated schema from subform
|
|
606
|
-
* @param {object} options
|
|
607
|
-
* @param {string} options.subformPath - Path to the subform
|
|
608
|
-
* @param {boolean} [options.resolveLayout=false] - Whether to resolve layout
|
|
609
|
-
* @returns {Promise<any>}
|
|
610
|
-
*/
|
|
611
|
-
async getEvaluatedSchemaSubform({ subformPath, resolveLayout = false }) {
|
|
612
|
-
await this.init();
|
|
613
|
-
return this._instance.getEvaluatedSchemaSubformJS(subformPath, resolveLayout);
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
/**
|
|
617
|
-
* Get schema value from subform (all .value fields)
|
|
618
|
-
* @param {object} options
|
|
619
|
-
* @param {string} options.subformPath - Path to the subform
|
|
620
|
-
* @returns {Promise<any>}
|
|
621
|
-
*/
|
|
622
|
-
async getSchemaValueSubform({ subformPath }) {
|
|
623
|
-
await this.init();
|
|
624
|
-
return this._instance.getSchemaValueSubform(subformPath);
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
/**
|
|
628
|
-
* Get evaluated schema without $params from subform
|
|
629
|
-
* @param {object} options
|
|
630
|
-
* @param {string} options.subformPath - Path to the subform
|
|
631
|
-
* @param {boolean} [options.resolveLayout=false] - Whether to resolve layout
|
|
632
|
-
* @returns {Promise<any>}
|
|
633
|
-
*/
|
|
634
|
-
async getEvaluatedSchemaWithoutParamsSubform({ subformPath, resolveLayout = false }) {
|
|
635
|
-
await this.init();
|
|
636
|
-
return this._instance.getEvaluatedSchemaWithoutParamsSubformJS(subformPath, resolveLayout);
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
/**
|
|
640
|
-
* Get evaluated schema by specific path from subform
|
|
641
|
-
* @param {object} options
|
|
642
|
-
* @param {string} options.subformPath - Path to the subform
|
|
643
|
-
* @param {string} options.schemaPath - Path within the subform
|
|
644
|
-
* @param {boolean} [options.skipLayout=false] - Whether to skip layout resolution
|
|
645
|
-
* @returns {Promise<any|null>}
|
|
646
|
-
*/
|
|
647
|
-
async getEvaluatedSchemaByPathSubform({ subformPath, schemaPath, skipLayout = false }) {
|
|
648
|
-
await this.init();
|
|
649
|
-
return this._instance.getEvaluatedSchemaByPathSubformJS(subformPath, schemaPath, skipLayout);
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
/**
|
|
653
|
-
* Get evaluated schema by multiple paths from subform
|
|
654
|
-
* Returns data in the specified format (skips paths that are not found)
|
|
655
|
-
* @param {object} options
|
|
656
|
-
* @param {string} options.subformPath - Path to the subform
|
|
657
|
-
* @param {string[]} options.schemaPaths - Array of paths within the subform
|
|
658
|
-
* @param {boolean} [options.skipLayout=false] - Whether to skip layout resolution
|
|
659
|
-
* @param {number} [options.format=0] - Return format (0=Nested, 1=Flat, 2=Array)
|
|
660
|
-
* @returns {Promise<any>}
|
|
661
|
-
*/
|
|
662
|
-
async getEvaluatedSchemaByPathsSubform({ subformPath, schemaPaths, skipLayout = false, format = 0 }) {
|
|
663
|
-
await this.init();
|
|
664
|
-
return this._instance.getEvaluatedSchemaByPathsSubformJS(subformPath, JSON.stringify(schemaPaths), skipLayout, format);
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
/**
|
|
668
|
-
* Get list of available subform paths
|
|
669
|
-
* @returns {Promise<Array<string>>}
|
|
670
|
-
*/
|
|
671
|
-
async getSubformPaths() {
|
|
672
|
-
await this.init();
|
|
673
|
-
return this._instance.getSubformPaths();
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
/**
|
|
677
|
-
* Get schema by specific path from subform
|
|
678
|
-
* @param {object} options
|
|
679
|
-
* @param {string} options.subformPath - Path to the subform
|
|
680
|
-
* @param {string} options.schemaPath - Path within the subform
|
|
681
|
-
* @returns {Promise<any|null>}
|
|
682
|
-
*/
|
|
683
|
-
async getSchemaByPathSubform({ subformPath, schemaPath }) {
|
|
684
|
-
await this.init();
|
|
685
|
-
return this._instance.getSchemaByPathSubformJS(subformPath, schemaPath);
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
/**
|
|
689
|
-
* Get schema by multiple paths from subform
|
|
690
|
-
* Returns data in the specified format (skips paths that are not found)
|
|
691
|
-
* @param {object} options
|
|
692
|
-
* @param {string} options.subformPath - Path to the subform
|
|
693
|
-
* @param {string[]} options.schemaPaths - Array of paths within the subform
|
|
694
|
-
* @param {number} [options.format=0] - Return format (0=Nested, 1=Flat, 2=Array)
|
|
695
|
-
* @returns {Promise<any>}
|
|
696
|
-
*/
|
|
697
|
-
async getSchemaByPathsSubform({ subformPath, schemaPaths, format = 0 }) {
|
|
698
|
-
await this.init();
|
|
699
|
-
return this._instance.getSchemaByPathsSubformJS(subformPath, JSON.stringify(schemaPaths), format);
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
/**
|
|
703
|
-
* Check if a subform exists at the given path
|
|
704
|
-
* @param {string} subformPath - Path to check
|
|
705
|
-
* @returns {Promise<boolean>}
|
|
706
|
-
*/
|
|
707
|
-
async hasSubform(subformPath) {
|
|
708
|
-
await this.init();
|
|
709
|
-
return this._instance.hasSubform(subformPath);
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
/**
|
|
713
|
-
* Free WASM resources
|
|
714
|
-
*/
|
|
715
|
-
free() {
|
|
716
|
-
if (this._instance) {
|
|
717
|
-
this._instance.free();
|
|
718
|
-
this._instance = null;
|
|
719
|
-
this._ready = false;
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
/**
|
|
725
|
-
* Get library version (internal - use from specific packages)
|
|
726
|
-
* @param {any} wasmModule - WASM module
|
|
727
|
-
* @returns {string}
|
|
728
|
-
*/
|
|
729
|
-
export function getVersion(wasmModule) {
|
|
730
|
-
return wasmModule.version();
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
export default JSONEvalCore;
|