@sladg/apex-state 3.11.4 → 4.0.0

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 CHANGED
@@ -284,6 +284,269 @@ type BoolLogic<STATE, Depth extends number = DefaultDepth> = {
284
284
  CONTAINS_ALL: PathArrayElementsPair<STATE, Depth>;
285
285
  } | PathValuePair<STATE, Depth>;
286
286
 
287
+ type Stage = "input" | "aggregation_write" | "diff" | "sync" | "flip" | "clear_path" | "aggregation_read" | "computation" | "bool_logic" | "value_logic" | "listeners" | "apply";
288
+ type ChangeKind = "real" | "redundant" | "breakdown" | "consumed";
289
+ type ChangeContext = "Initial" | "Mutation";
290
+ type Lineage = "Input" | {
291
+ "Derived": {
292
+ parent_id: number;
293
+ via: Stage;
294
+ context: ChangeContext;
295
+ };
296
+ };
297
+ type SkipReason = "wrong_kind" | "guard_failed" | "redundant" | "anchor_missing";
298
+ type SkippedChange = {
299
+ path: string;
300
+ kind: ChangeKind;
301
+ reason: SkipReason;
302
+ /**
303
+ * Human-readable explanation of why this change was skipped.
304
+ */
305
+ detail: string;
306
+ /**
307
+ * Which registration owns the resource that was skipped (if applicable).
308
+ */
309
+ registration_id: string | null;
310
+ /**
311
+ * Anchor path that caused the skip (if applicable).
312
+ */
313
+ anchor_path: string | null;
314
+ };
315
+ type ProducedChange = {
316
+ path: string;
317
+ /**
318
+ * JSON-encoded value.
319
+ */
320
+ value: string;
321
+ /**
322
+ * Which registration produced this change (if traceable).
323
+ */
324
+ registration_id: string | null;
325
+ /**
326
+ * What input path caused this (e.g. sync source path).
327
+ */
328
+ source_path: string | null;
329
+ };
330
+ type ChangeAudit = {
331
+ source_path: string | null;
332
+ logic_id: number | null;
333
+ };
334
+ type Change$1 = {
335
+ path: string;
336
+ value_json: string;
337
+ /**
338
+ * Opaque JS meta object — carried through the pipeline unchanged.
339
+ * WASM never inspects the contents. Returned on listener_changes so JS
340
+ * meta survives the boundary without any stringify/parse.
341
+ */
342
+ meta: unknown | null;
343
+ /**
344
+ * Coarse classification: Real | Redundant | Breakdown | Consumed.
345
+ */
346
+ kind: ChangeKind;
347
+ /**
348
+ * Causal chain. Always set. Carries ChangeContext for stage routing.
349
+ */
350
+ lineage: Lineage;
351
+ /**
352
+ * Debug-mode only. None in production.
353
+ */
354
+ audit: ChangeAudit | null;
355
+ };
356
+ type StageTrace = {
357
+ stage: Stage;
358
+ duration_us: number;
359
+ /**
360
+ * Paths (with JSON-encoded values) that this stage processed.
361
+ */
362
+ matched: Array<[string, string]>;
363
+ skipped: Array<SkippedChange>;
364
+ /**
365
+ * Changes produced by this stage.
366
+ */
367
+ produced: Array<ProducedChange>;
368
+ followup: Array<StageTrace>;
369
+ };
370
+ type PipelineTrace = {
371
+ total_duration_us: number;
372
+ stages: Array<StageTrace>;
373
+ /**
374
+ * Anchor path → present? Gives display layer full context on anchor-dependent resources.
375
+ */
376
+ anchor_states: Record<string, boolean>;
377
+ };
378
+ type ValidatorDispatch = {
379
+ validator_id: number;
380
+ output_path: string;
381
+ dependency_values: Record<string, string>;
382
+ };
383
+ type GraphSnapshot = {
384
+ sync_pairs: Array<[string, string]>;
385
+ directed_sync_pairs: Array<[string, string]>;
386
+ flip_pairs: Array<[string, string]>;
387
+ listeners: Array<{
388
+ id: number;
389
+ topic: string;
390
+ scope: string;
391
+ }>;
392
+ bool_logics: Array<{
393
+ id: number;
394
+ output_path: string;
395
+ definition: {
396
+ "IS_EQUAL": [string, unknown];
397
+ } | {
398
+ "EXISTS": string;
399
+ } | {
400
+ "IS_EMPTY": string;
401
+ } | {
402
+ "AND": Array<BoolLogicNode>;
403
+ } | {
404
+ "OR": Array<BoolLogicNode>;
405
+ } | {
406
+ "NOT": BoolLogicNode;
407
+ } | {
408
+ "GT": [string, number];
409
+ } | {
410
+ "LT": [string, number];
411
+ } | {
412
+ "GTE": [string, number];
413
+ } | {
414
+ "LTE": [string, number];
415
+ } | {
416
+ "IN": [string, Array<unknown>];
417
+ } | {
418
+ "CONTAINS_ANY": [string, Array<unknown>];
419
+ } | {
420
+ "CONTAINS_ALL": [string, Array<unknown>];
421
+ };
422
+ }>;
423
+ value_logics: Array<{
424
+ id: number;
425
+ output_path: string;
426
+ }>;
427
+ aggregations: Array<{
428
+ target: string;
429
+ sources: Array<string>;
430
+ }>;
431
+ computations: Array<{
432
+ target: string;
433
+ op: string;
434
+ sources: Array<string>;
435
+ }>;
436
+ };
437
+ type SideEffectsResult$1 = {
438
+ sync_changes: Array<Change$1>;
439
+ aggregation_changes: Array<Change$1>;
440
+ computation_changes: Array<Change$1>;
441
+ registered_listener_ids: Array<number>;
442
+ };
443
+ type ListenerRegistration$1 = {
444
+ subscriber_id: number;
445
+ topic_paths: Array<string>;
446
+ scope_path: string;
447
+ anchor_path?: string;
448
+ };
449
+ type SideEffectsRegistration = {
450
+ registration_id: string;
451
+ sync_pairs: Array<[string, string]>;
452
+ /**
453
+ * One-way sync pairs: source → target only. Changes to target do NOT propagate back to source.
454
+ */
455
+ directed_sync_pairs: Array<[string, string]>;
456
+ flip_pairs: Array<[string, string]>;
457
+ aggregation_pairs: Array<[string, string] | [string, string, string]>;
458
+ clear_paths: Array<{
459
+ triggers: Array<string>;
460
+ targets: Array<string>;
461
+ }>;
462
+ computation_pairs: Array<[string, string, string] | [string, string, string, string]>;
463
+ listeners: Array<ListenerRegistration$1>;
464
+ anchor_path?: string;
465
+ };
466
+ type BoolLogicRegistration = {
467
+ output_path: string;
468
+ tree_json: string;
469
+ };
470
+ type ValueLogicRegistration = {
471
+ output_path: string;
472
+ tree_json: string;
473
+ };
474
+ type ValidatorRegistration = {
475
+ validator_id: number;
476
+ output_path: string;
477
+ dependency_paths: Array<string>;
478
+ };
479
+ type ConcernsRegistration = {
480
+ /**
481
+ * Used by JS for unregister tracking; not consumed by Rust pipeline logic.
482
+ */
483
+ registration_id: string;
484
+ bool_logics: Array<BoolLogicRegistration>;
485
+ validators: Array<ValidatorRegistration>;
486
+ value_logics: Array<ValueLogicRegistration>;
487
+ anchor_path?: string;
488
+ };
489
+ type FullExecutionPlan = {
490
+ /**
491
+ * Sequential groups of dispatches (flattened from depth levels + batches).
492
+ */
493
+ groups: Array<{
494
+ dispatches: Array<{
495
+ dispatch_id: number;
496
+ subscriber_id: number;
497
+ scope_path: string;
498
+ topic_path: string;
499
+ /**
500
+ * Indexes into the PrepareResult.listener_changes array.
501
+ */
502
+ input_change_ids: Array<number>;
503
+ }>;
504
+ }>;
505
+ /**
506
+ * propagation_map[dispatch_id] = targets to forward produced changes to.
507
+ * Flat array indexed by dispatch_id, empty vec = no propagation.
508
+ */
509
+ propagation_map: Array<Array<{
510
+ target_dispatch_id: number;
511
+ /**
512
+ * Prefix to prepend to child's relative paths for the target's scope.
513
+ */
514
+ remap_prefix: string;
515
+ }>>;
516
+ /**
517
+ * cascade_map[dispatch_id] = sibling dispatch_ids (same group, later position)
518
+ * that should receive this dispatch's produced changes.
519
+ */
520
+ cascade_map: Array<Array<number>>;
521
+ };
522
+ type BoolLogicNode = {
523
+ "IS_EQUAL": [string, unknown];
524
+ } | {
525
+ "EXISTS": string;
526
+ } | {
527
+ "IS_EMPTY": string;
528
+ } | {
529
+ "AND": Array<BoolLogicNode>;
530
+ } | {
531
+ "OR": Array<BoolLogicNode>;
532
+ } | {
533
+ "NOT": BoolLogicNode;
534
+ } | {
535
+ "GT": [string, number];
536
+ } | {
537
+ "LT": [string, number];
538
+ } | {
539
+ "GTE": [string, number];
540
+ } | {
541
+ "LTE": [string, number];
542
+ } | {
543
+ "IN": [string, Array<unknown>];
544
+ } | {
545
+ "CONTAINS_ANY": [string, Array<unknown>];
546
+ } | {
547
+ "CONTAINS_ALL": [string, Array<unknown>];
548
+ };
549
+
287
550
  /**
288
551
  * GenericMeta interface
289
552
  *
@@ -336,9 +599,14 @@ interface GenericMeta {
336
599
  isComputationChange?: boolean;
337
600
  /**
338
601
  * Identifies the originator of the change.
339
- * Can be a user ID, component name, or any identifier string.
602
+ * Can be a user ID, component name, listener function name, or any identifier string.
340
603
  */
