sibujs 4.6.0 → 4.7.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 +1 -1
- package/dist/browser.cjs +18 -5
- package/dist/browser.js +4 -4
- package/dist/build.cjs +1956 -1007
- package/dist/build.d.cts +133 -44
- package/dist/build.d.ts +133 -44
- package/dist/build.js +1368 -569
- package/dist/cdn.dev.global.js +12 -12
- package/dist/cdn.full.dev.global.js +11 -11
- package/dist/cdn.full.global.js +10 -10
- package/dist/cdn.global.js +12 -12
- package/dist/{chunk-SXXVZMKZ.js → chunk-2BPG2XDA.js} +5 -5
- package/dist/{chunk-BAAG6ZTI.js → chunk-3QWBSL5R.js} +4 -4
- package/dist/{chunk-5MT6SJ3P.js → chunk-4AWA2PVD.js} +2 -2
- package/dist/{chunk-JSXPZCET.js → chunk-7LUJQAOJ.js} +1 -1
- package/dist/{chunk-3ISI6ACU.js → chunk-BC2SECJD.js} +1 -1
- package/dist/{chunk-DKGBBKOF.js → chunk-BSY63EM6.js} +2 -2
- package/dist/{chunk-7NCARGJW.js → chunk-DKXRACVN.js} +3 -3
- package/dist/{chunk-47M47FOM.js → chunk-FNJXNGYZ.js} +1 -1
- package/dist/{chunk-D33YTSX5.js → chunk-FQRUXCEE.js} +5 -4
- package/dist/{chunk-5Q4R7HCL.js → chunk-JWKYU5GV.js} +11 -2
- package/dist/{chunk-QE4TTDU3.js → chunk-RUSSKG6G.js} +12 -11
- package/dist/{chunk-UZQ6ALFS.js → chunk-SLM3IA34.js} +1 -1
- package/dist/{chunk-XRRZKZYX.js → chunk-UNWRJRKC.js} +1 -1
- package/dist/{chunk-VVWPJ543.js → chunk-UOL2ECCS.js} +40 -11
- package/dist/{chunk-ORMZXBKQ.js → chunk-VZSG24LS.js} +3 -3
- package/dist/{chunk-XC4MEKGA.js → chunk-WEQ3DMVL.js} +8 -2
- package/dist/{chunk-PK6FK2G2.js → chunk-WOLJZUFQ.js} +176 -27
- package/dist/{chunk-7GQCWFOE.js → chunk-XYV3EDB7.js} +143 -74
- package/dist/{chunk-AIF3Z2T7.js → chunk-XZR4PXRE.js} +3 -3
- package/dist/{chunk-HYXDKS4N.js → chunk-Z3OHK6QT.js} +4 -4
- package/dist/{chunk-OXUY2A6L.js → chunk-ZVL7TY4K.js} +2 -2
- package/dist/{contracts-DRIuclVT.d.ts → contracts-CLqzJnOV.d.ts} +28 -17
- package/dist/{contracts-DRIuclVT.d.cts → contracts-CTOJXu-x.d.cts} +28 -17
- package/dist/data.cjs +198 -39
- package/dist/data.d.cts +119 -3
- package/dist/data.d.ts +119 -3
- package/dist/data.js +5 -5
- package/dist/devtools.cjs +18 -5
- package/dist/devtools.js +4 -4
- package/dist/ecosystem.cjs +64 -23
- package/dist/ecosystem.d.cts +2 -1
- package/dist/ecosystem.d.ts +2 -1
- package/dist/ecosystem.js +7 -7
- package/dist/extras.cjs +236 -49
- package/dist/extras.d.cts +3 -2
- package/dist/extras.d.ts +3 -2
- package/dist/extras.js +20 -20
- package/dist/index.cjs +259 -108
- package/dist/index.d.cts +193 -168
- package/dist/index.d.ts +193 -168
- package/dist/index.js +10 -10
- package/dist/motion.cjs +12 -4
- package/dist/motion.js +3 -3
- package/dist/patterns.cjs +28 -15
- package/dist/patterns.d.cts +2 -1
- package/dist/patterns.d.ts +2 -1
- package/dist/patterns.js +5 -5
- package/dist/performance.cjs +18 -5
- package/dist/performance.js +4 -4
- package/dist/plugins.cjs +118 -34
- package/dist/plugins.d.cts +124 -11
- package/dist/plugins.d.ts +124 -11
- package/dist/plugins.js +68 -26
- package/dist/ssr.cjs +54 -13
- package/dist/ssr.js +7 -7
- package/dist/{tagFactory-DFstCLQV.d.cts → tagFactory-8qL9LCIx.d.cts} +58 -19
- package/dist/{tagFactory-DkaNVUNV.d.ts → tagFactory-BL2fymez.d.ts} +58 -19
- package/dist/testing.cjs +15 -2
- package/dist/testing.js +2 -2
- package/dist/types-CJFViL6Q.d.cts +26 -0
- package/dist/types-CJFViL6Q.d.ts +26 -0
- package/dist/ui.cjs +28 -15
- package/dist/ui.d.cts +2 -1
- package/dist/ui.d.ts +2 -1
- package/dist/ui.js +7 -7
- package/dist/widgets.cjs +22 -14
- package/dist/widgets.js +6 -6
- package/package.json +4 -2
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
drainNotificationQueue,
|
|
3
|
+
emitDevtools,
|
|
3
4
|
notifySubscribers,
|
|
4
5
|
queueSignalNotification,
|
|
5
6
|
recordDependency
|
|
6
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-JWKYU5GV.js";
|
|
7
8
|
import {
|
|
8
9
|
DEV
|
|
9
10
|
} from "./chunk-NYNYSPK7.js";
|
|
@@ -91,7 +92,7 @@ function signal(initial, options) {
|
|
|
91
92
|
state.__v++;
|
|
92
93
|
if (DEV) {
|
|
93
94
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
94
|
-
if (hook) hook
|
|
95
|
+
if (hook) emitDevtools(hook, "signal:update", { signal: state, name: debugName, oldValue: prev, newValue });
|
|
95
96
|
}
|
|
96
97
|
if (!enqueueBatchedSignal(state)) {
|
|
97
98
|
notifySubscribers(state);
|
|
@@ -105,7 +106,7 @@ function signal(initial, options) {
|
|
|
105
106
|
state.value = newValue;
|
|
106
107
|
state.__v++;
|
|
107
108
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
108
|
-
if (hook) hook
|
|
109
|
+
if (hook) emitDevtools(hook, "signal:update", { signal: state, name: debugName, oldValue: prev, newValue });
|
|
109
110
|
if (!enqueueBatchedSignal(state)) {
|
|
110
111
|
notifySubscribers(state);
|
|
111
112
|
}
|
|
@@ -124,7 +125,7 @@ function signal(initial, options) {
|
|
|
124
125
|
}
|
|
125
126
|
if (DEV) {
|
|
126
127
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
127
|
-
if (hook) hook
|
|
128
|
+
if (hook) emitDevtools(hook, "signal:create", { signal: state, name: debugName, getter: get, initial });
|
|
128
129
|
}
|
|
129
130
|
return [get, set];
|
|
130
131
|
}
|
|
@@ -498,7 +498,7 @@ function forEachSubscriber(signal, visit) {
|
|
|
498
498
|
}
|
|
499
499
|
|
|
500
500
|
// src/reactivity/track.ts
|
|
501
|
-
var _runtimeVersion = true ? "4.
|
|
501
|
+
var _runtimeVersion = true ? "4.7.0" : "dev";
|
|
502
502
|
var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
|
|
503
503
|
function resolveReactiveApi() {
|
|
504
504
|
const g = globalThis;
|
|
@@ -554,6 +554,14 @@ var getSubscriberCount2 = API.getSubscriberCount;
|
|
|
554
554
|
var getSubscriberDeps2 = API.getSubscriberDeps;
|
|
555
555
|
var forEachSubscriber2 = API.forEachSubscriber;
|
|
556
556
|
|
|
557
|
+
// src/core/devtoolsHook.ts
|
|
558
|
+
function emitDevtools(hook, event, payload) {
|
|
559
|
+
try {
|
|
560
|
+
hook.emit(event, payload);
|
|
561
|
+
} catch {
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
557
565
|
export {
|
|
558
566
|
suspendTracking2 as suspendTracking,
|
|
559
567
|
resumeTracking2 as resumeTracking,
|
|
@@ -570,5 +578,6 @@ export {
|
|
|
570
578
|
notifySubscribers2 as notifySubscribers,
|
|
571
579
|
getSubscriberCount2 as getSubscriberCount,
|
|
572
580
|
getSubscriberDeps2 as getSubscriberDeps,
|
|
573
|
-
forEachSubscriber2 as forEachSubscriber
|
|
581
|
+
forEachSubscriber2 as forEachSubscriber,
|
|
582
|
+
emitDevtools
|
|
574
583
|
};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
cleanup,
|
|
3
|
+
emitDevtools,
|
|
3
4
|
isTrackingSuspended,
|
|
4
5
|
recordDependency,
|
|
5
6
|
retrack,
|
|
6
7
|
track
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-JWKYU5GV.js";
|
|
8
9
|
import {
|
|
9
10
|
devAssert
|
|
10
11
|
} from "./chunk-NYNYSPK7.js";
|
|
@@ -35,17 +36,17 @@ function derived(getter, options) {
|
|
|
35
36
|
cs._d = false;
|
|
36
37
|
cs._init = true;
|
|
37
38
|
};
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
try {
|
|
39
|
+
try {
|
|
40
|
+
track(() => {
|
|
41
41
|
cs._v = getter();
|
|
42
42
|
cs._d = false;
|
|
43
43
|
cs._init = true;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
}, markDirty);
|
|
45
|
+
} catch (err) {
|
|
46
|
+
disposed = true;
|
|
47
|
+
cleanup(markDirty);
|
|
48
|
+
throw err;
|
|
49
|
+
}
|
|
49
50
|
const hook = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
50
51
|
const validate = () => {
|
|
51
52
|
if (!cs._d || disposed || pendingError !== void 0) return;
|
|
@@ -64,7 +65,7 @@ function derived(getter, options) {
|
|
|
64
65
|
if (disposed) cleanup(markDirty);
|
|
65
66
|
}
|
|
66
67
|
if (hook && !disposed && !Object.is(oldValue, cs._v)) {
|
|
67
|
-
hook
|
|
68
|
+
emitDevtools(hook, "computed:update", { signal: cs, oldValue, newValue: cs._v });
|
|
68
69
|
}
|
|
69
70
|
};
|
|
70
71
|
cs._validate = validate;
|
|
@@ -115,7 +116,7 @@ function derived(getter, options) {
|
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
118
|
};
|
|
118
|
-
if (hook) hook
|
|
119
|
+
if (hook) emitDevtools(hook, "computed:create", { signal: cs, name: debugName, getter: computedGetter });
|
|
119
120
|
return computedGetter;
|
|
120
121
|
}
|
|
121
122
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
bindAttribute,
|
|
3
3
|
setSafeAttribute
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-FNJXNGYZ.js";
|
|
5
5
|
import {
|
|
6
6
|
isEventHandlerAttr,
|
|
7
7
|
sanitizeCSSValue,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from "./chunk-2INLLLMZ.js";
|
|
10
10
|
import {
|
|
11
11
|
reactiveBinding
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-JWKYU5GV.js";
|
|
13
13
|
import {
|
|
14
14
|
DEV,
|
|
15
15
|
devWarn,
|
|
@@ -219,8 +219,34 @@ function toKebab(prop) {
|
|
|
219
219
|
}
|
|
220
220
|
function applyStyle(el, style) {
|
|
221
221
|
if (typeof style === "function") {
|
|
222
|
+
const getter = style;
|
|
223
|
+
let written = [];
|
|
224
|
+
let wroteString = false;
|
|
222
225
|
const teardown = reactiveBinding(() => {
|
|
223
|
-
|
|
226
|
+
const value = getter();
|
|
227
|
+
if (value === null || typeof value !== "object") {
|
|
228
|
+
written = [];
|
|
229
|
+
wroteString = true;
|
|
230
|
+
el.setAttribute("style", sanitizeStyleAttribute(String(value), { element: el }));
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const decl = el.style;
|
|
234
|
+
if (wroteString) {
|
|
235
|
+
el.removeAttribute("style");
|
|
236
|
+
wroteString = false;
|
|
237
|
+
}
|
|
238
|
+
const next = [];
|
|
239
|
+
for (const prop in value) {
|
|
240
|
+
const val = value[prop];
|
|
241
|
+
if (val == null) continue;
|
|
242
|
+
const name = toKebab(prop);
|
|
243
|
+
next.push(name);
|
|
244
|
+
decl.setProperty(name, sanitizeCSSValue(String(val), { property: name, element: el }));
|
|
245
|
+
}
|
|
246
|
+
for (let i = 0; i < written.length; i++) {
|
|
247
|
+
if (next.indexOf(written[i]) === -1) decl.removeProperty(written[i]);
|
|
248
|
+
}
|
|
249
|
+
written = next;
|
|
224
250
|
}, el);
|
|
225
251
|
registerDisposer(el, teardown);
|
|
226
252
|
return;
|
|
@@ -246,7 +272,7 @@ function applyStyle(el, style) {
|
|
|
246
272
|
}
|
|
247
273
|
function resolveClassValue(cls) {
|
|
248
274
|
if (typeof cls === "string") return cls;
|
|
249
|
-
if (typeof cls === "function") return cls();
|
|
275
|
+
if (typeof cls === "function") return cls() || "";
|
|
250
276
|
if (!cls) return "";
|
|
251
277
|
let out = "";
|
|
252
278
|
for (const name in cls) {
|
|
@@ -263,7 +289,9 @@ function applyClass(el, cls) {
|
|
|
263
289
|
}
|
|
264
290
|
if (typeof cls === "function") {
|
|
265
291
|
const teardown = reactiveBinding(() => {
|
|
266
|
-
|
|
292
|
+
const value = cls();
|
|
293
|
+
if (value == null || value === false) el.removeAttribute("class");
|
|
294
|
+
else el.setAttribute("class", value);
|
|
267
295
|
}, el);
|
|
268
296
|
registerDisposer(el, teardown);
|
|
269
297
|
return;
|
|
@@ -345,7 +373,7 @@ function appendChildren(el, nodes) {
|
|
|
345
373
|
}
|
|
346
374
|
}
|
|
347
375
|
}
|
|
348
|
-
|
|
376
|
+
function tagFactory(tag, ns) {
|
|
349
377
|
const blocked = isBlockedTag(tag);
|
|
350
378
|
return (first, second) => {
|
|
351
379
|
if (blocked) {
|
|
@@ -394,7 +422,9 @@ var tagFactory = (tag, ns) => {
|
|
|
394
422
|
const pClass = props.class;
|
|
395
423
|
if (pClass != null) applyClass(el, pClass);
|
|
396
424
|
const pId = props.id;
|
|
397
|
-
if (pId
|
|
425
|
+
if (typeof pId === "function") {
|
|
426
|
+
registerDisposer(el, bindAttribute(el, "id", pId));
|
|
427
|
+
} else if (pId != null) {
|
|
398
428
|
if (DEV && typeof pId === "string" && CLOBBER_RISKY_IDS.has(pId.toLowerCase())) {
|
|
399
429
|
devWarn(
|
|
400
430
|
`tagFactory: element id="${pId}" matches a common global and may cause DOM clobbering. Avoid setting ids from untrusted input.`
|
|
@@ -444,12 +474,10 @@ var tagFactory = (tag, ns) => {
|
|
|
444
474
|
}
|
|
445
475
|
}
|
|
446
476
|
}
|
|
447
|
-
if (
|
|
448
|
-
props.onElement(el);
|
|
449
|
-
}
|
|
477
|
+
if (typeof props.onElement === "function") props.onElement(el);
|
|
450
478
|
return el;
|
|
451
479
|
};
|
|
452
|
-
}
|
|
480
|
+
}
|
|
453
481
|
|
|
454
482
|
export {
|
|
455
483
|
captureFocusWithin,
|
|
@@ -457,5 +485,6 @@ export {
|
|
|
457
485
|
bindChildNode,
|
|
458
486
|
SVG_NS,
|
|
459
487
|
resolveClassValue,
|
|
488
|
+
appendChildren,
|
|
460
489
|
tagFactory
|
|
461
490
|
};
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
div,
|
|
8
8
|
span
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-7LUJQAOJ.js";
|
|
10
10
|
import {
|
|
11
11
|
STATIC_VALUE_RESOLVER,
|
|
12
12
|
planHeadElementEntry,
|
|
@@ -20,11 +20,11 @@ import {
|
|
|
20
20
|
} from "./chunk-7ZHH77QA.js";
|
|
21
21
|
import {
|
|
22
22
|
effect
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-WEQ3DMVL.js";
|
|
24
24
|
import {
|
|
25
25
|
batch,
|
|
26
26
|
signal
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-FQRUXCEE.js";
|
|
28
28
|
import {
|
|
29
29
|
registerDisposer,
|
|
30
30
|
replaceChildrenSafely,
|
|
@@ -3,9 +3,10 @@ import {
|
|
|
3
3
|
} from "./chunk-7XHATCIH.js";
|
|
4
4
|
import {
|
|
5
5
|
cleanup,
|
|
6
|
+
emitDevtools,
|
|
6
7
|
retrack,
|
|
7
8
|
untracked
|
|
8
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-JWKYU5GV.js";
|
|
9
10
|
import {
|
|
10
11
|
devAssert,
|
|
11
12
|
reportError
|
|
@@ -142,12 +143,17 @@ function effect(effectFn, options) {
|
|
|
142
143
|
try {
|
|
143
144
|
retrack(ctx.bodyFn, ctx.subscriber);
|
|
144
145
|
if (ctx.rerunPending) drainReruns(ctx);
|
|
146
|
+
} catch (err) {
|
|
147
|
+
ctx.disposed = true;
|
|
148
|
+
if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
|
|
149
|
+
cleanup(ctx.subscriber);
|
|
150
|
+
throw err;
|
|
145
151
|
} finally {
|
|
146
152
|
ctx.running = false;
|
|
147
153
|
ctx.rerunPending = false;
|
|
148
154
|
}
|
|
149
155
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
150
|
-
if (hook) hook
|
|
156
|
+
if (hook) emitDevtools(hook, "effect:create", { effectFn });
|
|
151
157
|
return () => disposeEffect(ctx);
|
|
152
158
|
}
|
|
153
159
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
derived
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-RUSSKG6G.js";
|
|
4
4
|
import {
|
|
5
5
|
sanitizeUrl
|
|
6
6
|
} from "./chunk-2INLLLMZ.js";
|
|
@@ -9,14 +9,17 @@ import {
|
|
|
9
9
|
} from "./chunk-7ZHH77QA.js";
|
|
10
10
|
import {
|
|
11
11
|
effect
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-WEQ3DMVL.js";
|
|
13
13
|
import {
|
|
14
14
|
getRequestScopedCache
|
|
15
15
|
} from "./chunk-7XHATCIH.js";
|
|
16
16
|
import {
|
|
17
17
|
batch,
|
|
18
18
|
signal
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-FQRUXCEE.js";
|
|
20
|
+
import {
|
|
21
|
+
untracked
|
|
22
|
+
} from "./chunk-JWKYU5GV.js";
|
|
20
23
|
import {
|
|
21
24
|
reportError
|
|
22
25
|
} from "./chunk-NYNYSPK7.js";
|
|
@@ -132,7 +135,83 @@ function waitForRetryDelay(delay, signal2) {
|
|
|
132
135
|
});
|
|
133
136
|
}
|
|
134
137
|
|
|
138
|
+
// src/data/structuralSharing.ts
|
|
139
|
+
function isPlainObject(value) {
|
|
140
|
+
if (value === null || typeof value !== "object") return false;
|
|
141
|
+
const proto = Object.getPrototypeOf(value);
|
|
142
|
+
return proto === Object.prototype || proto === null;
|
|
143
|
+
}
|
|
144
|
+
function isPlainArray(value) {
|
|
145
|
+
return Array.isArray(value) && Object.getPrototypeOf(value) === Array.prototype;
|
|
146
|
+
}
|
|
147
|
+
function reconcile(prev, next, depth, walk, newRoot) {
|
|
148
|
+
if (Object.is(prev, next)) return prev;
|
|
149
|
+
const arrays = isPlainArray(prev) && isPlainArray(next);
|
|
150
|
+
if (!arrays && !(isPlainObject(prev) && isPlainObject(next))) return next;
|
|
151
|
+
if (Object.getPrototypeOf(prev) !== Object.getPrototypeOf(next)) return next;
|
|
152
|
+
const nextObject = next;
|
|
153
|
+
const seenAt = walk.path.get(nextObject);
|
|
154
|
+
if (seenAt !== void 0) {
|
|
155
|
+
walk.cycleTo = Math.min(walk.cycleTo, seenAt);
|
|
156
|
+
return next;
|
|
157
|
+
}
|
|
158
|
+
const prevRecord = prev;
|
|
159
|
+
const nextRecord = next;
|
|
160
|
+
const nextKeys = arrays ? Array.from({ length: next.length }, (_, i) => i) : Object.keys(nextRecord);
|
|
161
|
+
const prevSize = arrays ? prev.length : Object.keys(prevRecord).length;
|
|
162
|
+
const copy = arrays ? new Array(nextKeys.length) : Object.create(Object.getPrototypeOf(next));
|
|
163
|
+
let allFromPrev = prevSize === nextKeys.length;
|
|
164
|
+
let allFromNext = true;
|
|
165
|
+
const outerCycleTo = walk.cycleTo;
|
|
166
|
+
walk.cycleTo = Number.POSITIVE_INFINITY;
|
|
167
|
+
walk.path.set(nextObject, depth);
|
|
168
|
+
for (const key of nextKeys) {
|
|
169
|
+
if (arrays && !Object.hasOwn(nextRecord, key)) {
|
|
170
|
+
if (Object.hasOwn(prevRecord, key)) allFromPrev = false;
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
const nextChild = nextRecord[key];
|
|
174
|
+
const hasPrev = Object.hasOwn(prevRecord, key);
|
|
175
|
+
const shared = hasPrev ? reconcile(prevRecord[key], nextChild, depth + 1, walk, false) : nextChild;
|
|
176
|
+
copy[key] = shared;
|
|
177
|
+
if (!hasPrev || !Object.is(shared, prevRecord[key])) allFromPrev = false;
|
|
178
|
+
if (!Object.is(shared, nextChild)) allFromNext = false;
|
|
179
|
+
}
|
|
180
|
+
walk.path.delete(nextObject);
|
|
181
|
+
const reached = walk.cycleTo;
|
|
182
|
+
walk.cycleTo = Math.min(outerCycleTo, reached < depth ? reached : Number.POSITIVE_INFINITY);
|
|
183
|
+
if (reached <= depth) return next;
|
|
184
|
+
if (allFromPrev && !newRoot) return prev;
|
|
185
|
+
if (allFromNext) return next;
|
|
186
|
+
return copy;
|
|
187
|
+
}
|
|
188
|
+
function applyStructuralSharing(option, prev, next, explicit = false) {
|
|
189
|
+
if (option === false || prev === void 0) return next;
|
|
190
|
+
const forceNew = explicit && !Object.is(prev, next);
|
|
191
|
+
if (typeof option === "function") {
|
|
192
|
+
const shared = option(prev, next);
|
|
193
|
+
return forceNew && Object.is(shared, prev) ? next : shared;
|
|
194
|
+
}
|
|
195
|
+
return reconcile(prev, next, 0, { path: /* @__PURE__ */ new Map(), cycleTo: Number.POSITIVE_INFINITY }, forceNew);
|
|
196
|
+
}
|
|
197
|
+
|
|
135
198
|
// src/data/query.ts
|
|
199
|
+
function shareSafely(option, prev, next, explicit) {
|
|
200
|
+
const shared = untracked(
|
|
201
|
+
() => runSelect("query structuralSharing", () => applyStructuralSharing(option, prev, next, explicit))
|
|
202
|
+
);
|
|
203
|
+
return shared.ok ? shared.value : next;
|
|
204
|
+
}
|
|
205
|
+
function sharedView(entry) {
|
|
206
|
+
const raw = entry.data;
|
|
207
|
+
if (raw === void 0) return void 0;
|
|
208
|
+
if (entry.hasShared && Object.is(entry.sharedFrom, raw)) return entry.shared;
|
|
209
|
+
const value = shareSafely(true, entry.hasShared ? entry.shared : void 0, raw, entry.explicit);
|
|
210
|
+
entry.shared = value;
|
|
211
|
+
entry.sharedFrom = raw;
|
|
212
|
+
entry.hasShared = true;
|
|
213
|
+
return value;
|
|
214
|
+
}
|
|
136
215
|
var globalQueryCache = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.query.cache.v1"), () => /* @__PURE__ */ new Map());
|
|
137
216
|
function getActiveQueryCache() {
|
|
138
217
|
return getRequestScopedCache("query") ?? globalQueryCache;
|
|
@@ -158,7 +237,11 @@ function getOrCreateEntry(cache, key, initialData) {
|
|
|
158
237
|
listeners: /* @__PURE__ */ new Set(),
|
|
159
238
|
refetchers: /* @__PURE__ */ new Set(),
|
|
160
239
|
controller: null,
|
|
161
|
-
generation: 0
|
|
240
|
+
generation: 0,
|
|
241
|
+
explicit: false,
|
|
242
|
+
shared: void 0,
|
|
243
|
+
sharedFrom: void 0,
|
|
244
|
+
hasShared: false
|
|
162
245
|
};
|
|
163
246
|
cache.set(key, entry);
|
|
164
247
|
}
|
|
@@ -177,13 +260,24 @@ function query(key, fetcher, options = {}) {
|
|
|
177
260
|
onSuccess,
|
|
178
261
|
onError,
|
|
179
262
|
onSettled,
|
|
180
|
-
select
|
|
263
|
+
select,
|
|
264
|
+
structuralSharing = true
|
|
181
265
|
} = options;
|
|
182
266
|
const resolveKey = typeof key === "function" ? key : () => key;
|
|
183
267
|
const cache = getActiveQueryCache();
|
|
184
268
|
const [data, setData] = signal(initialData);
|
|
185
269
|
const [isFetching, setIsFetching] = signal(false);
|
|
186
270
|
const [error, setError] = signal(void 0);
|
|
271
|
+
const [updatedAt, setUpdatedAt] = signal(0);
|
|
272
|
+
const [base, setBase] = signal(void 0);
|
|
273
|
+
let baseEntry = null;
|
|
274
|
+
let baseValue;
|
|
275
|
+
let baseExplicit = false;
|
|
276
|
+
let customEntry = null;
|
|
277
|
+
let customFrom;
|
|
278
|
+
let customValue;
|
|
279
|
+
let selectedEntry = null;
|
|
280
|
+
let selectedValue;
|
|
187
281
|
let disposed = false;
|
|
188
282
|
let currentKey = null;
|
|
189
283
|
let attachedEntry = null;
|
|
@@ -192,11 +286,57 @@ function query(key, fetcher, options = {}) {
|
|
|
192
286
|
const loading = derived(() => isFetching() && data() === void 0);
|
|
193
287
|
const isStale = derived(() => {
|
|
194
288
|
data();
|
|
289
|
+
updatedAt();
|
|
195
290
|
if (!currentKey) return true;
|
|
196
291
|
const entry = cache.get(currentKey);
|
|
197
292
|
if (!entry || entry.dataUpdatedAt === 0) return true;
|
|
198
293
|
return Date.now() - entry.dataUpdatedAt >= staleTime;
|
|
199
294
|
});
|
|
295
|
+
function viewOf(entry) {
|
|
296
|
+
const raw = entry.data;
|
|
297
|
+
if (raw === void 0) return void 0;
|
|
298
|
+
if (structuralSharing === false) return raw;
|
|
299
|
+
if (typeof structuralSharing !== "function") return sharedView(entry);
|
|
300
|
+
const sameEntry = customEntry === entry;
|
|
301
|
+
if (sameEntry && Object.is(customFrom, raw)) return customValue;
|
|
302
|
+
const value = shareSafely(structuralSharing, sameEntry ? customValue : void 0, raw, entry.explicit);
|
|
303
|
+
customEntry = entry;
|
|
304
|
+
customFrom = raw;
|
|
305
|
+
customValue = value;
|
|
306
|
+
return value;
|
|
307
|
+
}
|
|
308
|
+
function commitBase(entry, value) {
|
|
309
|
+
const changed = !Object.is(value, baseValue);
|
|
310
|
+
baseEntry = entry;
|
|
311
|
+
baseValue = value;
|
|
312
|
+
if (!select) {
|
|
313
|
+
setData(value);
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
if (!changed) return;
|
|
317
|
+
baseExplicit = entry?.explicit === true;
|
|
318
|
+
setBase(value);
|
|
319
|
+
}
|
|
320
|
+
const stopSelect = select ? effect(() => {
|
|
321
|
+
const raw = base();
|
|
322
|
+
const entry = baseEntry;
|
|
323
|
+
const explicit = baseExplicit;
|
|
324
|
+
baseExplicit = false;
|
|
325
|
+
if (entry === null && selectedEntry === null) return;
|
|
326
|
+
if (raw === void 0) {
|
|
327
|
+
selectedEntry = entry;
|
|
328
|
+
selectedValue = void 0;
|
|
329
|
+
setData(void 0);
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
const selected = runSelect("query select", () => select(raw));
|
|
333
|
+
if (!selected.ok) return;
|
|
334
|
+
const prev = selectedEntry === entry ? selectedValue : void 0;
|
|
335
|
+
const value = shareSafely(structuralSharing, prev, selected.value, explicit);
|
|
336
|
+
selectedEntry = entry;
|
|
337
|
+
selectedValue = value;
|
|
338
|
+
setData(value);
|
|
339
|
+
}) : null;
|
|
200
340
|
function detachFromEntry() {
|
|
201
341
|
const entry = attachedEntry;
|
|
202
342
|
const key2 = attachedKey;
|
|
@@ -255,7 +395,7 @@ function query(key, fetcher, options = {}) {
|
|
|
255
395
|
const settledError = entry.error;
|
|
256
396
|
runCallback("query onError", () => onError?.(settledError));
|
|
257
397
|
} else if (entry.data !== void 0) {
|
|
258
|
-
const settledData = entry
|
|
398
|
+
const settledData = viewOf(entry);
|
|
259
399
|
runCallback("query onSuccess", () => onSuccess?.(settledData));
|
|
260
400
|
}
|
|
261
401
|
runCallback("query onSettled", () => onSettled?.());
|
|
@@ -286,17 +426,14 @@ function query(key, fetcher, options = {}) {
|
|
|
286
426
|
entry.promise = null;
|
|
287
427
|
entry.controller = null;
|
|
288
428
|
entry.data = result;
|
|
429
|
+
entry.explicit = false;
|
|
289
430
|
entry.dataUpdatedAt = Date.now();
|
|
290
431
|
entry.error = void 0;
|
|
291
432
|
notifyListeners(entry.listeners, "query cache listener");
|
|
292
433
|
if (disposed || currentKey !== key2) return;
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
setIsFetching(false);
|
|
297
|
-
setError(void 0);
|
|
298
|
-
});
|
|
299
|
-
runCallback("query onSuccess", () => onSuccess?.(result));
|
|
434
|
+
if (!entry.listeners.has(onCacheUpdate)) onCacheUpdate();
|
|
435
|
+
const committedResult = viewOf(entry);
|
|
436
|
+
runCallback("query onSuccess", () => onSuccess?.(committedResult));
|
|
300
437
|
} catch (err) {
|
|
301
438
|
if (entry.generation !== generation) return;
|
|
302
439
|
entry.promise = null;
|
|
@@ -326,18 +463,19 @@ function query(key, fetcher, options = {}) {
|
|
|
326
463
|
const entry = cache.get(currentKey);
|
|
327
464
|
if (!entry) {
|
|
328
465
|
batch(() => {
|
|
329
|
-
|
|
466
|
+
commitBase(null, void 0);
|
|
330
467
|
setError(void 0);
|
|
331
468
|
setIsFetching(false);
|
|
469
|
+
setUpdatedAt(0);
|
|
332
470
|
});
|
|
333
471
|
return;
|
|
334
472
|
}
|
|
335
|
-
const
|
|
336
|
-
const selected = raw !== void 0 && select ? runSelect("query select", () => select(raw)) : { ok: true, value: raw };
|
|
473
|
+
const view = viewOf(entry);
|
|
337
474
|
batch(() => {
|
|
338
|
-
|
|
475
|
+
commitBase(entry, view);
|
|
339
476
|
setError(entry.error);
|
|
340
477
|
if (!entry.promise) setIsFetching(false);
|
|
478
|
+
setUpdatedAt(entry.dataUpdatedAt);
|
|
341
479
|
});
|
|
342
480
|
}
|
|
343
481
|
const effectCleanup = effect(() => {
|
|
@@ -347,11 +485,11 @@ function query(key, fetcher, options = {}) {
|
|
|
347
485
|
const entry = getOrCreateEntry(cache, key2, initialData);
|
|
348
486
|
attachToEntry(entry, key2);
|
|
349
487
|
if (entry.data !== void 0) {
|
|
350
|
-
const
|
|
351
|
-
const selected = runSelect("query select", () => select ? select(raw) : raw);
|
|
488
|
+
const view = viewOf(entry);
|
|
352
489
|
batch(() => {
|
|
353
|
-
|
|
490
|
+
commitBase(entry, view);
|
|
354
491
|
setError(entry.error);
|
|
492
|
+
setUpdatedAt(entry.dataUpdatedAt);
|
|
355
493
|
});
|
|
356
494
|
}
|
|
357
495
|
if (!keyChanged && currentKey === key2 && entry.data !== void 0) {
|
|
@@ -389,6 +527,7 @@ function query(key, fetcher, options = {}) {
|
|
|
389
527
|
if (disposed) return;
|
|
390
528
|
disposed = true;
|
|
391
529
|
effectCleanup();
|
|
530
|
+
stopSelect?.();
|
|
392
531
|
loading.dispose();
|
|
393
532
|
isStale.dispose();
|
|
394
533
|
if (intervalTimer) clearInterval(intervalTimer);
|
|
@@ -420,13 +559,15 @@ function invalidateQueries(keyOrPredicate) {
|
|
|
420
559
|
}
|
|
421
560
|
}
|
|
422
561
|
function getQueryData(key) {
|
|
423
|
-
|
|
562
|
+
const entry = getActiveQueryCache().get(key);
|
|
563
|
+
return entry ? sharedView(entry) : void 0;
|
|
424
564
|
}
|
|
425
565
|
function setQueryData(key, data) {
|
|
426
566
|
const entry = getActiveQueryCache().get(key);
|
|
427
567
|
if (!entry) return;
|
|
428
|
-
const newData = typeof data === "function" ? data(entry
|
|
568
|
+
const newData = typeof data === "function" ? data(sharedView(entry)) : data;
|
|
429
569
|
entry.data = newData;
|
|
570
|
+
entry.explicit = true;
|
|
430
571
|
entry.dataUpdatedAt = Date.now();
|
|
431
572
|
notifyListeners(entry.listeners, "query cache listener");
|
|
432
573
|
}
|
|
@@ -810,6 +951,15 @@ function resource(sourceOrFetcher, fetcherOrOptions, maybeOptions) {
|
|
|
810
951
|
const [loading, setLoading] = signal(false);
|
|
811
952
|
const [error, setError] = signal(void 0);
|
|
812
953
|
let currentData = options.initialValue;
|
|
954
|
+
function commitData(next, explicit) {
|
|
955
|
+
const sharing = options.structuralSharing ?? true;
|
|
956
|
+
const shared = untracked(
|
|
957
|
+
() => runSelect("resource structuralSharing", () => applyStructuralSharing(sharing, currentData, next, explicit))
|
|
958
|
+
);
|
|
959
|
+
currentData = shared.ok ? shared.value : next;
|
|
960
|
+
setData(currentData);
|
|
961
|
+
return currentData;
|
|
962
|
+
}
|
|
813
963
|
let abortController = null;
|
|
814
964
|
let disposed = false;
|
|
815
965
|
let effectCleanup = null;
|
|
@@ -829,12 +979,12 @@ function resource(sourceOrFetcher, fetcherOrOptions, maybeOptions) {
|
|
|
829
979
|
try {
|
|
830
980
|
const result = await withRetry(() => fetcher(sourceValue, { signal: signal2, prev }), options.retry, void 0, signal2);
|
|
831
981
|
if (version !== fetchVersion || disposed) return;
|
|
832
|
-
|
|
982
|
+
let committed = result;
|
|
833
983
|
batch(() => {
|
|
834
|
-
|
|
984
|
+
committed = commitData(result, false);
|
|
835
985
|
setLoading(false);
|
|
836
986
|
});
|
|
837
|
-
runCallback("resource onSuccess", () => options.onSuccess?.(
|
|
987
|
+
runCallback("resource onSuccess", () => options.onSuccess?.(committed));
|
|
838
988
|
} catch (err) {
|
|
839
989
|
if (version !== fetchVersion || disposed) return;
|
|
840
990
|
if (isAbortError(err)) {
|
|
@@ -868,8 +1018,7 @@ function resource(sourceOrFetcher, fetcherOrOptions, maybeOptions) {
|
|
|
868
1018
|
refetch: () => doFetch(source ? source() : void 0),
|
|
869
1019
|
mutate: (value) => {
|
|
870
1020
|
const newValue = typeof value === "function" ? value(currentData) : value;
|
|
871
|
-
|
|
872
|
-
setData(newValue);
|
|
1021
|
+
commitData(newValue, true);
|
|
873
1022
|
},
|
|
874
1023
|
abort: () => abortController?.abort(),
|
|
875
1024
|
dispose: () => {
|