@victorylabs/params 0.2.0 → 0.3.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/{chunk-S276UVQK.js → chunk-DSAHBEAQ.js} +43 -17
- package/dist/chunk-DSAHBEAQ.js.map +1 -0
- package/dist/devtools.d.cts +1 -1
- package/dist/devtools.d.ts +1 -1
- package/dist/index.cjs +42 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/integrations/forms-reverse.cjs +42 -16
- package/dist/integrations/forms-reverse.cjs.map +1 -1
- package/dist/integrations/forms-reverse.js +1 -1
- package/dist/integrations/forms.cjs +42 -16
- package/dist/integrations/forms.cjs.map +1 -1
- package/dist/integrations/forms.js +1 -1
- package/dist/{params-store-Cgbtn53j.d.cts → params-store-4Lcb1M_X.d.cts} +29 -1
- package/dist/{params-store-CguA9-yr.d.ts → params-store-f3pmPdw3.d.ts} +29 -1
- package/dist/react.cjs +98 -53
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +42 -4
- package/dist/react.d.ts +42 -4
- package/dist/react.js +37 -19
- package/dist/react.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-S276UVQK.js.map +0 -1
package/dist/react.cjs
CHANGED
|
@@ -20,14 +20,30 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/react/index.ts
|
|
21
21
|
var react_exports = {};
|
|
22
22
|
__export(react_exports, {
|
|
23
|
+
useDebouncedValue: () => useDebouncedValue,
|
|
23
24
|
useFieldInput: () => useFieldInput,
|
|
24
25
|
useFieldValue: () => useFieldValue,
|
|
25
26
|
useParams: () => useParams
|
|
26
27
|
});
|
|
27
28
|
module.exports = __toCommonJS(react_exports);
|
|
28
29
|
|
|
30
|
+
// src/react/use-debounced-value.ts
|
|
31
|
+
var import_react = require("react");
|
|
32
|
+
function useDebouncedValue(value, ms) {
|
|
33
|
+
const [debounced, setDebounced] = (0, import_react.useState)(value);
|
|
34
|
+
(0, import_react.useEffect)(() => {
|
|
35
|
+
if (ms <= 0) {
|
|
36
|
+
setDebounced(value);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const id = setTimeout(() => setDebounced(value), ms);
|
|
40
|
+
return () => clearTimeout(id);
|
|
41
|
+
}, [value, ms]);
|
|
42
|
+
return debounced;
|
|
43
|
+
}
|
|
44
|
+
|
|
29
45
|
// src/react/use-field-input.tsx
|
|
30
|
-
var
|
|
46
|
+
var import_react3 = require("react");
|
|
31
47
|
|
|
32
48
|
// src/schema.ts
|
|
33
49
|
function isStandardSchema(spec) {
|
|
@@ -121,10 +137,10 @@ function extractEnumValues(spec) {
|
|
|
121
137
|
}
|
|
122
138
|
|
|
123
139
|
// src/react/use-field-value.ts
|
|
124
|
-
var
|
|
140
|
+
var import_react2 = require("react");
|
|
125
141
|
function useFieldValue(store, path) {
|
|
126
|
-
const [, forceRender] = (0,
|
|
127
|
-
(0,
|
|
142
|
+
const [, forceRender] = (0, import_react2.useReducer)((tick) => tick + 1, 0);
|
|
143
|
+
(0, import_react2.useEffect)(() => store.subscribe(path, forceRender), [store, path]);
|
|
128
144
|
return store.getValue(path);
|
|
129
145
|
}
|
|
130
146
|
|
|
@@ -133,10 +149,10 @@ function useFieldInput(store, path) {
|
|
|
133
149
|
const storeValue = useFieldValue(store, path);
|
|
134
150
|
const config = store.getFieldConfig(path);
|
|
135
151
|
const debounceMs = config?.debounce ?? 0;
|
|
136
|
-
const [shadow, setShadow] = (0,
|
|
137
|
-
const debouncerRef = (0,
|
|
138
|
-
const lastStoreValueRef = (0,
|
|
139
|
-
(0,
|
|
152
|
+
const [shadow, setShadow] = (0, import_react3.useState)(null);
|
|
153
|
+
const debouncerRef = (0, import_react3.useRef)(null);
|
|
154
|
+
const lastStoreValueRef = (0, import_react3.useRef)(storeValue);
|
|
155
|
+
(0, import_react3.useEffect)(() => {
|
|
140
156
|
if (Object.is(lastStoreValueRef.current, storeValue)) return;
|
|
141
157
|
lastStoreValueRef.current = storeValue;
|
|
142
158
|
if (shadow !== null && shadow !== defaultSerialize(storeValue)) {
|
|
@@ -147,19 +163,19 @@ function useFieldInput(store, path) {
|
|
|
147
163
|
if (debounceMs > 0 && debouncerRef.current === null) {
|
|
148
164
|
debouncerRef.current = createDebouncer(store, path, debounceMs, () => setShadow(null));
|
|
149
165
|
}
|
|
150
|
-
const onChange = (0,
|
|
166
|
+
const onChange = (0, import_react3.useCallback)(
|
|
151
167
|
(event) => {
|
|
152
168
|
const next = event.target.value;
|
|
153
169
|
if (debounceMs > 0) {
|
|
154
170
|
setShadow(next);
|
|
155
171
|
debouncerRef.current?.trigger(next);
|
|
156
172
|
} else {
|
|
157
|
-
store.
|
|
173
|
+
store.setField(path, next);
|
|
158
174
|
}
|
|
159
175
|
},
|
|
160
176
|
[store, path, debounceMs]
|
|
161
177
|
);
|
|
162
|
-
const onBlur = (0,
|
|
178
|
+
const onBlur = (0, import_react3.useCallback)(() => {
|
|
163
179
|
debouncerRef.current?.flush();
|
|
164
180
|
}, []);
|
|
165
181
|
return {
|
|
@@ -174,7 +190,7 @@ function createDebouncer(store, path, ms, onCommit) {
|
|
|
174
190
|
let pendingValue = null;
|
|
175
191
|
const commit = () => {
|
|
176
192
|
if (pendingValue !== null) {
|
|
177
|
-
store.
|
|
193
|
+
store.setField(path, pendingValue);
|
|
178
194
|
pendingValue = null;
|
|
179
195
|
onCommit();
|
|
180
196
|
}
|
|
@@ -202,10 +218,10 @@ function createDebouncer(store, path, ms, onCommit) {
|
|
|
202
218
|
}
|
|
203
219
|
|
|
204
220
|
// src/react/use-params.tsx
|
|
205
|
-
var
|
|
221
|
+
var import_react5 = require("react");
|
|
206
222
|
|
|
207
223
|
// src/react/use-shared-store.ts
|
|
208
|
-
var
|
|
224
|
+
var import_react4 = require("react");
|
|
209
225
|
|
|
210
226
|
// src/dev.ts
|
|
211
227
|
var isDev = (() => {
|
|
@@ -485,17 +501,43 @@ var ParamsStore = class {
|
|
|
485
501
|
getFieldConfig(path) {
|
|
486
502
|
return this.fieldConfigs[path];
|
|
487
503
|
}
|
|
488
|
-
|
|
504
|
+
// ─── Writes ───────────────────────────────────────────────────────────
|
|
505
|
+
/**
|
|
506
|
+
* Apply a partial update — write multiple fields at once.
|
|
507
|
+
*
|
|
508
|
+
* `set(partial)` is the canonical write form. The path-and-value form
|
|
509
|
+
* (`set(path, value)` historically) is now `setField(path, value)` —
|
|
510
|
+
* see {@link setField}. The split keeps `set`'s single-signature
|
|
511
|
+
* inference clean for the common `set({ [key]: value })` pattern, which
|
|
512
|
+
* previously required `as Partial<T>` casts because TypeScript couldn't
|
|
513
|
+
* resolve the overload from a generic-keyed object literal.
|
|
514
|
+
*
|
|
515
|
+
* @example
|
|
516
|
+
* ```ts
|
|
517
|
+
* p.set({ page: 1, sort: 'updated' })
|
|
518
|
+
* p.set({ [key]: value }) // works without a cast now
|
|
519
|
+
* ```
|
|
520
|
+
*/
|
|
521
|
+
set(partial, options) {
|
|
489
522
|
if (this.disposed) return;
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
523
|
+
this.applyUpdates(partial, options);
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Write a single field by path. Equivalent to `set({ [path]: value })`
|
|
527
|
+
* but skips the object-literal allocation and avoids the inference issue
|
|
528
|
+
* that motivated splitting the API.
|
|
529
|
+
*
|
|
530
|
+
* @example
|
|
531
|
+
* ```ts
|
|
532
|
+
* p.setField('query', 'react')
|
|
533
|
+
* p.setField('filters.tags', ['ts', 'react'])
|
|
534
|
+
* ```
|
|
535
|
+
*/
|
|
536
|
+
setField(path, value, options) {
|
|
537
|
+
if (this.disposed) return;
|
|
538
|
+
this.applyUpdates({ [path]: value }, options);
|
|
539
|
+
}
|
|
540
|
+
applyUpdates(updates, options) {
|
|
499
541
|
const initialChanges = {};
|
|
500
542
|
for (const [path, v] of Object.entries(updates)) {
|
|
501
543
|
const old = deepGet(this.values, path);
|
|
@@ -527,13 +569,13 @@ var ParamsStore = class {
|
|
|
527
569
|
/** Boolean-flip helper. */
|
|
528
570
|
toggle(path, options) {
|
|
529
571
|
const current = this.getValue(path);
|
|
530
|
-
this.
|
|
572
|
+
this.setField(path, !current, options);
|
|
531
573
|
}
|
|
532
574
|
/** Push a value onto an array field. */
|
|
533
575
|
append(path, value, options) {
|
|
534
576
|
const current = this.getValue(path);
|
|
535
577
|
if (!Array.isArray(current)) return;
|
|
536
|
-
this.
|
|
578
|
+
this.setField(path, [...current, value], options);
|
|
537
579
|
}
|
|
538
580
|
/** Remove the first array element matching `value` by deepEqual. */
|
|
539
581
|
remove(path, value, options) {
|
|
@@ -541,14 +583,14 @@ var ParamsStore = class {
|
|
|
541
583
|
if (!Array.isArray(current)) return;
|
|
542
584
|
const idx = current.findIndex((item) => deepEqual(item, value));
|
|
543
585
|
if (idx === -1) return;
|
|
544
|
-
this.
|
|
586
|
+
this.setField(path, [...current.slice(0, idx), ...current.slice(idx + 1)], options);
|
|
545
587
|
}
|
|
546
588
|
/** Remove the array element at the given index. */
|
|
547
589
|
removeAt(path, index, options) {
|
|
548
590
|
const current = this.getValue(path);
|
|
549
591
|
if (!Array.isArray(current)) return;
|
|
550
592
|
if (index < 0 || index >= current.length) return;
|
|
551
|
-
this.
|
|
593
|
+
this.setField(path, [...current.slice(0, index), ...current.slice(index + 1)], options);
|
|
552
594
|
}
|
|
553
595
|
cycle(path, valuesOrOptions, maybeOptions) {
|
|
554
596
|
let resolved;
|
|
@@ -574,12 +616,12 @@ var ParamsStore = class {
|
|
|
574
616
|
const current = this.getValue(path);
|
|
575
617
|
const idx = resolved.findIndex((o) => deepEqual(o, current));
|
|
576
618
|
const next = idx === -1 ? resolved[0] : resolved[(idx + 1) % resolved.length];
|
|
577
|
-
this.
|
|
619
|
+
this.setField(path, next, setOpts);
|
|
578
620
|
}
|
|
579
621
|
/** Reset a single field to its default. */
|
|
580
622
|
clear(path, options) {
|
|
581
623
|
const def = deepGet(this.defaults, path);
|
|
582
|
-
this.
|
|
624
|
+
this.setField(path, def, options);
|
|
583
625
|
}
|
|
584
626
|
/** Reset all fields to defaults; optional partial overrides + SetOptions. */
|
|
585
627
|
reset(values, options) {
|
|
@@ -833,11 +875,11 @@ function warnOnDuplicateName(def) {
|
|
|
833
875
|
|
|
834
876
|
// src/react/use-shared-store.ts
|
|
835
877
|
function useSharedStore(def) {
|
|
836
|
-
const storeRef = (0,
|
|
878
|
+
const storeRef = (0, import_react4.useRef)(null);
|
|
837
879
|
if (storeRef.current === null) {
|
|
838
880
|
storeRef.current = acquire(def);
|
|
839
881
|
}
|
|
840
|
-
(0,
|
|
882
|
+
(0, import_react4.useEffect)(
|
|
841
883
|
() => () => {
|
|
842
884
|
release(def);
|
|
843
885
|
storeRef.current = null;
|
|
@@ -850,35 +892,33 @@ function useSharedStore(def) {
|
|
|
850
892
|
// src/react/use-params.tsx
|
|
851
893
|
function useParams(def) {
|
|
852
894
|
const store = useSharedStore(def);
|
|
853
|
-
const [, forceRender] = (0,
|
|
854
|
-
(0,
|
|
855
|
-
const set = (0,
|
|
856
|
-
(
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
}
|
|
862
|
-
}),
|
|
895
|
+
const [, forceRender] = (0, import_react5.useReducer)((tick) => tick + 1, 0);
|
|
896
|
+
(0, import_react5.useEffect)(() => store.subscribe("", forceRender), [store]);
|
|
897
|
+
const set = (0, import_react5.useCallback)(
|
|
898
|
+
(partial, options) => store.set(partial, options),
|
|
899
|
+
[store]
|
|
900
|
+
);
|
|
901
|
+
const setField = (0, import_react5.useCallback)(
|
|
902
|
+
(path, value2, options) => store.setField(path, value2, options),
|
|
863
903
|
[store]
|
|
864
904
|
);
|
|
865
|
-
const toggle = (0,
|
|
905
|
+
const toggle = (0, import_react5.useCallback)(
|
|
866
906
|
(path, options) => store.toggle(path, options),
|
|
867
907
|
[store]
|
|
868
908
|
);
|
|
869
|
-
const append = (0,
|
|
909
|
+
const append = (0, import_react5.useCallback)(
|
|
870
910
|
(path, value2, options) => store.append(path, value2, options),
|
|
871
911
|
[store]
|
|
872
912
|
);
|
|
873
|
-
const removeFn = (0,
|
|
913
|
+
const removeFn = (0, import_react5.useCallback)(
|
|
874
914
|
(path, value2, options) => store.remove(path, value2, options),
|
|
875
915
|
[store]
|
|
876
916
|
);
|
|
877
|
-
const removeAt = (0,
|
|
917
|
+
const removeAt = (0, import_react5.useCallback)(
|
|
878
918
|
(path, index, options) => store.removeAt(path, index, options),
|
|
879
919
|
[store]
|
|
880
920
|
);
|
|
881
|
-
const cycle = (0,
|
|
921
|
+
const cycle = (0, import_react5.useCallback)(
|
|
882
922
|
((path, valuesOrOptions, maybeOptions) => {
|
|
883
923
|
if (Array.isArray(valuesOrOptions)) {
|
|
884
924
|
store.cycle(path, valuesOrOptions, maybeOptions);
|
|
@@ -890,32 +930,36 @@ function useParams(def) {
|
|
|
890
930
|
}),
|
|
891
931
|
[store]
|
|
892
932
|
);
|
|
893
|
-
const clear = (0,
|
|
933
|
+
const clear = (0, import_react5.useCallback)(
|
|
894
934
|
(path, options) => store.clear(path, options),
|
|
895
935
|
[store]
|
|
896
936
|
);
|
|
897
|
-
const reset = (0,
|
|
937
|
+
const reset = (0, import_react5.useCallback)(
|
|
898
938
|
(values, options) => store.reset(values, options),
|
|
899
939
|
[store]
|
|
900
940
|
);
|
|
901
|
-
const subscribe = (0,
|
|
941
|
+
const subscribe = (0, import_react5.useCallback)(
|
|
902
942
|
(path, listener) => store.subscribe(path, listener),
|
|
903
943
|
[store]
|
|
904
944
|
);
|
|
905
|
-
const toQuery = (0,
|
|
945
|
+
const toQuery = (0, import_react5.useCallback)(
|
|
906
946
|
(overrides) => store.toQuery(overrides),
|
|
907
947
|
[store]
|
|
908
948
|
);
|
|
909
|
-
const href = (0,
|
|
949
|
+
const href = (0, import_react5.useCallback)((overrides) => store.href(overrides), [store]);
|
|
910
950
|
const value = (path) => useFieldValue(store, path);
|
|
911
|
-
const deferred = (path) => (0,
|
|
951
|
+
const deferred = (path) => (0, import_react5.useDeferredValue)(useFieldValue(store, path));
|
|
912
952
|
const input = (path) => useFieldInput(store, path);
|
|
913
953
|
return {
|
|
954
|
+
// Cast: store.getValues() returns Partial<T> for the storage layer's
|
|
955
|
+
// sake, but every field in ParamsDefinition declares a default so the
|
|
956
|
+
// hydrated view is structurally complete. See ParamsController.values.
|
|
914
957
|
values: store.getValues(),
|
|
915
958
|
value,
|
|
916
959
|
deferred,
|
|
917
960
|
input,
|
|
918
961
|
set,
|
|
962
|
+
setField,
|
|
919
963
|
toggle,
|
|
920
964
|
append,
|
|
921
965
|
remove: removeFn,
|
|
@@ -931,6 +975,7 @@ function useParams(def) {
|
|
|
931
975
|
}
|
|
932
976
|
// Annotate the CommonJS export names for ESM import in node:
|
|
933
977
|
0 && (module.exports = {
|
|
978
|
+
useDebouncedValue,
|
|
934
979
|
useFieldInput,
|
|
935
980
|
useFieldValue,
|
|
936
981
|
useParams
|