@sladg/apex-state 3.11.4 → 4.6.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/README.md +111 -234
- package/dist/index.d.ts +353 -320
- package/dist/index.js +12 -3571
- package/dist/index.js.map +1 -1
- package/dist/preload.d.ts +2 -0
- package/dist/preload.js +3 -0
- package/dist/preload.js.map +1 -0
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +12 -2227
- package/dist/testing/index.js.map +1 -1
- package/package.json +20 -5
package/dist/index.d.ts
CHANGED
|
@@ -334,11 +334,26 @@ interface GenericMeta {
|
|
|
334
334
|
* Used to track changes triggered by computation logic.
|
|
335
335
|
*/
|
|
336
336
|
isComputationChange?: boolean;
|
|
337
|
+
/**
|
|
338
|
+
* Indicates if the change originated from an expression evaluation (BoolLogic/ValueLogic).
|
|
339
|
+
* Used to track changes produced by the expression stage in the pipeline.
|
|
340
|
+
*/
|
|
341
|
+
isExpressionChange?: boolean;
|
|
342
|
+
/**
|
|
343
|
+
* Indicates if the change is a concern output (BoolLogic, ValueLogic, or validator result).
|
|
344
|
+
* Stamped by WASM from the registration_meta provided at expression/listener registration.
|
|
345
|
+
*/
|
|
346
|
+
isConcern?: boolean;
|
|
337
347
|
/**
|
|
338
348
|
* Identifies the originator of the change.
|
|
339
|
-
* Can be a user ID, component name, or any identifier string.
|
|
349
|
+
* Can be a user ID, component name, listener function name, or any identifier string.
|
|
340
350
|
*/
|
|
341
351
|
sender?: string;
|
|
352
|
+
/**
|
|
353
|
+
* The pipeline stage that produced this change (e.g., 'sync', 'flip', 'aggregation_write', 'listeners').
|
|
354
|
+
* Used for debugging to understand the source of a change.
|
|
355
|
+
*/
|
|
356
|
+
stage?: string;
|
|
342
357
|
}
|
|
343
358
|
|
|
344
359
|
/**
|
|
@@ -669,16 +684,28 @@ type PathsWithSameValueAs<DATA extends object, PATH extends ResolvableDeepKey<DA
|
|
|
669
684
|
}[ResolvableDeepKey<DATA, Depth>];
|
|
670
685
|
/**
|
|
671
686
|
* A tuple of two paths that must have the same value type.
|
|
672
|
-
* Format: [path1, path2]
|
|
687
|
+
* Format: [path1, path2] or [path1, path2, { oneWay: '[0]->[1]' | '[1]->[0]' }]
|
|
688
|
+
*
|
|
689
|
+
* `oneWay` makes sync unidirectional. The value declares the direction explicitly:
|
|
690
|
+
* - `'[0]->[1]'` — first path pushes to second path (left → right)
|
|
691
|
+
* - `'[1]->[0]'` — second path pushes to first path (right → left)
|
|
692
|
+
*
|
|
693
|
+
* Without the option, sync is bidirectional.
|
|
673
694
|
*
|
|
674
695
|
* **Scaling note**: This type is O(N²) where N = number of paths. It hits TS2589
|
|
675
696
|
* at ~1,500 paths. For large state types, use the `syncPairs()` helper function
|
|
676
697
|
* or `store.syncPairs()` (pre-warmed from `createGenericStore`) instead —
|
|
677
698
|
* they scale to ~50K–80K paths.
|
|
678
699
|
*
|
|
679
|
-
* @example
|
|
700
|
+
* @example Bidirectional
|
|
680
701
|
* const pair: SyncPair<State> = ['user.email', 'profile.email']
|
|
681
702
|
*
|
|
703
|
+
* @example One-way: user.email → profile.email only
|
|
704
|
+
* const pair: SyncPair<State> = ['user.email', 'profile.email', { oneWay: '[0]->[1]' }]
|
|
705
|
+
*
|
|
706
|
+
* @example One-way: profile.email → user.email only (reversed direction)
|
|
707
|
+
* const pair: SyncPair<State> = ['user.email', 'profile.email', { oneWay: '[1]->[0]' }]
|
|
708
|
+
*
|
|
682
709
|
* @example Custom depth — propagates to DeepKey and PathsWithSameValueAs
|
|
683
710
|
* ```typescript
|
|
684
711
|
* // Limit path traversal to 10 levels
|
|
@@ -686,13 +713,16 @@ type PathsWithSameValueAs<DATA extends object, PATH extends ResolvableDeepKey<DA
|
|
|
686
713
|
* ```
|
|
687
714
|
*/
|
|
688
715
|
type SyncPair<DATA extends object, Depth extends number = DefaultDepth> = {
|
|
689
|
-
[P1 in ResolvableDeepKey<DATA, Depth>]: [
|
|
716
|
+
[P1 in ResolvableDeepKey<DATA, Depth>]: [P1, PathsWithSameValueAs<DATA, P1, Depth>] | [
|
|
690
717
|
P1,
|
|
691
|
-
PathsWithSameValueAs<DATA, P1, Depth
|
|
718
|
+
PathsWithSameValueAs<DATA, P1, Depth>,
|
|
719
|
+
{
|
|
720
|
+
oneWay: '[0]->[1]' | '[1]->[0]';
|
|
721
|
+
}
|
|
692
722
|
];
|
|
693
723
|
}[ResolvableDeepKey<DATA, Depth>];
|
|
694
724
|
/**
|
|
695
|
-
* A tuple of two paths for flip (
|
|
725
|
+
* A tuple of two paths for flip. Always bidirectional: path1 ↔ path2 (inverted values).
|
|
696
726
|
* Format: [path1, path2]
|
|
697
727
|
*
|
|
698
728
|
* **Scaling note**: O(N²) — hits TS2589 at ~1,500 paths. Use `flipPairs()` helper
|
|
@@ -701,7 +731,12 @@ type SyncPair<DATA extends object, Depth extends number = DefaultDepth> = {
|
|
|
701
731
|
* @example
|
|
702
732
|
* const pair: FlipPair<State> = ['isActive', 'isInactive']
|
|
703
733
|
*/
|
|
704
|
-
type FlipPair<DATA extends object, Depth extends number = DefaultDepth> =
|
|
734
|
+
type FlipPair<DATA extends object, Depth extends number = DefaultDepth> = {
|
|
735
|
+
[P1 in ResolvableDeepKey<DATA, Depth>]: [
|
|
736
|
+
P1,
|
|
737
|
+
PathsWithSameValueAs<DATA, P1, Depth>
|
|
738
|
+
];
|
|
739
|
+
}[ResolvableDeepKey<DATA, Depth>];
|
|
705
740
|
/**
|
|
706
741
|
* A tuple for aggregation: [target, source] or [target, source, excludeWhen]
|
|
707
742
|
* First element (left) is ALWAYS the target (aggregated) path.
|
|
@@ -779,13 +814,24 @@ type CheckPairValueMatch<DATA extends object, P1 extends string, P2 extends stri
|
|
|
779
814
|
NonNullable<DeepValue<DATA, P1>>
|
|
780
815
|
] ? [P1, P2] : [P1, never] : [P1, never] : never : never;
|
|
781
816
|
/**
|
|
782
|
-
* Validates an array of
|
|
817
|
+
* Validates an array of sync/flip pairs lazily — O(K) where K = pairs written.
|
|
818
|
+
* Accepts [P1, P2] or [P1, P2, { oneWay: '[0]->[1]' | '[1]->[0]' }].
|
|
819
|
+
* The optional third element declares direction — does not affect value type validation.
|
|
783
820
|
*/
|
|
784
|
-
type CheckSyncPairs<DATA extends object, T extends readonly [string, string][
|
|
821
|
+
type CheckSyncPairs<DATA extends object, T extends readonly ([string, string] | [string, string, {
|
|
822
|
+
oneWay: '[0]->[1]' | '[1]->[0]';
|
|
823
|
+
}])[], Depth extends number = DefaultDepth> = {
|
|
785
824
|
[I in keyof T]: T[I] extends [
|
|
786
825
|
infer P1 extends string,
|
|
787
|
-
infer P2 extends string
|
|
788
|
-
|
|
826
|
+
infer P2 extends string,
|
|
827
|
+
{
|
|
828
|
+
oneWay: '[0]->[1]' | '[1]->[0]';
|
|
829
|
+
}
|
|
830
|
+
] ? CheckPairValueMatch<DATA, P1, P2, Depth> extends [P1, P2] ? [P1, P2, {
|
|
831
|
+
oneWay: '[0]->[1]' | '[1]->[0]';
|
|
832
|
+
}] : [P1, never, {
|
|
833
|
+
oneWay: '[0]->[1]' | '[1]->[0]';
|
|
834
|
+
}] : T[I] extends [infer P1 extends string, infer P2 extends string] ? CheckPairValueMatch<DATA, P1, P2, Depth> : T[I];
|
|
789
835
|
};
|
|
790
836
|
/**
|
|
791
837
|
* Validates that two paths both resolve to number.
|
|
@@ -851,10 +897,9 @@ type DeepPartial<T> = T extends (infer U)[] ? DeepPartial<U>[] : T extends reado
|
|
|
851
897
|
declare const VALIDATED: unique symbol;
|
|
852
898
|
declare const STORE_DATA: unique symbol;
|
|
853
899
|
/** Pre-validated sync pair array. Returned by `syncPairs()`. Branded with DATA to prevent cross-store use. */
|
|
854
|
-
type ValidatedSyncPairs<DATA extends object = object> = [
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
][] & {
|
|
900
|
+
type ValidatedSyncPairs<DATA extends object = object> = ([string, string] | [string, string, {
|
|
901
|
+
oneWay: '[0]->[1]' | '[1]->[0]';
|
|
902
|
+
}])[] & {
|
|
858
903
|
[VALIDATED]: 'sync';
|
|
859
904
|
[STORE_DATA]: DATA;
|
|
860
905
|
};
|
|
@@ -885,76 +930,105 @@ type ValidatedListeners<DATA extends object = object, META extends GenericMeta =
|
|
|
885
930
|
[STORE_DATA]: DATA;
|
|
886
931
|
};
|
|
887
932
|
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
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;
|
|
933
|
+
type Stage = "input" | "aggregation_write" | "diff" | "sync" | "flip" | "clear_path" | "aggregation_read" | "computation" | "expression" | "listeners" | "apply";
|
|
934
|
+
type ChangeKind = "real" | "redundant" | "breakdown" | "consumed";
|
|
935
|
+
type ChangeContext = "Initial" | "Mutation";
|
|
936
|
+
type Lineage = "Input" | {
|
|
937
|
+
"Derived": {
|
|
938
|
+
parent_id: number;
|
|
939
|
+
via: Stage;
|
|
940
|
+
context: ChangeContext;
|
|
941
|
+
};
|
|
942
|
+
};
|
|
943
|
+
type ChangeAudit = {
|
|
944
|
+
source_path?: string;
|
|
945
|
+
logic_id?: number;
|
|
946
|
+
};
|
|
947
|
+
type TraceEntry = {
|
|
948
|
+
/**
|
|
949
|
+
* Monotonic counter. Parents numbered pipeline-globally, children within parent.
|
|
950
|
+
*/
|
|
951
|
+
seq: number;
|
|
952
|
+
/**
|
|
953
|
+
* Stage or operation name (e.g. "input", "sync", "sync_pair", "listener", "input:skip").
|
|
954
|
+
*/
|
|
955
|
+
stage: string;
|
|
956
|
+
/**
|
|
957
|
+
* Actual input values as JSON. Per-child: only what that operation matched.
|
|
958
|
+
*/
|
|
959
|
+
inputs: Array<unknown>;
|
|
960
|
+
/**
|
|
961
|
+
* Actual output values as JSON. What this operation produced.
|
|
962
|
+
*/
|
|
963
|
+
outputs: Array<unknown>;
|
|
964
|
+
/**
|
|
965
|
+
* Microseconds. Parent = total stage time. Child = per-operation time. 0 when timing unavailable.
|
|
966
|
+
*/
|
|
967
|
+
duration_us: number;
|
|
968
|
+
/**
|
|
969
|
+
* Extra metadata (registration_id, reason, etc.). Omitted when empty.
|
|
970
|
+
*/
|
|
971
|
+
meta: Record<string, unknown>;
|
|
972
|
+
/**
|
|
973
|
+
* Per-operation breakdown. Omitted when empty. Recursive (same struct).
|
|
974
|
+
*/
|
|
975
|
+
children: Array<TraceEntry>;
|
|
976
|
+
};
|
|
977
|
+
type PipelineTrace = {
|
|
978
|
+
entries: Array<TraceEntry>;
|
|
979
|
+
};
|
|
980
|
+
type ListenerError = {
|
|
981
|
+
subscriber_id: number;
|
|
952
982
|
name: string;
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
983
|
+
error: string;
|
|
984
|
+
};
|
|
985
|
+
type ClearPathInput = {
|
|
986
|
+
triggers: Array<string>;
|
|
987
|
+
targets: Array<string>;
|
|
988
|
+
};
|
|
989
|
+
type SideEffectsRegistration = {
|
|
990
|
+
registration_id: string;
|
|
991
|
+
sync_pairs: Array<[string, string]>;
|
|
992
|
+
directed_sync_pairs: Array<[string, string]>;
|
|
993
|
+
flip_pairs: Array<[string, string]>;
|
|
994
|
+
aggregation_pairs: Array<unknown>;
|
|
995
|
+
clear_paths: Array<ClearPathInput>;
|
|
996
|
+
computation_pairs: Array<unknown>;
|
|
997
|
+
listeners: Array<ListenerRegistration$1>;
|
|
998
|
+
anchor_path: string | null;
|
|
999
|
+
};
|
|
1000
|
+
type ListenerRegistration$1 = {
|
|
1001
|
+
subscriber_id: number;
|
|
1002
|
+
topic_paths: Array<string>;
|
|
1003
|
+
scope_path: string;
|
|
1004
|
+
name?: string;
|
|
1005
|
+
/**
|
|
1006
|
+
* Whether to dispatch this subscriber immediately on registration with current shadow state.
|
|
1007
|
+
* Used by validators to produce initial validation results without requiring a state change.
|
|
1008
|
+
*/
|
|
1009
|
+
run_on_registration: boolean | null;
|
|
1010
|
+
};
|
|
1011
|
+
type ConcernsRegistration = {
|
|
1012
|
+
/**
|
|
1013
|
+
* Expression registrations (logic, value, options — WASM auto-detects export type from tree_json).
|
|
1014
|
+
*/
|
|
1015
|
+
expressions: Array<ExpressionRegistration>;
|
|
1016
|
+
/**
|
|
1017
|
+
* Subscriber registrations (validators, custom concerns, etc.).
|
|
1018
|
+
* Same format as SideEffectsRegistration.listeners — WASM treats them
|
|
1019
|
+
* identically. TS controls wave_priority at registration time.
|
|
1020
|
+
*/
|
|
1021
|
+
listeners: Array<ListenerRegistration$1>;
|
|
1022
|
+
};
|
|
1023
|
+
type ExpressionRegistration = {
|
|
1024
|
+
output_path: string;
|
|
1025
|
+
tree_json: string;
|
|
1026
|
+
/**
|
|
1027
|
+
* Opaque meta stamped on every change produced by this expression.
|
|
1028
|
+
* TS uses this for concern tagging (e.g. `{ isConcern: true }`).
|
|
1029
|
+
*/
|
|
1030
|
+
meta: unknown | null;
|
|
1031
|
+
};
|
|
958
1032
|
|
|
959
1033
|
/**
|
|
960
1034
|
* WASM Bridge — Thin namespace over Rust/WASM exports.
|
|
@@ -970,211 +1044,129 @@ interface Timing {
|
|
|
970
1044
|
* @module wasm/bridge
|
|
971
1045
|
*/
|
|
972
1046
|
|
|
973
|
-
/**
|
|
1047
|
+
/**
|
|
1048
|
+
* JS-facing change — derived from Wasm.Change with `value_json` replaced by
|
|
1049
|
+
* parsed `value: unknown` and `meta` typed as GenericMeta.
|
|
1050
|
+
*
|
|
1051
|
+
* `kind`, `lineage`, and `audit` are optional: they are populated on changes
|
|
1052
|
+
* returned from WASM (output) but absent on changes constructed in JS (input).
|
|
1053
|
+
*/
|
|
974
1054
|
interface Change {
|
|
975
1055
|
path: string;
|
|
976
1056
|
value: unknown;
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
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;
|
|
1057
|
+
meta: GenericMeta;
|
|
1058
|
+
kind?: ChangeKind;
|
|
1059
|
+
lineage?: Lineage;
|
|
1060
|
+
audit?: ChangeAudit;
|
|
1097
1061
|
}
|
|
1098
1062
|
/**
|
|
1099
|
-
*
|
|
1100
|
-
* Each store
|
|
1101
|
-
*
|
|
1063
|
+
* Create a new isolated WASM pipeline instance.
|
|
1064
|
+
* Each store should call this once and store the result.
|
|
1065
|
+
* Call pipeline.destroy() on cleanup.
|
|
1102
1066
|
*/
|
|
1103
|
-
|
|
1104
|
-
|
|
1067
|
+
declare const createWasmPipeline: (options?: {
|
|
1068
|
+
debug?: boolean;
|
|
1069
|
+
}) => {
|
|
1070
|
+
id: number;
|
|
1071
|
+
readonly destroyed: boolean;
|
|
1105
1072
|
shadowInit: (state: object) => void;
|
|
1106
1073
|
shadowDump: () => unknown;
|
|
1107
|
-
processChanges: (changes: Change[]) =>
|
|
1108
|
-
|
|
1109
|
-
|
|
1074
|
+
processChanges: (changes: Change[]) => {
|
|
1075
|
+
changes: Change[];
|
|
1076
|
+
listener_errors: ListenerError[];
|
|
1077
|
+
trace: PipelineTrace | undefined;
|
|
1078
|
+
};
|
|
1079
|
+
registerSideEffects: (reg: Partial<SideEffectsRegistration>, subscriberFns?: Map<number, (...args: unknown[]) => unknown>) => {
|
|
1080
|
+
sync_changes: Change[];
|
|
1081
|
+
aggregation_changes: Change[];
|
|
1082
|
+
computation_changes: Change[];
|
|
1083
|
+
registered_side_effects: Record<string, ListenerRegistration$1[]>;
|
|
1084
|
+
};
|
|
1085
|
+
unregisterSideEffects: (registrationId: string) => {
|
|
1086
|
+
sync_changes: Change[];
|
|
1087
|
+
aggregation_changes: Change[];
|
|
1088
|
+
computation_changes: Change[];
|
|
1089
|
+
registered_side_effects: Record<string, ListenerRegistration$1[]>;
|
|
1090
|
+
};
|
|
1091
|
+
registerConcerns: (reg: Partial<ConcernsRegistration>, subscriberFns?: Map<number, (...args: unknown[]) => unknown>) => {
|
|
1092
|
+
expression_changes: Change[];
|
|
1093
|
+
registered_expression_ids: number[];
|
|
1094
|
+
registered_subscriber_ids: number[];
|
|
1095
|
+
initial_listener_changes: Change[];
|
|
1110
1096
|
};
|
|
1111
|
-
registerSideEffects: (reg: SideEffectsRegistration) => SideEffectsResult;
|
|
1112
|
-
unregisterSideEffects: (registrationId: string) => void;
|
|
1113
|
-
registerConcerns: (reg: ConcernsRegistration) => ConcernsResult;
|
|
1114
1097
|
unregisterConcerns: (registrationId: string) => void;
|
|
1115
1098
|
registerBoolLogic: (outputPath: string, tree: unknown) => number;
|
|
1116
1099
|
unregisterBoolLogic: (logicId: number) => void;
|
|
1117
1100
|
pipelineReset: () => void;
|
|
1118
1101
|
destroy: () => void;
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
}
|
|
1102
|
+
};
|
|
1103
|
+
type WasmPipeline = ReturnType<typeof createWasmPipeline>;
|
|
1122
1104
|
|
|
1123
1105
|
/**
|
|
1124
|
-
*
|
|
1106
|
+
* Apex State Logger — Simplified debug logging with colored console output.
|
|
1125
1107
|
*
|
|
1126
|
-
*
|
|
1127
|
-
*
|
|
1108
|
+
* Two log functions:
|
|
1109
|
+
* 1. logPipeline — called once per processChanges with WASM pipeline trace
|
|
1110
|
+
* 2. logRegistration — called once per register/unregister with graph snapshot
|
|
1128
1111
|
*
|
|
1129
|
-
*
|
|
1130
|
-
* mirror registrations to WASM bridge for pipeline processing.
|
|
1112
|
+
* Zero runtime cost when log flag is false (returns no-op logger).
|
|
1131
1113
|
*
|
|
1132
|
-
*
|
|
1133
|
-
*
|
|
1134
|
-
* -
|
|
1135
|
-
*
|
|
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.
|
|
1114
|
+
* Responsible for:
|
|
1115
|
+
* - Rendering PipelineTrace entries recursively with [NN]/[NN.MM] numbering
|
|
1116
|
+
* - Color-coding entries by registration_id (deterministic palette) or stage
|
|
1117
|
+
* - Formatting timing as ms from duration_us
|
|
1144
1118
|
*
|
|
1145
|
-
*
|
|
1146
|
-
*
|
|
1147
|
-
*
|
|
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
|
|
1119
|
+
* Out of scope:
|
|
1120
|
+
* - Trace collection (handled by Rust pipeline_trace.rs)
|
|
1121
|
+
* - DevTools integration (handled by store/devtools.ts)
|
|
1151
1122
|
*/
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1123
|
+
|
|
1124
|
+
type GraphSnapshot$1 = Record<string, unknown>;
|
|
1125
|
+
type SideEffectsResult = ReturnType<WasmPipeline['registerSideEffects']>;
|
|
1126
|
+
interface PipelineLogData {
|
|
1127
|
+
initialChanges: Change[];
|
|
1128
|
+
/** WASM pipeline trace (undefined if not traced). */
|
|
1129
|
+
trace: PipelineTrace | undefined;
|
|
1130
|
+
/** Final applied changes: always present (can be empty). */
|
|
1131
|
+
appliedChanges: Change[];
|
|
1132
|
+
/** State snapshot after changes (undefined if not captured). */
|
|
1133
|
+
stateSnapshot: unknown | undefined;
|
|
1134
|
+
}
|
|
1135
|
+
interface RegistrationLogData {
|
|
1136
|
+
result: SideEffectsResult | undefined;
|
|
1137
|
+
appliedChanges: Change[];
|
|
1138
|
+
stateSnapshot: unknown | undefined;
|
|
1139
|
+
durationMs: number;
|
|
1140
|
+
}
|
|
1141
|
+
interface RegistrationLogParams {
|
|
1142
|
+
type: 'register' | 'unregister';
|
|
1143
|
+
id: string;
|
|
1144
|
+
snapshot: GraphSnapshot$1;
|
|
1145
|
+
data?: RegistrationLogData;
|
|
1146
|
+
}
|
|
1147
|
+
interface ApexLogger {
|
|
1148
|
+
logPipeline: (data: PipelineLogData) => void;
|
|
1149
|
+
logRegistration: (params: RegistrationLogParams) => void;
|
|
1150
|
+
destroy: () => void;
|
|
1159
1151
|
}
|
|
1160
1152
|
|
|
1161
1153
|
/**
|
|
1162
|
-
*
|
|
1154
|
+
* Valtio DevTools — Connects state and concerns proxies to Redux DevTools,
|
|
1155
|
+
* and provides a pipeline notifier for sending pipeline/registration events.
|
|
1163
1156
|
*
|
|
1164
|
-
*
|
|
1165
|
-
*
|
|
1157
|
+
* Uses valtio/utils devtools() to expose both proxies as separate DevTools instances:
|
|
1158
|
+
* - '{prefix}:state' — application state proxy
|
|
1159
|
+
* - '{prefix}:concerns' — computed concern values proxy
|
|
1160
|
+
*
|
|
1161
|
+
* Singleton connections per proxy — survives StrictMode remounts and HMR reloads.
|
|
1166
1162
|
*/
|
|
1167
1163
|
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
* Flip graph: Paths with inverted boolean values
|
|
1175
|
-
* Type alias for PathGroups - maintains backward compatibility
|
|
1176
|
-
*/
|
|
1177
|
-
type FlipGraph = PathGroups;
|
|
1164
|
+
type GraphSnapshot = Record<string, unknown>;
|
|
1165
|
+
interface DevToolsNotifier {
|
|
1166
|
+
notifyPipeline: (data: PipelineLogData) => void;
|
|
1167
|
+
notifyRegistration: (type: 'register' | 'unregister', id: string, snapshot: GraphSnapshot) => void;
|
|
1168
|
+
destroy: () => void;
|
|
1169
|
+
}
|
|
1178
1170
|
|
|
1179
1171
|
/**
|
|
1180
1172
|
* Core Store Types
|
|
@@ -1187,18 +1179,14 @@ type FlipGraph = PathGroups;
|
|
|
1187
1179
|
* Debug configuration for development tooling
|
|
1188
1180
|
*/
|
|
1189
1181
|
interface DebugConfig {
|
|
1190
|
-
/** Enable
|
|
1182
|
+
/** Enable console logging for pipeline runs and registrations */
|
|
1183
|
+
log?: boolean;
|
|
1184
|
+
/** Enable timing warnings for slow listeners */
|
|
1191
1185
|
timing?: boolean;
|
|
1192
|
-
/** Threshold in milliseconds for slow
|
|
1186
|
+
/** Threshold in milliseconds for slow listener warnings (default: 5ms) */
|
|
1193
1187
|
timingThreshold?: number;
|
|
1194
1188
|
/** Enable tracking of processChanges calls and applied changes for testing/debugging */
|
|
1195
1189
|
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
1190
|
/** Connect to Redux DevTools Extension for state inspection */
|
|
1203
1191
|
devtools?: boolean;
|
|
1204
1192
|
}
|
|
@@ -1240,8 +1228,6 @@ interface StoreConfig {
|
|
|
1240
1228
|
maxIterations?: number;
|
|
1241
1229
|
/** Debug configuration for development tooling */
|
|
1242
1230
|
debug?: DebugConfig;
|
|
1243
|
-
/** Use legacy TypeScript implementation instead of WASM (default: false) */
|
|
1244
|
-
useLegacyImplementation?: boolean;
|
|
1245
1231
|
}
|
|
1246
1232
|
interface ProviderProps<DATA extends object> {
|
|
1247
1233
|
initialState: DATA;
|
|
@@ -1306,12 +1292,18 @@ type OnStateListener<DATA extends object = object, SUB_STATE = DATA, META extend
|
|
|
1306
1292
|
* }
|
|
1307
1293
|
* ```
|
|
1308
1294
|
*/
|
|
1309
|
-
|
|
1295
|
+
/**
|
|
1296
|
+
* Single-path listener — watches one path (or all paths when null).
|
|
1297
|
+
* `scope` may be omitted (defaults to `path`).
|
|
1298
|
+
*/
|
|
1299
|
+
interface SinglePathListener<DATA extends object = object, META extends GenericMeta = GenericMeta, Depth extends number = DefaultDepth> {
|
|
1310
1300
|
/**
|
|
1311
|
-
* Path to watch - only changes under this path will trigger the listener
|
|
1312
|
-
* null = watch all paths (receives every change)
|
|
1301
|
+
* Path to watch - only changes under this path will trigger the listener.
|
|
1302
|
+
* null = watch all paths (receives every change).
|
|
1303
|
+
* Array = watch multiple paths; listener fires once per run when any match,
|
|
1304
|
+
* receiving all matching changes merged into a single input array.
|
|
1313
1305
|
*/
|
|
1314
|
-
path: DeepKey<DATA, Depth> | null;
|
|
1306
|
+
path: DeepKey<DATA, Depth> | DeepKey<DATA, Depth>[] | null;
|
|
1315
1307
|
/**
|
|
1316
1308
|
* Scope for state and changes presentation
|
|
1317
1309
|
* - If omitted/undefined: defaults to `path` (scoped state matching the watched path)
|
|
@@ -1323,52 +1315,70 @@ interface ListenerRegistration<DATA extends object = object, META extends Generi
|
|
|
1323
1315
|
scope?: DeepKey<DATA, Depth> | null;
|
|
1324
1316
|
fn: OnStateListener<DATA, any, META>;
|
|
1325
1317
|
}
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1318
|
+
/**
|
|
1319
|
+
* Multi-path listener — watches multiple paths simultaneously.
|
|
1320
|
+
* Handler fires once per pipeline run with all matched changes merged.
|
|
1321
|
+
* `scope` is required (use null for full paths).
|
|
1322
|
+
*/
|
|
1323
|
+
interface MultiPathListener<DATA extends object = object, META extends GenericMeta = GenericMeta, Depth extends number = DefaultDepth> {
|
|
1324
|
+
/**
|
|
1325
|
+
* Array of paths to watch. Handler fires once with changes from any matched path.
|
|
1326
|
+
*/
|
|
1327
|
+
path: DeepKey<DATA, Depth>[];
|
|
1328
|
+
/**
|
|
1329
|
+
* Scope for state and changes presentation (required for multi-path listeners).
|
|
1330
|
+
* - null: state is full DATA, changes use FULL paths
|
|
1331
|
+
* - string: state is value at scope, changes use paths RELATIVE to scope
|
|
1332
|
+
*/
|
|
1333
|
+
scope: DeepKey<DATA, Depth> | null;
|
|
1334
|
+
fn: OnStateListener<DATA, any, META>;
|
|
1337
1335
|
}
|
|
1336
|
+
/** Listener registration — single-path or multi-path. */
|
|
1337
|
+
type ListenerRegistration<DATA extends object = object, META extends GenericMeta = GenericMeta, Depth extends number = DefaultDepth> = SinglePathListener<DATA, META, Depth> | MultiPathListener<DATA, META, Depth>;
|
|
1338
1338
|
interface Registrations {
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
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>;
|
|
1339
|
+
/** Cleanup functions keyed by registration ID. Multiple cleanups may exist per registration. */
|
|
1340
|
+
cleanups: Record<string, (() => void)[]>;
|
|
1346
1341
|
}
|
|
1347
1342
|
/** Internal store state (NOT tracked - wrapped in ref()) */
|
|
1348
|
-
interface InternalState
|
|
1349
|
-
graphs: SideEffectGraphs<DATA, META>;
|
|
1343
|
+
interface InternalState {
|
|
1350
1344
|
registrations: Registrations;
|
|
1351
|
-
processing: ProcessingState<DATA, META>;
|
|
1352
|
-
timing: Timing;
|
|
1353
|
-
observer: PipelineObserver;
|
|
1354
1345
|
config: DeepRequired<StoreConfig>;
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1346
|
+
logger: ApexLogger;
|
|
1347
|
+
/** DevTools — pipeline notifier + proxy inspection. Null when devtools disabled. */
|
|
1348
|
+
devtools: DevToolsNotifier | null;
|
|
1349
|
+
/** Per-store WASM pipeline instance (null after destroy). */
|
|
1358
1350
|
pipeline: WasmPipeline | null;
|
|
1359
|
-
/** Pending deferred destroy timer — cancelled on StrictMode re-mount. */
|
|
1360
|
-
_destroyTimer?: ReturnType<typeof setTimeout> | undefined;
|
|
1361
1351
|
}
|
|
1362
1352
|
type ConcernValues = Record<string, Record<string, unknown>>;
|
|
1363
1353
|
/** Two-proxy pattern: state and _concerns are independent to prevent infinite loops */
|
|
1364
|
-
interface StoreInstance<DATA extends object
|
|
1354
|
+
interface StoreInstance<DATA extends object> {
|
|
1365
1355
|
state: DATA;
|
|
1366
1356
|
_concerns: ConcernValues;
|
|
1367
|
-
_internal: InternalState
|
|
1357
|
+
_internal: InternalState;
|
|
1368
1358
|
/** Debug tracking data, only populated when debug.track is enabled */
|
|
1369
1359
|
_debug: DebugTrack | null;
|
|
1370
1360
|
}
|
|
1371
1361
|
|
|
1362
|
+
interface BaseConcernProps<STATE, PATH extends string> {
|
|
1363
|
+
state: STATE;
|
|
1364
|
+
path: PATH;
|
|
1365
|
+
value: unknown;
|
|
1366
|
+
}
|
|
1367
|
+
interface ConcernType<NAME extends string = string, EXTRA_PROPS = Record<string, unknown>, RETURN_TYPE = unknown> {
|
|
1368
|
+
name: NAME;
|
|
1369
|
+
description: string;
|
|
1370
|
+
/** Evaluated inside effect() - all state accesses are tracked */
|
|
1371
|
+
evaluate: (props: BaseConcernProps<Record<string, unknown>, string> & EXTRA_PROPS) => RETURN_TYPE;
|
|
1372
|
+
}
|
|
1373
|
+
interface ConcernRegistration {
|
|
1374
|
+
id: string;
|
|
1375
|
+
path: string;
|
|
1376
|
+
concernName: string;
|
|
1377
|
+
concern: ConcernType;
|
|
1378
|
+
config: Record<string, unknown>;
|
|
1379
|
+
dispose: () => void;
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1372
1382
|
interface ValidationError {
|
|
1373
1383
|
field?: string;
|
|
1374
1384
|
message: string;
|
|
@@ -1701,6 +1711,13 @@ interface SideEffects<DATA extends object, META extends GenericMeta = GenericMet
|
|
|
1701
1711
|
* Accepts direct `ListenerRegistration<T>[]` or pre-validated result from `listeners()`.
|
|
1702
1712
|
*/
|
|
1703
1713
|
listeners?: ListenerRegistration<DATA, META>[];
|
|
1714
|
+
/**
|
|
1715
|
+
* Anchor path - guard for all resources in this registration.
|
|
1716
|
+
* When the anchor path is structurally absent from shadow state, all listeners,
|
|
1717
|
+
* BoolLogics, and validators silently skip execution for that pipeline run
|
|
1718
|
+
* (no unregistration — they resume when the path reappears).
|
|
1719
|
+
*/
|
|
1720
|
+
anchorPath?: DeepKey<DATA, Depth>;
|
|
1704
1721
|
}
|
|
1705
1722
|
|
|
1706
1723
|
/**
|
|
@@ -1735,14 +1752,34 @@ interface GenericStoreApi<DATA extends object, META extends GenericMeta = Generi
|
|
|
1735
1752
|
} & {
|
|
1736
1753
|
[K in keyof SELECTION as SELECTION[K] extends true ? K : never]?: K extends keyof EvaluatedConcerns<CONCERNS> ? EvaluatedConcerns<CONCERNS>[K] : never;
|
|
1737
1754
|
};
|
|
1755
|
+
/** Reactive snapshot of all concerns matching this selection, keyed by path. Re-renders when any concern changes. */
|
|
1756
|
+
useConcernsSnapshot: () => Record<string, {
|
|
1757
|
+
[K in keyof SELECTION as SELECTION[K] extends true ? K : never]?: K extends keyof EvaluatedConcerns<CONCERNS> ? EvaluatedConcerns<CONCERNS>[K] : never;
|
|
1758
|
+
}>;
|
|
1738
1759
|
};
|
|
1760
|
+
/**
|
|
1761
|
+
* React hook. Fires callback whenever concerns matching the selection change.
|
|
1762
|
+
* Does NOT trigger re-renders — use useConcernsSnapshot() for reactive UI instead.
|
|
1763
|
+
* Callback is stable across renders (no need to memoize).
|
|
1764
|
+
*/
|
|
1765
|
+
useWatchConcerns: <SELECTION extends Partial<Record<Extract<CONCERNS[number], {
|
|
1766
|
+
name: string;
|
|
1767
|
+
}>['name'], boolean>>>(selection: SELECTION, callback: (concerns: Record<string, {
|
|
1768
|
+
[K in keyof SELECTION as SELECTION[K] extends true ? K : never]?: K extends keyof EvaluatedConcerns<CONCERNS> ? EvaluatedConcerns<CONCERNS>[K] : never;
|
|
1769
|
+
}>) => void) => void;
|
|
1739
1770
|
withMeta: (presetMeta: Partial<META>) => {
|
|
1740
1771
|
useFieldStore: <P extends DeepKey<DATA>>(path: P) => {
|
|
1741
1772
|
value: DeepValue<DATA, P>;
|
|
1742
1773
|
setValue: (newValue: DeepValue<DATA, P>, meta?: META) => void;
|
|
1743
1774
|
};
|
|
1744
1775
|
};
|
|
1745
|
-
syncPairs: <T extends [ResolvableDeepKey<DATA>, ResolvableDeepKey<DATA>]
|
|
1776
|
+
syncPairs: <T extends ([ResolvableDeepKey<DATA>, ResolvableDeepKey<DATA>] | [
|
|
1777
|
+
ResolvableDeepKey<DATA>,
|
|
1778
|
+
ResolvableDeepKey<DATA>,
|
|
1779
|
+
{
|
|
1780
|
+
oneWay: '[0]->[1]' | '[1]->[0]';
|
|
1781
|
+
}
|
|
1782
|
+
])[]>(pairs: CheckSyncPairs<DATA, T>) => ValidatedSyncPairs<DATA>;
|
|
1746
1783
|
flipPairs: <T extends [ResolvableDeepKey<DATA>, ResolvableDeepKey<DATA>][]>(pairs: CheckSyncPairs<DATA, T>) => ValidatedFlipPairs<DATA>;
|
|
1747
1784
|
aggregationPairs: <T extends ([ResolvableDeepKey<DATA>, ResolvableDeepKey<DATA>] | [ResolvableDeepKey<DATA>, ResolvableDeepKey<DATA>, BoolLogic<DATA>])[]>(pairs: CheckAggregationPairs<DATA, T>) => ValidatedAggregationPairs<DATA>;
|
|
1748
1785
|
computationPairs: <T extends ([
|
|
@@ -1971,20 +2008,14 @@ interface FieldInput<T> {
|
|
|
1971
2008
|
*/
|
|
1972
2009
|
declare const useTransformedField: <TStored, TDisplay, TField extends FieldInput<TStored>>(field: TField, config: TransformConfig<TStored, TDisplay>) => Omit<TField, "value" | "setValue"> & FieldInput<TDisplay>;
|
|
1973
2010
|
|
|
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
2011
|
/**
|
|
1981
|
-
*
|
|
1982
|
-
*
|
|
1983
|
-
*
|
|
2012
|
+
* WASM Implementation - Side Effects Registration
|
|
2013
|
+
*
|
|
2014
|
+
* Consolidates all side effects (sync, flip, aggregation, listeners) into a single
|
|
2015
|
+
* WASM call for efficiency. No legacy fallback logic - assumes WASM is loaded.
|
|
1984
2016
|
*/
|
|
1985
|
-
declare const registerSyncPairsBatch: <DATA extends object, META extends GenericMeta = GenericMeta>(store: StoreInstance<DATA, META>, pairs: [string & {}, string & {}][]) => (() => void);
|
|
1986
2017
|
|
|
1987
|
-
declare const registerSideEffects: <DATA extends object, META extends GenericMeta = GenericMeta>(store: StoreInstance<DATA
|
|
2018
|
+
declare const registerSideEffects: <DATA extends object, META extends GenericMeta = GenericMeta>(store: StoreInstance<DATA>, id: string, effects: SideEffects<DATA, META>) => (() => void);
|
|
1988
2019
|
|
|
1989
2020
|
/**
|
|
1990
2021
|
* Lazy-validated pair helper functions
|
|
@@ -2042,7 +2073,9 @@ declare const registerSideEffects: <DATA extends object, META extends GenericMet
|
|
|
2042
2073
|
* useSideEffects('my-syncs', { syncPaths: syncs }) // no O(N²) re-check
|
|
2043
2074
|
* ```
|
|
2044
2075
|
*/
|
|
2045
|
-
declare const syncPairs: <DATA extends object, Depth extends number = DefaultDepth>() => <T extends [ResolvableDeepKey<DATA, Depth>, ResolvableDeepKey<DATA, Depth>][
|
|
2076
|
+
declare const syncPairs: <DATA extends object, Depth extends number = DefaultDepth>() => <T extends ([ResolvableDeepKey<DATA, Depth>, ResolvableDeepKey<DATA, Depth>] | [ResolvableDeepKey<DATA, Depth>, ResolvableDeepKey<DATA, Depth>, {
|
|
2077
|
+
oneWay: "[0]->[1]" | "[1]->[0]";
|
|
2078
|
+
}])[]>(pairs: CheckSyncPairs<DATA, T, Depth>) => ValidatedSyncPairs<DATA>;
|
|
2046
2079
|
/**
|
|
2047
2080
|
* Lazy-validated flip pairs. Curried: `flipPairs<State>()(pairs)`.
|
|
2048
2081
|
*
|
|
@@ -2340,4 +2373,4 @@ declare const applyChangesToObject: <T extends object>(obj: T, changes: AnyChang
|
|
|
2340
2373
|
*/
|
|
2341
2374
|
declare const deepClone: <T>(value: T) => T;
|
|
2342
2375
|
|
|
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
|
|
2376
|
+
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 };
|