341
604
  sender?: string;
605
+ /**
606
+ * The pipeline stage that produced this change (e.g., 'sync', 'flip', 'aggregation_write', 'listeners').
607
+ * Used for debugging to understand the source of a change.
608
+ */
609
+ stage?: string;
342
610
  }
343
611
 
344
612
  /**
@@ -371,6 +639,13 @@ interface GenericMeta {
371
639
  type ArrayOfChanges<DATA, META extends GenericMeta = GenericMeta> = {
372
640
  [K in DeepKey<DATA>]: [K, DeepValue<DATA, K>, META] | [K, DeepValue<DATA, K>];
373
641
  }[DeepKey<DATA>][];
642
+ /** A single state change in internal pipeline form. */
643
+ interface Change {
644
+ path: string;
645
+ value: unknown;
646
+ /** Meta object threaded through the pipeline. Lineage is merged in by the bridge on WASM→JS conversion. */
647
+ meta: GenericMeta;
648
+ }
374
649
 
375
650
  /**
376
651
  * Concern type utilities
@@ -669,16 +944,28 @@ type PathsWithSameValueAs<DATA extends object, PATH extends ResolvableDeepKey<DA
669
944
  }[ResolvableDeepKey<DATA, Depth>];
670
945
  /**
671
946
  * A tuple of two paths that must have the same value type.
672
- * Format: [path1, path2]
947
+ * Format: [path1, path2] or [path1, path2, { oneWay: '[0]->[1]' | '[1]->[0]' }]
948
+ *
949
+ * `oneWay` makes sync unidirectional. The value declares the direction explicitly:
950
+ * - `'[0]->[1]'` — first path pushes to second path (left → right)
951
+ * - `'[1]->[0]'` — second path pushes to first path (right → left)
952
+ *
953
+ * Without the option, sync is bidirectional.
673
954
  *
674
955
  * **Scaling note**: This type is O(N²) where N = number of paths. It hits TS2589
675
956
  * at ~1,500 paths. For large state types, use the `syncPairs()` helper function
676
957
  * or `store.syncPairs()` (pre-warmed from `createGenericStore`) instead —
677
958
  * they scale to ~50K–80K paths.
678
959
  *
679
- * @example
960
+ * @example Bidirectional
680
961
  * const pair: SyncPair<State> = ['user.email', 'profile.email']
681
962
  *
963
+ * @example One-way: user.email → profile.email only
964
+ * const pair: SyncPair<State> = ['user.email', 'profile.email', { oneWay: '[0]->[1]' }]
965
+ *
966
+ * @example One-way: profile.email → user.email only (reversed direction)
967
+ * const pair: SyncPair<State> = ['user.email', 'profile.email', { oneWay: '[1]->[0]' }]
968
+ *
682
969
  * @example Custom depth — propagates to DeepKey and PathsWithSameValueAs
683
970
  * ```typescript
684
971
  * // Limit path traversal to 10 levels
@@ -686,13 +973,16 @@ type PathsWithSameValueAs<DATA extends object, PATH extends ResolvableDeepKey<DA
686
973
  * ```
687
974
  */
