sibujs 4.5.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 +326 -133
- package/dist/browser.d.cts +46 -14
- package/dist/browser.d.ts +46 -14
- package/dist/browser.js +8 -6
- package/dist/build.cjs +2094 -1033
- package/dist/build.d.cts +133 -44
- package/dist/build.d.ts +133 -44
- package/dist/build.js +1372 -574
- package/dist/cdn.dev.global.js +10 -10
- package/dist/cdn.full.dev.global.js +11 -11
- package/dist/cdn.full.global.js +10 -10
- package/dist/cdn.global.js +10 -10
- package/dist/{chunk-2DCGACUU.js → chunk-2BPG2XDA.js} +251 -66
- package/dist/{chunk-IXKSNWV5.js → chunk-2INLLLMZ.js} +1 -1
- package/dist/{chunk-4PMLNECI.js → chunk-3QWBSL5R.js} +98 -29
- package/dist/{chunk-KKLW7YWL.js → chunk-4AWA2PVD.js} +275 -144
- package/dist/chunk-5HZXGZ6T.js +24 -0
- package/dist/{chunk-PCT43HW3.js → chunk-7LUJQAOJ.js} +1 -1
- package/dist/{chunk-5DXA2J44.js → chunk-7XHATCIH.js} +5 -2
- package/dist/chunk-BC2SECJD.js +44 -0
- package/dist/{chunk-TBYTO6BS.js → chunk-BSY63EM6.js} +136 -80
- package/dist/{chunk-FTIR4QW2.js → chunk-DKXRACVN.js} +6 -8
- package/dist/{chunk-ONOHFDLG.js → chunk-FNJXNGYZ.js} +3 -3
- package/dist/{chunk-XZZOBQAY.js → chunk-FQRUXCEE.js} +6 -5
- package/dist/{chunk-NIOYEGBQ.js → chunk-HURREPU2.js} +27 -13
- package/dist/chunk-J6FW5TV6.js +233 -0
- package/dist/{chunk-UGRX3S57.js → chunk-JWKYU5GV.js} +22 -4
- package/dist/chunk-NYNYSPK7.js +318 -0
- package/dist/{chunk-RBTPLM32.js → chunk-RUSSKG6G.js} +13 -12
- package/dist/{chunk-7LN645I6.js → chunk-SLM3IA34.js} +3 -3
- package/dist/{chunk-R25EFXXC.js → chunk-TUCPL2HB.js} +3 -3
- package/dist/{chunk-B3WHI2QA.js → chunk-UNWRJRKC.js} +55 -31
- package/dist/{chunk-KEISJXBU.js → chunk-UOL2ECCS.js} +44 -17
- package/dist/{chunk-RJE2BNI4.js → chunk-VZSG24LS.js} +108 -45
- package/dist/{chunk-RIXRAYIU.js → chunk-WEQ3DMVL.js} +10 -4
- package/dist/{chunk-3JZ4L5TJ.js → chunk-WOLJZUFQ.js} +354 -90
- package/dist/{chunk-S373NSMK.js → chunk-XYV3EDB7.js} +283 -123
- package/dist/{chunk-VZKNK2V7.js → chunk-XZR4PXRE.js} +296 -38
- package/dist/{chunk-GW3SCCZG.js → chunk-Z3OHK6QT.js} +153 -110
- package/dist/{chunk-OMJJM3KM.js → chunk-ZVL7TY4K.js} +287 -130
- package/dist/{contracts-DBdg9J_a.d.ts → contracts-CLqzJnOV.d.ts} +36 -17
- package/dist/{contracts-DBdg9J_a.d.cts → contracts-CTOJXu-x.d.cts} +36 -17
- package/dist/{customElement-OB9CIsc5.d.cts → customElement-MmInOW1U.d.cts} +21 -0
- package/dist/{customElement-OB9CIsc5.d.ts → customElement-MmInOW1U.d.ts} +21 -0
- package/dist/data.cjs +410 -155
- package/dist/data.d.cts +166 -12
- package/dist/data.d.ts +166 -12
- package/dist/data.js +12 -9
- package/dist/devtools.cjs +98 -61
- package/dist/devtools.js +7 -8
- package/dist/dispose-GEIG2KOF.js +28 -0
- package/dist/ecosystem.cjs +372 -126
- package/dist/ecosystem.d.cts +20 -3
- package/dist/ecosystem.d.ts +20 -3
- package/dist/ecosystem.js +12 -12
- package/dist/extras.cjs +2366 -909
- package/dist/extras.d.cts +11 -9
- package/dist/extras.d.ts +11 -9
- package/dist/extras.js +39 -28
- package/dist/index.cjs +421 -158
- package/dist/index.d.cts +213 -171
- package/dist/index.d.ts +213 -171
- package/dist/index.js +24 -27
- package/dist/motion.cjs +118 -44
- package/dist/motion.js +5 -5
- package/dist/patterns.cjs +344 -53
- package/dist/patterns.d.cts +28 -9
- package/dist/patterns.d.ts +28 -9
- package/dist/patterns.js +8 -8
- package/dist/performance.cjs +325 -220
- package/dist/performance.d.cts +2 -2
- package/dist/performance.d.ts +2 -2
- package/dist/performance.js +8 -9
- package/dist/plugin-DVgSnTfK.d.cts +112 -0
- package/dist/plugin-DVgSnTfK.d.ts +112 -0
- package/dist/plugins.cjs +664 -233
- package/dist/plugins.d.cts +127 -14
- package/dist/plugins.d.ts +127 -14
- package/dist/plugins.js +96 -42
- package/dist/signal-EotCj4hS.d.cts +110 -0
- package/dist/signal-EotCj4hS.d.ts +110 -0
- package/dist/{ssr-BiPRdZ6n.d.cts → ssr-Bli9XRW5.d.cts} +5 -0
- package/dist/{ssr-BiPRdZ6n.d.ts → ssr-Bli9XRW5.d.ts} +5 -0
- package/dist/{ssr-Y7XOEPEN.js → ssr-XOTUASDO.js} +4 -5
- package/dist/ssr.cjs +229 -84
- package/dist/ssr.d.cts +9 -3
- package/dist/ssr.d.ts +9 -3
- package/dist/ssr.js +11 -12
- package/dist/{startup-BMpaiMhP.d.ts → startup-BLfSeL15.d.cts} +73 -22
- package/dist/{startup-BMpaiMhP.d.cts → startup-BLfSeL15.d.ts} +73 -22
- package/dist/tagFactory-8qL9LCIx.d.cts +156 -0
- package/dist/tagFactory-BL2fymez.d.ts +156 -0
- package/dist/testing.cjs +2503 -2191
- package/dist/testing.d.cts +56 -5
- package/dist/testing.d.ts +56 -5
- package/dist/testing.js +580 -307
- package/dist/types-CJFViL6Q.d.cts +26 -0
- package/dist/types-CJFViL6Q.d.ts +26 -0
- package/dist/ui.cjs +732 -329
- package/dist/ui.d.cts +41 -7
- package/dist/ui.d.ts +41 -7
- package/dist/ui.js +151 -56
- package/dist/widgets.cjs +267 -291
- package/dist/widgets.js +9 -10
- package/package.json +4 -2
- package/dist/chunk-2WLZ6757.js +0 -149
- package/dist/chunk-CCSJMTRN.js +0 -15
- package/dist/chunk-QKRPLZ2V.js +0 -108
- package/dist/chunk-VUF4ALSW.js +0 -60
- package/dist/chunk-WWV3SJ3L.js +0 -131
- package/dist/dispose-46BOMMQJ.js +0 -19
- package/dist/plugin-D30wlGW5.d.cts +0 -71
- package/dist/plugin-D30wlGW5.d.ts +0 -71
- package/dist/tagFactory-DVoDpHye.d.cts +0 -215
- package/dist/tagFactory-DVoDpHye.d.ts +0 -215
package/dist/ecosystem.cjs
CHANGED
|
@@ -141,6 +141,90 @@ function reportError(error, context) {
|
|
|
141
141
|
});
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
+
// src/core/rendering/dispose.ts
|
|
145
|
+
var elementDisposers = /* @__PURE__ */ new WeakMap();
|
|
146
|
+
var MAX_DRAIN_TEARDOWNS = 1e4;
|
|
147
|
+
function reportDrainRunaway(label, executed, remaining) {
|
|
148
|
+
if (typeof console === "undefined") return;
|
|
149
|
+
console.error(
|
|
150
|
+
`[SibuJS ${label}] runaway cleanup: stopped after running ${executed} teardowns with ${remaining} still queued. Cleanup production did not stabilize before the teardown safety ceiling was reached \u2014 the remaining work was NOT run.`,
|
|
151
|
+
{ executed, remaining }
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
var activeBindingCount = 0;
|
|
155
|
+
function resolveCapture(capture) {
|
|
156
|
+
let frame = capture;
|
|
157
|
+
while (frame?.closed) frame = frame.forwardTo;
|
|
158
|
+
return frame ?? null;
|
|
159
|
+
}
|
|
160
|
+
var registrationCaptures = [];
|
|
161
|
+
function currentDisposerCapture() {
|
|
162
|
+
return resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
|
|
163
|
+
}
|
|
164
|
+
function beginDisposerCapture(capture) {
|
|
165
|
+
if (capture === null && registrationCaptures.length === 0) return false;
|
|
166
|
+
registrationCaptures.push(resolveCapture(capture));
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
function endDisposerCapture() {
|
|
170
|
+
registrationCaptures.pop();
|
|
171
|
+
}
|
|
172
|
+
function registerDisposer(node, teardown) {
|
|
173
|
+
let disposers = elementDisposers.get(node);
|
|
174
|
+
if (!disposers) {
|
|
175
|
+
disposers = [];
|
|
176
|
+
elementDisposers.set(node, disposers);
|
|
177
|
+
}
|
|
178
|
+
disposers.push(teardown);
|
|
179
|
+
if (DEV) activeBindingCount++;
|
|
180
|
+
const capture = resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
|
|
181
|
+
if (capture) capture.entries.push([node, teardown]);
|
|
182
|
+
}
|
|
183
|
+
function dispose(node) {
|
|
184
|
+
const stack = [node];
|
|
185
|
+
const order = [];
|
|
186
|
+
while (stack.length > 0) {
|
|
187
|
+
const current = stack.pop();
|
|
188
|
+
order.push(current);
|
|
189
|
+
const children = Array.from(current.childNodes);
|
|
190
|
+
for (let i = 0; i < children.length; i++) {
|
|
191
|
+
stack.push(children[i]);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
for (let i = order.length - 1; i >= 0; i--) {
|
|
195
|
+
disposeNodeOwn(order[i]);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function disposeNodeOwn(node) {
|
|
199
|
+
if (!elementDisposers.has(node)) return;
|
|
200
|
+
let executed = 0;
|
|
201
|
+
let runaway = false;
|
|
202
|
+
while (!runaway) {
|
|
203
|
+
const pending = elementDisposers.get(node);
|
|
204
|
+
if (!pending || pending.length === 0) break;
|
|
205
|
+
const snapshot = pending.slice();
|
|
206
|
+
elementDisposers.delete(node);
|
|
207
|
+
if (DEV) activeBindingCount -= snapshot.length;
|
|
208
|
+
for (let i = 0; i < snapshot.length; i++) {
|
|
209
|
+
if (executed >= MAX_DRAIN_TEARDOWNS) {
|
|
210
|
+
const rest = snapshot.slice(i);
|
|
211
|
+
const added = elementDisposers.get(node);
|
|
212
|
+
elementDisposers.set(node, added ? rest.concat(added) : rest);
|
|
213
|
+
if (DEV) activeBindingCount += rest.length;
|
|
214
|
+
reportDrainRunaway("dispose", executed, rest.length + (added?.length ?? 0));
|
|
215
|
+
runaway = true;
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
executed++;
|
|
219
|
+
try {
|
|
220
|
+
snapshot[i]();
|
|
221
|
+
} catch (err) {
|
|
222
|
+
reportError(err, { phase: "cleanup", name: "disposer" });
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
144
228
|
// src/reactivity/track-core.ts
|
|
145
229
|
var POOL_MAX = 4096;
|
|
146
230
|
var nodePool = [];
|
|
@@ -299,6 +383,7 @@ function retrack(effectFn, subscriber) {
|
|
|
299
383
|
}
|
|
300
384
|
currentSubscriber = subscriber;
|
|
301
385
|
const sub = subscriber;
|
|
386
|
+
if (sub._cap === void 0) sub._cap = currentDisposerCapture();
|
|
302
387
|
const epoch = ++subscriberEpochCounter;
|
|
303
388
|
sub._epoch = epoch;
|
|
304
389
|
sub._structDirty = false;
|
|
@@ -490,7 +575,12 @@ function drainQueue() {
|
|
|
490
575
|
quarantined.add(sub);
|
|
491
576
|
continue;
|
|
492
577
|
}
|
|
493
|
-
|
|
578
|
+
const pushed = beginDisposerCapture(sub._cap ?? null);
|
|
579
|
+
try {
|
|
580
|
+
safeInvoke(sub);
|
|
581
|
+
} finally {
|
|
582
|
+
if (pushed) endDisposerCapture();
|
|
583
|
+
}
|
|
494
584
|
}
|
|
495
585
|
}
|
|
496
586
|
function drainNotificationQueue() {
|
|
@@ -626,7 +716,7 @@ function forEachSubscriber(signal2, visit) {
|
|
|
626
716
|
}
|
|
627
717
|
|
|
628
718
|
// src/reactivity/track.ts
|
|
629
|
-
var _runtimeVersion = true ? "4.
|
|
719
|
+
var _runtimeVersion = true ? "4.7.0" : "dev";
|
|
630
720
|
var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
|
|
631
721
|
function resolveReactiveApi() {
|
|
632
722
|
const g = globalThis;
|
|
@@ -682,6 +772,14 @@ var getSubscriberCount2 = API.getSubscriberCount;
|
|
|
682
772
|
var getSubscriberDeps2 = API.getSubscriberDeps;
|
|
683
773
|
var forEachSubscriber2 = API.forEachSubscriber;
|
|
684
774
|
|
|
775
|
+
// src/core/devtoolsHook.ts
|
|
776
|
+
function emitDevtools(hook, event, payload) {
|
|
777
|
+
try {
|
|
778
|
+
hook.emit(event, payload);
|
|
779
|
+
} catch {
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
|
|
685
783
|
// src/core/ssr-context.ts
|
|
686
784
|
var SSR_KEY = /* @__PURE__ */ Symbol.for("sibujs.ssr.v1");
|
|
687
785
|
function detectSSRShared() {
|
|
@@ -836,12 +934,17 @@ function effect(effectFn, options) {
|
|
|
836
934
|
try {
|
|
837
935
|
retrack2(ctx.bodyFn, ctx.subscriber);
|
|
838
936
|
if (ctx.rerunPending) drainReruns(ctx);
|
|
937
|
+
} catch (err) {
|
|
938
|
+
ctx.disposed = true;
|
|
939
|
+
if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
|
|
940
|
+
cleanup2(ctx.subscriber);
|
|
941
|
+
throw err;
|
|
839
942
|
} finally {
|
|
840
943
|
ctx.running = false;
|
|
841
944
|
ctx.rerunPending = false;
|
|
842
945
|
}
|
|
843
946
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
844
|
-
if (hook) hook
|
|
947
|
+
if (hook) emitDevtools(hook, "effect:create", { effectFn });
|
|
845
948
|
return () => disposeEffect(ctx);
|
|
846
949
|
}
|
|
847
950
|
|
|
@@ -928,7 +1031,7 @@ function signal(initial, options) {
|
|
|
928
1031
|
state2.__v++;
|
|
929
1032
|
if (DEV) {
|
|
930
1033
|
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
931
|
-
if (hook) hook
|
|
1034
|
+
if (hook) emitDevtools(hook, "signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
|
|
932
1035
|
}
|
|
933
1036
|
if (!enqueueBatchedSignal(state2)) {
|
|
934
1037
|
notifySubscribers2(state2);
|
|
@@ -942,7 +1045,7 @@ function signal(initial, options) {
|
|
|
942
1045
|
state2.value = newValue;
|
|
943
1046
|
state2.__v++;
|
|
944
1047
|
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
945
|
-
if (hook) hook
|
|
1048
|
+
if (hook) emitDevtools(hook, "signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
|
|
946
1049
|
if (!enqueueBatchedSignal(state2)) {
|
|
947
1050
|
notifySubscribers2(state2);
|
|
948
1051
|
}
|
|
@@ -961,11 +1064,32 @@ function signal(initial, options) {
|
|
|
961
1064
|
}
|
|
962
1065
|
if (DEV) {
|
|
963
1066
|
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
964
|
-
if (hook) hook
|
|
1067
|
+
if (hook) emitDevtools(hook, "signal:create", { signal: state2, name: debugName, getter: get, initial });
|
|
965
1068
|
}
|
|
966
1069
|
return [get, set];
|
|
967
1070
|
}
|
|
968
1071
|
|
|
1072
|
+
// src/utils/adoptThenable.ts
|
|
1073
|
+
function adoptThenable(value) {
|
|
1074
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") return null;
|
|
1075
|
+
let then;
|
|
1076
|
+
try {
|
|
1077
|
+
then = value.then;
|
|
1078
|
+
} catch (error) {
|
|
1079
|
+
return Promise.reject(error);
|
|
1080
|
+
}
|
|
1081
|
+
if (typeof then !== "function") return null;
|
|
1082
|
+
return new Promise((resolve, reject) => {
|
|
1083
|
+
queueMicrotask(() => {
|
|
1084
|
+
try {
|
|
1085
|
+
Reflect.apply(then, value, [resolve, reject]);
|
|
1086
|
+
} catch (error) {
|
|
1087
|
+
reject(error);
|
|
1088
|
+
}
|
|
1089
|
+
});
|
|
1090
|
+
});
|
|
1091
|
+
}
|
|
1092
|
+
|
|
969
1093
|
// src/utils/globalSingleton.ts
|
|
970
1094
|
function globalSingleton(key, create) {
|
|
971
1095
|
const g = globalThis;
|
|
@@ -973,37 +1097,127 @@ function globalSingleton(key, create) {
|
|
|
973
1097
|
}
|
|
974
1098
|
|
|
975
1099
|
// src/plugins/plugin.ts
|
|
1100
|
+
var CANCELLED_BRAND = /* @__PURE__ */ Symbol.for("sibujs.plugins.installCancelled.v1");
|
|
1101
|
+
var _a;
|
|
1102
|
+
var PluginInstallCancelledError = class extends Error {
|
|
1103
|
+
constructor(pluginName) {
|
|
1104
|
+
super(`[Plugin] Installation of "${pluginName}" was cancelled before it was committed (registry reset).`);
|
|
1105
|
+
/**
|
|
1106
|
+
* Brand, not identity: the default registry is shared across duplicate copies
|
|
1107
|
+
* of this module, so the error a caller receives may come from another copy's
|
|
1108
|
+
* constructor. `instanceof` is taught to recognise the brand instead.
|
|
1109
|
+
*/
|
|
1110
|
+
this[_a] = true;
|
|
1111
|
+
this.name = "PluginInstallCancelledError";
|
|
1112
|
+
this.pluginName = pluginName;
|
|
1113
|
+
}
|
|
1114
|
+
static [(_a = CANCELLED_BRAND, Symbol.hasInstance)](value) {
|
|
1115
|
+
return isPluginInstallCancelledError(value);
|
|
1116
|
+
}
|
|
1117
|
+
};
|
|
1118
|
+
function isPluginInstallCancelledError(value) {
|
|
1119
|
+
return typeof value === "object" && value !== null && value[CANCELLED_BRAND] === true;
|
|
1120
|
+
}
|
|
976
1121
|
function createPluginRegistry() {
|
|
977
1122
|
const installedPlugins = /* @__PURE__ */ new Set();
|
|
978
1123
|
const hooks = { init: [], mount: [], unmount: [], error: [] };
|
|
979
1124
|
const provided = /* @__PURE__ */ new Map();
|
|
1125
|
+
const installStack = /* @__PURE__ */ new Set();
|
|
1126
|
+
const pendingInstalls = /* @__PURE__ */ new Map();
|
|
1127
|
+
let generation = 0;
|
|
980
1128
|
const registry = {
|
|
981
1129
|
installedPlugins,
|
|
982
1130
|
hooks,
|
|
983
1131
|
provided,
|
|
1132
|
+
/**
|
|
1133
|
+
* Install a plugin as a transaction.
|
|
1134
|
+
*
|
|
1135
|
+
* Hooks and providers registered through `ctx` are staged and committed
|
|
1136
|
+
* only if `install()` returns; a throwing install leaves the registry
|
|
1137
|
+
* exactly as it found it (and can simply be retried). The plugin is marked
|
|
1138
|
+
* installed at commit, before its init hooks run.
|
|
1139
|
+
*
|
|
1140
|
+
* Each `plugin()` call is its own transaction: a dependency installed by a
|
|
1141
|
+
* nested `plugin()` call commits on its own and stays installed even if the
|
|
1142
|
+
* outer installation later fails.
|
|
1143
|
+
*/
|
|
984
1144
|
plugin(p, options) {
|
|
985
1145
|
if (installedPlugins.has(p.name)) {
|
|
986
1146
|
console.warn(`[Plugin] "${p.name}" is already installed.`);
|
|
987
1147
|
return;
|
|
988
1148
|
}
|
|
1149
|
+
if (installStack.has(p.name)) {
|
|
1150
|
+
throw new Error(`[Plugin] "${p.name}" is already being installed (recursive installation).`);
|
|
1151
|
+
}
|
|
1152
|
+
if (pendingInstalls.has(p.name)) {
|
|
1153
|
+
throw new Error(`[Plugin] "${p.name}" is already being installed (asynchronous installation in flight).`);
|
|
1154
|
+
}
|
|
1155
|
+
const staged = { init: [], mount: [], unmount: [], error: [] };
|
|
1156
|
+
const stagedProvided = /* @__PURE__ */ new Map();
|
|
1157
|
+
let committed = false;
|
|
1158
|
+
const myGeneration = generation;
|
|
1159
|
+
const stale = () => {
|
|
1160
|
+
if (myGeneration === generation) return false;
|
|
1161
|
+
if (DEV) devWarn(`plugin: "${p.name}" registered after the registry was reset; the registration was ignored.`);
|
|
1162
|
+
return true;
|
|
1163
|
+
};
|
|
1164
|
+
const target = () => stale() ? null : committed ? hooks : staged;
|
|
989
1165
|
const ctx = {
|
|
990
|
-
onInit: (cb) =>
|
|
991
|
-
onMount: (cb) =>
|
|
992
|
-
onUnmount: (cb) =>
|
|
993
|
-
onError: (cb) =>
|
|
994
|
-
provide: (key, value) =>
|
|
1166
|
+
onInit: (cb) => void target()?.init.push(cb),
|
|
1167
|
+
onMount: (cb) => void target()?.mount.push(cb),
|
|
1168
|
+
onUnmount: (cb) => void target()?.unmount.push(cb),
|
|
1169
|
+
onError: (cb) => void target()?.error.push(cb),
|
|
1170
|
+
provide: (key, value) => {
|
|
1171
|
+
if (stale()) return;
|
|
1172
|
+
(committed ? provided : stagedProvided).set(key, value);
|
|
1173
|
+
}
|
|
995
1174
|
};
|
|
996
|
-
const
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1175
|
+
const commit = () => {
|
|
1176
|
+
if (myGeneration !== generation) return false;
|
|
1177
|
+
hooks.init.push(...staged.init);
|
|
1178
|
+
hooks.mount.push(...staged.mount);
|
|
1179
|
+
hooks.unmount.push(...staged.unmount);
|
|
1180
|
+
hooks.error.push(...staged.error);
|
|
1181
|
+
for (const [key, value] of stagedProvided) provided.set(key, value);
|
|
1182
|
+
installedPlugins.add(p.name);
|
|
1183
|
+
committed = true;
|
|
1184
|
+
if (pendingInstalls.get(p.name) === myGeneration) pendingInstalls.delete(p.name);
|
|
1185
|
+
for (const cb of staged.init.slice()) {
|
|
1186
|
+
try {
|
|
1187
|
+
cb();
|
|
1188
|
+
} catch (e) {
|
|
1189
|
+
console.error(`[Plugin] "${p.name}" init error:`, e);
|
|
1190
|
+
}
|
|
1005
1191
|
}
|
|
1192
|
+
return true;
|
|
1193
|
+
};
|
|
1194
|
+
installStack.add(p.name);
|
|
1195
|
+
let pending;
|
|
1196
|
+
try {
|
|
1197
|
+
pending = adoptThenable(p.install(ctx, options));
|
|
1198
|
+
} finally {
|
|
1199
|
+
installStack.delete(p.name);
|
|
1200
|
+
}
|
|
1201
|
+
if (!pending) {
|
|
1202
|
+
if (!commit()) throw new PluginInstallCancelledError(p.name);
|
|
1203
|
+
return;
|
|
1006
1204
|
}
|
|
1205
|
+
if (myGeneration === generation) pendingInstalls.set(p.name, myGeneration);
|
|
1206
|
+
const settled = pending.then(
|
|
1207
|
+
() => {
|
|
1208
|
+
if (commit()) return;
|
|
1209
|
+
if (pendingInstalls.get(p.name) === myGeneration) pendingInstalls.delete(p.name);
|
|
1210
|
+
throw new PluginInstallCancelledError(p.name);
|
|
1211
|
+
},
|
|
1212
|
+
(err) => {
|
|
1213
|
+
if (pendingInstalls.get(p.name) === myGeneration) pendingInstalls.delete(p.name);
|
|
1214
|
+
reportError(err, { phase: "async", name: `plugin(${p.name})` });
|
|
1215
|
+
throw err;
|
|
1216
|
+
}
|
|
1217
|
+
);
|
|
1218
|
+
settled.catch(() => {
|
|
1219
|
+
});
|
|
1220
|
+
return settled;
|
|
1007
1221
|
},
|
|
1008
1222
|
inject(key, defaultValue) {
|
|
1009
1223
|
if (provided.has(key)) return provided.get(key);
|
|
@@ -1041,6 +1255,8 @@ function createPluginRegistry() {
|
|
|
1041
1255
|
}
|
|
1042
1256
|
},
|
|
1043
1257
|
reset() {
|
|
1258
|
+
generation++;
|
|
1259
|
+
pendingInstalls.clear();
|
|
1044
1260
|
installedPlugins.clear();
|
|
1045
1261
|
hooks.init.length = 0;
|
|
1046
1262
|
hooks.mount.length = 0;
|
|
@@ -1131,17 +1347,17 @@ function derived(getter, options) {
|
|
|
1131
1347
|
cs._d = false;
|
|
1132
1348
|
cs._init = true;
|
|
1133
1349
|
};
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
try {
|
|
1350
|
+
try {
|
|
1351
|
+
track2(() => {
|
|
1137
1352
|
cs._v = getter();
|
|
1138
1353
|
cs._d = false;
|
|
1139
1354
|
cs._init = true;
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1355
|
+
}, markDirty);
|
|
1356
|
+
} catch (err) {
|
|
1357
|
+
disposed = true;
|
|
1358
|
+
cleanup2(markDirty);
|
|
1359
|
+
throw err;
|
|
1360
|
+
}
|
|
1145
1361
|
const hook = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
1146
1362
|
const validate = () => {
|
|
1147
1363
|
if (!cs._d || disposed || pendingError !== void 0) return;
|
|
@@ -1160,7 +1376,7 @@ function derived(getter, options) {
|
|
|
1160
1376
|
if (disposed) cleanup2(markDirty);
|
|
1161
1377
|
}
|
|
1162
1378
|
if (hook && !disposed && !Object.is(oldValue, cs._v)) {
|
|
1163
|
-
hook
|
|
1379
|
+
emitDevtools(hook, "computed:update", { signal: cs, oldValue, newValue: cs._v });
|
|
1164
1380
|
}
|
|
1165
1381
|
};
|
|
1166
1382
|
cs._validate = validate;
|
|
@@ -1211,7 +1427,7 @@ function derived(getter, options) {
|
|
|
1211
1427
|
}
|
|
1212
1428
|
}
|
|
1213
1429
|
};
|
|
1214
|
-
if (hook) hook
|
|
1430
|
+
if (hook) emitDevtools(hook, "computed:create", { signal: cs, name: debugName, getter: computedGetter });
|
|
1215
1431
|
return computedGetter;
|
|
1216
1432
|
}
|
|
1217
1433
|
|
|
@@ -1581,70 +1797,6 @@ function bindAttribute(el, attr, getter) {
|
|
|
1581
1797
|
return reactiveBinding2(commit, el);
|
|
1582
1798
|
}
|
|
1583
1799
|
|
|
1584
|
-
// src/core/rendering/dispose.ts
|
|
1585
|
-
var elementDisposers = /* @__PURE__ */ new WeakMap();
|
|
1586
|
-
var MAX_DRAIN_TEARDOWNS = 1e4;
|
|
1587
|
-
function reportDrainRunaway(label, executed, remaining) {
|
|
1588
|
-
if (typeof console === "undefined") return;
|
|
1589
|
-
console.error(
|
|
1590
|
-
`[SibuJS ${label}] runaway cleanup: stopped after running ${executed} teardowns with ${remaining} still queued. Cleanup production did not stabilize before the teardown safety ceiling was reached \u2014 the remaining work was NOT run.`,
|
|
1591
|
-
{ executed, remaining }
|
|
1592
|
-
);
|
|
1593
|
-
}
|
|
1594
|
-
var activeBindingCount = 0;
|
|
1595
|
-
function registerDisposer(node, teardown) {
|
|
1596
|
-
let disposers = elementDisposers.get(node);
|
|
1597
|
-
if (!disposers) {
|
|
1598
|
-
disposers = [];
|
|
1599
|
-
elementDisposers.set(node, disposers);
|
|
1600
|
-
}
|
|
1601
|
-
disposers.push(teardown);
|
|
1602
|
-
if (DEV) activeBindingCount++;
|
|
1603
|
-
}
|
|
1604
|
-
function dispose(node) {
|
|
1605
|
-
const stack = [node];
|
|
1606
|
-
const order = [];
|
|
1607
|
-
while (stack.length > 0) {
|
|
1608
|
-
const current = stack.pop();
|
|
1609
|
-
order.push(current);
|
|
1610
|
-
const children = Array.from(current.childNodes);
|
|
1611
|
-
for (let i = 0; i < children.length; i++) {
|
|
1612
|
-
stack.push(children[i]);
|
|
1613
|
-
}
|
|
1614
|
-
}
|
|
1615
|
-
for (let i = order.length - 1; i >= 0; i--) {
|
|
1616
|
-
const current = order[i];
|
|
1617
|
-
if (elementDisposers.has(current)) {
|
|
1618
|
-
let executed = 0;
|
|
1619
|
-
let runaway = false;
|
|
1620
|
-
while (!runaway) {
|
|
1621
|
-
const pending = elementDisposers.get(current);
|
|
1622
|
-
if (!pending || pending.length === 0) break;
|
|
1623
|
-
const snapshot = pending.slice();
|
|
1624
|
-
elementDisposers.delete(current);
|
|
1625
|
-
if (DEV) activeBindingCount -= snapshot.length;
|
|
1626
|
-
for (let i2 = 0; i2 < snapshot.length; i2++) {
|
|
1627
|
-
if (executed >= MAX_DRAIN_TEARDOWNS) {
|
|
1628
|
-
const rest = snapshot.slice(i2);
|
|
1629
|
-
const added = elementDisposers.get(current);
|
|
1630
|
-
elementDisposers.set(current, added ? rest.concat(added) : rest);
|
|
1631
|
-
if (DEV) activeBindingCount += rest.length;
|
|
1632
|
-
reportDrainRunaway("dispose", executed, rest.length + (added?.length ?? 0));
|
|
1633
|
-
runaway = true;
|
|
1634
|
-
break;
|
|
1635
|
-
}
|
|
1636
|
-
executed++;
|
|
1637
|
-
try {
|
|
1638
|
-
snapshot[i2]();
|
|
1639
|
-
} catch (err) {
|
|
1640
|
-
reportError(err, { phase: "cleanup", name: "disposer" });
|
|
1641
|
-
}
|
|
1642
|
-
}
|
|
1643
|
-
}
|
|
1644
|
-
}
|
|
1645
|
-
}
|
|
1646
|
-
}
|
|
1647
|
-
|
|
1648
1800
|
// src/core/rendering/focusPreservation.ts
|
|
1649
1801
|
var IDENTITY_ATTRS = ["data-focus-key", "id", "name"];
|
|
1650
1802
|
var SELECTABLE_TYPES = /* @__PURE__ */ new Set(["text", "search", "url", "tel", "password", ""]);
|
|
@@ -1844,8 +1996,34 @@ function toKebab(prop) {
|
|
|
1844
1996
|
}
|
|
1845
1997
|
function applyStyle(el, style) {
|
|
1846
1998
|
if (typeof style === "function") {
|
|
1999
|
+
const getter = style;
|
|
2000
|
+
let written = [];
|
|
2001
|
+
let wroteString = false;
|
|
1847
2002
|
const teardown = reactiveBinding2(() => {
|
|
1848
|
-
|
|
2003
|
+
const value = getter();
|
|
2004
|
+
if (value === null || typeof value !== "object") {
|
|
2005
|
+
written = [];
|
|
2006
|
+
wroteString = true;
|
|
2007
|
+
el.setAttribute("style", sanitizeStyleAttribute(String(value), { element: el }));
|
|
2008
|
+
return;
|
|
2009
|
+
}
|
|
2010
|
+
const decl = el.style;
|
|
2011
|
+
if (wroteString) {
|
|
2012
|
+
el.removeAttribute("style");
|
|
2013
|
+
wroteString = false;
|
|
2014
|
+
}
|
|
2015
|
+
const next = [];
|
|
2016
|
+
for (const prop in value) {
|
|
2017
|
+
const val = value[prop];
|
|
2018
|
+
if (val == null) continue;
|
|
2019
|
+
const name = toKebab(prop);
|
|
2020
|
+
next.push(name);
|
|
2021
|
+
decl.setProperty(name, sanitizeCSSValue(String(val), { property: name, element: el }));
|
|
2022
|
+
}
|
|
2023
|
+
for (let i = 0; i < written.length; i++) {
|
|
2024
|
+
if (next.indexOf(written[i]) === -1) decl.removeProperty(written[i]);
|
|
2025
|
+
}
|
|
2026
|
+
written = next;
|
|
1849
2027
|
}, el);
|
|
1850
2028
|
registerDisposer(el, teardown);
|
|
1851
2029
|
return;
|
|
@@ -1876,7 +2054,9 @@ function applyClass(el, cls) {
|
|
|
1876
2054
|
}
|
|
1877
2055
|
if (typeof cls === "function") {
|
|
1878
2056
|
const teardown = reactiveBinding2(() => {
|
|
1879
|
-
|
|
2057
|
+
const value = cls();
|
|
2058
|
+
if (value == null || value === false) el.removeAttribute("class");
|
|
2059
|
+
else el.setAttribute("class", value);
|
|
1880
2060
|
}, el);
|
|
1881
2061
|
registerDisposer(el, teardown);
|
|
1882
2062
|
return;
|
|
@@ -1958,7 +2138,7 @@ function appendChildren(el, nodes) {
|
|
|
1958
2138
|
}
|
|
1959
2139
|
}
|
|
1960
2140
|
}
|
|
1961
|
-
|
|
2141
|
+
function tagFactory(tag, ns) {
|
|
1962
2142
|
const blocked = isBlockedTag(tag);
|
|
1963
2143
|
return (first, second) => {
|
|
1964
2144
|
if (blocked) {
|
|
@@ -2007,7 +2187,9 @@ var tagFactory = (tag, ns) => {
|
|
|
2007
2187
|
const pClass = props.class;
|
|
2008
2188
|
if (pClass != null) applyClass(el, pClass);
|
|
2009
2189
|
const pId = props.id;
|
|
2010
|
-
if (pId
|
|
2190
|
+
if (typeof pId === "function") {
|
|
2191
|
+
registerDisposer(el, bindAttribute(el, "id", pId));
|
|
2192
|
+
} else if (pId != null) {
|
|
2011
2193
|
if (DEV && typeof pId === "string" && CLOBBER_RISKY_IDS.has(pId.toLowerCase())) {
|
|
2012
2194
|
devWarn(
|
|
2013
2195
|
`tagFactory: element id="${pId}" matches a common global and may cause DOM clobbering. Avoid setting ids from untrusted input.`
|
|
@@ -2057,61 +2239,125 @@ var tagFactory = (tag, ns) => {
|
|
|
2057
2239
|
}
|
|
2058
2240
|
}
|
|
2059
2241
|
}
|
|
2060
|
-
if (
|
|
2061
|
-
props.onElement(el);
|
|
2062
|
-
}
|
|
2242
|
+
if (typeof props.onElement === "function") props.onElement(el);
|
|
2063
2243
|
return el;
|
|
2064
2244
|
};
|
|
2065
|
-
}
|
|
2245
|
+
}
|
|
2066
2246
|
|
|
2067
2247
|
// src/ecosystem/ui/componentAdapter.ts
|
|
2248
|
+
var _themeLayers = globalSingleton(
|
|
2249
|
+
/* @__PURE__ */ Symbol.for("sibujs.themeLayers.v1"),
|
|
2250
|
+
() => /* @__PURE__ */ new WeakMap()
|
|
2251
|
+
);
|
|
2252
|
+
function commitThemeProperty(root, name, record) {
|
|
2253
|
+
const top = record.layers[record.layers.length - 1];
|
|
2254
|
+
if (top) {
|
|
2255
|
+
root.style.setProperty(name, top.value);
|
|
2256
|
+
return;
|
|
2257
|
+
}
|
|
2258
|
+
_themeLayers.get(root)?.delete(name);
|
|
2259
|
+
if (record.original.value === "") root.style.removeProperty(name);
|
|
2260
|
+
else root.style.setProperty(name, record.original.value, record.original.priority);
|
|
2261
|
+
}
|
|
2262
|
+
function setThemeLayer(root, name, handle, value) {
|
|
2263
|
+
let properties = _themeLayers.get(root);
|
|
2264
|
+
if (!properties) _themeLayers.set(root, properties = /* @__PURE__ */ new Map());
|
|
2265
|
+
let record = properties.get(name);
|
|
2266
|
+
if (!record) {
|
|
2267
|
+
record = {
|
|
2268
|
+
original: { value: root.style.getPropertyValue(name), priority: root.style.getPropertyPriority(name) },
|
|
2269
|
+
layers: []
|
|
2270
|
+
};
|
|
2271
|
+
properties.set(name, record);
|
|
2272
|
+
}
|
|
2273
|
+
const layer = record.layers.find((l) => l.handle === handle);
|
|
2274
|
+
if (layer) layer.value = value;
|
|
2275
|
+
else record.layers.push({ handle, value });
|
|
2276
|
+
commitThemeProperty(root, name, record);
|
|
2277
|
+
}
|
|
2278
|
+
function removeThemeLayer(root, name, handle) {
|
|
2279
|
+
const record = _themeLayers.get(root)?.get(name);
|
|
2280
|
+
if (!record) return;
|
|
2281
|
+
const index = record.layers.findIndex((l) => l.handle === handle);
|
|
2282
|
+
if (index === -1) return;
|
|
2283
|
+
record.layers.splice(index, 1);
|
|
2284
|
+
commitThemeProperty(root, name, record);
|
|
2285
|
+
}
|
|
2286
|
+
function ownString(map, key) {
|
|
2287
|
+
if (!map || key === void 0 || !Object.hasOwn(map, key)) return void 0;
|
|
2288
|
+
const value = map[key];
|
|
2289
|
+
return typeof value === "string" ? value : void 0;
|
|
2290
|
+
}
|
|
2068
2291
|
function createTheme(initial) {
|
|
2069
2292
|
const [getConfig, setConfig] = signal(initial);
|
|
2070
2293
|
function resolveClass(component, variant) {
|
|
2071
2294
|
const config = getConfig();
|
|
2072
2295
|
const overrideKey = variant ? `${component}-${variant}` : component;
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
}
|
|
2296
|
+
const override = ownString(config.classOverrides, overrideKey);
|
|
2297
|
+
if (override) return override;
|
|
2076
2298
|
const base = `${config.prefix}-${component}`;
|
|
2077
2299
|
return variant ? `${base} ${config.prefix}-${component}--${variant}` : base;
|
|
2078
2300
|
}
|
|
2079
2301
|
function setTheme(partial) {
|
|
2080
2302
|
setConfig((prev) => ({ ...prev, ...partial }));
|
|
2081
2303
|
}
|
|
2082
|
-
|
|
2304
|
+
function applyTo(root) {
|
|
2305
|
+
const handle = {};
|
|
2306
|
+
let applied = /* @__PURE__ */ new Set();
|
|
2307
|
+
const stop = effect(() => {
|
|
2308
|
+
const variables = getConfig().variables ?? {};
|
|
2309
|
+
const next = new Set(Object.keys(variables));
|
|
2310
|
+
for (const name of applied) {
|
|
2311
|
+
if (!next.has(name)) removeThemeLayer(root, name, handle);
|
|
2312
|
+
}
|
|
2313
|
+
for (const [name, value] of Object.entries(variables)) setThemeLayer(root, name, handle, value);
|
|
2314
|
+
applied = next;
|
|
2315
|
+
});
|
|
2316
|
+
let released = false;
|
|
2317
|
+
return () => {
|
|
2318
|
+
if (released) return;
|
|
2319
|
+
released = true;
|
|
2320
|
+
stop();
|
|
2321
|
+
for (const name of applied) removeThemeLayer(root, name, handle);
|
|
2322
|
+
applied.clear();
|
|
2323
|
+
};
|
|
2324
|
+
}
|
|
2325
|
+
return { config: getConfig, setTheme, resolveClass, applyTo };
|
|
2083
2326
|
}
|
|
2084
2327
|
function componentAdapter(config) {
|
|
2085
2328
|
const theme = createTheme({ prefix: config.prefix });
|
|
2329
|
+
const reprefix = (cls, prefix) => prefix !== config.prefix && cls.startsWith(`${config.prefix}-`) ? `${prefix}-${cls.slice(config.prefix.length + 1)}` : cls;
|
|
2086
2330
|
const components = {};
|
|
2087
2331
|
for (const [name, mapping] of Object.entries(config.components)) {
|
|
2088
2332
|
const factory = tagFactory(mapping.tag || "div");
|
|
2089
|
-
components[name] = (props = {}) => {
|
|
2333
|
+
components[name] = (props = {}, children) => {
|
|
2090
2334
|
const { variant, size, class: userClass, ...rest } = props;
|
|
2091
|
-
const
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
}
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2335
|
+
const themeClasses = () => {
|
|
2336
|
+
const current = theme.config();
|
|
2337
|
+
const overrides = current.classOverrides ?? {};
|
|
2338
|
+
const pick = (key, fallback) => Object.hasOwn(overrides, key) ? overrides[key] : reprefix(fallback, current.prefix);
|
|
2339
|
+
const classes = [pick(name, mapping.baseClass)];
|
|
2340
|
+
const variantClass = ownString(mapping.variants, variant);
|
|
2341
|
+
if (variant && variantClass) {
|
|
2342
|
+
classes.push(pick(`${name}-${variant}`, variantClass));
|
|
2343
|
+
}
|
|
2344
|
+
const sizeClass = ownString(mapping.sizes, size);
|
|
2345
|
+
if (size && sizeClass) {
|
|
2346
|
+
classes.push(pick(`${name}-${size}`, sizeClass));
|
|
2347
|
+
}
|
|
2348
|
+
return classes.filter(Boolean).join(" ");
|
|
2349
|
+
};
|
|
2350
|
+
const finalClass = () => {
|
|
2351
|
+
const base = themeClasses();
|
|
2352
|
+
const extra = typeof userClass === "function" ? userClass() : userClass;
|
|
2353
|
+
return typeof extra === "string" && extra ? `${base} ${extra}` : base;
|
|
2354
|
+
};
|
|
2109
2355
|
const mergedProps = {
|
|
2110
2356
|
...mapping.defaultProps,
|
|
2111
2357
|
...rest,
|
|
2112
2358
|
class: finalClass
|
|
2113
2359
|
};
|
|
2114
|
-
return factory(mergedProps);
|
|
2360
|
+
return children === void 0 ? factory(mergedProps) : factory(mergedProps, children);
|
|
2115
2361
|
};
|
|
2116
2362
|
}
|
|
2117
2363
|
return { name: config.name, components, theme };
|