yummies 7.11.0 → 7.13.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 +5 -87
- package/async.cjs +179 -48
- package/async.cjs.map +1 -1
- package/async.d.ts +125 -7
- package/async.js +180 -54
- package/async.js.map +1 -1
- package/chunk-CVq3Gv4J.cjs +50 -0
- package/chunk-YKewjYmz.js +37 -0
- package/common.cjs +48 -8
- package/common.cjs.map +1 -1
- package/common.d.ts +53 -2
- package/common.js +49 -11
- package/common.js.map +1 -1
- package/complex.cjs +275 -128
- package/complex.cjs.map +1 -1
- package/complex.d.ts +66 -0
- package/complex.js +275 -133
- package/complex.js.map +1 -1
- package/cookie.cjs +17 -7
- package/cookie.cjs.map +1 -1
- package/cookie.d.ts +26 -0
- package/cookie.js +18 -9
- package/cookie.js.map +1 -1
- package/css.cjs +163 -39
- package/css.cjs.map +1 -1
- package/css.d.ts +115 -6
- package/css.js +159 -41
- package/css.js.map +1 -1
- package/data.cjs +90 -55
- package/data.cjs.map +1 -1
- package/data.d.ts +50 -0
- package/data.js +91 -61
- package/data.js.map +1 -1
- package/date-time.cjs +594 -412
- package/date-time.cjs.map +1 -1
- package/date-time.d.ts +105 -0
- package/date-time.js +591 -421
- package/date-time.js.map +1 -1
- package/device.cjs +65 -23
- package/device.cjs.map +1 -1
- package/device.d.ts +49 -0
- package/device.js +66 -31
- package/device.js.map +1 -1
- package/encodings.cjs +275 -266
- package/encodings.cjs.map +1 -1
- package/encodings.d.ts +25 -0
- package/encodings.js +276 -268
- package/encodings.js.map +1 -1
- package/errors.cjs +36 -18
- package/errors.cjs.map +1 -1
- package/errors.d.ts +17 -0
- package/errors.js +35 -19
- package/errors.js.map +1 -1
- package/file.cjs +58 -24
- package/file.cjs.map +1 -1
- package/file.d.ts +32 -0
- package/file.js +59 -27
- package/file.js.map +1 -1
- package/format.cjs +125 -83
- package/format.cjs.map +1 -1
- package/format.d.ts +18 -0
- package/format.js +118 -82
- package/format.js.map +1 -1
- package/html.cjs +242 -137
- package/html.cjs.map +1 -1
- package/html.d.ts +81 -0
- package/html.js +239 -150
- package/html.js.map +1 -1
- package/id.cjs +90 -17
- package/id.cjs.map +1 -1
- package/id.d.ts +16 -0
- package/id.js +89 -24
- package/id.js.map +1 -1
- package/imports.cjs +57 -29
- package/imports.cjs.map +1 -1
- package/imports.d.ts +24 -0
- package/imports.js +56 -31
- package/imports.js.map +1 -1
- package/math.cjs +32 -6
- package/math.cjs.map +1 -1
- package/math.d.ts +33 -0
- package/math.js +33 -10
- package/math.js.map +1 -1
- package/media.cjs +291 -84
- package/media.cjs.map +1 -1
- package/media.d.ts +204 -2
- package/media.js +290 -93
- package/media.js.map +1 -1
- package/mobx.cjs +449 -193
- package/mobx.cjs.map +1 -1
- package/mobx.d.ts +108 -0
- package/mobx.js +447 -200
- package/mobx.js.map +1 -1
- package/ms.cjs +37 -10
- package/ms.cjs.map +1 -1
- package/ms.d.ts +16 -0
- package/ms.js +38 -13
- package/ms.js.map +1 -1
- package/number.cjs +29 -7
- package/number.cjs.map +1 -1
- package/number.d.ts +16 -0
- package/number.js +30 -9
- package/number.js.map +1 -1
- package/package.json +11 -3
- package/parser.cjs +117 -64
- package/parser.cjs.map +1 -1
- package/parser.d.ts +17 -0
- package/parser.js +111 -64
- package/parser.js.map +1 -1
- package/price.cjs +24 -18
- package/price.cjs.map +1 -1
- package/price.d.ts +24 -0
- package/price.js +25 -20
- package/price.js.map +1 -1
- package/random.cjs +95 -13
- package/random.cjs.map +1 -1
- package/random.d.ts +80 -0
- package/random.js +96 -22
- package/random.js.map +1 -1
- package/react.cjs +673 -214
- package/react.cjs.map +1 -1
- package/react.d.ts +21 -0
- package/react.js +674 -239
- package/react.js.map +1 -1
- package/sound.cjs +30 -9
- package/sound.cjs.map +1 -1
- package/sound.d.ts +16 -0
- package/sound.js +31 -11
- package/sound.js.map +1 -1
- package/storage.cjs +49 -50
- package/storage.cjs.map +1 -1
- package/storage.d.ts +24 -0
- package/storage.js +50 -53
- package/storage.js.map +1 -1
- package/text.cjs +67 -34
- package/text.cjs.map +1 -1
- package/text.d.ts +16 -0
- package/text.js +68 -37
- package/text.js.map +1 -1
- package/type-guard.cjs +292 -72
- package/type-guard.cjs.map +1 -1
- package/type-guard.d.ts +18 -0
- package/type-guard.js +288 -73
- package/type-guard.js.map +1 -1
- package/types.cjs +0 -2
- package/types.d.ts +41 -0
- package/types.global.cjs +0 -2
- package/types.global.d.ts +41 -0
- package/types.global.js +0 -2
- package/types.js +0 -2
- package/vibrate.cjs +47 -6
- package/vibrate.cjs.map +1 -1
- package/vibrate.d.ts +39 -1
- package/vibrate.js +48 -8
- package/vibrate.js.map +1 -1
- package/types.cjs.map +0 -1
- package/types.global.cjs.map +0 -1
- package/types.global.js.map +0 -1
- package/types.js.map +0 -1
package/mobx.cjs
CHANGED
|
@@ -1,202 +1,457 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
2
|
+
require("./chunk-CVq3Gv4J.cjs");
|
|
3
|
+
let yummies_type_guard = require("yummies/type-guard");
|
|
4
|
+
let mobx = require("mobx");
|
|
5
|
+
//#region src/mobx/apply-observable.ts
|
|
6
|
+
/**
|
|
7
|
+
* ---header-docs-section---
|
|
8
|
+
* # yummies/mobx
|
|
9
|
+
*
|
|
10
|
+
* ## Description
|
|
11
|
+
*
|
|
12
|
+
* Compact **MobX `makeObservable`** wiring from tuple lists of annotations and keys. Reduces boilerplate
|
|
13
|
+
* when many fields share `observable`, `action`, or `computed` decorators and you want one call site
|
|
14
|
+
* instead of sprawling annotation maps across large stores.
|
|
15
|
+
*
|
|
16
|
+
* ## Usage
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { applyObservable } from "yummies/mobx";
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Applies a compact list of MobX annotations to an object using either
|
|
24
|
+
* decorator-style invocation or the annotation map form accepted by `makeObservable`.
|
|
25
|
+
*
|
|
26
|
+
* @template T Target object type.
|
|
27
|
+
* @param context Object that should become observable.
|
|
28
|
+
* @param annotationsArray Tuples of annotation followed by annotated field names.
|
|
29
|
+
* @param useDecorators Enables decorator-style application before calling `makeObservable`.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* applyObservable(store, [[observable, 'items'], [action, 'setItems']]);
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* applyObservable(viewModel, [[computed, 'fullName']], true);
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
var applyObservable = (context, annotationsArray, useDecorators) => {
|
|
42
|
+
if (useDecorators) {
|
|
43
|
+
annotationsArray.forEach(([annotation, ...fields]) => {
|
|
44
|
+
fields.forEach((field) => {
|
|
45
|
+
annotation(context, field);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
(0, mobx.makeObservable)(context);
|
|
49
|
+
} else {
|
|
50
|
+
const annotationsObject = {};
|
|
51
|
+
annotationsArray.forEach(([annotation, ...fields]) => {
|
|
52
|
+
fields.forEach((field) => {
|
|
53
|
+
annotationsObject[field] = annotation;
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
(0, mobx.makeObservable)(context, annotationsObject);
|
|
57
|
+
}
|
|
22
58
|
};
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
59
|
+
//#endregion
|
|
60
|
+
//#region src/mobx/create-enhanced-atom.ts
|
|
61
|
+
/**
|
|
62
|
+
* ---header-docs-section---
|
|
63
|
+
* # yummies/mobx
|
|
64
|
+
*
|
|
65
|
+
* ## Description
|
|
66
|
+
*
|
|
67
|
+
* **`createAtom` wrapper** that attaches arbitrary metadata and keeps MobX’s observed/unobserved
|
|
68
|
+
* hooks in one place. Useful for custom reactive primitives, async resources, or debugging atoms
|
|
69
|
+
* where the stock API is too bare.
|
|
70
|
+
*
|
|
71
|
+
* ## Usage
|
|
72
|
+
*
|
|
73
|
+
* ```ts
|
|
74
|
+
* import { createEnhancedAtom } from "yummies/mobx";
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
/**
|
|
78
|
+
* Creates a MobX atom extended with metadata and bound reporting methods.
|
|
79
|
+
*
|
|
80
|
+
* @template TMeta Metadata object stored on the atom.
|
|
81
|
+
* @param name Atom name used by MobX for debugging.
|
|
82
|
+
* @param onBecomeObservedHandler Callback fired when the atom becomes observed.
|
|
83
|
+
* @param onBecomeUnobservedHandler Callback fired when the atom is no longer observed.
|
|
84
|
+
* @param meta Optional metadata attached to the atom.
|
|
85
|
+
* @returns Atom instance with `meta`, `reportChanged` and `reportObserved`.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```ts
|
|
89
|
+
* const atom = createEnhancedAtom('user-status');
|
|
90
|
+
* atom.reportChanged();
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```ts
|
|
95
|
+
* const atom = createEnhancedAtom('cache', undefined, undefined, { scope: 'users' });
|
|
96
|
+
* atom.meta.scope;
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
var createEnhancedAtom = (name, onBecomeObservedHandler, onBecomeUnobservedHandler, meta) => {
|
|
100
|
+
const atom = (0, mobx.createAtom)(name, onBecomeObservedHandler && (() => onBecomeObservedHandler(atom)), onBecomeUnobservedHandler && (() => onBecomeUnobservedHandler(atom)));
|
|
101
|
+
atom.meta = meta ?? {};
|
|
102
|
+
atom.reportChanged = atom.reportChanged.bind(atom);
|
|
103
|
+
atom.reportObserved = atom.reportObserved.bind(atom);
|
|
104
|
+
return atom;
|
|
33
105
|
};
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
106
|
+
//#endregion
|
|
107
|
+
//#region src/mobx/create-ref.ts
|
|
108
|
+
/**
|
|
109
|
+
* ---header-docs-section---
|
|
110
|
+
* # yummies/mobx
|
|
111
|
+
*
|
|
112
|
+
* ## Description
|
|
113
|
+
*
|
|
114
|
+
* **Observable ref** pattern for MobX: boxed mutable references with change listeners, metadata,
|
|
115
|
+
* and optional custom equality. Bridges React-style ref holders and MobX reactivity when a single
|
|
116
|
+
* mutable cell must notify dependents without replacing the whole parent object graph.
|
|
117
|
+
*
|
|
118
|
+
* ## Usage
|
|
119
|
+
*
|
|
120
|
+
* ```ts
|
|
121
|
+
* import { createRef } from "yummies/mobx";
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
/**
|
|
125
|
+
* Creates a MobX-aware ref that behaves like a callback ref and exposes
|
|
126
|
+
* observable `current` and `meta` fields.
|
|
127
|
+
*
|
|
128
|
+
* @template T Referenced value type.
|
|
129
|
+
* @template TMeta Additional observable metadata stored on the ref.
|
|
130
|
+
* @param cfg Optional callbacks, initial value and comparer configuration.
|
|
131
|
+
* @returns Observable ref function object.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```ts
|
|
135
|
+
* const inputRef = createRef<HTMLInputElement>();
|
|
136
|
+
* inputRef.set(document.createElement('input'));
|
|
137
|
+
* ```
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```ts
|
|
141
|
+
* const ref = createRef<number>();
|
|
142
|
+
* ref(3);
|
|
143
|
+
* ref.current; // 3
|
|
144
|
+
* ```
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```ts
|
|
148
|
+
* const nodeRef = createRef({
|
|
149
|
+
* onUnset: () => console.log('detached'),
|
|
150
|
+
* meta: { mounted: false },
|
|
151
|
+
* });
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
var createRef = (cfg) => {
|
|
155
|
+
let lastValue;
|
|
156
|
+
const comparer = cfg?.comparer ?? mobx.comparer.default;
|
|
157
|
+
const setValue = (value) => {
|
|
158
|
+
const nextValue = value ?? null;
|
|
159
|
+
if (comparer(ref.current, nextValue)) return;
|
|
160
|
+
(0, mobx.runInAction)(() => {
|
|
161
|
+
const prevLastValue = lastValue;
|
|
162
|
+
lastValue = ref.current ?? void 0;
|
|
163
|
+
ref.current = nextValue;
|
|
164
|
+
let isNextValueIgnored = false;
|
|
165
|
+
ref.listeners.forEach((listener) => {
|
|
166
|
+
if (listener(ref.current, lastValue) === false) isNextValueIgnored = true;
|
|
167
|
+
});
|
|
168
|
+
if (isNextValueIgnored) {
|
|
169
|
+
lastValue = prevLastValue;
|
|
170
|
+
ref.current = lastValue ?? null;
|
|
171
|
+
} else if (ref.current === null && lastValue !== void 0) lastValue = void 0;
|
|
172
|
+
});
|
|
173
|
+
};
|
|
174
|
+
const ref = setValue;
|
|
175
|
+
ref.set = setValue;
|
|
176
|
+
ref.listeners = new Set(cfg?.onChange ? [cfg.onChange] : []);
|
|
177
|
+
if (cfg?.onSet || cfg?.onUnset) ref.listeners.add((value, prevValue) => {
|
|
178
|
+
if (value) cfg.onSet?.(value, prevValue);
|
|
179
|
+
else cfg.onUnset?.(prevValue);
|
|
180
|
+
});
|
|
181
|
+
ref.current = cfg?.initial ?? null;
|
|
182
|
+
ref.meta = cfg?.meta ?? {};
|
|
183
|
+
(0, mobx.makeObservable)(ref, {
|
|
184
|
+
current: mobx.observable.ref,
|
|
185
|
+
meta: mobx.observable
|
|
186
|
+
});
|
|
187
|
+
return ref;
|
|
80
188
|
};
|
|
81
|
-
|
|
82
|
-
|
|
189
|
+
/**
|
|
190
|
+
* Checks whether the provided value is a ref created by `createRef`.
|
|
191
|
+
*
|
|
192
|
+
* @template T Referenced value type.
|
|
193
|
+
* @template TMeta Ref metadata type.
|
|
194
|
+
* @param value Value to inspect.
|
|
195
|
+
* @returns `true` when the value is a ref-like function with `current`.
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```ts
|
|
199
|
+
* const ref = createRef<number>();
|
|
200
|
+
* isRef(ref); // true
|
|
201
|
+
* ```
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* ```ts
|
|
205
|
+
* isRef({ current: 1 }); // false
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
var isRef = (value) => {
|
|
209
|
+
return typeof value === "function" && "current" in value;
|
|
83
210
|
};
|
|
84
|
-
|
|
85
|
-
|
|
211
|
+
/**
|
|
212
|
+
* Normalizes a plain value or an existing ref into a `Ref` instance.
|
|
213
|
+
*
|
|
214
|
+
* @template T Referenced value type.
|
|
215
|
+
* @template TMeta Ref metadata type.
|
|
216
|
+
* @param value Existing ref or initial plain value.
|
|
217
|
+
* @param cfg Optional ref configuration applied when a new ref is created.
|
|
218
|
+
* @returns Existing ref or a newly created ref initialized with `value`.
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* ```ts
|
|
222
|
+
* const ref = toRef(document.body);
|
|
223
|
+
* ref.current === document.body;
|
|
224
|
+
* ```
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* ```ts
|
|
228
|
+
* const existingRef = createRef<number>();
|
|
229
|
+
* const sameRef = toRef(existingRef);
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
var toRef = (value, cfg) => {
|
|
233
|
+
return isRef(value) ? value : createRef({
|
|
234
|
+
initial: value,
|
|
235
|
+
...cfg
|
|
236
|
+
});
|
|
86
237
|
};
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
metaData = void 0;
|
|
166
|
-
}, endDelay);
|
|
167
|
-
};
|
|
168
|
-
const start = (property2) => {
|
|
169
|
-
const isAlreadyObserving = observingProps.size > 0;
|
|
170
|
-
observingProps.add(property2);
|
|
171
|
-
if (isAlreadyObserving) {
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
if (timeoutId) {
|
|
175
|
-
clearTimeout(timeoutId);
|
|
176
|
-
timeoutId = void 0;
|
|
177
|
-
}
|
|
178
|
-
metaData = onStart?.();
|
|
179
|
-
};
|
|
180
|
-
const stop = (property2) => {
|
|
181
|
-
const isAlreadyNotObserving = !observingProps.size;
|
|
182
|
-
observingProps.delete(property2);
|
|
183
|
-
const isObserving = observingProps.size > 0;
|
|
184
|
-
if (isAlreadyNotObserving || isObserving) {
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
cleanup();
|
|
188
|
-
};
|
|
189
|
-
properties.forEach((property2) => {
|
|
190
|
-
if (context) {
|
|
191
|
-
mobx.onBecomeObserved(context, property2, () => start(property2));
|
|
192
|
-
mobx.onBecomeUnobserved(context, property2, () => stop(property2));
|
|
193
|
-
} else {
|
|
194
|
-
mobx.onBecomeObserved(property2, () => start(property2));
|
|
195
|
-
mobx.onBecomeUnobserved(property2, () => stop(property2));
|
|
196
|
-
}
|
|
197
|
-
});
|
|
198
|
-
return cleanup;
|
|
238
|
+
//#endregion
|
|
239
|
+
//#region src/mobx/deep-observable-struct.ts
|
|
240
|
+
/**
|
|
241
|
+
* ---header-docs-section---
|
|
242
|
+
* # yummies/mobx
|
|
243
|
+
*
|
|
244
|
+
* ## Description
|
|
245
|
+
*
|
|
246
|
+
* **Deep observable object** with structural `set` patches that reuse nested observables when keys
|
|
247
|
+
* overlap. Helps store trees (forms, filters, entities) under MobX without wholesale replacement
|
|
248
|
+
* and without manual `observable.map` wiring for every level.
|
|
249
|
+
*
|
|
250
|
+
* ## Usage
|
|
251
|
+
*
|
|
252
|
+
* ```ts
|
|
253
|
+
* import { DeepObservableStruct } from "yummies/mobx";
|
|
254
|
+
* ```
|
|
255
|
+
*/
|
|
256
|
+
/**
|
|
257
|
+
* Wraps a plain object into a deeply observable structure and allows
|
|
258
|
+
* patch-like updates while preserving nested observable references where possible.
|
|
259
|
+
*
|
|
260
|
+
* @template TData Observable object shape.
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```ts
|
|
264
|
+
* const state = new DeepObservableStruct({ user: { name: 'Ann' } });
|
|
265
|
+
* state.set({ user: { name: 'Bob' } });
|
|
266
|
+
* ```
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```ts
|
|
270
|
+
* const state = new DeepObservableStruct({ filters: { active: true } });
|
|
271
|
+
* state.set({ filters: { active: false, archived: true } });
|
|
272
|
+
* ```
|
|
273
|
+
*/
|
|
274
|
+
var DeepObservableStruct = class {
|
|
275
|
+
data;
|
|
276
|
+
constructor(data) {
|
|
277
|
+
this.data = data;
|
|
278
|
+
(0, mobx.makeObservable)(this, {
|
|
279
|
+
data: mobx.observable.deep,
|
|
280
|
+
set: mobx.action
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
set(newData) {
|
|
284
|
+
const stack = Object.keys(this.data).map((key) => [
|
|
285
|
+
key,
|
|
286
|
+
this.data,
|
|
287
|
+
newData
|
|
288
|
+
]);
|
|
289
|
+
let currentIndex = 0;
|
|
290
|
+
let stackLength = stack.length;
|
|
291
|
+
while (currentIndex < stackLength) {
|
|
292
|
+
const [key, currObservableData, newData] = stack[currentIndex];
|
|
293
|
+
const newValue = newData[key];
|
|
294
|
+
const currValue = currObservableData[key];
|
|
295
|
+
currentIndex++;
|
|
296
|
+
if (key in newData) {
|
|
297
|
+
if (yummies_type_guard.typeGuard.isObject(newValue) && yummies_type_guard.typeGuard.isObject(currValue)) {
|
|
298
|
+
const newValueKeys = Object.keys(newValue);
|
|
299
|
+
Object.keys(currValue).forEach((childKey) => {
|
|
300
|
+
if (!(childKey in newValue)) delete currObservableData[key][childKey];
|
|
301
|
+
});
|
|
302
|
+
newValueKeys.forEach((childKey) => {
|
|
303
|
+
stackLength = stack.push([
|
|
304
|
+
childKey,
|
|
305
|
+
currObservableData[key],
|
|
306
|
+
newValue
|
|
307
|
+
]);
|
|
308
|
+
});
|
|
309
|
+
} else if (newValue !== currValue) currObservableData[key] = newValue;
|
|
310
|
+
} else delete currObservableData[key];
|
|
311
|
+
}
|
|
312
|
+
Object.keys(newData).forEach((newDataKey) => {
|
|
313
|
+
if (!this.data[newDataKey]) this.data[newDataKey] = newData[newDataKey];
|
|
314
|
+
});
|
|
315
|
+
}
|
|
199
316
|
};
|
|
317
|
+
//#endregion
|
|
318
|
+
//#region src/mobx/get-mobx-administration.ts
|
|
319
|
+
/**
|
|
320
|
+
* ---header-docs-section---
|
|
321
|
+
* # yummies/mobx
|
|
322
|
+
*
|
|
323
|
+
* ## Description
|
|
324
|
+
*
|
|
325
|
+
* Typed access to MobX **internal administration** (`$mobx`) for advanced tooling, migration scripts,
|
|
326
|
+
* or introspection. Prefer public MobX APIs in application code; reach for this when you must align
|
|
327
|
+
* with library internals or patch behavior at the administration layer.
|
|
328
|
+
*
|
|
329
|
+
* ## Usage
|
|
330
|
+
*
|
|
331
|
+
* ```ts
|
|
332
|
+
* import { getMobxAdministration } from "yummies/mobx";
|
|
333
|
+
* ```
|
|
334
|
+
*/
|
|
335
|
+
/**
|
|
336
|
+
* Returns the internal MobX administration object associated with an observable target.
|
|
337
|
+
*
|
|
338
|
+
* @param context Observable object instance.
|
|
339
|
+
* @returns MobX administration internals stored under `$mobx`.
|
|
340
|
+
*
|
|
341
|
+
* @example
|
|
342
|
+
* ```ts
|
|
343
|
+
* const admin = getMobxAdministration(store);
|
|
344
|
+
* admin.name_;
|
|
345
|
+
* ```
|
|
346
|
+
*
|
|
347
|
+
* @example
|
|
348
|
+
* ```ts
|
|
349
|
+
* const values = getMobxAdministration(formState).values_;
|
|
350
|
+
* ```
|
|
351
|
+
*/
|
|
352
|
+
var getMobxAdministration = (context) => context[mobx.$mobx];
|
|
353
|
+
//#endregion
|
|
354
|
+
//#region src/mobx/lazy-observe.ts
|
|
355
|
+
/**
|
|
356
|
+
* ---header-docs-section---
|
|
357
|
+
* # yummies/mobx
|
|
358
|
+
*
|
|
359
|
+
* ## Description
|
|
360
|
+
*
|
|
361
|
+
* **Lazy subscriptions** tied to MobX observation: start work when the first reaction observes
|
|
362
|
+
* tracked keys, stop when nothing listens anymore (optionally after a delay). Ideal for polling,
|
|
363
|
+
* WebSocket feeds, or expensive caches that should idle when the UI is not mounted.
|
|
364
|
+
*
|
|
365
|
+
* ## Usage
|
|
366
|
+
*
|
|
367
|
+
* ```ts
|
|
368
|
+
* import { lazyObserve } from "yummies/mobx";
|
|
369
|
+
* ```
|
|
370
|
+
*/
|
|
371
|
+
/**
|
|
372
|
+
* Starts side effects only while one or more MobX observables are being observed.
|
|
373
|
+
*
|
|
374
|
+
* When the first property becomes observed, `onStart` is called. When all tracked
|
|
375
|
+
* properties become unobserved, `onEnd` is called with the value returned by
|
|
376
|
+
* `onStart`. Cleanup can be delayed via `endDelay`.
|
|
377
|
+
*
|
|
378
|
+
* It uses MobX `onBecomeObserved` and `onBecomeUnobserved` hooks to perform
|
|
379
|
+
* lazy subscription management.
|
|
380
|
+
*
|
|
381
|
+
* @template TMetaData Data returned from `onStart` and forwarded to `onEnd`.
|
|
382
|
+
* @param config Configuration for tracked properties and lifecycle callbacks.
|
|
383
|
+
* @returns Cleanup function that clears the tracked state and runs `onEnd`.
|
|
384
|
+
*
|
|
385
|
+
* @example
|
|
386
|
+
* ```ts
|
|
387
|
+
* const stop = lazyObserve({
|
|
388
|
+
* context: store,
|
|
389
|
+
* property: 'items',
|
|
390
|
+
* onStart: () => api.subscribe(),
|
|
391
|
+
* onEnd: (subscription) => subscription.unsubscribe(),
|
|
392
|
+
* });
|
|
393
|
+
* ```
|
|
394
|
+
*
|
|
395
|
+
* @example
|
|
396
|
+
* ```ts
|
|
397
|
+
* lazyObserve({
|
|
398
|
+
* property: [boxA, boxB],
|
|
399
|
+
* onStart: () => console.log('observed'),
|
|
400
|
+
* endDelay: 300,
|
|
401
|
+
* });
|
|
402
|
+
* ```
|
|
403
|
+
*/
|
|
404
|
+
var lazyObserve = ({ context, property, onStart, onEnd, endDelay = false }) => {
|
|
405
|
+
let timeoutId;
|
|
406
|
+
let metaData;
|
|
407
|
+
const observingProps = /* @__PURE__ */ new Set();
|
|
408
|
+
const properties = Array.isArray(property) ? property : [property];
|
|
409
|
+
const cleanup = () => {
|
|
410
|
+
observingProps.clear();
|
|
411
|
+
if (endDelay === false) {
|
|
412
|
+
onEnd?.(metaData, cleanup);
|
|
413
|
+
metaData = void 0;
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
if (timeoutId) {
|
|
417
|
+
clearTimeout(timeoutId);
|
|
418
|
+
timeoutId = void 0;
|
|
419
|
+
}
|
|
420
|
+
timeoutId = setTimeout(() => {
|
|
421
|
+
onEnd?.(metaData, cleanup);
|
|
422
|
+
timeoutId = void 0;
|
|
423
|
+
metaData = void 0;
|
|
424
|
+
}, endDelay);
|
|
425
|
+
};
|
|
426
|
+
const start = (property) => {
|
|
427
|
+
const isAlreadyObserving = observingProps.size > 0;
|
|
428
|
+
observingProps.add(property);
|
|
429
|
+
if (isAlreadyObserving) return;
|
|
430
|
+
if (timeoutId) {
|
|
431
|
+
clearTimeout(timeoutId);
|
|
432
|
+
timeoutId = void 0;
|
|
433
|
+
}
|
|
434
|
+
metaData = onStart?.();
|
|
435
|
+
};
|
|
436
|
+
const stop = (property) => {
|
|
437
|
+
const isAlreadyNotObserving = !observingProps.size;
|
|
438
|
+
observingProps.delete(property);
|
|
439
|
+
const isObserving = observingProps.size > 0;
|
|
440
|
+
if (isAlreadyNotObserving || isObserving) return;
|
|
441
|
+
cleanup();
|
|
442
|
+
};
|
|
443
|
+
properties.forEach((property) => {
|
|
444
|
+
if (context) {
|
|
445
|
+
(0, mobx.onBecomeObserved)(context, property, () => start(property));
|
|
446
|
+
(0, mobx.onBecomeUnobserved)(context, property, () => stop(property));
|
|
447
|
+
} else {
|
|
448
|
+
(0, mobx.onBecomeObserved)(property, () => start(property));
|
|
449
|
+
(0, mobx.onBecomeUnobserved)(property, () => stop(property));
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
return cleanup;
|
|
453
|
+
};
|
|
454
|
+
//#endregion
|
|
200
455
|
exports.DeepObservableStruct = DeepObservableStruct;
|
|
201
456
|
exports.applyObservable = applyObservable;
|
|
202
457
|
exports.createEnhancedAtom = createEnhancedAtom;
|
|
@@ -205,4 +460,5 @@ exports.getMobxAdministration = getMobxAdministration;
|
|
|
205
460
|
exports.isRef = isRef;
|
|
206
461
|
exports.lazyObserve = lazyObserve;
|
|
207
462
|
exports.toRef = toRef;
|
|
208
|
-
|
|
463
|
+
|
|
464
|
+
//# sourceMappingURL=mobx.cjs.map
|