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