sibujs 3.4.1 → 4.0.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/LICENSE +21 -21
- package/README.md +118 -15
- package/dist/browser.cjs +410 -101
- package/dist/browser.d.cts +50 -5
- package/dist/browser.d.ts +50 -5
- package/dist/browser.js +8 -6
- package/dist/build.cjs +784 -392
- package/dist/build.js +15 -15
- package/dist/cdn.global.js +11 -7
- package/dist/{chunk-PBZWJQNY.js → chunk-52ERIVFD.js} +8 -8
- package/dist/chunk-52XFPGSN.js +123 -0
- package/dist/{chunk-Y22QAKJX.js → chunk-5BVKQX2F.js} +4 -4
- package/dist/chunk-5INI7D2L.js +194 -0
- package/dist/{chunk-4I3M326N.js → chunk-AD5YSZAN.js} +19 -25
- package/dist/{chunk-F7HW2NI5.js → chunk-AW6HPJ3L.js} +1 -1
- package/dist/chunk-DHDZ7IVN.js +109 -0
- package/dist/{chunk-VQZDHAEK.js → chunk-E72G5JSK.js} +1 -1
- package/dist/{chunk-MPE75KOA.js → chunk-HPXTUPJD.js} +259 -124
- package/dist/{chunk-EX77FXTT.js → chunk-HYCCIYNS.js} +228 -51
- package/dist/{chunk-FWFEBYQ6.js → chunk-IKVUUE7D.js} +115 -41
- package/dist/{chunk-5MFF5EPT.js → chunk-J4WZMCIW.js} +5 -5
- package/dist/{chunk-BQLVTAUZ.js → chunk-JYXQCELN.js} +57 -22
- package/dist/{chunk-WEZ5SP7L.js → chunk-PHB3MCK4.js} +73 -34
- package/dist/chunk-PHRH66Y7.js +147 -0
- package/dist/{chunk-S2VW4NBA.js → chunk-PJDSI2K7.js} +295 -198
- package/dist/{chunk-QHPUFNHZ.js → chunk-PTLJ7NQX.js} +3 -3
- package/dist/{chunk-NXR2YFZB.js → chunk-QD4I7ZGZ.js} +24 -34
- package/dist/{chunk-S3NFJO6L.js → chunk-TIRZCERI.js} +36 -5
- package/dist/{chunk-7PNKW3FJ.js → chunk-TNEHT3NG.js} +232 -67
- package/dist/{chunk-335KJEN2.js → chunk-TVURNWDK.js} +5 -3
- package/dist/{chunk-CV7FAQ2R.js → chunk-UNAYBND2.js} +9 -3
- package/dist/chunk-VPP2FONR.js +142 -0
- package/dist/{chunk-X4JS367G.js → chunk-XDOMTQHM.js} +14 -10
- package/dist/chunk-XET2RUJF.js +61 -0
- package/dist/{chunk-3FFCUIGV.js → chunk-XZMCVZW6.js} +309 -188
- package/dist/{chunk-YDWP3ZOU.js → chunk-YLV26GAJ.js} +228 -86
- package/dist/{contracts-ey_Qh8ef.d.ts → contracts-Hg6ITAEF.d.cts} +6 -6
- package/dist/{contracts-ey_Qh8ef.d.cts → contracts-Hg6ITAEF.d.ts} +6 -6
- package/dist/{customElement-CPfIrbvg.d.cts → customElement-CKLoO63w.d.cts} +73 -11
- package/dist/{customElement-CPfIrbvg.d.ts → customElement-CKLoO63w.d.ts} +73 -11
- package/dist/data.cjs +483 -205
- package/dist/data.d.cts +139 -7
- package/dist/data.d.ts +139 -7
- package/dist/data.js +9 -9
- package/dist/devtools.cjs +222 -87
- package/dist/devtools.js +8 -8
- package/dist/dispose-4FZ6OFXR.js +19 -0
- package/dist/ecosystem.cjs +426 -182
- package/dist/ecosystem.js +11 -11
- package/dist/extras.cjs +1988 -772
- package/dist/extras.d.cts +7 -7
- package/dist/extras.d.ts +7 -7
- package/dist/extras.js +29 -26
- package/dist/index.cjs +791 -392
- package/dist/index.d.cts +299 -28
- package/dist/index.d.ts +299 -28
- package/dist/index.js +33 -18
- package/dist/motion.cjs +180 -50
- package/dist/motion.d.cts +26 -0
- package/dist/motion.d.ts +26 -0
- package/dist/motion.js +5 -5
- package/dist/patterns.cjs +437 -170
- package/dist/patterns.d.cts +60 -13
- package/dist/patterns.d.ts +60 -13
- package/dist/patterns.js +7 -7
- package/dist/performance.cjs +333 -148
- package/dist/performance.d.cts +55 -7
- package/dist/performance.d.ts +55 -7
- package/dist/performance.js +9 -9
- package/dist/plugins.cjs +1378 -583
- package/dist/plugins.d.cts +227 -9
- package/dist/plugins.d.ts +227 -9
- package/dist/plugins.js +610 -321
- package/dist/{ssr-D62yFwuw.d.cts → ssr-BiPRdZ6n.d.cts} +44 -15
- package/dist/{ssr-D62yFwuw.d.ts → ssr-BiPRdZ6n.d.ts} +44 -15
- package/dist/{ssr-2PPULEK2.js → ssr-JFP5535P.js} +5 -4
- package/dist/ssr.cjs +1111 -450
- package/dist/ssr.d.cts +230 -20
- package/dist/ssr.d.ts +230 -20
- package/dist/ssr.js +15 -12
- package/dist/{startup-0Qv6aosO.d.cts → startup-BMpaiMhP.d.cts} +1 -1
- package/dist/{startup-0Qv6aosO.d.ts → startup-BMpaiMhP.d.ts} +1 -1
- package/dist/testing.cjs +205 -63
- package/dist/testing.d.cts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +8 -10
- package/dist/ui.cjs +640 -199
- package/dist/ui.d.cts +2 -2
- package/dist/ui.d.ts +2 -2
- package/dist/ui.js +10 -10
- package/dist/widgets.cjs +207 -82
- package/dist/widgets.js +9 -9
- package/package.json +12 -7
- package/dist/chunk-5VGSK6D2.js +0 -80
- package/dist/chunk-6CAJU5TP.js +0 -38
- package/dist/chunk-COY6PUD2.js +0 -34
- package/dist/chunk-DLBFEAIS.js +0 -96
- package/dist/chunk-L3GAGWCC.js +0 -111
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
devWarn,
|
|
3
|
-
isDev
|
|
4
|
-
|
|
3
|
+
isDev,
|
|
4
|
+
reportError
|
|
5
|
+
} from "./chunk-VPP2FONR.js";
|
|
5
6
|
|
|
6
7
|
// src/reactivity/track-core.ts
|
|
7
|
-
var _isDev = isDev();
|
|
8
8
|
var POOL_MAX = 4096;
|
|
9
9
|
var nodePool = [];
|
|
10
10
|
function createNode() {
|
|
@@ -12,6 +12,7 @@ function createNode() {
|
|
|
12
12
|
sig: null,
|
|
13
13
|
sub: null,
|
|
14
14
|
epoch: 0,
|
|
15
|
+
depVersion: 0,
|
|
15
16
|
sigPrev: null,
|
|
16
17
|
sigNext: null,
|
|
17
18
|
subPrev: null,
|
|
@@ -96,8 +97,27 @@ function safeInvoke(sub) {
|
|
|
96
97
|
try {
|
|
97
98
|
sub();
|
|
98
99
|
} catch (err) {
|
|
99
|
-
|
|
100
|
+
const s = sub;
|
|
101
|
+
reportError(err, { phase: s._errorPhase ?? "effect", name: s.__name, node: s._errorNode });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function depsChanged(sub) {
|
|
105
|
+
let node = sub.depsHead ?? null;
|
|
106
|
+
if (node === null) return true;
|
|
107
|
+
while (node !== null) {
|
|
108
|
+
const sig = node.sig;
|
|
109
|
+
if (sig === null) return true;
|
|
110
|
+
if (sig._d === true && sig._validate !== void 0) {
|
|
111
|
+
try {
|
|
112
|
+
sig._validate();
|
|
113
|
+
} catch {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (node.depVersion !== sig.__v) return true;
|
|
118
|
+
node = node.subNext;
|
|
100
119
|
}
|
|
120
|
+
return false;
|
|
101
121
|
}
|
|
102
122
|
var suspendDepth = 0;
|
|
103
123
|
var trackingSuspended = false;
|
|
@@ -179,7 +199,7 @@ function track(effectFn, subscriber) {
|
|
|
179
199
|
const sub = subscriber;
|
|
180
200
|
return sub._dispose ?? (sub._dispose = () => cleanup(subscriber));
|
|
181
201
|
}
|
|
182
|
-
function reactiveBinding(commit) {
|
|
202
|
+
function reactiveBinding(commit, ownerNode) {
|
|
183
203
|
const run = () => {
|
|
184
204
|
const s = subscriber;
|
|
185
205
|
if (s._disposed || s._reentrant) return;
|
|
@@ -195,13 +215,17 @@ function reactiveBinding(commit) {
|
|
|
195
215
|
subscriber.depsTail = null;
|
|
196
216
|
subscriber._epoch = 0;
|
|
197
217
|
subscriber._structDirty = false;
|
|
218
|
+
subscriber._hasComputedDep = false;
|
|
198
219
|
subscriber._runEpoch = 0;
|
|
199
220
|
subscriber._runs = 0;
|
|
200
221
|
subscriber._reentrant = false;
|
|
201
222
|
subscriber._disposed = false;
|
|
223
|
+
subscriber._errorPhase = "binding";
|
|
224
|
+
subscriber._errorNode = ownerNode;
|
|
202
225
|
run();
|
|
203
226
|
return subscriber._dispose ?? (subscriber._dispose = () => {
|
|
204
227
|
subscriber._disposed = true;
|
|
228
|
+
subscriber._errorNode = void 0;
|
|
205
229
|
cleanup(subscriber);
|
|
206
230
|
});
|
|
207
231
|
}
|
|
@@ -213,9 +237,12 @@ function recordDependency(signal) {
|
|
|
213
237
|
const active = sig.__activeNode ?? null;
|
|
214
238
|
if (active !== null && active.sub === sub) {
|
|
215
239
|
active.epoch = epoch;
|
|
240
|
+
active.depVersion = sig.__v ?? Number.NaN;
|
|
216
241
|
return;
|
|
217
242
|
}
|
|
243
|
+
if (sig._validate !== void 0) sub._hasComputedDep = true;
|
|
218
244
|
const node = allocNode(signal, sub, epoch);
|
|
245
|
+
node.depVersion = sig.__v ?? Number.NaN;
|
|
219
246
|
node.prevActive = active;
|
|
220
247
|
sig.__activeNode = node;
|
|
221
248
|
linkSub(sub, node);
|
|
@@ -234,9 +261,10 @@ function cleanup(subscriber) {
|
|
|
234
261
|
node = next;
|
|
235
262
|
}
|
|
236
263
|
}
|
|
237
|
-
var maxSubscriberRepeats =
|
|
264
|
+
var maxSubscriberRepeats = 1e3;
|
|
238
265
|
var maxDrainIterations = 1e6;
|
|
239
266
|
var drainEpoch = 0;
|
|
267
|
+
var quarantined = /* @__PURE__ */ new Set();
|
|
240
268
|
function setMaxSubscriberRepeats(n) {
|
|
241
269
|
const prev = maxSubscriberRepeats;
|
|
242
270
|
if (Number.isFinite(n) && n > 0) maxSubscriberRepeats = Math.floor(n);
|
|
@@ -258,19 +286,21 @@ function tickRepeat(sub) {
|
|
|
258
286
|
return s._runs > maxSubscriberRepeats;
|
|
259
287
|
}
|
|
260
288
|
function cycleError(sub) {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
`
|
|
265
|
-
)
|
|
266
|
-
|
|
289
|
+
const name = sub.__name ?? "<unnamed>";
|
|
290
|
+
reportError(
|
|
291
|
+
new Error(
|
|
292
|
+
`subscriber "${name}" fired more than ${maxSubscriberRepeats} times \u2014 likely a write-reads-self cycle between effects/signals. This subscriber is quarantined for the rest of this update; other pending work still runs.`
|
|
293
|
+
),
|
|
294
|
+
{ phase: "scheduler", name }
|
|
295
|
+
);
|
|
267
296
|
}
|
|
268
297
|
function absoluteDrainError() {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
`
|
|
272
|
-
)
|
|
273
|
-
|
|
298
|
+
reportError(
|
|
299
|
+
new Error(
|
|
300
|
+
`Notification drain exceeded ${maxDrainIterations} iterations \u2014 absolute safety net tripped. Breaking to prevent infinite loop.`
|
|
301
|
+
),
|
|
302
|
+
{ phase: "scheduler" }
|
|
303
|
+
);
|
|
274
304
|
}
|
|
275
305
|
function drainQueue() {
|
|
276
306
|
let i = 0;
|
|
@@ -280,11 +310,14 @@ function drainQueue() {
|
|
|
280
310
|
break;
|
|
281
311
|
}
|
|
282
312
|
const sub = pendingQueue[i++];
|
|
313
|
+
pendingSet.delete(sub);
|
|
314
|
+
if (quarantined.size > 0 && quarantined.has(sub)) continue;
|
|
315
|
+
if (sub._hasComputedDep === true && !depsChanged(sub)) continue;
|
|
283
316
|
if (tickRepeat(sub)) {
|
|
284
317
|
cycleError(sub);
|
|
285
|
-
|
|
318
|
+
quarantined.add(sub);
|
|
319
|
+
continue;
|
|
286
320
|
}
|
|
287
|
-
pendingSet.delete(sub);
|
|
288
321
|
safeInvoke(sub);
|
|
289
322
|
}
|
|
290
323
|
}
|
|
@@ -299,6 +332,7 @@ function drainNotificationQueue() {
|
|
|
299
332
|
if (notifyDepth === 0) {
|
|
300
333
|
pendingQueue.length = 0;
|
|
301
334
|
pendingSet.clear();
|
|
335
|
+
if (quarantined.size > 0) quarantined.clear();
|
|
302
336
|
}
|
|
303
337
|
}
|
|
304
338
|
}
|
|
@@ -392,6 +426,7 @@ function notifySubscribers(signal) {
|
|
|
392
426
|
if (notifyDepth === 0) {
|
|
393
427
|
pendingQueue.length = 0;
|
|
394
428
|
pendingSet.clear();
|
|
429
|
+
if (quarantined.size > 0) quarantined.clear();
|
|
395
430
|
}
|
|
396
431
|
}
|
|
397
432
|
}
|
|
@@ -418,14 +453,14 @@ function forEachSubscriber(signal, visit) {
|
|
|
418
453
|
}
|
|
419
454
|
|
|
420
455
|
// src/reactivity/track.ts
|
|
421
|
-
var
|
|
422
|
-
var _runtimeVersion = true ? "
|
|
456
|
+
var _isDev = isDev();
|
|
457
|
+
var _runtimeVersion = true ? "4.0.1" : "dev";
|
|
423
458
|
var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
|
|
424
459
|
function resolveReactiveApi() {
|
|
425
460
|
const g = globalThis;
|
|
426
461
|
const existing = g[REGISTRY_KEY];
|
|
427
462
|
if (existing) {
|
|
428
|
-
if (
|
|
463
|
+
if (_isDev && !existing.__dupWarned) {
|
|
429
464
|
existing.__dupWarned = true;
|
|
430
465
|
devWarn(
|
|
431
466
|
`Multiple instances of the reactive runtime detected on this page (active: ${existing.version}, duplicate: ${_runtimeVersion}). Reactivity still works \u2014 all copies share the first one \u2014 but de-duplicate sibujs in your bundler (e.g. Vite optimizeDeps.exclude: ['sibujs'] or resolve.dedupe: ['sibujs']).`
|
|
@@ -1,22 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
sanitizeUrl
|
|
3
|
+
} from "./chunk-5INI7D2L.js";
|
|
1
4
|
import {
|
|
2
5
|
globalSingleton
|
|
3
6
|
} from "./chunk-7ZHH77QA.js";
|
|
4
|
-
import {
|
|
5
|
-
sanitizeUrl
|
|
6
|
-
} from "./chunk-L3GAGWCC.js";
|
|
7
7
|
import {
|
|
8
8
|
effect
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-XDOMTQHM.js";
|
|
10
10
|
import {
|
|
11
|
-
dispose
|
|
12
|
-
|
|
11
|
+
dispose,
|
|
12
|
+
replaceChildrenSafely
|
|
13
|
+
} from "./chunk-DHDZ7IVN.js";
|
|
13
14
|
import {
|
|
14
15
|
signal
|
|
15
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-TVURNWDK.js";
|
|
16
17
|
import {
|
|
17
18
|
devWarn,
|
|
18
|
-
isDev
|
|
19
|
-
|
|
19
|
+
isDev,
|
|
20
|
+
reportError
|
|
21
|
+
} from "./chunk-VPP2FONR.js";
|
|
20
22
|
|
|
21
23
|
// src/performance/scheduler.ts
|
|
22
24
|
var Priority = {
|
|
@@ -265,7 +267,7 @@ var DOMPool = class {
|
|
|
265
267
|
this.pools.set(tag, pool);
|
|
266
268
|
}
|
|
267
269
|
if (pool.length >= this.maxSize) return;
|
|
268
|
-
element
|
|
270
|
+
replaceChildrenSafely(element);
|
|
269
271
|
element.className = "";
|
|
270
272
|
element.removeAttribute("style");
|
|
271
273
|
element.removeAttribute("id");
|
|
@@ -396,8 +398,9 @@ function normalizedStore(schema) {
|
|
|
396
398
|
ids: [],
|
|
397
399
|
entities: {}
|
|
398
400
|
});
|
|
401
|
+
const idOf = (entity) => String(entity[idKey]);
|
|
399
402
|
function add(entity) {
|
|
400
|
-
const id =
|
|
403
|
+
const id = idOf(entity);
|
|
401
404
|
setState((prev) => {
|
|
402
405
|
const ids = prev.ids.includes(id) ? prev.ids : [...prev.ids, id];
|
|
403
406
|
return {
|
|
@@ -411,7 +414,7 @@ function normalizedStore(schema) {
|
|
|
411
414
|
const nextIds = [...prev.ids];
|
|
412
415
|
const nextEntities = { ...prev.entities };
|
|
413
416
|
for (const entity of entities) {
|
|
414
|
-
const id =
|
|
417
|
+
const id = idOf(entity);
|
|
415
418
|
if (!nextIds.includes(id)) {
|
|
416
419
|
nextIds.push(id);
|
|
417
420
|
}
|
|
@@ -533,7 +536,14 @@ function createChunkRegistry(config = {}) {
|
|
|
533
536
|
} = config;
|
|
534
537
|
const cache = /* @__PURE__ */ new Map();
|
|
535
538
|
const pending = /* @__PURE__ */ new Map();
|
|
536
|
-
const preloaded = /* @__PURE__ */ new
|
|
539
|
+
const preloaded = /* @__PURE__ */ new Map();
|
|
540
|
+
function notify(name, run) {
|
|
541
|
+
try {
|
|
542
|
+
run();
|
|
543
|
+
} catch (err) {
|
|
544
|
+
reportError(err, { phase: "async", name: `chunkRegistry(${name})` });
|
|
545
|
+
}
|
|
546
|
+
}
|
|
537
547
|
function evict() {
|
|
538
548
|
while (cache.size >= maxCacheSize) {
|
|
539
549
|
let lru = null;
|
|
@@ -588,30 +598,47 @@ function createChunkRegistry(config = {}) {
|
|
|
588
598
|
cached.lastAccess = Date.now();
|
|
589
599
|
return cached.value;
|
|
590
600
|
}
|
|
591
|
-
const
|
|
592
|
-
if (
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
601
|
+
const existing = pending.get(id);
|
|
602
|
+
if (existing) return existing.promise;
|
|
603
|
+
let resolveOuter;
|
|
604
|
+
let rejectOuter;
|
|
605
|
+
const outcome = new Promise((resolve, reject) => {
|
|
606
|
+
resolveOuter = resolve;
|
|
607
|
+
rejectOuter = reject;
|
|
608
|
+
});
|
|
609
|
+
const entry = { promise: outcome };
|
|
610
|
+
pending.set(id, entry);
|
|
611
|
+
const owns = () => pending.get(id) === entry;
|
|
612
|
+
notify("onLoadStart", () => onLoadStart?.(id));
|
|
613
|
+
void loadWithRetry(id, loader).then(
|
|
614
|
+
(value) => {
|
|
615
|
+
if (owns()) {
|
|
616
|
+
pending.delete(id);
|
|
617
|
+
evict();
|
|
618
|
+
const now = Date.now();
|
|
619
|
+
cache.set(id, { value, timestamp: now, lastAccess: now, accessCount: 1 });
|
|
620
|
+
}
|
|
621
|
+
notify("onLoadEnd", () => onLoadEnd?.(id));
|
|
622
|
+
resolveOuter(value);
|
|
623
|
+
},
|
|
624
|
+
(err) => {
|
|
625
|
+
if (owns()) pending.delete(id);
|
|
626
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
627
|
+
notify("onLoadError", () => onLoadError?.(id, error));
|
|
628
|
+
rejectOuter(error);
|
|
629
|
+
}
|
|
630
|
+
).catch((internal) => {
|
|
631
|
+
reportError(internal, { phase: "async", name: "chunkRegistry(settlement)" });
|
|
632
|
+
rejectOuter(internal);
|
|
606
633
|
});
|
|
607
|
-
|
|
608
|
-
return loadPromise;
|
|
634
|
+
return outcome;
|
|
609
635
|
}
|
|
610
636
|
function preloadFn(id, loader) {
|
|
611
637
|
if (cache.has(id) || pending.has(id) || preloaded.has(id)) return;
|
|
612
|
-
|
|
638
|
+
const marker = {};
|
|
639
|
+
preloaded.set(id, marker);
|
|
613
640
|
loadFn(id, loader).catch(() => {
|
|
614
|
-
preloaded.delete(id);
|
|
641
|
+
if (preloaded.get(id) === marker) preloaded.delete(id);
|
|
615
642
|
});
|
|
616
643
|
}
|
|
617
644
|
return {
|
|
@@ -645,21 +672,33 @@ function createChunkRegistry(config = {}) {
|
|
|
645
672
|
return void 0;
|
|
646
673
|
},
|
|
647
674
|
/**
|
|
648
|
-
* Invalidate a cached chunk.
|
|
675
|
+
* Invalidate a cached chunk, and supersede any load still in flight for it.
|
|
676
|
+
*
|
|
677
|
+
* In-flight work is not cancelled — the loader API takes no abort signal, so
|
|
678
|
+
* claiming cancellation would be a lie. It is *superseded*: it still settles
|
|
679
|
+
* for whoever called `load()`, but it can no longer write to the cache, and
|
|
680
|
+
* a subsequent `load(id, …)` starts fresh work rather than adopting it.
|
|
649
681
|
*/
|
|
650
682
|
invalidate(id) {
|
|
651
683
|
cache.delete(id);
|
|
652
684
|
preloaded.delete(id);
|
|
685
|
+
pending.delete(id);
|
|
653
686
|
},
|
|
654
687
|
/**
|
|
655
|
-
* Clear all cached chunks.
|
|
688
|
+
* Clear all cached chunks, and supersede every load still in flight.
|
|
689
|
+
*
|
|
690
|
+
* Same barrier as `invalidate`, applied to every key at once.
|
|
656
691
|
*/
|
|
657
692
|
clear() {
|
|
658
693
|
cache.clear();
|
|
659
694
|
preloaded.clear();
|
|
695
|
+
pending.clear();
|
|
660
696
|
},
|
|
661
697
|
/**
|
|
662
698
|
* Get cache statistics.
|
|
699
|
+
*
|
|
700
|
+
* Describes currently OWNED state: superseded loads are already absent from
|
|
701
|
+
* `pending`, so the counts never include work whose result will be discarded.
|
|
663
702
|
*/
|
|
664
703
|
stats() {
|
|
665
704
|
return {
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isEventHandlerAttr,
|
|
3
|
+
isHtmlContentAttribute,
|
|
4
|
+
sanitizeAttributeString
|
|
5
|
+
} from "./chunk-5INI7D2L.js";
|
|
6
|
+
import {
|
|
7
|
+
reactiveBinding
|
|
8
|
+
} from "./chunk-JYXQCELN.js";
|
|
9
|
+
import {
|
|
10
|
+
devWarn,
|
|
11
|
+
isDev,
|
|
12
|
+
reportError
|
|
13
|
+
} from "./chunk-VPP2FONR.js";
|
|
14
|
+
|
|
15
|
+
// src/utils/setSafeAttribute.ts
|
|
16
|
+
var _isDev = isDev();
|
|
17
|
+
var HTML_NS = "http://www.w3.org/1999/xhtml";
|
|
18
|
+
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
19
|
+
var XLINK_NS = "http://www.w3.org/1999/xlink";
|
|
20
|
+
var XML_NS = "http://www.w3.org/XML/1998/namespace";
|
|
21
|
+
var BOOLEAN_IDL_ATTRS = /* @__PURE__ */ new Set(["checked", "disabled", "selected"]);
|
|
22
|
+
function isHtmlElement(el) {
|
|
23
|
+
return el.namespaceURI === null || el.namespaceURI === HTML_NS;
|
|
24
|
+
}
|
|
25
|
+
function setProp(el, key, val) {
|
|
26
|
+
el[key] = val;
|
|
27
|
+
}
|
|
28
|
+
function namespaceFor(el, name) {
|
|
29
|
+
if (el.namespaceURI !== SVG_NS) return null;
|
|
30
|
+
const lower = name.toLowerCase();
|
|
31
|
+
if (lower.startsWith("xlink:")) return XLINK_NS;
|
|
32
|
+
if (lower.startsWith("xml:")) return XML_NS;
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
function setSafeAttribute(el, name, value, options = {}) {
|
|
36
|
+
const ns = namespaceFor(el, name);
|
|
37
|
+
const localName = ns ? name.slice(name.indexOf(":") + 1) : name;
|
|
38
|
+
if (isEventHandlerAttr(name)) {
|
|
39
|
+
if (_isDev) {
|
|
40
|
+
devWarn(
|
|
41
|
+
`${options.label ?? "setSafeAttribute"}: refusing to set event-handler attribute "${name}". Its value would be evaluated as JavaScript. Use on:{ ${name.slice(2)}: fn } instead.`
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
if (ns) el.removeAttributeNS(ns, localName);
|
|
45
|
+
else el.removeAttribute(name);
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
if (value == null) {
|
|
49
|
+
if (ns) el.removeAttributeNS(ns, localName);
|
|
50
|
+
else el.removeAttribute(name);
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
if (isHtmlContentAttribute(name)) {
|
|
54
|
+
if (_isDev) {
|
|
55
|
+
devWarn(
|
|
56
|
+
`${options.label ?? "setSafeAttribute"}: refusing to set "${name}". The browser parses this attribute as a nested HTML document, so a generic string value cannot be made safe \u2014 attribute escaping is undone before the parse. Build the frame's content another way.`
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
if (ns) el.removeAttributeNS(ns, localName);
|
|
60
|
+
else el.removeAttribute(name);
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
const html = isHtmlElement(el);
|
|
64
|
+
const idlName = html ? name.toLowerCase() : name;
|
|
65
|
+
if (typeof value === "boolean") {
|
|
66
|
+
if (html && BOOLEAN_IDL_ATTRS.has(idlName) && idlName in el) {
|
|
67
|
+
setProp(el, idlName, value);
|
|
68
|
+
} else if (value) {
|
|
69
|
+
if (ns) el.setAttributeNS(ns, name, "");
|
|
70
|
+
else el.setAttribute(name, "");
|
|
71
|
+
} else if (ns) {
|
|
72
|
+
el.removeAttributeNS(ns, localName);
|
|
73
|
+
} else {
|
|
74
|
+
el.removeAttribute(name);
|
|
75
|
+
}
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
const str = String(value);
|
|
79
|
+
if (options.syncValueProperty !== false && html && (idlName === "value" || idlName === "checked") && idlName in el) {
|
|
80
|
+
setProp(el, idlName, idlName === "checked" ? Boolean(value) : str);
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
const safe = sanitizeAttributeString(name, str);
|
|
84
|
+
const current = ns ? el.getAttributeNS(ns, localName) : el.getAttribute(name);
|
|
85
|
+
if (current === safe) return true;
|
|
86
|
+
if (ns) el.setAttributeNS(ns, name, safe);
|
|
87
|
+
else el.setAttribute(name, safe);
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/reactivity/bindAttribute.ts
|
|
92
|
+
function bindAttribute(el, attr, getter) {
|
|
93
|
+
if (isEventHandlerAttr(attr)) {
|
|
94
|
+
setSafeAttribute(el, attr, "", { label: `bindAttribute("${attr}")` });
|
|
95
|
+
return () => {
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function commit() {
|
|
99
|
+
let value;
|
|
100
|
+
try {
|
|
101
|
+
value = getter();
|
|
102
|
+
} catch (err) {
|
|
103
|
+
reportError(err, { phase: "binding", name: `bindAttribute("${attr}")`, node: el });
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
setSafeAttribute(el, attr, value, { label: `bindAttribute("${attr}")` });
|
|
107
|
+
}
|
|
108
|
+
return reactiveBinding(commit, el);
|
|
109
|
+
}
|
|
110
|
+
function bindDynamic(el, nameGetter, valueGetter) {
|
|
111
|
+
let prevName = null;
|
|
112
|
+
function commit() {
|
|
113
|
+
let name;
|
|
114
|
+
try {
|
|
115
|
+
name = typeof nameGetter === "function" ? nameGetter() : nameGetter;
|
|
116
|
+
} catch (err) {
|
|
117
|
+
reportError(err, { phase: "binding", name: "bindDynamic (name getter)", node: el });
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
let value;
|
|
121
|
+
try {
|
|
122
|
+
value = typeof valueGetter === "function" ? valueGetter() : valueGetter;
|
|
123
|
+
} catch (err) {
|
|
124
|
+
reportError(err, { phase: "binding", name: "bindDynamic (value getter)", node: el });
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (prevName !== null && prevName !== name) {
|
|
128
|
+
el.removeAttribute(prevName);
|
|
129
|
+
prevName = null;
|
|
130
|
+
}
|
|
131
|
+
if (!setSafeAttribute(el, name, value, { label: "bindDynamic" })) return;
|
|
132
|
+
prevName = name;
|
|
133
|
+
}
|
|
134
|
+
const teardown = reactiveBinding(commit, el);
|
|
135
|
+
return () => {
|
|
136
|
+
teardown();
|
|
137
|
+
if (prevName !== null) {
|
|
138
|
+
el.removeAttribute(prevName);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export {
|
|
144
|
+
setSafeAttribute,
|
|
145
|
+
bindAttribute,
|
|
146
|
+
bindDynamic
|
|
147
|
+
};
|