688
975
  type SyncPair<DATA extends object, Depth extends number = DefaultDepth> = {
689
- [P1 in ResolvableDeepKey<DATA, Depth>]: [
976
+ [P1 in ResolvableDeepKey<DATA, Depth>]: [P1, PathsWithSameValueAs<DATA, P1, Depth>] | [
690
977
  P1,
691
- PathsWithSameValueAs<DATA, P1, Depth>
978
+ PathsWithSameValueAs<DATA, P1, Depth>,
979
+ {
980
+ oneWay: '[0]->[1]' | '[1]->[0]';
981
+ }
692
982
  ];
693
983
  }[ResolvableDeepKey<DATA, Depth>];
694
984
  /**
695
- * A tuple of two paths for flip (alias for SyncPair).
985
+ * A tuple of two paths for flip. Always bidirectional: path1 ↔ path2 (inverted values).
696
986
  * Format: [path1, path2]
697
987
  *
698
988
  * **Scaling note**: O(N²) — hits TS2589 at ~1,500 paths. Use `flipPairs()` helper
@@ -701,7 +991,12 @@ type SyncPair<DATA extends object, Depth extends number = DefaultDepth> = {
701
991
  * @example
702
992
  * const pair: FlipPair<State> = ['isActive', 'isInactive']
703
993
  */
704
- type FlipPair<DATA extends object, Depth extends number = DefaultDepth> = SyncPair<DATA, Depth>;
994
+ type FlipPair<DATA extends object, Depth extends number = DefaultDepth> = {
995
+ [P1 in ResolvableDeepKey<DATA, Depth>]: [
996
+ P1,
997
+ PathsWithSameValueAs<DATA, P1, Depth>
998
+ ];
999
+ }[ResolvableDeepKey<DATA, Depth>];
705
1000
  /**
706
1001
  * A tuple for aggregation: [target, source] or [target, source, excludeWhen]
707
1002
  * First element (left) is ALWAYS the target (aggregated) path.
@@ -779,13 +1074,24 @@ type CheckPairValueMatch<DATA extends object, P1 extends string, P2 extends stri
779
1074
  NonNullable<DeepValue<DATA, P1>>
780
1075
  ] ? [P1, P2] : [P1, never] : [P1, never] : never : never;
781
1076
  /**
782
- * Validates an array of [P1, P2] sync/flip pairs lazily — O(K) where K = pairs written.
1077
+ * Validates an array of sync/flip pairs lazily — O(K) where K = pairs written.
1078
+ * Accepts [P1, P2] or [P1, P2, { oneWay: '[0]->[1]' | '[1]->[0]' }].
1079
+ * The optional third element declares direction — does not affect value type validation.
783
1080
  */
784
- type CheckSyncPairs<DATA extends object, T extends readonly [string, string][], Depth extends number = DefaultDepth> = {
1081
+ type CheckSyncPairs<DATA extends object, T extends readonly ([string, string] | [string, string, {
1082
+ oneWay: '[0]->[1]' | '[1]->[0]';
1083
+ }])[], Depth extends number = DefaultDepth> = {
785
1084
  [I in keyof T]: T[I] extends [
786
1085
  infer P1 extends string,
787
- infer P2 extends string
788
- ] ? CheckPairValueMatch<DATA, P1, P2, Depth> : T[I];
1086
+ infer P2 extends string,
1087
+ {
1088
+ oneWay: '[0]->[1]' | '[1]->[0]';
1089
+ }
1090
+ ] ? CheckPairValueMatch<DATA, P1, P2, Depth> extends [P1, P2] ? [P1, P2, {
1091
+ oneWay: '[0]->[1]' | '[1]->[0]';
1092
+ }] : [P1, never, {
1093
+ oneWay: '[0]->[1]' | '[1]->[0]';
1094
+ }] : T[I] extends [infer P1 extends string, infer P2 extends string] ? CheckPairValueMatch<DATA, P1, P2, Depth> : T[I];
789
1095
  };
790
1096
  /**
791
1097
  * Validates that two paths both resolve to number.
@@ -851,10 +1157,9 @@ type DeepPartial<T> = T extends (infer U)[] ? DeepPartial<U>[] : T extends reado
851
1157
  declare const VALIDATED: unique symbol;
852
1158
  declare const STORE_DATA: unique symbol;
853
1159
  /** Pre-validated sync pair array. Returned by `syncPairs()`. Branded with DATA to prevent cross-store use. */
854
- type ValidatedSyncPairs<DATA extends object = object> = [
855
- string,
856
- string
857
- ][] & {
1160
+ type ValidatedSyncPairs<DATA extends object = object> = ([string, string] | [string, string, {
1161
+ oneWay: '[0]->[1]' | '[1]->[0]';
1162
+ }])[] & {
858
1163
  [VALIDATED]: 'sync';
859
1164
  [STORE_DATA]: DATA;
860
1165
  };
@@ -905,57 +1210,6 @@ interface ConcernRegistration {
905
1210
  dispose: () => void;
906
1211
  }
907
1212
 
908
- /**
909
- * Pipeline Observer — Unified debug logging + Redux DevTools integration.
910
- *
911
- * Single interface that dispatches to:
912
- * - Console logging (controlled by logPipeline / logListeners / logConcerns flags)
913
- * - Redux DevTools (controlled by devtools flag) with nested tree-shaped state
914
- *
915
- * Call sites use one `observer.xyz()` call; the observer fans out internally.
916
- * Zero runtime cost when all flags are false (returns no-op object).
917
- */
918
-
919
- interface PipelineObserver {
920
- pipelineStart: (label: string, input: unknown[]) => void;
921
- phase1: (stateChanges: unknown[]) => void;
922
- syncExpand: (changes: unknown[]) => void;
923
- flipExpand: (changes: unknown[]) => void;
924
- listenerDispatch: (subscriberId: number, fnName: string, scope: string, input: unknown[], output: unknown) => void;
925
- validatorResult: (outputPath: string, input: unknown, result: unknown) => void;
926
- phase2: (stateChanges: unknown[]) => void;
927
- pipelineEnd: () => void;
928
- concernEval: (path: string, name: string, value: unknown, result: unknown) => void;
929
- destroy: () => void;
930
- }
931
- interface DevToolsInstance {
932
- init: (state: unknown) => void;
933
- send: (action: {
934
- type: string;
935
- }, state: unknown) => void;
936
- unsubscribe: () => void;
937
- }
938
- interface DevToolsRef {
939
- prefix: string;
940
- pipeline: DevToolsInstance | null;
941
- }
942
-
943
- /**
944
- * Debug Timing Utilities
945
- *
946
- * Provides timing measurement for concerns and listeners
947
- * to detect slow operations during development.
948
- */
949
- type TimingType = 'concerns' | 'listeners' | 'registration';
950
- interface TimingMeta {
951
- path: string;
952
- name: string;
953
- }
954
- interface Timing {
955
- run: <T>(type: TimingType, fn: () => T, meta: TimingMeta) => T;
956
- reportBatch: (type: TimingType) => void;
957
- }
958
-
959
1213
  /**
960
1214
  * WASM Bridge — Thin namespace over Rust/WASM exports.
961
1215
  *
@@ -970,211 +1224,132 @@ interface Timing {
970
1224
  * @module wasm/bridge
971
1225
  */
972
1226
 
973
- /** A single state change (input or output). */
974
- interface Change {
975
- path: string;
976
- value: unknown;
977
- origin?: string;
978
- }
979
- /** A single dispatch entry with sequential ID and input change references. */
980
- interface DispatchEntry {
981
- dispatch_id: number;
982
- subscriber_id: number;
983
- scope_path: string;
984
- topic_path: string;
985
- /** Indexes into ProcessResult.changes array. */
986
- input_change_ids: number[];
987
- }
988
- /** A group of dispatches to execute sequentially. */
989
- interface DispatchGroup {
990
- dispatches: DispatchEntry[];
991
- }
992
- /** A target for propagating produced changes from child to parent dispatch. */
993
- interface PropagationTarget {
994
- target_dispatch_id: number;
995
- /** Prefix to prepend to child's relative paths for the target's scope. */
996
- remap_prefix: string;
997
- }
998
- /** Pre-computed execution plan with propagation map. */
999
- interface FullExecutionPlan {
1000
- groups: DispatchGroup[];
1001
- /** propagation_map[dispatch_id] = targets to forward produced changes to. */
1002
- propagation_map: PropagationTarget[][];
1003
- }
1004
- /** Validator dispatch info for JS-side execution. */
1005
- interface ValidatorDispatch {
1006
- validator_id: number;
1007
- output_path: string;
1008
- dependency_values: Record<string, string>;
1009
- }
1010
- /**
1011
- * Extends a base tuple with an optional trailing BoolLogic condition (JSON-serialized).
1012
- * Used by aggregation and computation pairs to share the "optional excludeWhen" pattern.
1013
- */
1014
- type WasmPairWithCondition<Base extends [...string[]]> = [...Base] | [...Base, condition: string];
1015
- /** WASM-side aggregation pair: [target, source] with optional excludeWhen condition. */
1016
- type WasmAggregationPair = WasmPairWithCondition<[
1017
- target: string,
1018
- source: string
1019
- ]>;
1020
- /** WASM-side computation pair: [operation, target, source] with optional excludeWhen condition. */
1021
- type WasmComputationPair = WasmPairWithCondition<[
1022
- op: string,
1023
- target: string,
1024
- source: string
1025
- ]>;
1026
- /** WASM-side sync pair: [source, target] — bidirectional sync. */
1027
- type WasmSyncPair = [source: string, target: string];
1028
- /** WASM-side flip pair: [source, target] — inverted boolean sync. */
1029
- type WasmFlipPair = [source: string, target: string];
1030
- /** WASM-side clear path rule: trigger paths → target paths to null. */
1031
- interface WasmClearPathRule {
1032
- triggers: string[];
1033
- targets: string[];
1034
- }
1035
- /** WASM-side listener entry for topic-based dispatch. */
1036
- interface WasmListenerEntry {
1037
- subscriber_id: number;
1038
- topic_path: string;
1039
- scope_path: string;
1040
- }
1041
- /** Consolidated registration input for side effects (sync, flip, aggregation, computation, clear, listeners). */
1042
- interface SideEffectsRegistration {
1043
- registration_id: string;
1044
- sync_pairs?: WasmSyncPair[];
1045
- flip_pairs?: WasmFlipPair[];
1046
- aggregation_pairs?: WasmAggregationPair[];
1047
- computation_pairs?: WasmComputationPair[];
1048
- clear_paths?: WasmClearPathRule[];
1049
- listeners?: WasmListenerEntry[];
1050
- }
1051
- /** Consolidated registration output from side effects registration. */
1052
- interface SideEffectsResult {
1053
- sync_changes: Change[];
1054
- aggregation_changes: Change[];
1055
- computation_changes: Change[];
1056
- registered_listener_ids: number[];
1057
- }
1058
- /** WASM-side BoolLogic entry for declarative boolean evaluation. */
1059
- interface WasmBoolLogicEntry {
1060
- output_path: string;
1061
- tree_json: string;
1062
- }
1063
- /** WASM-side validator entry for validation orchestration. */
1064
- interface WasmValidatorEntry {
1065
- validator_id: number;
1066
- output_path: string;
1067
- dependency_paths: string[];
1068
- scope: string;
1069
- }
1070
- /** WASM-side ValueLogic entry for declarative value computation. */
1071
- interface WasmValueLogicEntry {
1072
- output_path: string;
1073
- tree_json: string;
1074
- }
1075
- /** Consolidated registration input for concerns (BoolLogic, validators, and ValueLogic). */
1076
- interface ConcernsRegistration {
1077
- registration_id: string;
1078
- bool_logics?: WasmBoolLogicEntry[];
1079
- validators?: WasmValidatorEntry[];
1080
- value_logics?: WasmValueLogicEntry[];
1081
- }
1082
- /** Consolidated registration output from concerns registration. */
1083
- interface ConcernsResult {
1084
- bool_logic_changes: Change[];
1085
- registered_logic_ids: number[];
1086
- registered_validator_ids: number[];
1087
- value_logic_changes: Change[];
1088
- registered_value_logic_ids: number[];
1089
- }
1090
- /** Result of processChanges (Phase 1). */
1091
- interface ProcessChangesResult {
1092
- state_changes: Change[];
1093
- changes: Change[];
1094
- validators_to_run: ValidatorDispatch[];
1095
- execution_plan: FullExecutionPlan | null;
1096
- has_work: boolean;
1097
- }
1098
- /**
1099
- * An isolated WASM pipeline instance.
1100
- * Each store gets its own pipeline so multiple Providers don't interfere.
1101
- * All methods are pre-bound to the pipeline's ID — consumers never pass IDs.
1102
- */
1103
- interface WasmPipeline {
1104
- readonly id: number;
1227
+ /** Map a Wasm wire result type to JS-facing type: Wasm.Change[] → Change[], rest untouched. */
1228
+ type WireToJs<T> = {
1229
+ [K in keyof T]: T[K] extends Change$1[] ? Change[] : T[K];
1230
+ };
1231
+ /** JS-facing side effects result — same shape as Wasm wire type but with parsed Change values. */
1232
+ type SideEffectsResult = WireToJs<SideEffectsResult$1>;
1233
+ /**
1234
+ * Create a new isolated WASM pipeline instance.
1235
+ * Each store should call this once and store the result.
1236
+ * Call pipeline.destroy() on cleanup.
1237
+ */
1238
+ declare const createWasmPipeline: (options?: {
1239
+ debug?: boolean;
1240
+ }) => {
1241
+ id: number;
1242
+ readonly destroyed: boolean;
1105
1243
  shadowInit: (state: object) => void;
1106
1244
  shadowDump: () => unknown;
1107
- processChanges: (changes: Change[]) => ProcessChangesResult;
1108
- pipelineFinalize: (jsChanges: Change[]) => {
1245
+ processChanges: (changes: Change[]) => {
1246
+ listener_changes: Change[];
1247
+ validators_to_run: ValidatorDispatch[];
1248
+ execution_plan: FullExecutionPlan | null;
1249
+ has_work: boolean;
1250
+ };
1251
+ pipelineFinalize: (changes: Change[]) => {
1109
1252
  state_changes: Change[];
1253
+ trace: PipelineTrace | null;
1254
+ };
1255
+ registerSideEffects: (reg: Partial<SideEffectsRegistration>) => {
1256
+ sync_changes: Change[];
1257
+ aggregation_changes: Change[];
1258
+ computation_changes: Change[];
1259
+ registered_listener_ids: number[];
1110
1260
  };
1111
- registerSideEffects: (reg: SideEffectsRegistration) => SideEffectsResult;
1112
1261
  unregisterSideEffects: (registrationId: string) => void;
1113
- registerConcerns: (reg: ConcernsRegistration) => ConcernsResult;
1262
+ registerConcerns: (reg: Partial<ConcernsRegistration>) => {
1263
+ bool_logic_changes: Change[];
1264
+ registered_logic_ids: number[];
1265
+ registered_validator_ids: number[];
1266
+ value_logic_changes: Change[];
1267
+ registered_value_logic_ids: number[];
1268
+ };
1114
1269
  unregisterConcerns: (registrationId: string) => void;
1115
1270
  registerBoolLogic: (outputPath: string, tree: unknown) => number;
1116
1271
  unregisterBoolLogic: (logicId: number) => void;
1117
1272
  pipelineReset: () => void;
1118
1273
  destroy: () => void;
1119
- /** Per-instance storage for validation schemas (can't cross WASM boundary). */
1120
- validatorSchemas: Map<number, ValidationSchema>;
1121
- }
1274
+ getGraphSnapshot: () => GraphSnapshot;
1275
+ validatorSchemas: Map<number, ValidationSchema<unknown>>;
1276
+ };
1277
+ type WasmPipeline = ReturnType<typeof createWasmPipeline>;
1122
1278
 
1123
1279
  /**
1124
- * PathGroups Data Structure
1125
- *
1126
- * A custom data structure that provides O(1) connected component lookups
1127
- * instead of O(V+E) recomputation on every change like graphology's connectedComponents.
1280
+ * Apex State Logger — Simplified debug logging with colored console output.
1128
1281
  *
1129
- * When wasmGraphType is set ('sync' | 'flip'), addEdge/removeEdge automatically
1130
- * mirror registrations to WASM bridge for pipeline processing.
1131
- *
1132
- * Operations complexity:
1133
- * - getAllGroups(): O(G) where G is number of groups (typically small)
1134
- * - getGroupPaths(path): O(1) lookup
1135
- * - addEdge(p1, p2): O(n) where n is smaller group size (merge)
1136
- * - removeEdge(p1, p2): O(n) for affected component
1137
- * - hasPath(path): O(1)
1138
- * - hasEdge(p1, p2): O(1)
1139
- */
1140
- /** Graph type for WASM mirroring. When set, addEdge/removeEdge mirror to WASM. */
1141
- type WasmGraphType = 'sync' | 'flip';
1142
- /**
1143
- * PathGroups maintains connected components with O(1) lookups.
1282
+ * Two log functions:
1283
+ * 1. logPipeline called once per processChanges with unified trace
1284
+ * 2. logRegistration — called once per register/unregister with graph snapshot
1144
1285
  *
1145
- * Internal structure:
1146
- * - pathToGroup: Maps each path to its group ID
1147
- * - groupToPaths: Maps each group ID to the set of paths in that group
1148
- * - edges: Set of edge keys for edge existence checks and proper removal
1149
- * - adjacency: Maps each path to its direct neighbors (for split detection on removal)
1150
- * - nextGroupId: Counter for generating unique group IDs
1286
+ * Zero runtime cost when log flag is false (returns no-op logger).
1151
1287
  */
1152
- interface PathGroups {
1153
- pathToGroup: Map<string, number>;
1154
- groupToPaths: Map<number, Set<string>>;
1155
- edges: Set<string>;
1156
- adjacency: Map<string, Set<string>>;
1157
- nextGroupId: number;
1158
- wasmGraphType?: WasmGraphType;
1288
+
1289
+ /** Per-listener dispatch trace (JS-measured). */
1290
+ interface ListenerDispatchTrace {
1291
+ dispatchId: number;
1292
+ subscriberId: number;
1293
+ fnName: string;
1294
+ scope: string;
1295
+ topic: string;
1296
+ registrationId: string;
1297
+ input: [string, unknown, unknown][];
1298
+ output: Change[];
1299
+ currentState: unknown;
1300
+ durationMs: number;
1301
+ slow: boolean;
1302
+ }
1303
+ /** Universal trace — single object for console, devtools, any observability tool. */
1304
+ interface UnifiedPipelineTrace {
1305
+ wasm: PipelineTrace;
1306
+ listeners: ListenerDispatchTrace[];
1307
+ totalDurationMs: number;
1308
+ wasmDurationMs: number;
1309
+ listenerDurationMs: number;
1310
+ /** True when listener timing was actually measured (debug.timing: true). False → show N/A. */
1311
+ listenerTimingEnabled: boolean;
1312
+ }
1313
+ interface PipelineLogData {
1314
+ initialChanges: Change[];
1315
+ trace: UnifiedPipelineTrace | null;
1316
+ /** Pre-finalize changes: listener output + validator output before WASM merge/dedup. */
1317
+ preFinalizableChanges?: Change[];
1318
+ /** Final applied changes: after WASM finalization, partitioned to state + concerns. */
1319
+ appliedChanges?: Change[];
1320
+ /** Frozen valtio snapshot of state after all changes applied. */
1321
+ stateSnapshot?: unknown;
1322
+ }
1323
+ interface RegistrationLogData {
1324
+ result?: SideEffectsResult;
1325
+ appliedChanges?: Change[];
1326
+ stateSnapshot?: unknown;
1327
+ durationMs?: number;
1328
+ /** subscriber_id → function name, for enriching listener entries in the log. */
1329
+ listenerNames?: Map<number, string>;
1330
+ }
1331
+ interface ApexLogger {
1332
+ logPipeline: (data: PipelineLogData) => void;
1333
+ logRegistration: (type: 'register' | 'unregister', id: string, snapshot: GraphSnapshot, data?: RegistrationLogData) => void;
1334
+ destroy: () => void;
1159
1335
  }
1160
1336
 
1161
1337
  /**
1162
- * Graph Type Definitions
1338
+ * Valtio DevTools — Connects state and concerns proxies to Redux DevTools,
1339
+ * and provides a pipeline notifier for sending pipeline/registration events.
1340
+ *
1341
+ * Uses valtio/utils devtools() to expose both proxies as separate DevTools instances:
1342
+ * - '{prefix}:state' — application state proxy
1343
+ * - '{prefix}:concerns' — computed concern values proxy
1163
1344
  *
1164
- * Type aliases for the PathGroups data structure used in sync and flip operations.
1165
- * These aliases maintain backward compatibility with the previous graphology-based API.
1345
+ * Singleton connections per proxy survives StrictMode remounts and HMR reloads.
1166
1346
  */
1167
1347
 
1168
- /**
1169
- * Sync graph: Paths that must have synchronized values
1170
- * Type alias for PathGroups - maintains backward compatibility
1171
- */
1172
- type SyncGraph = PathGroups;
1173
- /**
1174
- * Flip graph: Paths with inverted boolean values
1175
- * Type alias for PathGroups - maintains backward compatibility
1176
- */
1177
- type FlipGraph = PathGroups;
1348
+ interface DevToolsNotifier {
1349
+ notifyPipeline: (data: PipelineLogData) => void;
1350
+ notifyRegistration: (type: 'register' | 'unregister', id: string, snapshot: GraphSnapshot) => void;
1351
+ destroy: () => void;
1352
+ }
1178
1353
 
1179
1354
  /**
1180
1355
  * Core Store Types
@@ -1187,18 +1362,14 @@ type FlipGraph = PathGroups;
1187
1362
  * Debug configuration for development tooling
1188
1363
  */
1189
1364
  interface DebugConfig {
1190
- /** Enable timing measurement for concerns and listeners */
1365
+ /** Enable console logging for pipeline runs and registrations */
1366
+ log?: boolean;
1367
+ /** Enable timing warnings for slow listeners */
1191
1368
  timing?: boolean;
1192
- /** Threshold in milliseconds for slow operation warnings (default: 5ms) */
1369
+ /** Threshold in milliseconds for slow listener warnings (default: 5ms) */
1193
1370
  timingThreshold?: number;
1194
1371
  /** Enable tracking of processChanges calls and applied changes for testing/debugging */
1195
1372
  track?: boolean;
1196
- /** Log pipeline phases, state changes, sync/flip expansions */
1197
- logPipeline?: boolean;
1198
- /** Log listener dispatch inputs and outputs */
1199
- logListeners?: boolean;
1200
- /** Log concern evaluations and validator runs */
1201
- logConcerns?: boolean;
1202
1373
  /** Connect to Redux DevTools Extension for state inspection */
1203
1374
  devtools?: boolean;
1204
1375
  }
@@ -1240,8 +1411,6 @@ interface StoreConfig {
1240
1411
  maxIterations?: number;
1241
1412
  /** Debug configuration for development tooling */
1242
1413
  debug?: DebugConfig;
1243
- /** Use legacy TypeScript implementation instead of WASM (default: false) */
1244
- useLegacyImplementation?: boolean;
1245
1414
  }
1246
1415
  interface ProviderProps<DATA extends object> {
1247
1416
  initialState: DATA;
@@ -1306,12 +1475,18 @@ type OnStateListener<DATA extends object = object, SUB_STATE = DATA, META extend
1306
1475
  * }
1307
1476
  * ```
1308
1477
  */
1309
- interface ListenerRegistration<DATA extends object = object, META extends GenericMeta = GenericMeta, Depth extends number = DefaultDepth> {
1478
+ /**
1479
+ * Single-path listener — watches one path (or all paths when null).
1480
+ * `scope` may be omitted (defaults to `path`).
1481
+ */
1482
+ interface SinglePathListener<DATA extends object = object, META extends GenericMeta = GenericMeta, Depth extends number = DefaultDepth> {
1310
1483
  /**
1311
- * Path to watch - only changes under this path will trigger the listener
1312
- * null = watch all paths (receives every change)
1484
+ * Path to watch - only changes under this path will trigger the listener.
1485
+ * null = watch all paths (receives every change).
1486
+ * Array = watch multiple paths; listener fires once per run when any match,
1487
+ * receiving all matching changes merged into a single input array.
1313
1488
  */
1314
- path: DeepKey<DATA, Depth> | null;
1489
+ path: DeepKey<DATA, Depth> | DeepKey<DATA, Depth>[] | null;
1315
1490
  /**
1316
1491
  * Scope for state and changes presentation
1317
1492
  * - If omitted/undefined: defaults to `path` (scoped state matching the watched path)
@@ -1323,48 +1498,55 @@ interface ListenerRegistration<DATA extends object = object, META extends Generi
1323
1498
  scope?: DeepKey<DATA, Depth> | null;
1324
1499
  fn: OnStateListener<DATA, any, META>;
1325
1500
  }
1501
+ /**
1502
+ * Multi-path listener — watches multiple paths simultaneously.
1503
+ * Handler fires once per pipeline run with all matched changes merged.
1504
+ * `scope` is required (use null for full paths).
1505
+ */
1506
+ interface MultiPathListener<DATA extends object = object, META extends GenericMeta = GenericMeta, Depth extends number = DefaultDepth> {
1507
+ /**
1508
+ * Array of paths to watch. Handler fires once with changes from any matched path.
1509
+ */
1510
+ path: DeepKey<DATA, Depth>[];
1511
+ /**
1512
+ * Scope for state and changes presentation (required for multi-path listeners).
1513
+ * - null: state is full DATA, changes use FULL paths
1514
+ * - string: state is value at scope, changes use paths RELATIVE to scope
1515
+ */
1516
+ scope: DeepKey<DATA, Depth> | null;
1517
+ fn: OnStateListener<DATA, any, META>;
1518
+ }
1519
+ /** Listener registration — single-path or multi-path. */
1520
+ type ListenerRegistration<DATA extends object = object, META extends GenericMeta = GenericMeta, Depth extends number = DefaultDepth> = SinglePathListener<DATA, META, Depth> | MultiPathListener<DATA, META, Depth>;
1326
1521
  interface ListenerHandlerRef {
1327
1522
  scope: string | null;
1328
- fn: (...args: unknown[]) => unknown;
1329
- }
1330
- interface SideEffectGraphs<DATA extends object = object, META extends GenericMeta = GenericMeta> {
1331
- sync: SyncGraph;
1332
- flip: FlipGraph;
1333
- listeners: Map<string, ListenerRegistration<DATA, META>[]>;
1334
- sortedListenerPaths: string[];
1335
- /** O(1) lookup: subscriber_id -> handler ref. Populated by registerListener. */
1336
- listenerHandlers: Map<number, ListenerHandlerRef>;
1523
+ fn: (...args: any[]) => unknown;
1524
+ name: string;
1525
+ registrationId: string;
1337
1526
  }
1338
1527
  interface Registrations {
1339
1528
  concerns: Map<string, ConcernType[]>;
1340
1529
  effectCleanups: Set<() => void>;
1341
1530
  sideEffectCleanups: Map<string, () => void>;
1342
- aggregations: Map<string, Aggregation[]>;
1343
- }
1344
- interface ProcessingState<DATA extends object = object, META extends GenericMeta = GenericMeta> {
1345
- queue: ArrayOfChanges<DATA, META>;
1531
+ /** O(1) lookup: subscriber_id -> handler ref. Populated by registerListener. */
1532
+ listenerHandlers: Map<number, ListenerHandlerRef>;
1346
1533
  }
1347
1534
  /** Internal store state (NOT tracked - wrapped in ref()) */
1348
- interface InternalState<DATA extends object = object, META extends GenericMeta = GenericMeta> {
1349
- graphs: SideEffectGraphs<DATA, META>;
1535
+ interface InternalState {
1350
1536
  registrations: Registrations;
1351
- processing: ProcessingState<DATA, META>;
1352
- timing: Timing;
1353
- observer: PipelineObserver;
1354
1537
  config: DeepRequired<StoreConfig>;
1355
- /** Redux DevTools state — prefix for naming + shared connection instance. */
1356
- _devtools: DevToolsRef;
1357
- /** Per-store WASM pipeline instance (null when using legacy implementation). */
1538
+ logger: ApexLogger;
1539
+ /** DevTools — pipeline notifier + proxy inspection. Null when devtools disabled. */
1540
+ devtools: DevToolsNotifier | null;
1541
+ /** Per-store WASM pipeline instance (null after destroy). */
1358
1542
  pipeline: WasmPipeline | null;
1359
- /** Pending deferred destroy timer — cancelled on StrictMode re-mount. */
1360
- _destroyTimer?: ReturnType<typeof setTimeout> | undefined;
1361
1543
  }
1362
1544
  type ConcernValues = Record<string, Record<string, unknown>>;
1363
1545
  /** Two-proxy pattern: state and _concerns are independent to prevent infinite loops */
1364
- interface StoreInstance<DATA extends object, META extends GenericMeta = GenericMeta> {
1546
+ interface StoreInstance<DATA extends object> {
1365
1547
  state: DATA;
1366
1548
  _concerns: ConcernValues;
1367
- _internal: InternalState<DATA, META>;
1549
+ _internal: InternalState;
1368
1550
  /** Debug tracking data, only populated when debug.track is enabled */
1369
1551
  _debug: DebugTrack | null;
1370
1552
  }
@@ -1701,6 +1883,13 @@ interface SideEffects<DATA extends object, META extends GenericMeta = GenericMet
1701
1883
  * Accepts direct `ListenerRegistration<T>[]` or pre-validated result from `listeners()`.
1702
1884
  */
1703
1885
  listeners?: ListenerRegistration<DATA, META>[];
1886
+ /**
1887
+ * Anchor path - guard for all resources in this registration.
1888
+ * When the anchor path is structurally absent from shadow state, all listeners,
1889
+ * BoolLogics, and validators silently skip execution for that pipeline run
1890
+ * (no unregistration — they resume when the path reappears).
1891
+ */
1892
+ anchorPath?: DeepKey<DATA, Depth>;
1704
1893
  }
1705
1894
 
1706
1895
  /**
@@ -1735,14 +1924,34 @@ interface GenericStoreApi<DATA extends object, META extends GenericMeta = Generi
1735
1924
  } & {
1736
1925
  [K in keyof SELECTION as SELECTION[K] extends true ? K : never]?: K extends keyof EvaluatedConcerns<CONCERNS> ? EvaluatedConcerns<CONCERNS>[K] : never;
1737
1926
  };
1927
+ /** Reactive snapshot of all concerns matching this selection, keyed by path. Re-renders when any concern changes. */
1928
+ useConcernsSnapshot: () => Record<string, {
1929
+ [K in keyof SELECTION as SELECTION[K] extends true ? K : never]?: K extends keyof EvaluatedConcerns<CONCERNS> ? EvaluatedConcerns<CONCERNS>[K] : never;
1930
+ }>;
1738
1931
  };
1932
+ /**
1933
+ * React hook. Fires callback whenever concerns matching the selection change.
1934
+ * Does NOT trigger re-renders — use useConcernsSnapshot() for reactive UI instead.
1935
+ * Callback is stable across renders (no need to memoize).
1936
+ */
1937
+ useWatchConcerns: <SELECTION extends Partial<Record<Extract<CONCERNS[number], {
1938
+ name: string;
1939
+ }>['name'], boolean>>>(selection: SELECTION, callback: (concerns: Record<string, {
1940
+ [K in keyof SELECTION as SELECTION[K] extends true ? K : never]?: K extends keyof EvaluatedConcerns<CONCERNS> ? EvaluatedConcerns<CONCERNS>[K] : never;
1941
+ }>) => void) => void;
1739
1942
  withMeta: (presetMeta: Partial<META>) => {
1740
1943
  useFieldStore: <P extends DeepKey<DATA>>(path: P) => {
1741
1944
  value: DeepValue<DATA, P>;
1742
1945
  setValue: (newValue: DeepValue<DATA, P>, meta?: META) => void;
1743
1946
  };
1744
1947
  };
1745
- syncPairs: <T extends [ResolvableDeepKey<DATA>, ResolvableDeepKey<DATA>][]>(pairs: CheckSyncPairs<DATA, T>) => ValidatedSyncPairs<DATA>;
1948
+ syncPairs: <T extends ([ResolvableDeepKey<DATA>, ResolvableDeepKey<DATA>] | [
1949
+ ResolvableDeepKey<DATA>,
1950
+ ResolvableDeepKey<DATA>,
1951
+ {
1952
+ oneWay: '[0]->[1]' | '[1]->[0]';
1953
+ }
1954
+ ])[]>(pairs: CheckSyncPairs<DATA, T>) => ValidatedSyncPairs<DATA>;
1746
1955
  flipPairs: <T extends [ResolvableDeepKey<DATA>, ResolvableDeepKey<DATA>][]>(pairs: CheckSyncPairs<DATA, T>) => ValidatedFlipPairs<DATA>;
1747
1956
  aggregationPairs: <T extends ([ResolvableDeepKey<DATA>, ResolvableDeepKey<DATA>] | [ResolvableDeepKey<DATA>, ResolvableDeepKey<DATA>, BoolLogic<DATA>])[]>(pairs: CheckAggregationPairs<DATA, T>) => ValidatedAggregationPairs<DATA>;
1748
1957
  computationPairs: <T extends ([
@@ -1971,20 +2180,14 @@ interface FieldInput<T> {
1971
2180
  */
1972
2181
  declare const useTransformedField: <TStored, TDisplay, TField extends FieldInput<TStored>>(field: TField, config: TransformConfig<TStored, TDisplay>) => Omit<TField, "value" | "setValue"> & FieldInput<TDisplay>;
1973
2182
 
1974
- /** Legacy JS implementation - uses JS graph structure */
1975
- declare const registerFlipPair: <DATA extends object, META extends GenericMeta = GenericMeta>(store: StoreInstance<DATA, META>, path1: string & {}, path2: string & {}) => (() => void);
1976
-
1977
- /** Legacy JS implementation - uses JS listener maps and sorted paths */
1978
- declare const registerListenerLegacy: <DATA extends object, META extends GenericMeta = GenericMeta>(store: StoreInstance<DATA, META>, registration: ListenerRegistration<DATA, META>) => (() => void);
1979
-
1980
2183
  /**
1981
- * Legacy batch version of registerSyncPair. Adds all edges first, then computes
1982
- * initial sync changes across all final groups and calls processChanges once.
1983
- * This avoids cascading effect re-evaluations when registering many pairs.
2184
+ * WASM Implementation - Side Effects Registration
2185
+ *
2186
+ * Consolidates all side effects (sync, flip, aggregation, listeners) into a single
2187
+ * WASM call for efficiency. No legacy fallback logic - assumes WASM is loaded.
1984
2188
  */
1985
- declare const registerSyncPairsBatch: <DATA extends object, META extends GenericMeta = GenericMeta>(store: StoreInstance<DATA, META>, pairs: [string & {}, string & {}][]) => (() => void);
1986
2189
 
1987
- declare const registerSideEffects: <DATA extends object, META extends GenericMeta = GenericMeta>(store: StoreInstance<DATA, META>, id: string, effects: SideEffects<DATA, META>) => (() => void);
2190
+ declare const registerSideEffects: <DATA extends object, META extends GenericMeta = GenericMeta>(store: StoreInstance<DATA>, id: string, effects: SideEffects<DATA, META>) => (() => void);
1988
2191
 
1989
2192
  /**
1990
2193
  * Lazy-validated pair helper functions
@@ -2042,7 +2245,9 @@ declare const registerSideEffects: <DATA extends object, META extends GenericMet
2042
2245
  * useSideEffects('my-syncs', { syncPaths: syncs }) // no O(N²) re-check
2043
2246
  * ```
2044
2247
  */
2045
- declare const syncPairs: <DATA extends object, Depth extends number = DefaultDepth>() => <T extends [ResolvableDeepKey<DATA, Depth>, ResolvableDeepKey<DATA, Depth>][]>(pairs: CheckSyncPairs<DATA, T, Depth>) => ValidatedSyncPairs<DATA>;
2248
+ declare const syncPairs: <DATA extends object, Depth extends number = DefaultDepth>() => <T extends ([ResolvableDeepKey<DATA, Depth>, ResolvableDeepKey<DATA, Depth>] | [ResolvableDeepKey<DATA, Depth>, ResolvableDeepKey<DATA, Depth>, {
2249
+ oneWay: "[0]->[1]" | "[1]->[0]";
2250
+ }])[]>(pairs: CheckSyncPairs<DATA, T, Depth>) => ValidatedSyncPairs<DATA>;
2046
2251
  /**
2047
2252
  * Lazy-validated flip pairs. Curried: `flipPairs<State>()(pairs)`.
2048
2253
  *
@@ -2340,4 +2545,4 @@ declare const applyChangesToObject: <T extends object>(obj: T, changes: AnyChang
2340
2545
  */
2341
2546
  declare const deepClone: <T>(value: T) => T;
2342
2547
 
2343
- export { type Aggregation, type AggregationPair, type ArrayOfChanges, type BaseConcernProps, type BoolLogic, type BufferedField, type CheckAggregationPairs, type CheckComputationPairs, type CheckPairValueMatch, type CheckSyncPairs, type ClearPathRule, type ComputationOp, type ComputationPair, type ConcernRegistration, type ConcernRegistrationMap, type ConcernType, type DebugConfig, type DebugTrack, type DebugTrackEntry, type DeepKey, type DeepKeyFiltered, type DeepPartial, type DeepRequired, type DeepValue, type EvaluatedConcerns, type ExtractEvaluateReturn, type FieldInput$2 as FieldInput, type FlipPair, type GenericMeta, type GenericStoreApi, type HASH_KEY, type KeyboardSelectConfig, type ListenerRegistration, type OnStateListener, type PathsWithSameValueAs, type PipelineObserver, type ProviderProps, STORE_DATA, type SelectOption, type SideEffects, type StoreConfig, type StoreInstance, type SyncPair, type ThrottleConfig, type ThrottleFieldInput, type TransformConfig, VALIDATED, type ValidatedAggregationPairs, type ValidatedComputationPairs, type ValidatedFlipPairs, type ValidatedListeners, type ValidatedSyncPairs, type ValidationError, type ValidationSchema, type ValidationStateConcern, type ValidationStateInput, type ValidationStateResult, _, aggregationPairs, applyChangesToObject, computationPairs, createGenericStore, deepClone, defaultConcerns, dot, evaluateBoolLogic, extractPlaceholders, findConcern, flipPairs, hashKey, interpolateTemplate, is, listeners, index as prebuilts, registerFlipPair, registerListenerLegacy, registerSideEffects, registerSyncPairsBatch, syncPairs, useBufferedField, useKeyboardSelect, useThrottledField, useTransformedField };
2548
+ export { type Aggregation, type AggregationPair, type ArrayOfChanges, type BaseConcernProps, type BoolLogic, type BufferedField, type CheckAggregationPairs, type CheckComputationPairs, type CheckPairValueMatch, type CheckSyncPairs, type ClearPathRule, type ComputationOp, type ComputationPair, type ConcernRegistration, type ConcernRegistrationMap, type ConcernType, type DebugConfig, type DebugTrack, type DebugTrackEntry, type DeepKey, type DeepKeyFiltered, type DeepPartial, type DeepRequired, type DeepValue, type EvaluatedConcerns, type ExtractEvaluateReturn, type FieldInput$2 as FieldInput, type FlipPair, type GenericMeta, type GenericStoreApi, type HASH_KEY, type KeyboardSelectConfig, type ListenerRegistration, type OnStateListener, type PathsWithSameValueAs, type ProviderProps, STORE_DATA, type SelectOption, type SideEffects, type StoreConfig, type StoreInstance, type SyncPair, type ThrottleConfig, type ThrottleFieldInput, type TransformConfig, VALIDATED, type ValidatedAggregationPairs, type ValidatedComputationPairs, type ValidatedFlipPairs, type ValidatedListeners, type ValidatedSyncPairs, type ValidationError, type ValidationSchema, type ValidationStateConcern, type ValidationStateInput, type ValidationStateResult, _, aggregationPairs, applyChangesToObject, computationPairs, createGenericStore, deepClone, defaultConcerns, dot, evaluateBoolLogic, extractPlaceholders, findConcern, flipPairs, hashKey, interpolateTemplate, is, listeners, index as prebuilts, registerSideEffects, syncPairs, useBufferedField, useKeyboardSelect, useThrottledField, useTransformedField };