@sladg/apex-state 3.7.3 → 3.9.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/deep-clone-DMRvv0Pr.d.ts +2119 -0
- package/dist/index.d.ts +91 -1771
- package/dist/index.js +157 -31
- package/dist/index.js.map +1 -1
- package/dist/testing/index.d.ts +3 -3
- package/dist/testing/index.js +21 -15
- package/dist/testing/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1752,7 +1752,7 @@ var filterAndRelativize = (changes, listenerPath) => {
|
|
|
1752
1752
|
return result;
|
|
1753
1753
|
};
|
|
1754
1754
|
var processListeners = (changes, store, currentState) => {
|
|
1755
|
-
const { listeners, sortedListenerPaths } = store._internal.graphs;
|
|
1755
|
+
const { listeners: listeners2, sortedListenerPaths } = store._internal.graphs;
|
|
1756
1756
|
const { queue } = store._internal.processing;
|
|
1757
1757
|
const effectiveChanges = [];
|
|
1758
1758
|
for (const change of changes) {
|
|
@@ -1767,7 +1767,7 @@ var processListeners = (changes, store, currentState) => {
|
|
|
1767
1767
|
(a, b) => getPathDepth(b[0]) - getPathDepth(a[0])
|
|
1768
1768
|
);
|
|
1769
1769
|
for (const listenerPath of sortedListenerPaths) {
|
|
1770
|
-
const pathListeners =
|
|
1770
|
+
const pathListeners = listeners2.get(listenerPath);
|
|
1771
1771
|
const relevantChanges = filterAndRelativize(sortedChanges, listenerPath);
|
|
1772
1772
|
for (const registration of pathListeners) {
|
|
1773
1773
|
processListener({
|
|
@@ -2068,12 +2068,12 @@ var processChangesWasm = (store, initialChanges) => {
|
|
|
2068
2068
|
|
|
2069
2069
|
// src/sideEffects/prebuilts/aggregation.ts
|
|
2070
2070
|
import { effect as effect3 } from "valtio-reactive";
|
|
2071
|
-
var registerAggregations = (store, id,
|
|
2071
|
+
var registerAggregations = (store, id, aggregationPairs2) => {
|
|
2072
2072
|
const { aggregations } = store._internal.registrations;
|
|
2073
2073
|
const disposeCallbacks = [];
|
|
2074
2074
|
const targets = /* @__PURE__ */ new Set();
|
|
2075
2075
|
const sources = /* @__PURE__ */ new Set();
|
|
2076
|
-
for (const [target, source] of
|
|
2076
|
+
for (const [target, source] of aggregationPairs2) {
|
|
2077
2077
|
targets.add(target);
|
|
2078
2078
|
sources.add(source);
|
|
2079
2079
|
}
|
|
@@ -2085,7 +2085,7 @@ var registerAggregations = (store, id, aggregationPairs) => {
|
|
|
2085
2085
|
}
|
|
2086
2086
|
}
|
|
2087
2087
|
const byTarget = /* @__PURE__ */ new Map();
|
|
2088
|
-
for (const [target, source] of
|
|
2088
|
+
for (const [target, source] of aggregationPairs2) {
|
|
2089
2089
|
const existing = byTarget.get(target) ?? [];
|
|
2090
2090
|
existing.push(source);
|
|
2091
2091
|
byTarget.set(target, existing);
|
|
@@ -2162,30 +2162,33 @@ var validateScopeAndPath = (path, scope) => {
|
|
|
2162
2162
|
};
|
|
2163
2163
|
var registerListenerLegacy = (store, registration) => {
|
|
2164
2164
|
const { graphs } = store._internal;
|
|
2165
|
-
const { listeners, listenerHandlers } = graphs;
|
|
2166
|
-
|
|
2165
|
+
const { listeners: listeners2, listenerHandlers } = graphs;
|
|
2166
|
+
if (registration.scope === void 0) {
|
|
2167
|
+
registration.scope = registration.path;
|
|
2168
|
+
}
|
|
2169
|
+
validateScopeAndPath(registration.path, registration.scope ?? null);
|
|
2167
2170
|
const subscriberId = nextSubscriberId++;
|
|
2168
2171
|
const mapKey = registration.path ?? "";
|
|
2169
|
-
const existing =
|
|
2172
|
+
const existing = listeners2.get(mapKey) ?? [];
|
|
2170
2173
|
const originalFn = registration.fn;
|
|
2171
2174
|
registration.fn = (changes, state) => store._internal.timing.run("listeners", () => originalFn(changes, state), {
|
|
2172
2175
|
path: mapKey,
|
|
2173
2176
|
name: "listener"
|
|
2174
2177
|
});
|
|
2175
|
-
|
|
2178
|
+
listeners2.set(mapKey, [...existing, registration]);
|
|
2176
2179
|
listenerHandlers.set(subscriberId, {
|
|
2177
2180
|
scope: registration.scope,
|
|
2178
2181
|
fn: registration.fn
|
|
2179
2182
|
});
|
|
2180
2183
|
updateSortedListenerPaths(graphs);
|
|
2181
2184
|
return () => {
|
|
2182
|
-
const list =
|
|
2185
|
+
const list = listeners2.get(mapKey);
|
|
2183
2186
|
if (list) {
|
|
2184
2187
|
const filtered = list.filter((l) => l !== registration);
|
|
2185
2188
|
if (filtered.length > 0) {
|
|
2186
|
-
|
|
2189
|
+
listeners2.set(mapKey, filtered);
|
|
2187
2190
|
} else {
|
|
2188
|
-
|
|
2191
|
+
listeners2.delete(mapKey);
|
|
2189
2192
|
}
|
|
2190
2193
|
updateSortedListenerPaths(graphs);
|
|
2191
2194
|
}
|
|
@@ -2264,17 +2267,20 @@ var registerSyncPairsBatch = (store, pairs) => {
|
|
|
2264
2267
|
var registerSideEffectsImpl = (store, id, effects) => {
|
|
2265
2268
|
const cleanups = [];
|
|
2266
2269
|
if (effects.syncPaths) {
|
|
2267
|
-
const
|
|
2270
|
+
const pairs = effects.syncPaths;
|
|
2271
|
+
const cleanup = registerSyncPairsBatch(store, pairs);
|
|
2268
2272
|
cleanups.push(cleanup);
|
|
2269
2273
|
}
|
|
2270
2274
|
if (effects.flipPaths) {
|
|
2271
|
-
|
|
2275
|
+
const pairs = effects.flipPaths;
|
|
2276
|
+
for (const [path1, path2] of pairs) {
|
|
2272
2277
|
const cleanup = registerFlipPair(store, path1, path2);
|
|
2273
2278
|
cleanups.push(cleanup);
|
|
2274
2279
|
}
|
|
2275
2280
|
}
|
|
2276
2281
|
if (effects.aggregations) {
|
|
2277
|
-
const
|
|
2282
|
+
const pairs = effects.aggregations;
|
|
2283
|
+
const cleanup = registerAggregations(store, id, pairs);
|
|
2278
2284
|
cleanups.push(cleanup);
|
|
2279
2285
|
}
|
|
2280
2286
|
if (effects.listeners) {
|
|
@@ -2299,12 +2305,12 @@ var registerSideEffects = (store, id, effects) => store._internal.timing.run(
|
|
|
2299
2305
|
// src/sideEffects/registration.wasm-impl.ts
|
|
2300
2306
|
var nextSubscriberId2 = 0;
|
|
2301
2307
|
var registerSideEffects2 = (store, id, effects) => {
|
|
2302
|
-
const
|
|
2303
|
-
const
|
|
2304
|
-
const
|
|
2308
|
+
const syncPairs2 = effects.syncPaths ?? [];
|
|
2309
|
+
const flipPairs2 = effects.flipPaths ?? [];
|
|
2310
|
+
const aggregationPairs2 = (effects.aggregations ?? []).map(
|
|
2305
2311
|
([target, source, condition]) => condition ? [target, source, JSON.stringify(condition)] : [target, source]
|
|
2306
2312
|
);
|
|
2307
|
-
const
|
|
2313
|
+
const computationPairs2 = (effects.computations ?? []).map(
|
|
2308
2314
|
([op, target, source, condition]) => condition ? [
|
|
2309
2315
|
op,
|
|
2310
2316
|
target,
|
|
@@ -2316,10 +2322,11 @@ var registerSideEffects2 = (store, id, effects) => {
|
|
|
2316
2322
|
triggers,
|
|
2317
2323
|
targets: opts?.expandMatch ? targets.map((t) => t.replace(/\[\*\]/g, "[**]")) : targets
|
|
2318
2324
|
}));
|
|
2319
|
-
const
|
|
2325
|
+
const listeners2 = effects.listeners?.map((listener) => {
|
|
2320
2326
|
const { listenerHandlers } = store._internal.graphs;
|
|
2321
2327
|
const subscriberId = nextSubscriberId2++;
|
|
2322
2328
|
const originalFn = listener.fn;
|
|
2329
|
+
const effectiveScope = listener.scope === void 0 ? listener.path : listener.scope;
|
|
2323
2330
|
const mapKey = listener.path ?? "";
|
|
2324
2331
|
const wrappedFn = (changes, state) => store._internal.timing.run(
|
|
2325
2332
|
"listeners",
|
|
@@ -2330,27 +2337,27 @@ var registerSideEffects2 = (store, id, effects) => {
|
|
|
2330
2337
|
}
|
|
2331
2338
|
);
|
|
2332
2339
|
listenerHandlers.set(subscriberId, {
|
|
2333
|
-
scope:
|
|
2340
|
+
scope: effectiveScope,
|
|
2334
2341
|
fn: wrappedFn
|
|
2335
2342
|
});
|
|
2336
2343
|
return {
|
|
2337
2344
|
subscriber_id: subscriberId,
|
|
2338
2345
|
topic_path: listener.path ?? "",
|
|
2339
|
-
scope_path:
|
|
2346
|
+
scope_path: effectiveScope ?? ""
|
|
2340
2347
|
};
|
|
2341
2348
|
});
|
|
2342
2349
|
const pipeline = store._internal.pipeline;
|
|
2343
2350
|
const registrationId = `sideEffects-${id}`;
|
|
2344
2351
|
const result = pipeline.registerSideEffects({
|
|
2345
2352
|
registration_id: registrationId,
|
|
2346
|
-
...
|
|
2347
|
-
...
|
|
2348
|
-
...
|
|
2349
|
-
...
|
|
2350
|
-
computation_pairs:
|
|
2353
|
+
...syncPairs2.length > 0 && { sync_pairs: syncPairs2 },
|
|
2354
|
+
...flipPairs2.length > 0 && { flip_pairs: flipPairs2 },
|
|
2355
|
+
...aggregationPairs2.length > 0 && { aggregation_pairs: aggregationPairs2 },
|
|
2356
|
+
...computationPairs2.length > 0 && {
|
|
2357
|
+
computation_pairs: computationPairs2
|
|
2351
2358
|
},
|
|
2352
2359
|
...clearPaths && clearPaths.length > 0 && { clear_paths: clearPaths },
|
|
2353
|
-
...
|
|
2360
|
+
...listeners2 && listeners2.length > 0 && { listeners: listeners2 }
|
|
2354
2361
|
});
|
|
2355
2362
|
if (result.sync_changes.length > 0) {
|
|
2356
2363
|
applyBatch(
|
|
@@ -2373,9 +2380,9 @@ var registerSideEffects2 = (store, id, effects) => {
|
|
|
2373
2380
|
const cleanup = () => {
|
|
2374
2381
|
pipeline.unregisterSideEffects(registrationId);
|
|
2375
2382
|
effects.listeners?.forEach((_listener, index) => {
|
|
2376
|
-
if (
|
|
2383
|
+
if (listeners2 && listeners2[index]) {
|
|
2377
2384
|
store._internal.graphs.listenerHandlers.delete(
|
|
2378
|
-
|
|
2385
|
+
listeners2[index].subscriber_id
|
|
2379
2386
|
);
|
|
2380
2387
|
}
|
|
2381
2388
|
});
|
|
@@ -2847,6 +2854,119 @@ var createProvider = (storeConfig) => {
|
|
|
2847
2854
|
return Provider;
|
|
2848
2855
|
};
|
|
2849
2856
|
|
|
2857
|
+
// src/utils/pair-helpers.ts
|
|
2858
|
+
var syncPairs = () => (pairs) => pairs;
|
|
2859
|
+
var flipPairs = () => (pairs) => pairs;
|
|
2860
|
+
var aggregationPairs = () => (pairs) => pairs;
|
|
2861
|
+
var computationPairs = () => (pairs) => pairs;
|
|
2862
|
+
var listeners = () => (items) => items;
|
|
2863
|
+
|
|
2864
|
+
// src/store/warm-pair-helpers.ts
|
|
2865
|
+
var createWarmPairHelpers = () => ({
|
|
2866
|
+
/**
|
|
2867
|
+
* Pre-warmed sync pair validator — DATA type is already bound.
|
|
2868
|
+
* Validates that both paths in each pair resolve to the same value type.
|
|
2869
|
+
* Pass the result to `useSideEffects` as `syncPaths`.
|
|
2870
|
+
*
|
|
2871
|
+
* @example
|
|
2872
|
+
* ```typescript
|
|
2873
|
+
* const { useSideEffects, syncPairs } = createGenericStore<MyState>()
|
|
2874
|
+
*
|
|
2875
|
+
* // Type-safe — no need to repeat <MyState>
|
|
2876
|
+
* const syncs = syncPairs([
|
|
2877
|
+
* ['user.email', 'profile.email'], // ✓ both string
|
|
2878
|
+
* ['user.age', 'profile.age'], // ✓ both number
|
|
2879
|
+
* ])
|
|
2880
|
+
*
|
|
2881
|
+
* // Inside a component:
|
|
2882
|
+
* useSideEffects('my-syncs', { syncPaths: syncs })
|
|
2883
|
+
* ```
|
|
2884
|
+
*/
|
|
2885
|
+
syncPairs: syncPairs(),
|
|
2886
|
+
/**
|
|
2887
|
+
* Pre-warmed flip pair validator — DATA type is already bound.
|
|
2888
|
+
* Validates that both paths in each pair resolve to the same value type.
|
|
2889
|
+
* Used for inverted boolean synchronization. Pass the result to `useSideEffects` as `flipPaths`.
|
|
2890
|
+
*
|
|
2891
|
+
* @example
|
|
2892
|
+
* ```typescript
|
|
2893
|
+
* const { useSideEffects, flipPairs } = createGenericStore<MyState>()
|
|
2894
|
+
*
|
|
2895
|
+
* const flips = flipPairs([
|
|
2896
|
+
* ['isExpanded', 'isCollapsed'], // ✓ both boolean
|
|
2897
|
+
* ])
|
|
2898
|
+
*
|
|
2899
|
+
* // Inside a component:
|
|
2900
|
+
* useSideEffects('my-flips', { flipPaths: flips })
|
|
2901
|
+
* ```
|
|
2902
|
+
*/
|
|
2903
|
+
flipPairs: flipPairs(),
|
|
2904
|
+
/**
|
|
2905
|
+
* Pre-warmed aggregation pair validator — DATA type is already bound.
|
|
2906
|
+
* Each pair is `[target, source]` or `[target, source, BoolLogic]`.
|
|
2907
|
+
* Validates that target and source resolve to the same value type.
|
|
2908
|
+
* Pass the result to `useSideEffects` as `aggregations`.
|
|
2909
|
+
*
|
|
2910
|
+
* @example
|
|
2911
|
+
* ```typescript
|
|
2912
|
+
* const { useSideEffects, aggregationPairs } = createGenericStore<MyState>()
|
|
2913
|
+
*
|
|
2914
|
+
* const aggs = aggregationPairs([
|
|
2915
|
+
* ['total', 'price1'],
|
|
2916
|
+
* ['total', 'price2', { IS_EQUAL: ['price2.disabled', true] }],
|
|
2917
|
+
* ])
|
|
2918
|
+
*
|
|
2919
|
+
* // Inside a component:
|
|
2920
|
+
* useSideEffects('my-aggs', { aggregations: aggs })
|
|
2921
|
+
* ```
|
|
2922
|
+
*/
|
|
2923
|
+
aggregationPairs: aggregationPairs(),
|
|
2924
|
+
/**
|
|
2925
|
+
* Pre-warmed computation pair validator — DATA type is already bound.
|
|
2926
|
+
* Each pair is `[op, target, source]` or `[op, target, source, BoolLogic]`.
|
|
2927
|
+
* Both target and source must be number paths.
|
|
2928
|
+
* Pass the result to `useSideEffects` as `computations`.
|
|
2929
|
+
*
|
|
2930
|
+
* @example
|
|
2931
|
+
* ```typescript
|
|
2932
|
+
* const { useSideEffects, computationPairs } = createGenericStore<MyState>()
|
|
2933
|
+
*
|
|
2934
|
+
* const comps = computationPairs([
|
|
2935
|
+
* ['SUM', 'total', 'price1'],
|
|
2936
|
+
* ['AVG', 'average', 'score1'],
|
|
2937
|
+
* ])
|
|
2938
|
+
*
|
|
2939
|
+
* // Inside a component:
|
|
2940
|
+
* useSideEffects('my-comps', { computations: comps })
|
|
2941
|
+
* ```
|
|
2942
|
+
*/
|
|
2943
|
+
computationPairs: computationPairs(),
|
|
2944
|
+
/**
|
|
2945
|
+
* Pre-warmed listener validator — DATA type is already bound.
|
|
2946
|
+
* Validates path/scope relationships and derives fn types from scope.
|
|
2947
|
+
* Pass the result to `useSideEffects` as `listeners`.
|
|
2948
|
+
*
|
|
2949
|
+
* @example
|
|
2950
|
+
* ```typescript
|
|
2951
|
+
* const { useSideEffects, listeners } = createGenericStore<MyState>()
|
|
2952
|
+
*
|
|
2953
|
+
* const myListeners = listeners([
|
|
2954
|
+
* {
|
|
2955
|
+
* path: 'user.profile.name',
|
|
2956
|
+
* scope: 'user.profile',
|
|
2957
|
+
* fn: (changes, state) => {
|
|
2958
|
+
* // state is typed as MyState['user']['profile']
|
|
2959
|
+
* return undefined
|
|
2960
|
+
* }
|
|
2961
|
+
* },
|
|
2962
|
+
* ])
|
|
2963
|
+
*
|
|
2964
|
+
* useSideEffects('my-listeners', { listeners: myListeners })
|
|
2965
|
+
* ```
|
|
2966
|
+
*/
|
|
2967
|
+
listeners: listeners()
|
|
2968
|
+
});
|
|
2969
|
+
|
|
2850
2970
|
// src/store/create-store.ts
|
|
2851
2971
|
var createGenericStore = (config) => {
|
|
2852
2972
|
const Provider = createProvider(config);
|
|
@@ -2947,7 +3067,8 @@ var createGenericStore = (config) => {
|
|
|
2947
3067
|
useSideEffects,
|
|
2948
3068
|
useConcerns,
|
|
2949
3069
|
withConcerns,
|
|
2950
|
-
withMeta
|
|
3070
|
+
withMeta,
|
|
3071
|
+
...createWarmPairHelpers()
|
|
2951
3072
|
};
|
|
2952
3073
|
};
|
|
2953
3074
|
|
|
@@ -3106,7 +3227,9 @@ var applyChangesToObject = (obj, changes) => {
|
|
|
3106
3227
|
};
|
|
3107
3228
|
export {
|
|
3108
3229
|
_,
|
|
3230
|
+
aggregationPairs,
|
|
3109
3231
|
applyChangesToObject,
|
|
3232
|
+
computationPairs,
|
|
3110
3233
|
createGenericStore,
|
|
3111
3234
|
deepClone,
|
|
3112
3235
|
defaultConcerns,
|
|
@@ -3114,14 +3237,17 @@ export {
|
|
|
3114
3237
|
evaluateBoolLogic,
|
|
3115
3238
|
extractPlaceholders,
|
|
3116
3239
|
findConcern,
|
|
3240
|
+
flipPairs,
|
|
3117
3241
|
hashKey,
|
|
3118
3242
|
interpolateTemplate,
|
|
3119
3243
|
is,
|
|
3244
|
+
listeners,
|
|
3120
3245
|
prebuilts_exports as prebuilts,
|
|
3121
3246
|
registerFlipPair,
|
|
3122
3247
|
registerListenerLegacy,
|
|
3123
3248
|
registerSideEffects,
|
|
3124
3249
|
registerSyncPairsBatch,
|
|
3250
|
+
syncPairs,
|
|
3125
3251
|
useBufferedField,
|
|
3126
3252
|
useKeyboardSelect,
|
|
3127
3253
|
useThrottledField,
|