@json-eval-rs/react-native 0.0.55 → 0.0.56

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/src/index.tsx CHANGED
@@ -18,6 +18,16 @@ const JsonEvalRs = NativeModules.JsonEvalRs
18
18
  }
19
19
  );
20
20
 
21
+ /**
22
+ * Item for get schema value array results
23
+ */
24
+ export interface SchemaValueItem {
25
+ /** Dotted path (e.g., "field1.field2") */
26
+ path: string;
27
+ /** Value at this path */
28
+ value: any;
29
+ }
30
+
21
31
  /**
22
32
  * Return format for path-based methods
23
33
  */
@@ -27,7 +37,7 @@ export enum ReturnFormat {
27
37
  /** Flat object with dotted keys */
28
38
  Flat = 1,
29
39
  /** Array of values in the order of requested paths */
30
- Array = 2
40
+ Array = 2,
31
41
  }
32
42
 
33
43
  /**
@@ -260,22 +270,22 @@ export interface GetSchemaByPathsSubformOptions {
260
270
 
261
271
  /**
262
272
  * High-performance JSON Logic evaluator with schema validation for React Native
263
- *
273
+ *
264
274
  * ## Zero-Copy Architecture
265
- *
275
+ *
266
276
  * This binding is optimized for minimal memory copies:
267
277
  * - **Rust FFI Layer**: Returns raw pointers (zero-copy)
268
278
  * - **C++ Bridge**: Uses direct pointer access with single-copy string construction
269
279
  * - **Native Platform**: Minimizes intermediate conversions
270
280
  * - **JS Bridge**: React Native's architecture requires serialization (unavoidable)
271
- *
281
+ *
272
282
  * While true zero-copy across JS/Native boundary is not possible due to React Native's
273
283
  * architecture, we minimize copies within the native layer to maximize performance.
274
- *
284
+ *
275
285
  * @example
276
286
  * ```typescript
277
287
  * import { JSONEval } from '@json-eval-rs/react-native';
278
- *
288
+ *
279
289
  * const schema = {
280
290
  * type: 'object',
281
291
  * properties: {
@@ -292,18 +302,18 @@ export interface GetSchemaByPathsSubformOptions {
292
302
  * }
293
303
  * }
294
304
  * };
295
- *
305
+ *
296
306
  * const eval = new JSONEval({ schema });
297
- *
307
+ *
298
308
  * const data = { user: { name: 'John' } };
299
309
  * const result = await eval.evaluate({ data });
300
310
  * console.log(result);
301
- *
311
+ *
302
312
  * const validation = await eval.validate({ data });
303
313
  * if (validation.hasError) {
304
314
  * console.error('Validation errors:', validation.errors);
305
315
  * }
306
- *
316
+ *
307
317
  * await eval.dispose();
308
318
  * ```
309
319
  */
@@ -324,9 +334,17 @@ export class JSONEval {
324
334
  context?: string | object | null,
325
335
  data?: string | object | null
326
336
  ): JSONEval {
327
- const contextStr = context ? (typeof context === 'string' ? context : JSON.stringify(context)) : null;
328
- const dataStr = data ? (typeof data === 'string' ? data : JSON.stringify(data)) : null;
329
-
337
+ const contextStr = context
338
+ ? typeof context === 'string'
339
+ ? context
340
+ : JSON.stringify(context)
341
+ : null;
342
+ const dataStr = data
343
+ ? typeof data === 'string'
344
+ ? data
345
+ : JSON.stringify(data)
346
+ : null;
347
+
330
348
  const handle = JsonEvalRs.createFromCache(cacheKey, contextStr, dataStr);
331
349
  return new JSONEval({ schema: {}, _handle: handle });
332
350
  }
@@ -343,11 +361,24 @@ export class JSONEval {
343
361
  data?: string | object | null,
344
362
  context?: string | object | null
345
363
  ): Promise<any> {
346
- const logic = typeof logicStr === 'string' ? logicStr : JSON.stringify(logicStr);
347
- const dataStr = data ? (typeof data === 'string' ? data : JSON.stringify(data)) : null;
348
- const contextStr = context ? (typeof context === 'string' ? context : JSON.stringify(context)) : null;
349
-
350
- const resultStr = await JsonEvalRs.evaluateLogic(logic, dataStr, contextStr);
364
+ const logic =
365
+ typeof logicStr === 'string' ? logicStr : JSON.stringify(logicStr);
366
+ const dataStr = data
367
+ ? typeof data === 'string'
368
+ ? data
369
+ : JSON.stringify(data)
370
+ : null;
371
+ const contextStr = context
372
+ ? typeof context === 'string'
373
+ ? context
374
+ : JSON.stringify(context)
375
+ : null;
376
+
377
+ const resultStr = await JsonEvalRs.evaluateLogic(
378
+ logic,
379
+ dataStr,
380
+ contextStr
381
+ );
351
382
  return JSON.parse(resultStr);
352
383
  }
