@bquery/bquery 1.7.0 → 1.8.1
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 +760 -716
- package/dist/{a11y-C5QOVvRn.js → a11y-DVBCy09c.js} +3 -3
- package/dist/a11y-DVBCy09c.js.map +1 -0
- package/dist/a11y.es.mjs +1 -1
- package/dist/component/library.d.ts.map +1 -1
- package/dist/{component-CuuTijA6.js → component-L3-JfOFz.js} +5 -5
- package/dist/component-L3-JfOFz.js.map +1 -0
- package/dist/component.es.mjs +1 -1
- package/dist/{config-BW35FKuA.js → config-DhT9auRm.js} +1 -1
- package/dist/{config-BW35FKuA.js.map → config-DhT9auRm.js.map} +1 -1
- package/dist/{constraints-3lV9yyBw.js → constraints-D5RHQLmP.js} +1 -1
- package/dist/constraints-D5RHQLmP.js.map +1 -0
- package/dist/core/collection.d.ts +86 -0
- package/dist/core/collection.d.ts.map +1 -1
- package/dist/core/element.d.ts +28 -0
- package/dist/core/element.d.ts.map +1 -1
- package/dist/core/shared.d.ts +6 -0
- package/dist/core/shared.d.ts.map +1 -1
- package/dist/core-DdtZHzsS.js +168 -0
- package/dist/core-DdtZHzsS.js.map +1 -0
- package/dist/{core-Cjl7GUu8.js → core-EMYSLzaT.js} +289 -259
- package/dist/core-EMYSLzaT.js.map +1 -0
- package/dist/core.es.mjs +48 -47
- package/dist/{custom-directives-7wAShnnd.js → custom-directives-Dr4C5lVV.js} +1 -1
- package/dist/custom-directives-Dr4C5lVV.js.map +1 -0
- package/dist/{devtools-D2fQLhDN.js → devtools-BhB2iDPT.js} +2 -2
- package/dist/devtools-BhB2iDPT.js.map +1 -0
- package/dist/devtools.es.mjs +1 -1
- package/dist/{dnd-B8EgyzaI.js → dnd-NwZBYh4l.js} +1 -1
- package/dist/dnd-NwZBYh4l.js.map +1 -0
- package/dist/dnd.es.mjs +1 -1
- package/dist/{env-NeVmr4Gf.js → env-CTdvLaH2.js} +1 -1
- package/dist/env-CTdvLaH2.js.map +1 -0
- package/dist/forms/create-form.d.ts.map +1 -1
- package/dist/forms/index.d.ts +3 -2
- package/dist/forms/index.d.ts.map +1 -1
- package/dist/forms/types.d.ts +46 -0
- package/dist/forms/types.d.ts.map +1 -1
- package/dist/forms/use-field.d.ts +34 -0
- package/dist/forms/use-field.d.ts.map +1 -0
- package/dist/forms/validators.d.ts +25 -0
- package/dist/forms/validators.d.ts.map +1 -1
- package/dist/forms-UcRHsYxC.js +227 -0
- package/dist/forms-UcRHsYxC.js.map +1 -0
- package/dist/forms.es.mjs +14 -12
- package/dist/full.d.ts +17 -26
- package/dist/full.d.ts.map +1 -1
- package/dist/full.es.mjs +206 -181
- package/dist/full.iife.js +33 -33
- package/dist/full.iife.js.map +1 -1
- package/dist/full.umd.js +33 -33
- package/dist/full.umd.js.map +1 -1
- package/dist/function-Cybd57JV.js +33 -0
- package/dist/function-Cybd57JV.js.map +1 -0
- package/dist/{i18n-BnnhTFOS.js → i18n-kuF6Ekj6.js} +3 -3
- package/dist/i18n-kuF6Ekj6.js.map +1 -0
- package/dist/i18n.es.mjs +1 -1
- package/dist/index.es.mjs +251 -228
- package/dist/media/breakpoints.d.ts.map +1 -1
- package/dist/media/types.d.ts +2 -2
- package/dist/media/types.d.ts.map +1 -1
- package/dist/{media-Di2Ta22s.js → media-i-fB5WxI.js} +3 -3
- package/dist/media-i-fB5WxI.js.map +1 -0
- package/dist/media.es.mjs +1 -1
- package/dist/{motion-qPj_TYGv.js → motion-BJsAuULb.js} +2 -2
- package/dist/motion-BJsAuULb.js.map +1 -0
- package/dist/motion.es.mjs +1 -1
- package/dist/{mount-SM07RUa6.js → mount-B4Y8bk8Z.js} +5 -5
- package/dist/mount-B4Y8bk8Z.js.map +1 -0
- package/dist/{platform-CPbCprb6.js → platform-Dw2gE3zI.js} +3 -3
- package/dist/{platform-CPbCprb6.js.map → platform-Dw2gE3zI.js.map} +1 -1
- package/dist/platform.es.mjs +2 -2
- package/dist/plugin/registry.d.ts.map +1 -1
- package/dist/{plugin-cPoOHFLY.js → plugin-C2WuC8SF.js} +20 -18
- package/dist/plugin-C2WuC8SF.js.map +1 -0
- package/dist/plugin.es.mjs +1 -1
- package/dist/reactive/async-data.d.ts +28 -3
- package/dist/reactive/async-data.d.ts.map +1 -1
- package/dist/reactive/computed.d.ts +3 -0
- package/dist/reactive/computed.d.ts.map +1 -1
- package/dist/reactive/effect.d.ts +3 -0
- package/dist/reactive/effect.d.ts.map +1 -1
- package/dist/reactive/http.d.ts +194 -0
- package/dist/reactive/http.d.ts.map +1 -0
- package/dist/reactive/index.d.ts +2 -2
- package/dist/reactive/index.d.ts.map +1 -1
- package/dist/reactive/pagination.d.ts +126 -0
- package/dist/reactive/pagination.d.ts.map +1 -0
- package/dist/reactive/polling.d.ts +55 -0
- package/dist/reactive/polling.d.ts.map +1 -0
- package/dist/reactive/readonly.d.ts +20 -1
- package/dist/reactive/readonly.d.ts.map +1 -1
- package/dist/reactive/rest.d.ts +293 -0
- package/dist/reactive/rest.d.ts.map +1 -0
- package/dist/reactive/scope.d.ts +140 -0
- package/dist/reactive/scope.d.ts.map +1 -0
- package/dist/reactive/signal.d.ts +16 -2
- package/dist/reactive/signal.d.ts.map +1 -1
- package/dist/reactive/to-value.d.ts +57 -0
- package/dist/reactive/to-value.d.ts.map +1 -0
- package/dist/reactive/websocket.d.ts +285 -0
- package/dist/reactive/websocket.d.ts.map +1 -0
- package/dist/reactive-DwkhUJfP.js +1148 -0
- package/dist/reactive-DwkhUJfP.js.map +1 -0
- package/dist/reactive.es.mjs +38 -19
- package/dist/{registry-CWf368tT.js → registry-B08iilIh.js} +1 -1
- package/dist/{registry-CWf368tT.js.map → registry-B08iilIh.js.map} +1 -1
- package/dist/router/constraints.d.ts.map +1 -1
- package/dist/router/index.d.ts +1 -1
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/router.d.ts.map +1 -1
- package/dist/router/state.d.ts +25 -2
- package/dist/router/state.d.ts.map +1 -1
- package/dist/router-CQikC9Ed.js +492 -0
- package/dist/router-CQikC9Ed.js.map +1 -0
- package/dist/router.es.mjs +9 -8
- package/dist/ssr/hydrate.d.ts.map +1 -1
- package/dist/{ssr-B2qd_WBB.js → ssr-_dAcGdzu.js} +4 -4
- package/dist/ssr-_dAcGdzu.js.map +1 -0
- package/dist/ssr.es.mjs +1 -1
- package/dist/store/persisted.d.ts.map +1 -1
- package/dist/{store-DWpyH6p5.js → store-Cb3gPRve.js} +7 -7
- package/dist/store-Cb3gPRve.js.map +1 -0
- package/dist/store.es.mjs +2 -2
- package/dist/storybook.es.mjs.map +1 -1
- package/dist/{testing-CsqjNUyy.js → testing-C5Sjfsna.js} +8 -8
- package/dist/testing-C5Sjfsna.js.map +1 -0
- package/dist/testing.es.mjs +1 -1
- package/dist/{type-guards-Do9DWgNp.js → type-guards-BMX2c0LP.js} +1 -1
- package/dist/{type-guards-Do9DWgNp.js.map → type-guards-BMX2c0LP.js.map} +1 -1
- package/dist/untrack-D0fnO5k2.js +36 -0
- package/dist/untrack-D0fnO5k2.js.map +1 -0
- package/dist/view/custom-directives.d.ts.map +1 -1
- package/dist/view.es.mjs +4 -4
- package/package.json +177 -177
- package/src/a11y/announce.ts +131 -131
- package/src/a11y/audit.ts +314 -314
- package/src/a11y/index.ts +68 -68
- package/src/a11y/media-preferences.ts +255 -255
- package/src/a11y/roving-tab-index.ts +164 -164
- package/src/a11y/skip-link.ts +255 -255
- package/src/a11y/trap-focus.ts +184 -184
- package/src/a11y/types.ts +183 -183
- package/src/component/component.ts +599 -599
- package/src/component/html.ts +153 -153
- package/src/component/index.ts +52 -52
- package/src/component/library.ts +540 -542
- package/src/component/scope.ts +212 -212
- package/src/component/types.ts +310 -310
- package/src/core/collection.ts +876 -707
- package/src/core/element.ts +1015 -981
- package/src/core/env.ts +60 -60
- package/src/core/index.ts +49 -49
- package/src/core/shared.ts +77 -62
- package/src/core/utils/index.ts +148 -148
- package/src/devtools/devtools.ts +410 -410
- package/src/devtools/index.ts +48 -48
- package/src/devtools/types.ts +104 -104
- package/src/dnd/draggable.ts +296 -296
- package/src/dnd/droppable.ts +228 -228
- package/src/dnd/index.ts +62 -62
- package/src/dnd/sortable.ts +307 -307
- package/src/dnd/types.ts +293 -293
- package/src/forms/create-form.ts +320 -278
- package/src/forms/index.ts +70 -65
- package/src/forms/types.ts +203 -154
- package/src/forms/use-field.ts +231 -0
- package/src/forms/validators.ts +294 -265
- package/src/full.ts +554 -480
- package/src/i18n/formatting.ts +67 -67
- package/src/i18n/i18n.ts +200 -200
- package/src/i18n/index.ts +67 -67
- package/src/i18n/translate.ts +182 -182
- package/src/i18n/types.ts +171 -171
- package/src/index.ts +108 -108
- package/src/media/battery.ts +116 -116
- package/src/media/breakpoints.ts +129 -131
- package/src/media/clipboard.ts +80 -80
- package/src/media/device-sensors.ts +158 -158
- package/src/media/geolocation.ts +119 -119
- package/src/media/index.ts +76 -76
- package/src/media/media-query.ts +92 -92
- package/src/media/network.ts +115 -115
- package/src/media/types.ts +177 -177
- package/src/media/viewport.ts +84 -84
- package/src/motion/index.ts +57 -57
- package/src/motion/morph.ts +151 -151
- package/src/motion/parallax.ts +120 -120
- package/src/motion/reduced-motion.ts +66 -66
- package/src/motion/types.ts +271 -271
- package/src/motion/typewriter.ts +164 -164
- package/src/plugin/index.ts +37 -37
- package/src/plugin/registry.ts +284 -269
- package/src/plugin/types.ts +137 -137
- package/src/reactive/async-data.ts +250 -29
- package/src/reactive/computed.ts +144 -130
- package/src/reactive/effect.ts +29 -6
- package/src/reactive/http.ts +790 -0
- package/src/reactive/index.ts +60 -0
- package/src/reactive/pagination.ts +317 -0
- package/src/reactive/polling.ts +179 -0
- package/src/reactive/readonly.ts +52 -8
- package/src/reactive/rest.ts +859 -0
- package/src/reactive/scope.ts +276 -0
- package/src/reactive/signal.ts +61 -1
- package/src/reactive/to-value.ts +71 -0
- package/src/reactive/websocket.ts +849 -0
- package/src/router/bq-link.ts +279 -279
- package/src/router/constraints.ts +204 -201
- package/src/router/index.ts +49 -49
- package/src/router/match.ts +312 -312
- package/src/router/path-pattern.ts +52 -52
- package/src/router/query.ts +38 -38
- package/src/router/router.ts +421 -402
- package/src/router/state.ts +51 -3
- package/src/router/types.ts +139 -139
- package/src/router/use-route.ts +68 -68
- package/src/router/utils.ts +157 -157
- package/src/security/index.ts +12 -12
- package/src/ssr/hydrate.ts +84 -82
- package/src/ssr/index.ts +70 -70
- package/src/ssr/render.ts +508 -508
- package/src/ssr/serialize.ts +296 -296
- package/src/ssr/types.ts +81 -81
- package/src/store/create-store.ts +467 -467
- package/src/store/index.ts +27 -27
- package/src/store/persisted.ts +245 -249
- package/src/store/types.ts +247 -247
- package/src/store/utils.ts +135 -135
- package/src/storybook/index.ts +480 -480
- package/src/testing/index.ts +42 -42
- package/src/testing/testing.ts +593 -593
- package/src/testing/types.ts +170 -170
- package/src/view/custom-directives.ts +28 -30
- package/src/view/evaluate.ts +292 -292
- package/src/view/process.ts +108 -108
- package/dist/a11y-C5QOVvRn.js.map +0 -1
- package/dist/component-CuuTijA6.js.map +0 -1
- package/dist/constraints-3lV9yyBw.js.map +0 -1
- package/dist/core-Cjl7GUu8.js.map +0 -1
- package/dist/core-DnlyjbF2.js +0 -112
- package/dist/core-DnlyjbF2.js.map +0 -1
- package/dist/custom-directives-7wAShnnd.js.map +0 -1
- package/dist/devtools-D2fQLhDN.js.map +0 -1
- package/dist/dnd-B8EgyzaI.js.map +0 -1
- package/dist/env-NeVmr4Gf.js.map +0 -1
- package/dist/forms-C3yovgH9.js +0 -141
- package/dist/forms-C3yovgH9.js.map +0 -1
- package/dist/i18n-BnnhTFOS.js.map +0 -1
- package/dist/media-Di2Ta22s.js.map +0 -1
- package/dist/motion-qPj_TYGv.js.map +0 -1
- package/dist/mount-SM07RUa6.js.map +0 -1
- package/dist/plugin-cPoOHFLY.js.map +0 -1
- package/dist/reactive-Cfv0RK6x.js +0 -233
- package/dist/reactive-Cfv0RK6x.js.map +0 -1
- package/dist/router-BrthaP_z.js +0 -473
- package/dist/router-BrthaP_z.js.map +0 -1
- package/dist/ssr-B2qd_WBB.js.map +0 -1
- package/dist/store-DWpyH6p5.js.map +0 -1
- package/dist/testing-CsqjNUyy.js.map +0 -1
- package/dist/untrack-DJVQQ2WM.js +0 -33
- package/dist/untrack-DJVQQ2WM.js.map +0 -1
package/src/store/utils.ts
CHANGED
|
@@ -1,135 +1,135 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Internal utilities for the store module.
|
|
3
|
-
* @internal
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { detectDevEnvironment } from '../core/env';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Check if a value is a plain object (not array, null, Date, etc.).
|
|
10
|
-
* @internal
|
|
11
|
-
*/
|
|
12
|
-
export const isPlainObject = (value: unknown): value is Record<string, unknown> => {
|
|
13
|
-
return (
|
|
14
|
-
value !== null && typeof value === 'object' && Object.getPrototypeOf(value) === Object.prototype
|
|
15
|
-
);
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Deep clones an object. Used for deep reactivity support.
|
|
20
|
-
* @internal
|
|
21
|
-
*/
|
|
22
|
-
export const deepClone = <T>(obj: T): T => {
|
|
23
|
-
if (obj === null || typeof obj !== 'object') {
|
|
24
|
-
return obj;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (Array.isArray(obj)) {
|
|
28
|
-
return obj.map(deepClone) as T;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (obj instanceof Date) {
|
|
32
|
-
return new Date(obj.getTime()) as T;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (obj instanceof Map) {
|
|
36
|
-
return new Map(Array.from(obj.entries()).map(([k, v]) => [k, deepClone(v)])) as T;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (obj instanceof Set) {
|
|
40
|
-
return new Set(Array.from(obj).map(deepClone)) as T;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const cloned = {} as T;
|
|
44
|
-
for (const key of Object.keys(obj)) {
|
|
45
|
-
(cloned as Record<string, unknown>)[key] = deepClone((obj as Record<string, unknown>)[key]);
|
|
46
|
-
}
|
|
47
|
-
return cloned;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Compares two values for deep equality.
|
|
52
|
-
* @internal
|
|
53
|
-
*/
|
|
54
|
-
export const deepEqual = (a: unknown, b: unknown): boolean => {
|
|
55
|
-
if (a === b) return true;
|
|
56
|
-
if (a === null || b === null) return false;
|
|
57
|
-
if (typeof a !== 'object' || typeof b !== 'object') return false;
|
|
58
|
-
|
|
59
|
-
if (a instanceof Date && b instanceof Date) {
|
|
60
|
-
return a.getTime() === b.getTime();
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (a instanceof Map && b instanceof Map) {
|
|
64
|
-
if (a.size !== b.size) return false;
|
|
65
|
-
for (const [key, value] of a.entries()) {
|
|
66
|
-
if (!b.has(key) || !deepEqual(value, b.get(key))) return false;
|
|
67
|
-
}
|
|
68
|
-
return true;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (a instanceof Set && b instanceof Set) {
|
|
72
|
-
if (a.size !== b.size) return false;
|
|
73
|
-
for (const value of a.values()) {
|
|
74
|
-
let found = false;
|
|
75
|
-
for (const candidate of b.values()) {
|
|
76
|
-
if (deepEqual(value, candidate)) {
|
|
77
|
-
found = true;
|
|
78
|
-
break;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
if (!found) return false;
|
|
82
|
-
}
|
|
83
|
-
return true;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (Array.isArray(a) && Array.isArray(b)) {
|
|
87
|
-
if (a.length !== b.length) return false;
|
|
88
|
-
return a.every((item, i) => deepEqual(item, b[i]));
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (Array.isArray(a) !== Array.isArray(b)) return false;
|
|
92
|
-
|
|
93
|
-
const keysA = Object.keys(a as object);
|
|
94
|
-
const keysB = Object.keys(b as object);
|
|
95
|
-
|
|
96
|
-
if (keysA.length !== keysB.length) return false;
|
|
97
|
-
|
|
98
|
-
return keysA.every((key) =>
|
|
99
|
-
deepEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])
|
|
100
|
-
);
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Detects if nested objects were mutated but the reference stayed the same.
|
|
105
|
-
* Returns the keys where nested mutations were detected.
|
|
106
|
-
* @internal
|
|
107
|
-
*/
|
|
108
|
-
export const detectNestedMutations = <S extends Record<string, unknown>>(
|
|
109
|
-
before: S,
|
|
110
|
-
after: S,
|
|
111
|
-
signalValues: Map<keyof S, unknown>
|
|
112
|
-
): Array<keyof S> => {
|
|
113
|
-
const mutatedKeys: Array<keyof S> = [];
|
|
114
|
-
|
|
115
|
-
for (const key of Object.keys(after) as Array<keyof S>) {
|
|
116
|
-
const beforeValue = before[key];
|
|
117
|
-
const afterValue = after[key];
|
|
118
|
-
const signalValue = signalValues.get(key);
|
|
119
|
-
|
|
120
|
-
// Check if it's the same reference but content changed
|
|
121
|
-
if (
|
|
122
|
-
signalValue === afterValue &&
|
|
123
|
-
isPlainObject(beforeValue) &&
|
|
124
|
-
isPlainObject(afterValue) &&
|
|
125
|
-
!deepEqual(beforeValue, afterValue)
|
|
126
|
-
) {
|
|
127
|
-
mutatedKeys.push(key);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return mutatedKeys;
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
/** @internal Returns whether development warnings should be enabled */
|
|
135
|
-
export const isDev = (): boolean => detectDevEnvironment();
|
|
1
|
+
/**
|
|
2
|
+
* Internal utilities for the store module.
|
|
3
|
+
* @internal
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { detectDevEnvironment } from '../core/env';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Check if a value is a plain object (not array, null, Date, etc.).
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export const isPlainObject = (value: unknown): value is Record<string, unknown> => {
|
|
13
|
+
return (
|
|
14
|
+
value !== null && typeof value === 'object' && Object.getPrototypeOf(value) === Object.prototype
|
|
15
|
+
);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Deep clones an object. Used for deep reactivity support.
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
export const deepClone = <T>(obj: T): T => {
|
|
23
|
+
if (obj === null || typeof obj !== 'object') {
|
|
24
|
+
return obj;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (Array.isArray(obj)) {
|
|
28
|
+
return obj.map(deepClone) as T;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (obj instanceof Date) {
|
|
32
|
+
return new Date(obj.getTime()) as T;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (obj instanceof Map) {
|
|
36
|
+
return new Map(Array.from(obj.entries()).map(([k, v]) => [k, deepClone(v)])) as T;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (obj instanceof Set) {
|
|
40
|
+
return new Set(Array.from(obj).map(deepClone)) as T;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const cloned = {} as T;
|
|
44
|
+
for (const key of Object.keys(obj)) {
|
|
45
|
+
(cloned as Record<string, unknown>)[key] = deepClone((obj as Record<string, unknown>)[key]);
|
|
46
|
+
}
|
|
47
|
+
return cloned;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Compares two values for deep equality.
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
54
|
+
export const deepEqual = (a: unknown, b: unknown): boolean => {
|
|
55
|
+
if (a === b) return true;
|
|
56
|
+
if (a === null || b === null) return false;
|
|
57
|
+
if (typeof a !== 'object' || typeof b !== 'object') return false;
|
|
58
|
+
|
|
59
|
+
if (a instanceof Date && b instanceof Date) {
|
|
60
|
+
return a.getTime() === b.getTime();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (a instanceof Map && b instanceof Map) {
|
|
64
|
+
if (a.size !== b.size) return false;
|
|
65
|
+
for (const [key, value] of a.entries()) {
|
|
66
|
+
if (!b.has(key) || !deepEqual(value, b.get(key))) return false;
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (a instanceof Set && b instanceof Set) {
|
|
72
|
+
if (a.size !== b.size) return false;
|
|
73
|
+
for (const value of a.values()) {
|
|
74
|
+
let found = false;
|
|
75
|
+
for (const candidate of b.values()) {
|
|
76
|
+
if (deepEqual(value, candidate)) {
|
|
77
|
+
found = true;
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (!found) return false;
|
|
82
|
+
}
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
87
|
+
if (a.length !== b.length) return false;
|
|
88
|
+
return a.every((item, i) => deepEqual(item, b[i]));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (Array.isArray(a) !== Array.isArray(b)) return false;
|
|
92
|
+
|
|
93
|
+
const keysA = Object.keys(a as object);
|
|
94
|
+
const keysB = Object.keys(b as object);
|
|
95
|
+
|
|
96
|
+
if (keysA.length !== keysB.length) return false;
|
|
97
|
+
|
|
98
|
+
return keysA.every((key) =>
|
|
99
|
+
deepEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])
|
|
100
|
+
);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Detects if nested objects were mutated but the reference stayed the same.
|
|
105
|
+
* Returns the keys where nested mutations were detected.
|
|
106
|
+
* @internal
|
|
107
|
+
*/
|
|
108
|
+
export const detectNestedMutations = <S extends Record<string, unknown>>(
|
|
109
|
+
before: S,
|
|
110
|
+
after: S,
|
|
111
|
+
signalValues: Map<keyof S, unknown>
|
|
112
|
+
): Array<keyof S> => {
|
|
113
|
+
const mutatedKeys: Array<keyof S> = [];
|
|
114
|
+
|
|
115
|
+
for (const key of Object.keys(after) as Array<keyof S>) {
|
|
116
|
+
const beforeValue = before[key];
|
|
117
|
+
const afterValue = after[key];
|
|
118
|
+
const signalValue = signalValues.get(key);
|
|
119
|
+
|
|
120
|
+
// Check if it's the same reference but content changed
|
|
121
|
+
if (
|
|
122
|
+
signalValue === afterValue &&
|
|
123
|
+
isPlainObject(beforeValue) &&
|
|
124
|
+
isPlainObject(afterValue) &&
|
|
125
|
+
!deepEqual(beforeValue, afterValue)
|
|
126
|
+
) {
|
|
127
|
+
mutatedKeys.push(key);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return mutatedKeys;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/** @internal Returns whether development warnings should be enabled */
|
|
135
|
+
export const isDev = (): boolean => detectDevEnvironment();
|