sibujs 4.6.0 → 4.8.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 +62 -8
- package/dist/browser.d.cts +23 -0
- package/dist/browser.d.ts +23 -0
- package/dist/browser.js +6 -5
- package/dist/build.cjs +2388 -1004
- package/dist/build.d.cts +147 -44
- package/dist/build.d.ts +147 -44
- package/dist/build.js +1410 -564
- package/dist/cdn.dev.global.js +14 -12
- package/dist/cdn.full.dev.global.js +15 -13
- package/dist/cdn.full.global.js +14 -12
- package/dist/cdn.global.js +12 -10
- package/dist/chunk-3ACAAQIN.js +224 -0
- package/dist/{chunk-7NCARGJW.js → chunk-44MTL7ED.js} +6 -6
- package/dist/{chunk-BAAG6ZTI.js → chunk-4WMSTZ7J.js} +8 -5
- package/dist/{chunk-H3SRKIYX.js → chunk-62BDYGAG.js} +8 -0
- package/dist/{chunk-DKGBBKOF.js → chunk-C5PEWEGH.js} +20 -5
- package/dist/{chunk-3ISI6ACU.js → chunk-C7AA2CZX.js} +1 -1
- package/dist/{chunk-UZQ6ALFS.js → chunk-CZPRSWSS.js} +1 -1
- package/dist/{chunk-D33YTSX5.js → chunk-DSID757X.js} +5 -4
- package/dist/{chunk-OXUY2A6L.js → chunk-EGUQLBHE.js} +22 -8
- package/dist/{chunk-2INLLLMZ.js → chunk-EXXSN3BW.js} +202 -26
- package/dist/{chunk-HURREPU2.js → chunk-FC6KCJSA.js} +87 -150
- package/dist/{chunk-HYXDKS4N.js → chunk-GSGNX35Q.js} +5 -5
- package/dist/{chunk-7GQCWFOE.js → chunk-J3YQ457H.js} +171 -85
- package/dist/{chunk-ORMZXBKQ.js → chunk-JUTFX2RM.js} +18 -10
- package/dist/{chunk-QE4TTDU3.js → chunk-KJ3UKABJ.js} +12 -11
- package/dist/{chunk-XRRZKZYX.js → chunk-LI4W3U6C.js} +1 -1
- package/dist/{chunk-47M47FOM.js → chunk-O6TRVMJI.js} +58 -6
- package/dist/{chunk-JSXPZCET.js → chunk-Q5J2LVKH.js} +1 -1
- package/dist/{chunk-5MT6SJ3P.js → chunk-QGMSESDD.js} +10 -5
- package/dist/{chunk-AIF3Z2T7.js → chunk-RGLPEBDE.js} +13 -10
- package/dist/{chunk-5Q4R7HCL.js → chunk-TQQUN4WR.js} +11 -2
- package/dist/{chunk-PK6FK2G2.js → chunk-UCNP3HVM.js} +183 -30
- package/dist/{chunk-XC4MEKGA.js → chunk-V3LHZSU5.js} +8 -2
- package/dist/{chunk-VVWPJ543.js → chunk-VWT3VXPL.js} +55 -20
- package/dist/{chunk-SXXVZMKZ.js → chunk-ZVLHNEEL.js} +17 -35
- package/dist/{contracts-DRIuclVT.d.cts → contracts-CLqzJnOV.d.ts} +28 -17
- package/dist/{contracts-DRIuclVT.d.ts → contracts-CTOJXu-x.d.cts} +28 -17
- package/dist/{customElement-MmInOW1U.d.ts → customElement-pYDKUzWl.d.cts} +11 -3
- package/dist/{customElement-MmInOW1U.d.cts → customElement-pYDKUzWl.d.ts} +11 -3
- package/dist/data.cjs +205 -39
- package/dist/data.d.cts +119 -3
- package/dist/data.d.ts +119 -3
- package/dist/data.js +6 -6
- package/dist/devtools.cjs +18 -5
- package/dist/devtools.js +5 -5
- package/dist/ecosystem.cjs +462 -58
- package/dist/ecosystem.d.cts +2 -1
- package/dist/ecosystem.d.ts +2 -1
- package/dist/ecosystem.js +9 -8
- package/dist/extras.cjs +852 -296
- package/dist/extras.d.cts +5 -4
- package/dist/extras.d.ts +5 -4
- package/dist/extras.js +24 -23
- package/dist/index.cjs +721 -176
- package/dist/index.d.cts +220 -169
- package/dist/index.d.ts +220 -169
- package/dist/index.js +16 -12
- package/dist/motion.cjs +12 -4
- package/dist/motion.js +3 -3
- package/dist/patterns.cjs +37 -21
- package/dist/patterns.d.cts +2 -1
- package/dist/patterns.d.ts +2 -1
- package/dist/patterns.js +6 -6
- package/dist/performance.cjs +48 -6
- package/dist/performance.d.cts +12 -2
- package/dist/performance.d.ts +12 -2
- package/dist/performance.js +8 -6
- package/dist/plugins.cjs +672 -261
- package/dist/plugins.d.cts +131 -13
- package/dist/plugins.d.ts +131 -13
- package/dist/plugins.js +83 -47
- package/dist/{ssr-XOTUASDO.js → ssr-5OWAH3U2.js} +4 -2
- package/dist/{ssr-Bli9XRW5.d.cts → ssr-C8hgIAw7.d.cts} +6 -0
- package/dist/{ssr-Bli9XRW5.d.ts → ssr-C8hgIAw7.d.ts} +6 -0
- package/dist/ssr.cjs +509 -142
- package/dist/ssr.d.cts +55 -5
- package/dist/ssr.d.ts +55 -5
- package/dist/ssr.js +11 -9
- 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 +17 -4
- package/dist/testing.js +4 -4
- package/dist/types-CJFViL6Q.d.cts +26 -0
- package/dist/types-CJFViL6Q.d.ts +26 -0
- package/dist/ui.cjs +635 -254
- package/dist/ui.d.cts +3 -2
- package/dist/ui.d.ts +3 -2
- package/dist/ui.js +9 -8
- package/dist/widgets.cjs +22 -14
- package/dist/widgets.js +7 -7
- package/package.json +8 -5
|
@@ -1,14 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ContextualRefusal,
|
|
3
|
+
contextualAttributeRefusal,
|
|
4
|
+
settleAttributeProvenance
|
|
5
|
+
} from "./chunk-3ACAAQIN.js";
|
|
1
6
|
import {
|
|
2
7
|
isEventHandlerAttr,
|
|
3
8
|
isHtmlContentAttribute,
|
|
4
|
-
|
|
5
|
-
} from "./chunk-
|
|
9
|
+
resolveAttributeValue
|
|
10
|
+
} from "./chunk-EXXSN3BW.js";
|
|
6
11
|
import {
|
|
7
12
|
reactiveBinding
|
|
8
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-TQQUN4WR.js";
|
|
9
14
|
import {
|
|
10
15
|
DEV,
|
|
11
16
|
devWarn,
|
|
17
|
+
devWarnLazy,
|
|
12
18
|
reportError
|
|
13
19
|
} from "./chunk-NYNYSPK7.js";
|
|
14
20
|
|
|
@@ -21,6 +27,19 @@ var BOOLEAN_IDL_ATTRS = /* @__PURE__ */ new Set(["checked", "disabled", "selecte
|
|
|
21
27
|
function isHtmlElement(el) {
|
|
22
28
|
return el.namespaceURI === null || el.namespaceURI === HTML_NS;
|
|
23
29
|
}
|
|
30
|
+
function warnContextualRefusal(label, name, refusal) {
|
|
31
|
+
devWarnLazy(() => {
|
|
32
|
+
const reasons = [
|
|
33
|
+
"",
|
|
34
|
+
'the element would become a <meta http-equiv="refresh"> directive the shared refresh policy forbids (a destination outside the URL allowlist, or a directive too malformed to read unambiguously)',
|
|
35
|
+
"a <meta> whose http-equiv or content is reactive may never carry a refresh directive: a browser schedules the navigation as soon as the directive is valid, and nothing can withdraw it when the state changes back",
|
|
36
|
+
"a runtime value may not choose the program a <script> runs; name the script in static template source, or load it through Head({ script }) as an explicit trust decision",
|
|
37
|
+
"an SVG animation may not target a URL, event-handler or nested-document attribute; its to / values would be written into that attribute without passing the URL policy",
|
|
38
|
+
'a runtime-chosen href may not become an applied <link rel="stylesheet">: a well-formed URL is not a trusted stylesheet. Name the stylesheet in static template source, or load a runtime-chosen one through Head({ link }) as an explicit trust decision'
|
|
39
|
+
];
|
|
40
|
+
return `${label}: refusing "${name}" in this element's context \u2014 ${reasons[refusal]}. The write was not performed.`;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
24
43
|
function setProp(el, key, val) {
|
|
25
44
|
el[key] = val;
|
|
26
45
|
}
|
|
@@ -32,6 +51,11 @@ function namespaceFor(el, name) {
|
|
|
32
51
|
return null;
|
|
33
52
|
}
|
|
34
53
|
function setSafeAttribute(el, name, value, options = {}) {
|
|
54
|
+
const written = commitSafeAttribute(el, name, value, options);
|
|
55
|
+
if (el.localName === "link") settleAttributeProvenance(el, name, options.reactive ? "reactive" : "runtime");
|
|
56
|
+
return written;
|
|
57
|
+
}
|
|
58
|
+
function commitSafeAttribute(el, name, value, options) {
|
|
35
59
|
const ns = namespaceFor(el, name);
|
|
36
60
|
const localName = ns ? name.slice(name.indexOf(":") + 1) : name;
|
|
37
61
|
if (isEventHandlerAttr(name)) {
|
|
@@ -44,6 +68,14 @@ function setSafeAttribute(el, name, value, options = {}) {
|
|
|
44
68
|
else el.removeAttribute(name);
|
|
45
69
|
return false;
|
|
46
70
|
}
|
|
71
|
+
const pending = value == null || value === false ? null : value === true ? "" : String(value);
|
|
72
|
+
const refusal = contextualAttributeRefusal(el, name, pending, options.reactive ? "reactive" : "runtime");
|
|
73
|
+
if (refusal !== ContextualRefusal.None) {
|
|
74
|
+
warnContextualRefusal(options.label ?? "setSafeAttribute", name, refusal);
|
|
75
|
+
if (ns) el.removeAttributeNS(ns, localName);
|
|
76
|
+
else el.removeAttribute(name);
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
47
79
|
if (value == null) {
|
|
48
80
|
if (ns) el.removeAttributeNS(ns, localName);
|
|
49
81
|
else el.removeAttribute(name);
|
|
@@ -87,13 +119,32 @@ function setSafeAttribute(el, name, value, options = {}) {
|
|
|
87
119
|
setProp(el, idlName, idlName === "checked" ? Boolean(value) : str);
|
|
88
120
|
return true;
|
|
89
121
|
}
|
|
90
|
-
const safe =
|
|
122
|
+
const safe = str === "" ? "" : resolveAttributeValue(name, str, { element: el });
|
|
123
|
+
if (safe === null) {
|
|
124
|
+
if (ns) el.removeAttributeNS(ns, localName);
|
|
125
|
+
else el.removeAttribute(name);
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
91
128
|
const current = ns ? el.getAttributeNS(ns, localName) : el.getAttribute(name);
|
|
92
129
|
if (current === safe) return true;
|
|
93
130
|
if (ns) el.setAttributeNS(ns, name, safe);
|
|
94
131
|
else el.setAttribute(name, safe);
|
|
95
132
|
return true;
|
|
96
133
|
}
|
|
134
|
+
function setTrustedAttribute(el, name, value) {
|
|
135
|
+
if (isHtmlContentAttribute(name)) {
|
|
136
|
+
if (DEV) devWarn(`html: refusing static attribute "${name}" \u2014 the browser parses it as a nested document.`);
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
const refusal = contextualAttributeRefusal(el, name, value, "static");
|
|
140
|
+
if (refusal !== ContextualRefusal.None) {
|
|
141
|
+
warnContextualRefusal("html (static attribute)", name, refusal);
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
el.setAttribute(name, value);
|
|
145
|
+
if (el.localName === "link") settleAttributeProvenance(el, name, "static");
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
97
148
|
|
|
98
149
|
// src/reactivity/bindAttribute.ts
|
|
99
150
|
function bindAttribute(el, attr, getter) {
|
|
@@ -110,7 +161,7 @@ function bindAttribute(el, attr, getter) {
|
|
|
110
161
|
reportError(err, { phase: "binding", name: `bindAttribute("${attr}")`, node: el });
|
|
111
162
|
return;
|
|
112
163
|
}
|
|
113
|
-
setSafeAttribute(el, attr, value, { label: `bindAttribute("${attr}")
|
|
164
|
+
setSafeAttribute(el, attr, value, { label: `bindAttribute("${attr}")`, reactive: true });
|
|
114
165
|
}
|
|
115
166
|
return reactiveBinding(commit, el);
|
|
116
167
|
}
|
|
@@ -135,7 +186,7 @@ function bindDynamic(el, nameGetter, valueGetter) {
|
|
|
135
186
|
el.removeAttribute(prevName);
|
|
136
187
|
prevName = null;
|
|
137
188
|
}
|
|
138
|
-
if (!setSafeAttribute(el, name, value, { label: "bindDynamic" })) return;
|
|
189
|
+
if (!setSafeAttribute(el, name, value, { label: "bindDynamic", reactive: true })) return;
|
|
139
190
|
prevName = name;
|
|
140
191
|
}
|
|
141
192
|
const teardown = reactiveBinding(commit, el);
|
|
@@ -149,6 +200,7 @@ function bindDynamic(el, nameGetter, valueGetter) {
|
|
|
149
200
|
|
|
150
201
|
export {
|
|
151
202
|
setSafeAttribute,
|
|
203
|
+
setTrustedAttribute,
|
|
152
204
|
bindAttribute,
|
|
153
205
|
bindDynamic
|
|
154
206
|
};
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
renderToString
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-FC6KCJSA.js";
|
|
4
4
|
import {
|
|
5
5
|
globalSingleton
|
|
6
6
|
} from "./chunk-7ZHH77QA.js";
|
|
7
|
+
import {
|
|
8
|
+
sanitizeUrl
|
|
9
|
+
} from "./chunk-EXXSN3BW.js";
|
|
7
10
|
import {
|
|
8
11
|
reportError
|
|
9
12
|
} from "./chunk-NYNYSPK7.js";
|
|
@@ -167,7 +170,7 @@ var CDN_ENTRY_POINTS = {
|
|
|
167
170
|
};
|
|
168
171
|
var packageInfo = {
|
|
169
172
|
name: "sibujs",
|
|
170
|
-
version: true ? "4.
|
|
173
|
+
version: true ? "4.8.0" : "dev",
|
|
171
174
|
entryPoints: MODULE_ENTRY_POINTS,
|
|
172
175
|
/**
|
|
173
176
|
* Generate the package.json `exports` map. Module entries resolve to the
|
|
@@ -312,7 +315,7 @@ var env = {
|
|
|
312
315
|
};
|
|
313
316
|
|
|
314
317
|
// src/plugins/versioning.ts
|
|
315
|
-
var VERSION = true ? "4.
|
|
318
|
+
var VERSION = true ? "4.8.0" : "dev";
|
|
316
319
|
var NUM = "(?:0|[1-9]\\d*)";
|
|
317
320
|
var PRE_ID = `(?:${NUM}|\\d*[a-zA-Z-][0-9a-zA-Z-]*)`;
|
|
318
321
|
var BUILD_ID = "[0-9a-zA-Z-]+";
|
|
@@ -595,12 +598,14 @@ function extractRangeTarget(range) {
|
|
|
595
598
|
function preloadCritical(resources) {
|
|
596
599
|
if (typeof document === "undefined") return;
|
|
597
600
|
for (const resource of resources) {
|
|
598
|
-
const
|
|
601
|
+
const href = sanitizeUrl(resource.href);
|
|
602
|
+
if (!href) continue;
|
|
603
|
+
const safeHref = typeof CSS !== "undefined" && typeof CSS.escape === "function" ? CSS.escape(href) : href.replace(/["\\]/g, "\\$&");
|
|
599
604
|
const existing = document.querySelector(`link[rel="preload"][href="${safeHref}"]`);
|
|
600
605
|
if (existing) continue;
|
|
601
606
|
const link = document.createElement("link");
|
|
602
607
|
link.rel = "preload";
|
|
603
|
-
link.href =
|
|
608
|
+
link.href = href;
|
|
604
609
|
link.setAttribute("as", resource.as);
|
|
605
610
|
if (resource.type) {
|
|
606
611
|
link.type = resource.type;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isUnsafeKey,
|
|
3
3
|
stripUnsafeKeys
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-62BDYGAG.js";
|
|
5
5
|
import {
|
|
6
6
|
derived
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-KJ3UKABJ.js";
|
|
8
8
|
import {
|
|
9
9
|
effect
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-V3LHZSU5.js";
|
|
11
11
|
import {
|
|
12
12
|
batch,
|
|
13
13
|
signal
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-DSID757X.js";
|
|
15
15
|
import {
|
|
16
16
|
DEV,
|
|
17
17
|
devWarn,
|
|
@@ -19,6 +19,9 @@ import {
|
|
|
19
19
|
} from "./chunk-NYNYSPK7.js";
|
|
20
20
|
|
|
21
21
|
// src/patterns/machine.ts
|
|
22
|
+
function ownEntry(table, key) {
|
|
23
|
+
return Object.hasOwn(table, key) ? table[key] : void 0;
|
|
24
|
+
}
|
|
22
25
|
function machine(config) {
|
|
23
26
|
const [state, setState] = signal(config.initial);
|
|
24
27
|
const [context, setContext] = signal(config.context || {});
|
|
@@ -40,9 +43,9 @@ function machine(config) {
|
|
|
40
43
|
}
|
|
41
44
|
}
|
|
42
45
|
function step(event) {
|
|
43
|
-
const stateDef = config.states
|
|
46
|
+
const stateDef = ownEntry(config.states, currentState);
|
|
44
47
|
if (!stateDef?.on) return;
|
|
45
|
-
const transition = stateDef.on
|
|
48
|
+
const transition = ownEntry(stateDef.on, event);
|
|
46
49
|
if (!transition) return;
|
|
47
50
|
let target;
|
|
48
51
|
let guard;
|
|
@@ -70,7 +73,7 @@ function machine(config) {
|
|
|
70
73
|
if (action) setContext(nextContext);
|
|
71
74
|
setState(target);
|
|
72
75
|
});
|
|
73
|
-
const targetDef = config.states
|
|
76
|
+
const targetDef = ownEntry(config.states, target);
|
|
74
77
|
if (targetDef?.entry) {
|
|
75
78
|
targetDef.entry(currentContext);
|
|
76
79
|
}
|
|
@@ -80,7 +83,7 @@ function machine(config) {
|
|
|
80
83
|
if (processing) return;
|
|
81
84
|
drain();
|
|
82
85
|
}
|
|
83
|
-
const initialDef = config.states
|
|
86
|
+
const initialDef = ownEntry(config.states, config.initial);
|
|
84
87
|
if (initialDef?.entry) {
|
|
85
88
|
processing = true;
|
|
86
89
|
try {
|
|
@@ -98,9 +101,9 @@ function machine(config) {
|
|
|
98
101
|
}
|
|
99
102
|
function can(event) {
|
|
100
103
|
const currentState2 = state();
|
|
101
|
-
const stateDef = config.states
|
|
104
|
+
const stateDef = ownEntry(config.states, currentState2);
|
|
102
105
|
if (!stateDef?.on) return false;
|
|
103
|
-
const transition = stateDef.on
|
|
106
|
+
const transition = ownEntry(stateDef.on, event);
|
|
104
107
|
if (!transition) return false;
|
|
105
108
|
if (typeof transition === "string") return true;
|
|
106
109
|
if (transition.guard) {
|
|
@@ -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.8.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,22 +1,25 @@
|
|
|
1
1
|
import {
|
|
2
2
|
derived
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import {
|
|
5
|
-
sanitizeUrl
|
|
6
|
-
} from "./chunk-2INLLLMZ.js";
|
|
3
|
+
} from "./chunk-KJ3UKABJ.js";
|
|
7
4
|
import {
|
|
8
5
|
globalSingleton
|
|
9
6
|
} from "./chunk-7ZHH77QA.js";
|
|
10
7
|
import {
|
|
11
8
|
effect
|
|
12
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-V3LHZSU5.js";
|
|
10
|
+
import {
|
|
11
|
+
sanitizeUrl
|
|
12
|
+
} from "./chunk-EXXSN3BW.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-DSID757X.js";
|
|
20
|
+
import {
|
|
21
|
+
untracked
|
|
22
|
+
} from "./chunk-TQQUN4WR.js";
|
|
20
23
|
import {
|
|
21
24
|
reportError
|
|
22
25
|
} from "./chunk-NYNYSPK7.js";
|
|
@@ -132,7 +135,87 @@ 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
|
+
if (key === "__proto__") {
|
|
177
|
+
Object.defineProperty(copy, key, { value: shared, writable: true, enumerable: true, configurable: true });
|
|
178
|
+
} else {
|
|
179
|
+
copy[key] = shared;
|
|
180
|
+
}
|
|
181
|
+
if (!hasPrev || !Object.is(shared, prevRecord[key])) allFromPrev = false;
|
|
182
|
+
if (!Object.is(shared, nextChild)) allFromNext = false;
|
|
183
|
+
}
|
|
184
|
+
walk.path.delete(nextObject);
|
|
185
|
+
const reached = walk.cycleTo;
|
|
186
|
+
walk.cycleTo = Math.min(outerCycleTo, reached < depth ? reached : Number.POSITIVE_INFINITY);
|
|
187
|
+
if (reached <= depth) return next;
|
|
188
|
+
if (allFromPrev && !newRoot) return prev;
|
|
189
|
+
if (allFromNext) return next;
|
|
190
|
+
return copy;
|
|
191
|
+
}
|
|
192
|
+
function applyStructuralSharing(option, prev, next, explicit = false) {
|
|
193
|
+
if (option === false || prev === void 0) return next;
|
|
194
|
+
const forceNew = explicit && !Object.is(prev, next);
|
|
195
|
+
if (typeof option === "function") {
|
|
196
|
+
const shared = option(prev, next);
|
|
197
|
+
return forceNew && Object.is(shared, prev) ? next : shared;
|
|
198
|
+
}
|
|
199
|
+
return reconcile(prev, next, 0, { path: /* @__PURE__ */ new Map(), cycleTo: Number.POSITIVE_INFINITY }, forceNew);
|
|
200
|
+
}
|
|
201
|
+
|
|
135
202
|
// src/data/query.ts
|
|
203
|
+
function shareSafely(option, prev, next, explicit) {
|
|
204
|
+
const shared = untracked(
|
|
205
|
+
() => runSelect("query structuralSharing", () => applyStructuralSharing(option, prev, next, explicit))
|
|
206
|
+
);
|
|
207
|
+
return shared.ok ? shared.value : next;
|
|
208
|
+
}
|
|
209
|
+
function sharedView(entry) {
|
|
210
|
+
const raw = entry.data;
|
|
211
|
+
if (raw === void 0) return void 0;
|
|
212
|
+
if (entry.hasShared && Object.is(entry.sharedFrom, raw)) return entry.shared;
|
|
213
|
+
const value = shareSafely(true, entry.hasShared ? entry.shared : void 0, raw, entry.explicit);
|
|
214
|
+
entry.shared = value;
|
|
215
|
+
entry.sharedFrom = raw;
|
|
216
|
+
entry.hasShared = true;
|
|
217
|
+
return value;
|
|
218
|
+
}
|
|
136
219
|
var globalQueryCache = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.query.cache.v1"), () => /* @__PURE__ */ new Map());
|
|
137
220
|
function getActiveQueryCache() {
|
|
138
221
|
return getRequestScopedCache("query") ?? globalQueryCache;
|
|
@@ -158,7 +241,11 @@ function getOrCreateEntry(cache, key, initialData) {
|
|
|
158
241
|
listeners: /* @__PURE__ */ new Set(),
|
|
159
242
|
refetchers: /* @__PURE__ */ new Set(),
|
|
160
243
|
controller: null,
|
|
161
|
-
generation: 0
|
|
244
|
+
generation: 0,
|
|
245
|
+
explicit: false,
|
|
246
|
+
shared: void 0,
|
|
247
|
+
sharedFrom: void 0,
|
|
248
|
+
hasShared: false
|
|
162
249
|
};
|
|
163
250
|
cache.set(key, entry);
|
|
164
251
|
}
|
|
@@ -177,13 +264,24 @@ function query(key, fetcher, options = {}) {
|
|
|
177
264
|
onSuccess,
|
|
178
265
|
onError,
|
|
179
266
|
onSettled,
|
|
180
|
-
select
|
|
267
|
+
select,
|
|
268
|
+
structuralSharing = true
|
|
181
269
|
} = options;
|
|
182
270
|
const resolveKey = typeof key === "function" ? key : () => key;
|
|
183
271
|
const cache = getActiveQueryCache();
|
|
184
272
|
const [data, setData] = signal(initialData);
|
|
185
273
|
const [isFetching, setIsFetching] = signal(false);
|
|
186
274
|
const [error, setError] = signal(void 0);
|
|
275
|
+
const [updatedAt, setUpdatedAt] = signal(0);
|
|
276
|
+
const [base, setBase] = signal(void 0);
|
|
277
|
+
let baseEntry = null;
|
|
278
|
+
let baseValue;
|
|
279
|
+
let baseExplicit = false;
|
|
280
|
+
let customEntry = null;
|
|
281
|
+
let customFrom;
|
|
282
|
+
let customValue;
|
|
283
|
+
let selectedEntry = null;
|
|
284
|
+
let selectedValue;
|
|
187
285
|
let disposed = false;
|
|
188
286
|
let currentKey = null;
|
|
189
287
|
let attachedEntry = null;
|
|
@@ -192,11 +290,57 @@ function query(key, fetcher, options = {}) {
|
|
|
192
290
|
const loading = derived(() => isFetching() && data() === void 0);
|
|
193
291
|
const isStale = derived(() => {
|
|
194
292
|
data();
|
|
293
|
+
updatedAt();
|
|
195
294
|
if (!currentKey) return true;
|
|
196
295
|
const entry = cache.get(currentKey);
|
|
197
296
|
if (!entry || entry.dataUpdatedAt === 0) return true;
|
|
198
297
|
return Date.now() - entry.dataUpdatedAt >= staleTime;
|
|
199
298
|
});
|
|
299
|
+
function viewOf(entry) {
|
|
300
|
+
const raw = entry.data;
|
|
301
|
+
if (raw === void 0) return void 0;
|
|
302
|
+
if (structuralSharing === false) return raw;
|
|
303
|
+
if (typeof structuralSharing !== "function") return sharedView(entry);
|
|
304
|
+
const sameEntry = customEntry === entry;
|
|
305
|
+
if (sameEntry && Object.is(customFrom, raw)) return customValue;
|
|
306
|
+
const value = shareSafely(structuralSharing, sameEntry ? customValue : void 0, raw, entry.explicit);
|
|
307
|
+
customEntry = entry;
|
|
308
|
+
customFrom = raw;
|
|
309
|
+
customValue = value;
|
|
310
|
+
return value;
|
|
311
|
+
}
|
|
312
|
+
function commitBase(entry, value) {
|
|
313
|
+
const changed = !Object.is(value, baseValue);
|
|
314
|
+
baseEntry = entry;
|
|
315
|
+
baseValue = value;
|
|
316
|
+
if (!select) {
|
|
317
|
+
setData(value);
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
if (!changed) return;
|
|
321
|
+
baseExplicit = entry?.explicit === true;
|
|
322
|
+
setBase(value);
|
|
323
|
+
}
|
|
324
|
+
const stopSelect = select ? effect(() => {
|
|
325
|
+
const raw = base();
|
|
326
|
+
const entry = baseEntry;
|
|
327
|
+
const explicit = baseExplicit;
|
|
328
|
+
baseExplicit = false;
|
|
329
|
+
if (entry === null && selectedEntry === null) return;
|
|
330
|
+
if (raw === void 0) {
|
|
331
|
+
selectedEntry = entry;
|
|
332
|
+
selectedValue = void 0;
|
|
333
|
+
setData(void 0);
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
const selected = runSelect("query select", () => select(raw));
|
|
337
|
+
if (!selected.ok) return;
|
|
338
|
+
const prev = selectedEntry === entry ? selectedValue : void 0;
|
|
339
|
+
const value = shareSafely(structuralSharing, prev, selected.value, explicit);
|
|
340
|
+
selectedEntry = entry;
|
|
341
|
+
selectedValue = value;
|
|
342
|
+
setData(value);
|
|
343
|
+
}) : null;
|
|
200
344
|
function detachFromEntry() {
|
|
201
345
|
const entry = attachedEntry;
|
|
202
346
|
const key2 = attachedKey;
|
|
@@ -255,7 +399,7 @@ function query(key, fetcher, options = {}) {
|
|
|
255
399
|
const settledError = entry.error;
|
|
256
400
|
runCallback("query onError", () => onError?.(settledError));
|
|
257
401
|
} else if (entry.data !== void 0) {
|
|
258
|
-
const settledData = entry
|
|
402
|
+
const settledData = viewOf(entry);
|
|
259
403
|
runCallback("query onSuccess", () => onSuccess?.(settledData));
|
|
260
404
|
}
|
|
261
405
|
runCallback("query onSettled", () => onSettled?.());
|
|
@@ -286,17 +430,14 @@ function query(key, fetcher, options = {}) {
|
|
|
286
430
|
entry.promise = null;
|
|
287
431
|
entry.controller = null;
|
|
288
432
|
entry.data = result;
|
|
433
|
+
entry.explicit = false;
|
|
289
434
|
entry.dataUpdatedAt = Date.now();
|
|
290
435
|
entry.error = void 0;
|
|
291
436
|
notifyListeners(entry.listeners, "query cache listener");
|
|
292
437
|
if (disposed || currentKey !== key2) return;
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
setIsFetching(false);
|
|
297
|
-
setError(void 0);
|
|
298
|
-
});
|
|
299
|
-
runCallback("query onSuccess", () => onSuccess?.(result));
|
|
438
|
+
if (!entry.listeners.has(onCacheUpdate)) onCacheUpdate();
|
|
439
|
+
const committedResult = viewOf(entry);
|
|
440
|
+
runCallback("query onSuccess", () => onSuccess?.(committedResult));
|
|
300
441
|
} catch (err) {
|
|
301
442
|
if (entry.generation !== generation) return;
|
|
302
443
|
entry.promise = null;
|
|
@@ -326,18 +467,19 @@ function query(key, fetcher, options = {}) {
|
|
|
326
467
|
const entry = cache.get(currentKey);
|
|
327
468
|
if (!entry) {
|
|
328
469
|
batch(() => {
|
|
329
|
-
|
|
470
|
+
commitBase(null, void 0);
|
|
330
471
|
setError(void 0);
|
|
331
472
|
setIsFetching(false);
|
|
473
|
+
setUpdatedAt(0);
|
|
332
474
|
});
|
|
333
475
|
return;
|
|
334
476
|
}
|
|
335
|
-
const
|
|
336
|
-
const selected = raw !== void 0 && select ? runSelect("query select", () => select(raw)) : { ok: true, value: raw };
|
|
477
|
+
const view = viewOf(entry);
|
|
337
478
|
batch(() => {
|
|
338
|
-
|
|
479
|
+
commitBase(entry, view);
|
|
339
480
|
setError(entry.error);
|
|
340
481
|
if (!entry.promise) setIsFetching(false);
|
|
482
|
+
setUpdatedAt(entry.dataUpdatedAt);
|
|
341
483
|
});
|
|
342
484
|
}
|
|
343
485
|
const effectCleanup = effect(() => {
|
|
@@ -347,11 +489,11 @@ function query(key, fetcher, options = {}) {
|
|
|
347
489
|
const entry = getOrCreateEntry(cache, key2, initialData);
|
|
348
490
|
attachToEntry(entry, key2);
|
|
349
491
|
if (entry.data !== void 0) {
|
|
350
|
-
const
|
|
351
|
-
const selected = runSelect("query select", () => select ? select(raw) : raw);
|
|
492
|
+
const view = viewOf(entry);
|
|
352
493
|
batch(() => {
|
|
353
|
-
|
|
494
|
+
commitBase(entry, view);
|
|
354
495
|
setError(entry.error);
|
|
496
|
+
setUpdatedAt(entry.dataUpdatedAt);
|
|
355
497
|
});
|
|
356
498
|
}
|
|
357
499
|
if (!keyChanged && currentKey === key2 && entry.data !== void 0) {
|
|
@@ -389,6 +531,7 @@ function query(key, fetcher, options = {}) {
|
|
|
389
531
|
if (disposed) return;
|
|
390
532
|
disposed = true;
|
|
391
533
|
effectCleanup();
|
|
534
|
+
stopSelect?.();
|
|
392
535
|
loading.dispose();
|
|
393
536
|
isStale.dispose();
|
|
394
537
|
if (intervalTimer) clearInterval(intervalTimer);
|
|
@@ -420,13 +563,15 @@ function invalidateQueries(keyOrPredicate) {
|
|
|
420
563
|
}
|
|
421
564
|
}
|
|
422
565
|
function getQueryData(key) {
|
|
423
|
-
|
|
566
|
+
const entry = getActiveQueryCache().get(key);
|
|
567
|
+
return entry ? sharedView(entry) : void 0;
|
|
424
568
|
}
|
|
425
569
|
function setQueryData(key, data) {
|
|
426
570
|
const entry = getActiveQueryCache().get(key);
|
|
427
571
|
if (!entry) return;
|
|
428
|
-
const newData = typeof data === "function" ? data(entry
|
|
572
|
+
const newData = typeof data === "function" ? data(sharedView(entry)) : data;
|
|
429
573
|
entry.data = newData;
|
|
574
|
+
entry.explicit = true;
|
|
430
575
|
entry.dataUpdatedAt = Date.now();
|
|
431
576
|
notifyListeners(entry.listeners, "query cache listener");
|
|
432
577
|
}
|
|
@@ -810,6 +955,15 @@ function resource(sourceOrFetcher, fetcherOrOptions, maybeOptions) {
|
|
|
810
955
|
const [loading, setLoading] = signal(false);
|
|
811
956
|
const [error, setError] = signal(void 0);
|
|
812
957
|
let currentData = options.initialValue;
|
|
958
|
+
function commitData(next, explicit) {
|
|
959
|
+
const sharing = options.structuralSharing ?? true;
|
|
960
|
+
const shared = untracked(
|
|
961
|
+
() => runSelect("resource structuralSharing", () => applyStructuralSharing(sharing, currentData, next, explicit))
|
|
962
|
+
);
|
|
963
|
+
currentData = shared.ok ? shared.value : next;
|
|
964
|
+
setData(currentData);
|
|
965
|
+
return currentData;
|
|
966
|
+
}
|
|
813
967
|
let abortController = null;
|
|
814
968
|
let disposed = false;
|
|
815
969
|
let effectCleanup = null;
|
|
@@ -829,12 +983,12 @@ function resource(sourceOrFetcher, fetcherOrOptions, maybeOptions) {
|
|
|
829
983
|
try {
|
|
830
984
|
const result = await withRetry(() => fetcher(sourceValue, { signal: signal2, prev }), options.retry, void 0, signal2);
|
|
831
985
|
if (version !== fetchVersion || disposed) return;
|
|
832
|
-
|
|
986
|
+
let committed = result;
|
|
833
987
|
batch(() => {
|
|
834
|
-
|
|
988
|
+
committed = commitData(result, false);
|
|
835
989
|
setLoading(false);
|
|
836
990
|
});
|
|
837
|
-
runCallback("resource onSuccess", () => options.onSuccess?.(
|
|
991
|
+
runCallback("resource onSuccess", () => options.onSuccess?.(committed));
|
|
838
992
|
} catch (err) {
|
|
839
993
|
if (version !== fetchVersion || disposed) return;
|
|
840
994
|
if (isAbortError(err)) {
|
|
@@ -868,8 +1022,7 @@ function resource(sourceOrFetcher, fetcherOrOptions, maybeOptions) {
|
|
|
868
1022
|
refetch: () => doFetch(source ? source() : void 0),
|
|
869
1023
|
mutate: (value) => {
|
|
870
1024
|
const newValue = typeof value === "function" ? value(currentData) : value;
|
|
871
|
-
|
|
872
|
-
setData(newValue);
|
|
1025
|
+
commitData(newValue, true);
|
|
873
1026
|
},
|
|
874
1027
|
abort: () => abortController?.abort(),
|
|
875
1028
|
dispose: () => {
|
|
@@ -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-TQQUN4WR.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
|
|