353
384
 
@@ -362,17 +393,27 @@ export class JSONEval {
362
393
  this.handle = options._handle;
363
394
  return;
364
395
  }
365
-
396
+
366
397
  const { schema, context, data } = options;
367
-
398
+
368
399
  try {
369
- const schemaStr = typeof schema === 'string' ? schema : JSON.stringify(schema);
370
- const contextStr = context ? (typeof context === 'string' ? context : JSON.stringify(context)) : null;
371
- const dataStr = data ? (typeof data === 'string' ? data : JSON.stringify(data)) : null;
372
-
400
+ const schemaStr =
401
+ typeof schema === 'string' ? schema : JSON.stringify(schema);
402
+ const contextStr = context
403
+ ? typeof context === 'string'
404
+ ? context
405
+ : JSON.stringify(context)
406
+ : null;
407
+ const dataStr = data
408
+ ? typeof data === 'string'
409
+ ? data
410
+ : JSON.stringify(data)
411
+ : null;
412
+
373
413
  this.handle = JsonEvalRs.create(schemaStr, contextStr, dataStr);
374
414
  } catch (error) {
375
- const errorMessage = error instanceof Error ? error.message : String(error);
415
+ const errorMessage =
416
+ error instanceof Error ? error.message : String(error);
376
417
  throw new Error(`Failed to create JSONEval instance: ${errorMessage}`);
377
418
  }
378
419
  }
@@ -394,7 +435,7 @@ export class JSONEval {
394
435
 
395
436
  /**
396
437
  * Cancel any running evaluation
397
- * The generic auto-cancellation on new evaluation will still work,
438
+ * The generic auto-cancellation on new evaluation will still work,
398
439
  * but this allows manual cancellation.
399
440
  */
400
441
  async cancel(): Promise<void> {
@@ -410,16 +451,24 @@ export class JSONEval {
410
451
  */
411
452
  async evaluate(options: EvaluateOptions): Promise<any> {
412
453
  this.throwIfDisposed();
413
-
454
+
414
455
  try {
415
456
  const dataStr = this.toJsonString(options.data);
416
- const contextStr = options.context ? this.toJsonString(options.context) : null;
457
+ const contextStr = options.context
458
+ ? this.toJsonString(options.context)
459
+ : null;
417
460
  const pathsJson = options.paths ? JSON.stringify(options.paths) : null;
418
-
419
- const resultStr = await JsonEvalRs.evaluate(this.handle, dataStr, contextStr, pathsJson);
461
+
462
+ const resultStr = await JsonEvalRs.evaluate(
463
+ this.handle,
464
+ dataStr,
465
+ contextStr,
466
+ pathsJson
467
+ );
420
468
  return JSON.parse(resultStr);
421
469
  } catch (error) {
422
- const errorMessage = error instanceof Error ? error.message : String(error);
470
+ const errorMessage =
471
+ error instanceof Error ? error.message : String(error);
423
472
  throw new Error(`Evaluation failed: ${errorMessage}`);
424
473
  }
425
474
  }
@@ -432,15 +481,22 @@ export class JSONEval {
432
481
  */
433
482
  async validate(options: EvaluateOptions): Promise<ValidationResult> {
434
483
  this.throwIfDisposed();
435
-
484
+
436
485
  try {
437
486
  const dataStr = this.toJsonString(options.data);
438
- const contextStr = options.context ? this.toJsonString(options.context) : null;
439
-
440
- const resultStr = await JsonEvalRs.validate(this.handle, dataStr, contextStr);
487
+ const contextStr = options.context
488
+ ? this.toJsonString(options.context)
489
+ : null;
490
+
491
+ const resultStr = await JsonEvalRs.validate(
492
+ this.handle,
493
+ dataStr,
494
+ contextStr
495
+ );
441
496
  return JSON.parse(resultStr);
442
497
  } catch (error) {
443
- const errorMessage = error instanceof Error ? error.message : String(error);
498
+ const errorMessage =
499
+ error instanceof Error ? error.message : String(error);
444
500
  throw new Error(`Validation failed: ${errorMessage}`);
445
501
  }
446
502
  }
@@ -451,15 +507,17 @@ export class JSONEval {
451
507
  * @returns Promise resolving to array of dependent field changes
452
508
  * @throws {Error} If evaluation fails
453
509
  */
454
- async evaluateDependents(options: EvaluateDependentsOptions): Promise<DependentChange[]> {
510
+ async evaluateDependents(
511
+ options: EvaluateDependentsOptions
512
+ ): Promise<DependentChange[]> {
455
513
  this.throwIfDisposed();
456
-
514
+
457
515
  try {
458
516
  const { changedPaths, data, context, reEvaluate = true } = options;
459
517
  const changedPathsJson = JSON.stringify(changedPaths);
460
518
  const dataStr = data ? this.toJsonString(data) : null;
461
519
  const contextStr = context ? this.toJsonString(context) : null;
462
-
520
+
463
521
  const resultStr = await JsonEvalRs.evaluateDependents(
464
522
  this.handle,
465
523
  changedPathsJson,
@@ -469,7 +527,8 @@ export class JSONEval {
469
527
  );
470
528
  return JSON.parse(resultStr);
471
529
  } catch (error) {
472
- const errorMessage = error instanceof Error ? error.message : String(error);
530
+ const errorMessage =
531
+ error instanceof Error ? error.message : String(error);
473
532
  throw new Error(`Dependent evaluation failed: ${errorMessage}`);
474
533
  }
475
534
  }
@@ -482,7 +541,10 @@ export class JSONEval {
482
541
  */
483
542
  async getEvaluatedSchema(skipLayout: boolean = false): Promise<any> {
484
543
  this.throwIfDisposed();
485
- const resultStr = await JsonEvalRs.getEvaluatedSchema(this.handle, skipLayout);
544
+ const resultStr = await JsonEvalRs.getEvaluatedSchema(
545
+ this.handle,
546
+ skipLayout
547
+ );
486
548
  return JSON.parse(resultStr);
487
549
  }
488
550
 
@@ -497,15 +559,44 @@ export class JSONEval {
497
559
  return JSON.parse(resultStr);
498
560
  }
499
561
 
562
+ /**
563
+ * Get all schema values as array of path-value pairs
564
+ * Returns [{path: "", value: ""}, ...]
565
+ * @returns Promise resolving to array of SchemaValueItem objects
566
+ * @throws {Error} If operation fails
567
+ */
568
+ async getSchemaValueArray(): Promise<SchemaValueItem[]> {
569
+ this.throwIfDisposed();
570
+ const resultStr = await JsonEvalRs.getSchemaValueArray(this.handle);
571
+ return JSON.parse(resultStr);
572
+ }
573
+
574
+ /**
575
+ * Get all schema values as object with dotted path keys
576
+ * Returns {path: value, ...}
577
+ * @returns Promise resolving to flat object with dotted paths as keys
578
+ * @throws {Error} If operation fails
579
+ */
580
+ async getSchemaValueObject(): Promise<Record<string, any>> {
581
+ this.throwIfDisposed();
582
+ const resultStr = await JsonEvalRs.getSchemaValueObject(this.handle);
583
+ return JSON.parse(resultStr);
584
+ }
585
+
500
586
  /**
501
587
  * Get the evaluated schema without $params field
502
588
  * @param skipLayout - Whether to skip layout resolution (default: false)
503
589
  * @returns Promise resolving to evaluated schema object
504
590
  * @throws {Error} If operation fails
505
591
  */
506
- async getEvaluatedSchemaWithoutParams(skipLayout: boolean = false): Promise<any> {
592
+ async getEvaluatedSchemaWithoutParams(
593
+ skipLayout: boolean = false
594
+ ): Promise<any> {
507
595
  this.throwIfDisposed();
508
- const resultStr = await JsonEvalRs.getEvaluatedSchemaWithoutParams(this.handle, skipLayout);
596
+ const resultStr = await JsonEvalRs.getEvaluatedSchemaWithoutParams(
597
+ this.handle,
598
+ skipLayout
599
+ );
509
600
  return JSON.parse(resultStr);
510
601
  }
511
602
 
@@ -516,9 +607,16 @@ export class JSONEval {
516
607
  * @returns Promise resolving to the value at the path, or null if not found
517
608
  * @throws {Error} If operation fails
518
609
  */
519
- async getEvaluatedSchemaByPath(path: string, skipLayout: boolean = false): Promise<any | null> {
610
+ async getEvaluatedSchemaByPath(
611
+ path: string,
612
+ skipLayout: boolean = false
613
+ ): Promise<any | null> {
520
614
  this.throwIfDisposed();
521
- const resultStr = await JsonEvalRs.getEvaluatedSchemaByPath(this.handle, path, skipLayout);
615
+ const resultStr = await JsonEvalRs.getEvaluatedSchemaByPath(
616
+ this.handle,
617
+ path,
618
+ skipLayout
619
+ );
522
620
  return resultStr ? JSON.parse(resultStr) : null;
523
621
  }
524
622
 
@@ -531,10 +629,19 @@ export class JSONEval {
531
629
  * @returns Promise resolving to data in the specified format
532
630
  * @throws {Error} If operation fails
533
631
  */
534
- async getEvaluatedSchemaByPaths(paths: string[], skipLayout: boolean = false, format: ReturnFormat = ReturnFormat.Nested): Promise<any> {
632
+ async getEvaluatedSchemaByPaths(
633
+ paths: string[],
634
+ skipLayout: boolean = false,
635
+ format: ReturnFormat = ReturnFormat.Nested
636
+ ): Promise<any> {
535
637
  this.throwIfDisposed();
536
638
  const pathsJson = JSON.stringify(paths);
537
- const resultStr = await JsonEvalRs.getEvaluatedSchemaByPaths(this.handle, pathsJson, skipLayout, format);
639
+ const resultStr = await JsonEvalRs.getEvaluatedSchemaByPaths(
640
+ this.handle,
641
+ pathsJson,
642
+ skipLayout,
643
+ format
644
+ );
538
645
  return JSON.parse(resultStr);
539
646
  }
540
647
 
@@ -558,10 +665,17 @@ export class JSONEval {
558
665
  * @returns Promise resolving to data in the specified format
559
666
  * @throws {Error} If operation fails
560
667
  */
561
- async getSchemaByPaths(paths: string[], format: ReturnFormat = ReturnFormat.Nested): Promise<any> {
668
+ async getSchemaByPaths(
669
+ paths: string[],
670
+ format: ReturnFormat = ReturnFormat.Nested
671
+ ): Promise<any> {
562
672
  this.throwIfDisposed();
563
673
  const pathsJson = JSON.stringify(paths);
564
- const resultStr = await JsonEvalRs.getSchemaByPaths(this.handle, pathsJson, format);
674
+ const resultStr = await JsonEvalRs.getSchemaByPaths(
675
+ this.handle,
676
+ pathsJson,
677
+ format
678
+ );
565
679
  return JSON.parse(resultStr);
566
680
  }
567
681
 
@@ -572,16 +686,31 @@ export class JSONEval {
572
686
  */
573
687
  async reloadSchema(options: JSONEvalOptions): Promise<void> {
574
688
  this.throwIfDisposed();
575
-
689
+
576
690
  try {
577
691
  const { schema, context, data } = options;
578
- const schemaStr = typeof schema === 'string' ? schema : JSON.stringify(schema);
579
- const contextStr = context ? (typeof context === 'string' ? context : JSON.stringify(context)) : null;
580
- const dataStr = data ? (typeof data === 'string' ? data : JSON.stringify(data)) : null;
581
-
582
- await JsonEvalRs.reloadSchema(this.handle, schemaStr, contextStr, dataStr);
692
+ const schemaStr =
693
+ typeof schema === 'string' ? schema : JSON.stringify(schema);
694
+ const contextStr = context
695
+ ? typeof context === 'string'
696
+ ? context
697
+ : JSON.stringify(context)
698
+ : null;
699
+ const dataStr = data
700
+ ? typeof data === 'string'
701
+ ? data
702
+ : JSON.stringify(data)
703
+ : null;
704
+
705
+ await JsonEvalRs.reloadSchema(
706
+ this.handle,
707
+ schemaStr,
708
+ contextStr,
709
+ dataStr
710
+ );
583
711
  } catch (error) {
584
- const errorMessage = error instanceof Error ? error.message : String(error);
712
+ const errorMessage =
713
+ error instanceof Error ? error.message : String(error);
585
714
  throw new Error(`Failed to reload schema: ${errorMessage}`);
586
715
  }
587
716
  }
@@ -599,20 +728,37 @@ export class JSONEval {
599
728
  data?: string | object | null
600
729
  ): Promise<void> {
601
730
  this.throwIfDisposed();
602
-
731
+
603
732
  try {
604
733
  // Convert Uint8Array to number array if needed
605
- const msgpackArray = schemaMsgpack instanceof Uint8Array
606
- ? Array.from(schemaMsgpack)
607
- : schemaMsgpack;
608
-
609
- const contextStr = context ? (typeof context === 'string' ? context : JSON.stringify(context)) : null;
610
- const dataStr = data ? (typeof data === 'string' ? data : JSON.stringify(data)) : null;
611
-
612
- await JsonEvalRs.reloadSchemaMsgpack(this.handle, msgpackArray, contextStr, dataStr);
734
+ const msgpackArray =
735
+ schemaMsgpack instanceof Uint8Array
736
+ ? Array.from(schemaMsgpack)
737
+ : schemaMsgpack;
738
+
739
+ const contextStr = context
740
+ ? typeof context === 'string'
741
+ ? context
742
+ : JSON.stringify(context)
743
+ : null;
744
+ const dataStr = data
745
+ ? typeof data === 'string'
746
+ ? data
747
+ : JSON.stringify(data)
748
+ : null;
749
+
750
+ await JsonEvalRs.reloadSchemaMsgpack(
751
+ this.handle,
752
+ msgpackArray,
753
+ contextStr,
754
+ dataStr
755
+ );
613
756
  } catch (error) {
614
- const errorMessage = error instanceof Error ? error.message : String(error);
615
- throw new Error(`Failed to reload schema from MessagePack: ${errorMessage}`);
757
+ const errorMessage =
758
+ error instanceof Error ? error.message : String(error);
759
+ throw new Error(
760
+ `Failed to reload schema from MessagePack: ${errorMessage}`
761
+ );
616
762
  }
617
763
  }
618
764
 
@@ -629,14 +775,28 @@ export class JSONEval {
629
775
  data?: string | object | null
630
776
  ): Promise<void> {
631
777
  this.throwIfDisposed();
632
-
778
+
633
779
  try {
634
- const contextStr = context ? (typeof context === 'string' ? context : JSON.stringify(context)) : null;
635
- const dataStr = data ? (typeof data === 'string' ? data : JSON.stringify(data)) : null;
636
-
637
- await JsonEvalRs.reloadSchemaFromCache(this.handle, cacheKey, contextStr, dataStr);
780
+ const contextStr = context
781
+ ? typeof context === 'string'
782
+ ? context
783
+ : JSON.stringify(context)
784
+ : null;
785
+ const dataStr = data
786
+ ? typeof data === 'string'
787
+ ? data
788
+ : JSON.stringify(data)
789
+ : null;
790
+
791
+ await JsonEvalRs.reloadSchemaFromCache(
792
+ this.handle,
793
+ cacheKey,
794
+ contextStr,
795
+ dataStr
796
+ );
638
797
  } catch (error) {
639
- const errorMessage = error instanceof Error ? error.message : String(error);
798
+ const errorMessage =
799
+ error instanceof Error ? error.message : String(error);
640
800
  throw new Error(`Failed to reload schema from cache: ${errorMessage}`);
641
801
  }
642
802
  }
@@ -722,15 +882,15 @@ export class JSONEval {
722
882
  * Pass null to reset to UTC
723
883
  * @returns Promise that resolves when timezone is set
724
884
  * @throws {Error} If operation fails
725
- *
885
+ *
726
886
  * @example
727
887
  * ```typescript
728
888
  * // Set to UTC+7 (Jakarta, Bangkok)
729
889
  * await eval.setTimezoneOffset(420);
730
- *
890
+ *
731
891
  * // Set to UTC-5 (New York, EST)
732
892
  * await eval.setTimezoneOffset(-300);
733
- *
893
+ *
734
894
  * // Reset to UTC
735
895
  * await eval.setTimezoneOffset(null);
736
896
  * ```
@@ -748,14 +908,23 @@ export class JSONEval {
748
908
  * @returns Promise resolving to the result of the evaluation
749
909
  * @throws {Error} If compilation or evaluation fails
750
910
  */
751
- async compileAndRunLogic(logicStr: string | object, data?: string | object, context?: string | object): Promise<any> {
911
+ async compileAndRunLogic(
912
+ logicStr: string | object,
913
+ data?: string | object,
914
+ context?: string | object
915
+ ): Promise<any> {
752
916
  this.throwIfDisposed();
753
-
917
+
754
918
  const logic = this.toJsonString(logicStr);
755
919
  const dataStr = data ? this.toJsonString(data) : null;
756
920
  const contextStr = context ? this.toJsonString(context) : null;
757
-
758
- const resultStr = await JsonEvalRs.compileAndRunLogic(this.handle, logic, dataStr, contextStr);
921
+
922
+ const resultStr = await JsonEvalRs.compileAndRunLogic(
923
+ this.handle,
924
+ logic,
925
+ dataStr,
926
+ contextStr
927
+ );
759
928
  return JSON.parse(resultStr);
760
929
  }
761
930
 
@@ -767,7 +936,7 @@ export class JSONEval {
767
936
  */
768
937
  async compileLogic(logicStr: string | object): Promise<number> {
769
938
  this.throwIfDisposed();
770
-
939
+
771
940
  const logic = this.toJsonString(logicStr);
772
941
  return await JsonEvalRs.compileLogic(this.handle, logic);
773
942
  }
@@ -780,13 +949,22 @@ export class JSONEval {
780
949
  * @returns Promise resolving to the result of the evaluation
781
950
  * @throws {Error} If execution fails
782
951
  */
783
- async runLogic(logicId: number, data?: string | object, context?: string | object): Promise<any> {
952
+ async runLogic(
953
+ logicId: number,
954
+ data?: string | object,
955
+ context?: string | object
956
+ ): Promise<any> {
784
957
  this.throwIfDisposed();
785
-
958
+
786
959
  const dataStr = data ? this.toJsonString(data) : null;
787
960
  const contextStr = context ? this.toJsonString(context) : null;
788
-
789
- const resultStr = await JsonEvalRs.runLogic(this.handle, logicId, dataStr, contextStr);
961
+
962
+ const resultStr = await JsonEvalRs.runLogic(
963
+ this.handle,
964
+ logicId,
965
+ dataStr,
966
+ contextStr
967
+ );
790
968
  return JSON.parse(resultStr);
791
969
  }
792
970
 
@@ -796,14 +974,23 @@ export class JSONEval {
796
974
  * @returns Promise resolving to ValidationResult
797
975
  * @throws {Error} If validation operation fails
798
976
  */
799
- async validatePaths(options: ValidatePathsOptions): Promise<ValidationResult> {
977
+ async validatePaths(
978
+ options: ValidatePathsOptions
979
+ ): Promise<ValidationResult> {
800
980
  this.throwIfDisposed();
801
-
981
+
802
982
  const dataStr = this.toJsonString(options.data);
803
- const contextStr = options.context ? this.toJsonString(options.context) : null;
983
+ const contextStr = options.context
984
+ ? this.toJsonString(options.context)
985
+ : null;
804
986
  const paths = options.paths || null;
805
-
806
- const resultStr = await JsonEvalRs.validatePaths(this.handle, dataStr, contextStr, paths);
987
+
988
+ const resultStr = await JsonEvalRs.validatePaths(
989
+ this.handle,
990
+ dataStr,
991
+ contextStr,
992
+ paths
993
+ );
807
994
  return JSON.parse(resultStr);
808
995
  }
809
996
 
@@ -819,11 +1006,19 @@ export class JSONEval {
819
1006
  */
820
1007
  async evaluateSubform(options: EvaluateSubformOptions): Promise<void> {
821
1008
  this.throwIfDisposed();
822
-
1009
+
823
1010
  const dataStr = this.toJsonString(options.data);
824
- const contextStr = options.context ? this.toJsonString(options.context) : null;
825
-
826
- return JsonEvalRs.evaluateSubform(this.handle, options.subformPath, dataStr, contextStr, options.paths);
1011
+ const contextStr = options.context
1012
+ ? this.toJsonString(options.context)
1013
+ : null;
1014
+
1015
+ return JsonEvalRs.evaluateSubform(
1016
+ this.handle,
1017
+ options.subformPath,
1018
+ dataStr,
1019
+ contextStr,
1020
+ options.paths
1021
+ );
827
1022
  }
828
1023
 
829
1024
  /**
@@ -832,13 +1027,22 @@ export class JSONEval {
832
1027
  * @returns Promise resolving to ValidationResult
833
1028
  * @throws {Error} If validation fails
834
1029
  */
835
- async validateSubform(options: ValidateSubformOptions): Promise<ValidationResult> {
1030
+ async validateSubform(
1031
+ options: ValidateSubformOptions
1032
+ ): Promise<ValidationResult> {
836
1033
  this.throwIfDisposed();
837
-
1034
+
838
1035
  const dataStr = this.toJsonString(options.data);
839
- const contextStr = options.context ? this.toJsonString(options.context) : null;
840
-
841
- const resultStr = await JsonEvalRs.validateSubform(this.handle, options.subformPath, dataStr, contextStr);
1036
+ const contextStr = options.context
1037
+ ? this.toJsonString(options.context)
1038
+ : null;
1039
+
1040
+ const resultStr = await JsonEvalRs.validateSubform(
1041
+ this.handle,
1042
+ options.subformPath,
1043
+ dataStr,
1044
+ contextStr
1045
+ );
842
1046
  return JSON.parse(resultStr);
843
1047
  }
844
1048
 
@@ -848,15 +1052,19 @@ export class JSONEval {
848
1052
  * @returns Promise resolving to dependent evaluation results
849
1053
  * @throws {Error} If evaluation fails
850
1054
  */
851
- async evaluateDependentsSubform(options: EvaluateDependentsSubformOptions): Promise<DependentChange[]> {
1055
+ async evaluateDependentsSubform(
1056
+ options: EvaluateDependentsSubformOptions
1057
+ ): Promise<DependentChange[]> {
852
1058
  this.throwIfDisposed();
853
-
1059
+
854
1060
  const dataStr = options.data ? this.toJsonString(options.data) : null;
855
- const contextStr = options.context ? this.toJsonString(options.context) : null;
856
-
1061
+ const contextStr = options.context
1062
+ ? this.toJsonString(options.context)
1063
+ : null;
1064
+
857
1065
  // For now, pass the first path since native bridge expects single path (wraps internally)
858
1066
  const changedPath = options.changedPaths[0] || '';
859
-
1067
+
860
1068
  const resultStr = await JsonEvalRs.evaluateDependentsSubform(
861
1069
  this.handle,
862
1070
  options.subformPath,
@@ -874,10 +1082,16 @@ export class JSONEval {
874
1082
  * @returns Promise that resolves when layout is resolved
875
1083
  * @throws {Error} If layout resolution fails
876
1084
  */
877
- async resolveLayoutSubform(options: ResolveLayoutSubformOptions): Promise<void> {
1085
+ async resolveLayoutSubform(
1086
+ options: ResolveLayoutSubformOptions
1087
+ ): Promise<void> {
878
1088
  this.throwIfDisposed();
879
-
880
- return JsonEvalRs.resolveLayoutSubform(this.handle, options.subformPath, options.evaluate || false);
1089
+
1090
+ return JsonEvalRs.resolveLayoutSubform(
1091
+ this.handle,
1092
+ options.subformPath,
1093
+ options.evaluate || false
1094
+ );
881
1095
  }
882
1096
 
883
1097
  /**
@@ -886,9 +1100,11 @@ export class JSONEval {
886
1100
  * @returns Promise resolving to evaluated schema
887
1101
  * @throws {Error} If operation fails
888
1102
  */
889
- async getEvaluatedSchemaSubform(options: GetEvaluatedSchemaSubformOptions): Promise<any> {
1103
+ async getEvaluatedSchemaSubform(
1104
+ options: GetEvaluatedSchemaSubformOptions
1105
+ ): Promise<any> {
890
1106
  this.throwIfDisposed();
891
-
1107
+
892
1108
  const resultStr = await JsonEvalRs.getEvaluatedSchemaSubform(
893
1109
  this.handle,
894
1110
  options.subformPath,
@@ -903,10 +1119,53 @@ export class JSONEval {
903
1119
  * @returns Promise resolving to schema values
904
1120
  * @throws {Error} If operation fails
905
1121
  */
906
- async getSchemaValueSubform(options: GetSchemaValueSubformOptions): Promise<any> {
1122
+ async getSchemaValueSubform(
1123
+ options: GetSchemaValueSubformOptions
1124
+ ): Promise<any> {
907
1125
  this.throwIfDisposed();
908
-
909
- const resultStr = await JsonEvalRs.getSchemaValueSubform(this.handle, options.subformPath);
1126
+
1127
+ const resultStr = await JsonEvalRs.getSchemaValueSubform(
1128
+ this.handle,
1129
+ options.subformPath
1130
+ );
1131
+ return JSON.parse(resultStr);
1132
+ }
1133
+
1134
+ /**
1135
+ * Get schema values from subform as a flat array of path-value pairs.
1136
+ * Returns an array like `[{path: "field.sub", value: 123}, ...]`.
1137
+ * @param options - Options including subform path
1138
+ * @returns Promise resolving to array of SchemaValueItem objects
1139
+ * @throws {Error} If operation fails
1140
+ */
1141
+ async getSchemaValueArraySubform(
1142
+ options: GetSchemaValueSubformOptions
1143
+ ): Promise<SchemaValueItem[]> {
1144
+ this.throwIfDisposed();
1145
+
1146
+ const resultStr = await JsonEvalRs.getSchemaValueArraySubform(
1147
+ this.handle,
1148
+ options.subformPath
1149
+ );
1150
+ return JSON.parse(resultStr);
1151
+ }
1152
+
1153
+ /**
1154
+ * Get schema values from subform as a flat object with dotted path keys.
1155
+ * Returns an object like `{"field.sub": 123, ...}`.
1156
+ * @param options - Options including subform path
1157
+ * @returns Promise resolving to flat object with dotted paths
1158
+ * @throws {Error} If operation fails
1159
+ */
1160
+ async getSchemaValueObjectSubform(
1161
+ options: GetSchemaValueSubformOptions
1162
+ ): Promise<Record<string, any>> {
1163
+ this.throwIfDisposed();
1164
+
1165
+ const resultStr = await JsonEvalRs.getSchemaValueObjectSubform(
1166
+ this.handle,
1167
+ options.subformPath
1168
+ );
910
1169
  return JSON.parse(resultStr);
911
1170
  }
912
1171
 
@@ -916,9 +1175,11 @@ export class JSONEval {
916
1175
  * @returns Promise resolving to evaluated schema without $params
917
1176
  * @throws {Error} If operation fails
918
1177
  */
919
- async getEvaluatedSchemaWithoutParamsSubform(options: GetEvaluatedSchemaSubformOptions): Promise<any> {
1178
+ async getEvaluatedSchemaWithoutParamsSubform(
1179
+ options: GetEvaluatedSchemaSubformOptions
1180
+ ): Promise<any> {
920
1181
  this.throwIfDisposed();
921
-
1182
+
922
1183
  const resultStr = await JsonEvalRs.getEvaluatedSchemaWithoutParamsSubform(
923
1184
  this.handle,
924
1185
  options.subformPath,
@@ -933,9 +1194,11 @@ export class JSONEval {
933
1194
  * @returns Promise resolving to value at path or null if not found
934
1195
  * @throws {Error} If operation fails
935
1196
  */
936
- async getEvaluatedSchemaByPathSubform(options: GetEvaluatedSchemaByPathSubformOptions): Promise<any | null> {
1197
+ async getEvaluatedSchemaByPathSubform(
1198
+ options: GetEvaluatedSchemaByPathSubformOptions
1199
+ ): Promise<any | null> {
937
1200
  this.throwIfDisposed();
938
-
1201
+
939
1202
  const resultStr = await JsonEvalRs.getEvaluatedSchemaByPathSubform(
940
1203
  this.handle,
941
1204
  options.subformPath,
@@ -952,9 +1215,11 @@ export class JSONEval {
952
1215
  * @returns Promise resolving to data in the specified format
953
1216
  * @throws {Error} If operation fails
954
1217
  */
955
- async getEvaluatedSchemaByPathsSubform(options: GetEvaluatedSchemaByPathsSubformOptions): Promise<any> {
1218
+ async getEvaluatedSchemaByPathsSubform(
1219
+ options: GetEvaluatedSchemaByPathsSubformOptions
1220
+ ): Promise<any> {
956
1221
  this.throwIfDisposed();
957
-
1222
+
958
1223
  const pathsJson = JSON.stringify(options.schemaPaths);
959
1224
  const resultStr = await JsonEvalRs.getEvaluatedSchemaByPathsSubform(
960
1225
  this.handle,
@@ -973,7 +1238,7 @@ export class JSONEval {
973
1238
  */
974
1239
  async getSubformPaths(): Promise<string[]> {
975
1240
  this.throwIfDisposed();
976
-
1241
+
977
1242
  const resultStr = await JsonEvalRs.getSubformPaths(this.handle);
978
1243
  return JSON.parse(resultStr);
979
1244
  }
@@ -984,9 +1249,11 @@ export class JSONEval {
984
1249
  * @returns Promise resolving to value at path or null if not found
985
1250
  * @throws {Error} If operation fails
986
1251
  */
987
- async getSchemaByPathSubform(options: GetSchemaByPathSubformOptions): Promise<any | null> {
1252
+ async getSchemaByPathSubform(
1253
+ options: GetSchemaByPathSubformOptions
1254
+ ): Promise<any | null> {
988
1255
  this.throwIfDisposed();
989
-
1256
+
990
1257
  const resultStr = await JsonEvalRs.getSchemaByPathSubform(
991
1258
  this.handle,
992
1259
  options.subformPath,
@@ -1002,9 +1269,11 @@ export class JSONEval {
1002
1269
  * @returns Promise resolving to data in the specified format
1003
1270
  * @throws {Error} If operation fails
1004
1271
  */
1005
- async getSchemaByPathsSubform(options: GetSchemaByPathsSubformOptions): Promise<any> {
1272
+ async getSchemaByPathsSubform(
1273
+ options: GetSchemaByPathsSubformOptions
1274
+ ): Promise<any> {
1006
1275
  this.throwIfDisposed();
1007
-
1276
+
1008
1277
  const pathsJson = JSON.stringify(options.schemaPaths);
1009
1278
  const resultStr = await JsonEvalRs.getSchemaByPathsSubform(
1010
1279
  this.handle,
@@ -1023,7 +1292,7 @@ export class JSONEval {
1023
1292
  */
1024
1293
  async hasSubform(subformPath: string): Promise<boolean> {
1025
1294
  this.throwIfDisposed();
1026
-
1295
+
1027
1296
  return JsonEvalRs.hasSubform(this.handle, subformPath);
1028
1297
  }
1029
1298
 
@@ -1034,7 +1303,7 @@ export class JSONEval {
1034
1303
  */
1035
1304
  async dispose(): Promise<void> {
1036
1305
  if (this.disposed) return;
1037
-
1306
+
1038
1307
  await JsonEvalRs.dispose(this.handle);
1039
1308
  this.disposed = true;
1040
1309
  }
@@ -1052,20 +1321,20 @@ export class JSONEval {
1052
1321
  * Hook for using JSONEval in React components with automatic cleanup
1053
1322
  * @param options - Configuration options
1054
1323
  * @returns JSONEval instance or null if not yet initialized
1055
- *
1324
+ *
1056
1325
  * @example
1057
1326
  * ```typescript
1058
1327
  * import { useJSONEval } from '@json-eval-rs/react-native';
1059
- *
1328
+ *
1060
1329
  * function MyComponent() {
1061
1330
  * const eval = useJSONEval({ schema: mySchema });
1062
- *
1331
+ *
1063
1332
  * const handleValidate = async () => {
1064
1333
  * if (!eval) return;
1065
1334
  * const result = await eval.validate({ data: myData });
1066
1335
  * console.log(result);
1067
1336
  * };
1068
- *
1337
+ *
1069
1338
  * return <Button onPress={handleValidate} title="Validate" />;
1070
1339
  * }
1071
1340
  * ```