sibujs 2.0.0 → 2.2.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/dist/browser.cjs +369 -276
- package/dist/browser.js +4 -4
- package/dist/build.cjs +411 -300
- package/dist/build.js +10 -10
- package/dist/cdn.global.js +8 -8
- package/dist/{chunk-JA6667UN.js → chunk-2JQUV4Y3.js} +4 -4
- package/dist/{chunk-3NSGB5JN.js → chunk-2KM2724A.js} +2 -2
- package/dist/{chunk-52YJLLRO.js → chunk-4YTVESDX.js} +1 -1
- package/dist/chunk-5WD7BYTZ.js +152 -0
- package/dist/{chunk-CC65Y57T.js → chunk-6QZO7MMG.js} +48 -16
- package/dist/{chunk-54EDRCEF.js → chunk-DF3GTP4Q.js} +7 -2
- package/dist/{chunk-ND2664SF.js → chunk-J63GPPCJ.js} +13 -9
- package/dist/{chunk-O2MNQFLP.js → chunk-KH4OE6WY.js} +5 -5
- package/dist/{chunk-3LR7GLWQ.js → chunk-KZA7ANXP.js} +3 -3
- package/dist/chunk-L4DAT4WU.js +400 -0
- package/dist/{chunk-WOMYAHHI.js → chunk-L52H775O.js} +4 -4
- package/dist/{chunk-ITX6OO3F.js → chunk-NEWH4O5U.js} +1 -1
- package/dist/{chunk-7JDB7I65.js → chunk-RJIRT46U.js} +4 -4
- package/dist/{chunk-KLRMB5ZS.js → chunk-STFTTMO2.js} +2 -2
- package/dist/{chunk-DFPFITST.js → chunk-UKMXT5T6.js} +1 -1
- package/dist/{chunk-SAHNHTFC.js → chunk-V65KTDZW.js} +3 -3
- package/dist/{chunk-R73P76YZ.js → chunk-VSNLICTS.js} +1 -1
- package/dist/{chunk-MIUAXB7K.js → chunk-XDKP4T7G.js} +2 -2
- package/dist/{chunk-JXMMDLBY.js → chunk-XVYB3J6C.js} +27 -29
- package/dist/{chunk-GTBNNBJ6.js → chunk-YMOIAHWA.js} +1 -1
- package/dist/data.cjs +382 -274
- package/dist/data.js +6 -6
- package/dist/devtools.cjs +398 -284
- package/dist/devtools.d.cts +1 -1
- package/dist/devtools.d.ts +1 -1
- package/dist/devtools.js +4 -4
- package/dist/ecosystem.cjs +382 -274
- package/dist/ecosystem.js +7 -7
- package/dist/extras.cjs +421 -299
- package/dist/extras.d.cts +1 -1
- package/dist/extras.d.ts +1 -1
- package/dist/extras.js +19 -19
- package/dist/index.cjs +413 -300
- package/dist/index.d.cts +16 -11
- package/dist/index.d.ts +16 -11
- package/dist/index.js +14 -10
- package/dist/{introspect-cY2pg9pW.d.ts → introspect-BZWKvQUZ.d.ts} +2 -1
- package/dist/{introspect-BWNjNw64.d.cts → introspect-DsJlDD2T.d.cts} +2 -1
- package/dist/motion.cjs +189 -149
- package/dist/motion.js +3 -3
- package/dist/patterns.cjs +382 -274
- package/dist/patterns.js +5 -5
- package/dist/performance.cjs +360 -260
- package/dist/performance.js +4 -4
- package/dist/plugins.cjs +376 -257
- package/dist/plugins.js +6 -6
- package/dist/ssr.cjs +383 -271
- package/dist/ssr.js +7 -7
- package/dist/testing.cjs +168 -109
- package/dist/testing.js +2 -2
- package/dist/ui.cjs +373 -258
- package/dist/ui.js +6 -6
- package/dist/widgets.cjs +382 -274
- package/dist/widgets.js +6 -6
- package/package.json +1 -1
- package/dist/chunk-HB24TBAF.js +0 -121
- package/dist/chunk-VLPPXTYG.js +0 -332
package/dist/browser.cjs
CHANGED
|
@@ -77,11 +77,88 @@ function devWarn(message) {
|
|
|
77
77
|
|
|
78
78
|
// src/reactivity/track.ts
|
|
79
79
|
var _isDev2 = isDev();
|
|
80
|
-
var
|
|
81
|
-
var
|
|
82
|
-
|
|
80
|
+
var POOL_MAX = 4096;
|
|
81
|
+
var nodePool = [];
|
|
82
|
+
function createNode() {
|
|
83
|
+
return {
|
|
84
|
+
sig: null,
|
|
85
|
+
sub: null,
|
|
86
|
+
epoch: 0,
|
|
87
|
+
sigPrev: null,
|
|
88
|
+
sigNext: null,
|
|
89
|
+
subPrev: null,
|
|
90
|
+
subNext: null,
|
|
91
|
+
prevActive: null
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function allocNode(sig, sub, epoch) {
|
|
95
|
+
const n = nodePool.pop();
|
|
96
|
+
if (n) {
|
|
97
|
+
n.sig = sig;
|
|
98
|
+
n.sub = sub;
|
|
99
|
+
n.epoch = epoch;
|
|
100
|
+
return n;
|
|
101
|
+
}
|
|
102
|
+
const fresh = createNode();
|
|
103
|
+
fresh.sig = sig;
|
|
104
|
+
fresh.sub = sub;
|
|
105
|
+
fresh.epoch = epoch;
|
|
106
|
+
return fresh;
|
|
107
|
+
}
|
|
108
|
+
function freeNode(node) {
|
|
109
|
+
node.sig = null;
|
|
110
|
+
node.sub = null;
|
|
111
|
+
node.sigPrev = null;
|
|
112
|
+
node.sigNext = null;
|
|
113
|
+
node.subPrev = null;
|
|
114
|
+
node.subNext = null;
|
|
115
|
+
node.prevActive = null;
|
|
116
|
+
if (nodePool.length < POOL_MAX) nodePool.push(node);
|
|
117
|
+
}
|
|
118
|
+
function linkSignal(sig, node) {
|
|
119
|
+
const oldHead = sig.subsHead ?? null;
|
|
120
|
+
node.sigPrev = null;
|
|
121
|
+
node.sigNext = oldHead;
|
|
122
|
+
if (oldHead) oldHead.sigPrev = node;
|
|
123
|
+
else sig.subsTail = node;
|
|
124
|
+
sig.subsHead = node;
|
|
125
|
+
sig.__sc = (sig.__sc ?? 0) + 1;
|
|
126
|
+
}
|
|
127
|
+
function unlinkSignal(node) {
|
|
128
|
+
const sig = node.sig;
|
|
129
|
+
if (!sig) return;
|
|
130
|
+
const prev = node.sigPrev;
|
|
131
|
+
const next = node.sigNext;
|
|
132
|
+
if (prev) prev.sigNext = next;
|
|
133
|
+
else sig.subsHead = next;
|
|
134
|
+
if (next) next.sigPrev = prev;
|
|
135
|
+
else sig.subsTail = prev;
|
|
136
|
+
sig.__sc = (sig.__sc ?? 1) - 1;
|
|
137
|
+
if (sig.__activeNode === node) sig.__activeNode = node.prevActive;
|
|
138
|
+
if (sig.__sc === 0) {
|
|
139
|
+
sig.subsHead = null;
|
|
140
|
+
sig.subsTail = null;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function linkSub(sub, node) {
|
|
144
|
+
const oldTail = sub.depsTail ?? null;
|
|
145
|
+
node.subPrev = oldTail;
|
|
146
|
+
node.subNext = null;
|
|
147
|
+
if (oldTail) oldTail.subNext = node;
|
|
148
|
+
else sub.depsHead = node;
|
|
149
|
+
sub.depsTail = node;
|
|
150
|
+
}
|
|
151
|
+
function unlinkSub(node) {
|
|
152
|
+
const sub = node.sub;
|
|
153
|
+
if (!sub) return;
|
|
154
|
+
const prev = node.subPrev;
|
|
155
|
+
const next = node.subNext;
|
|
156
|
+
if (prev) prev.subNext = next;
|
|
157
|
+
else sub.depsHead = next;
|
|
158
|
+
if (next) next.subPrev = prev;
|
|
159
|
+
else sub.depsTail = prev;
|
|
160
|
+
}
|
|
83
161
|
var currentSubscriber = null;
|
|
84
|
-
var SUBS = "__s";
|
|
85
162
|
var notifyDepth = 0;
|
|
86
163
|
var pendingQueue = [];
|
|
87
164
|
var pendingSet = /* @__PURE__ */ new Set();
|
|
@@ -93,83 +170,117 @@ function safeInvoke(sub) {
|
|
|
93
170
|
if (_isDev2) devWarn(`Subscriber threw during notification: ${err instanceof Error ? err.message : String(err)}`);
|
|
94
171
|
}
|
|
95
172
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
++stackTop;
|
|
100
|
-
if (stackTop >= stackCapacity) {
|
|
101
|
-
stackCapacity *= 2;
|
|
102
|
-
subscriberStack.length = stackCapacity;
|
|
103
|
-
}
|
|
104
|
-
subscriberStack[stackTop] = subscriber;
|
|
173
|
+
var subscriberEpochCounter = 0;
|
|
174
|
+
function retrack(effectFn, subscriber) {
|
|
175
|
+
const prev = currentSubscriber;
|
|
105
176
|
currentSubscriber = subscriber;
|
|
177
|
+
const sub = subscriber;
|
|
178
|
+
const epoch = ++subscriberEpochCounter;
|
|
179
|
+
sub._epoch = epoch;
|
|
180
|
+
sub._structDirty = false;
|
|
181
|
+
for (let n = sub.depsHead ?? null; n !== null; n = n.subNext) {
|
|
182
|
+
const sig = n.sig;
|
|
183
|
+
n.prevActive = sig.__activeNode ?? null;
|
|
184
|
+
sig.__activeNode = n;
|
|
185
|
+
}
|
|
106
186
|
try {
|
|
107
187
|
effectFn();
|
|
108
188
|
} finally {
|
|
109
|
-
|
|
110
|
-
|
|
189
|
+
currentSubscriber = prev;
|
|
190
|
+
let node = sub.depsHead ?? null;
|
|
191
|
+
while (node !== null) {
|
|
192
|
+
const next = node.subNext;
|
|
193
|
+
const sig = node.sig;
|
|
194
|
+
sig.__activeNode = node.prevActive;
|
|
195
|
+
node.prevActive = null;
|
|
196
|
+
if (node.epoch !== epoch) {
|
|
197
|
+
unlinkSub(node);
|
|
198
|
+
unlinkSignal(node);
|
|
199
|
+
freeNode(node);
|
|
200
|
+
}
|
|
201
|
+
node = next;
|
|
202
|
+
}
|
|
111
203
|
}
|
|
112
|
-
return () => cleanup(subscriber);
|
|
113
204
|
}
|
|
114
205
|
function recordDependency(signal2) {
|
|
115
206
|
if (!currentSubscriber) return;
|
|
116
207
|
const sub = currentSubscriber;
|
|
117
|
-
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const set = /* @__PURE__ */ new Set();
|
|
124
|
-
set.add(sub._dep);
|
|
125
|
-
set.add(signal2);
|
|
126
|
-
sub._deps = set;
|
|
127
|
-
sub._dep = void 0;
|
|
128
|
-
} else {
|
|
129
|
-
sub._dep = signal2;
|
|
208
|
+
const sig = signal2;
|
|
209
|
+
const epoch = sub._epoch ?? 0;
|
|
210
|
+
const active = sig.__activeNode ?? null;
|
|
211
|
+
if (active !== null && active.sub === sub) {
|
|
212
|
+
active.epoch = epoch;
|
|
213
|
+
return;
|
|
130
214
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
215
|
+
const node = allocNode(signal2, sub, epoch);
|
|
216
|
+
node.prevActive = active;
|
|
217
|
+
sig.__activeNode = node;
|
|
218
|
+
linkSub(sub, node);
|
|
219
|
+
linkSignal(sig, node);
|
|
220
|
+
sub._structDirty = true;
|
|
221
|
+
}
|
|
222
|
+
function cleanup(subscriber) {
|
|
223
|
+
const sub = subscriber;
|
|
224
|
+
let node = sub.depsHead ?? null;
|
|
225
|
+
sub.depsHead = null;
|
|
226
|
+
sub.depsTail = null;
|
|
227
|
+
while (node) {
|
|
228
|
+
const next = node.subNext;
|
|
229
|
+
unlinkSignal(node);
|
|
230
|
+
freeNode(node);
|
|
231
|
+
node = next;
|
|
135
232
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
233
|
+
}
|
|
234
|
+
var maxSubscriberRepeats = 50;
|
|
235
|
+
var maxDrainIterations = 1e6;
|
|
236
|
+
var drainEpoch = 0;
|
|
237
|
+
function tickRepeat(sub) {
|
|
238
|
+
const s = sub;
|
|
239
|
+
if (s._runEpoch !== drainEpoch) {
|
|
240
|
+
s._runEpoch = drainEpoch;
|
|
241
|
+
s._runs = 1;
|
|
242
|
+
return false;
|
|
141
243
|
}
|
|
244
|
+
s._runs = (s._runs ?? 0) + 1;
|
|
245
|
+
return s._runs > maxSubscriberRepeats;
|
|
142
246
|
}
|
|
143
|
-
function
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
247
|
+
function cycleError(sub) {
|
|
248
|
+
if (typeof console !== "undefined") {
|
|
249
|
+
const name = sub.__name ?? "<unnamed>";
|
|
250
|
+
console.error(
|
|
251
|
+
`[SibuJS] subscriber "${name}" fired more than ${maxSubscriberRepeats} times \u2014 likely a write-reads-self cycle between effects/signals. Breaking to prevent infinite loop.`
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
function absoluteDrainError() {
|
|
256
|
+
if (typeof console !== "undefined") {
|
|
257
|
+
console.error(
|
|
258
|
+
`[SibuJS] Notification drain exceeded ${maxDrainIterations} iterations \u2014 absolute safety net tripped. Breaking to prevent infinite loop.`
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function drainQueue() {
|
|
263
|
+
let i = 0;
|
|
264
|
+
while (i < pendingQueue.length) {
|
|
265
|
+
if (i >= maxDrainIterations) {
|
|
266
|
+
absoluteDrainError();
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
const sub = pendingQueue[i++];
|
|
270
|
+
if (tickRepeat(sub)) {
|
|
271
|
+
cycleError(sub);
|
|
272
|
+
break;
|
|
152
273
|
}
|
|
274
|
+
pendingSet.delete(sub);
|
|
275
|
+
safeInvoke(sub);
|
|
153
276
|
}
|
|
154
277
|
}
|
|
155
|
-
var maxDrainIterations = 1e5;
|
|
156
278
|
function drainNotificationQueue() {
|
|
157
279
|
if (notifyDepth > 0) return;
|
|
158
280
|
notifyDepth++;
|
|
281
|
+
drainEpoch++;
|
|
159
282
|
try {
|
|
160
|
-
|
|
161
|
-
while (i < pendingQueue.length) {
|
|
162
|
-
if (i >= maxDrainIterations) {
|
|
163
|
-
if (typeof console !== "undefined") {
|
|
164
|
-
console.error(
|
|
165
|
-
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
break;
|
|
169
|
-
}
|
|
170
|
-
safeInvoke(pendingQueue[i]);
|
|
171
|
-
i++;
|
|
172
|
-
}
|
|
283
|
+
drainQueue();
|
|
173
284
|
} finally {
|
|
174
285
|
notifyDepth--;
|
|
175
286
|
if (notifyDepth === 0) {
|
|
@@ -187,131 +298,82 @@ function propagateDirty(sub) {
|
|
|
187
298
|
stack.push(rootSig);
|
|
188
299
|
while (stack.length > baseLen) {
|
|
189
300
|
const sig = stack.pop();
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
if (
|
|
195
|
-
nSig
|
|
196
|
-
|
|
301
|
+
let node = sig.subsHead ?? null;
|
|
302
|
+
while (node) {
|
|
303
|
+
const s = node.sub;
|
|
304
|
+
if (s) {
|
|
305
|
+
if (s._c) {
|
|
306
|
+
const nSig = s._sig;
|
|
307
|
+
if (nSig) {
|
|
308
|
+
if (!nSig._d) {
|
|
309
|
+
nSig._d = true;
|
|
310
|
+
stack.push(nSig);
|
|
311
|
+
}
|
|
312
|
+
} else {
|
|
313
|
+
s();
|
|
314
|
+
}
|
|
315
|
+
} else if (!pendingSet.has(s)) {
|
|
316
|
+
pendingSet.add(s);
|
|
317
|
+
pendingQueue.push(s);
|
|
197
318
|
}
|
|
198
|
-
} else if (!pendingSet.has(first)) {
|
|
199
|
-
pendingSet.add(first);
|
|
200
|
-
pendingQueue.push(first);
|
|
201
319
|
}
|
|
202
|
-
|
|
320
|
+
node = node.sigNext;
|
|
203
321
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
function queueSignalNotification(signal2) {
|
|
325
|
+
const sig = signal2;
|
|
326
|
+
let node = sig.subsHead ?? null;
|
|
327
|
+
while (node) {
|
|
328
|
+
const s = node.sub;
|
|
329
|
+
if (s) {
|
|
207
330
|
if (s._c) {
|
|
208
|
-
|
|
209
|
-
if (nSig && !nSig._d) {
|
|
210
|
-
nSig._d = true;
|
|
211
|
-
stack.push(nSig);
|
|
212
|
-
} else if (!nSig) {
|
|
213
|
-
s();
|
|
214
|
-
}
|
|
331
|
+
propagateDirty(s);
|
|
215
332
|
} else if (!pendingSet.has(s)) {
|
|
216
333
|
pendingSet.add(s);
|
|
217
334
|
pendingQueue.push(s);
|
|
218
335
|
}
|
|
219
336
|
}
|
|
337
|
+
node = node.sigNext;
|
|
220
338
|
}
|
|
221
339
|
}
|
|
222
340
|
function notifySubscribers(signal2) {
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
if (first._c) {
|
|
227
|
-
propagateDirty(first);
|
|
228
|
-
} else if (!pendingSet.has(first)) {
|
|
229
|
-
pendingSet.add(first);
|
|
230
|
-
pendingQueue.push(first);
|
|
231
|
-
}
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
notifyDepth++;
|
|
235
|
-
try {
|
|
236
|
-
if (first._c) {
|
|
237
|
-
propagateDirty(first);
|
|
238
|
-
} else {
|
|
239
|
-
safeInvoke(first);
|
|
240
|
-
}
|
|
241
|
-
let i = 0;
|
|
242
|
-
while (i < pendingQueue.length) {
|
|
243
|
-
if (i >= maxDrainIterations) {
|
|
244
|
-
if (typeof console !== "undefined") {
|
|
245
|
-
console.error(
|
|
246
|
-
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
247
|
-
);
|
|
248
|
-
}
|
|
249
|
-
break;
|
|
250
|
-
}
|
|
251
|
-
safeInvoke(pendingQueue[i]);
|
|
252
|
-
i++;
|
|
253
|
-
}
|
|
254
|
-
} finally {
|
|
255
|
-
notifyDepth--;
|
|
256
|
-
if (notifyDepth === 0) {
|
|
257
|
-
pendingQueue.length = 0;
|
|
258
|
-
pendingSet.clear();
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
|
-
const subs = signal2[SUBS];
|
|
264
|
-
if (!subs || subs.size === 0) return;
|
|
341
|
+
const sig = signal2;
|
|
342
|
+
const head = sig.subsHead;
|
|
343
|
+
if (!head) return;
|
|
265
344
|
if (notifyDepth > 0) {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
345
|
+
let node = head;
|
|
346
|
+
while (node) {
|
|
347
|
+
const s = node.sub;
|
|
348
|
+
if (s) {
|
|
349
|
+
if (s._c) {
|
|
350
|
+
propagateDirty(s);
|
|
351
|
+
} else if (!pendingSet.has(s)) {
|
|
352
|
+
pendingSet.add(s);
|
|
353
|
+
pendingQueue.push(s);
|
|
354
|
+
}
|
|
272
355
|
}
|
|
356
|
+
node = node.sigNext;
|
|
273
357
|
}
|
|
274
358
|
return;
|
|
275
359
|
}
|
|
276
360
|
notifyDepth++;
|
|
361
|
+
drainEpoch++;
|
|
277
362
|
try {
|
|
278
|
-
let
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
if (
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
}
|
|
288
|
-
} else {
|
|
289
|
-
for (let i2 = 0; i2 < directCount; i2++) {
|
|
290
|
-
if (pendingQueue[i2]._c) {
|
|
291
|
-
propagateDirty(pendingQueue[i2]);
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
for (let i2 = 0; i2 < directCount; i2++) {
|
|
295
|
-
const sub = pendingQueue[i2];
|
|
296
|
-
if (!sub._c && !pendingSet.has(sub)) {
|
|
297
|
-
pendingSet.add(sub);
|
|
298
|
-
safeInvoke(sub);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
let i = directCount;
|
|
303
|
-
while (i < pendingQueue.length) {
|
|
304
|
-
if (i - directCount >= maxDrainIterations) {
|
|
305
|
-
if (typeof console !== "undefined") {
|
|
306
|
-
console.error(
|
|
307
|
-
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
308
|
-
);
|
|
363
|
+
let node = head;
|
|
364
|
+
while (node) {
|
|
365
|
+
const s = node.sub;
|
|
366
|
+
if (s) {
|
|
367
|
+
if (s._c) {
|
|
368
|
+
propagateDirty(s);
|
|
369
|
+
} else if (!pendingSet.has(s)) {
|
|
370
|
+
pendingSet.add(s);
|
|
371
|
+
pendingQueue.push(s);
|
|
309
372
|
}
|
|
310
|
-
break;
|
|
311
373
|
}
|
|
312
|
-
|
|
313
|
-
i++;
|
|
374
|
+
node = node.sigNext;
|
|
314
375
|
}
|
|
376
|
+
drainQueue();
|
|
315
377
|
} finally {
|
|
316
378
|
notifyDepth--;
|
|
317
379
|
if (notifyDepth === 0) {
|
|
@@ -320,37 +382,6 @@ function notifySubscribers(signal2) {
|
|
|
320
382
|
}
|
|
321
383
|
}
|
|
322
384
|
}
|
|
323
|
-
function cleanup(subscriber) {
|
|
324
|
-
const sub = subscriber;
|
|
325
|
-
const singleDep = sub._dep;
|
|
326
|
-
if (singleDep !== void 0) {
|
|
327
|
-
const subs = singleDep[SUBS];
|
|
328
|
-
if (subs) {
|
|
329
|
-
subs.delete(subscriber);
|
|
330
|
-
if (singleDep.__f === subscriber) {
|
|
331
|
-
singleDep.__f = subs.size === 1 ? subs.values().next().value : void 0;
|
|
332
|
-
} else if (subs.size === 1 && singleDep.__f === void 0) {
|
|
333
|
-
singleDep.__f = subs.values().next().value;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
sub._dep = void 0;
|
|
337
|
-
return;
|
|
338
|
-
}
|
|
339
|
-
const deps = sub._deps;
|
|
340
|
-
if (!deps || deps.size === 0) return;
|
|
341
|
-
for (const signal2 of deps) {
|
|
342
|
-
const subs = signal2[SUBS];
|
|
343
|
-
if (subs) {
|
|
344
|
-
subs.delete(subscriber);
|
|
345
|
-
if (signal2.__f === subscriber) {
|
|
346
|
-
signal2.__f = subs.size === 1 ? subs.values().next().value : void 0;
|
|
347
|
-
} else if (subs.size === 1 && signal2.__f === void 0) {
|
|
348
|
-
signal2.__f = subs.values().next().value;
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
deps.clear();
|
|
353
|
-
}
|
|
354
385
|
|
|
355
386
|
// src/reactivity/batch.ts
|
|
356
387
|
var batchDepth = 0;
|
|
@@ -386,32 +417,64 @@ function flushBatch() {
|
|
|
386
417
|
var _g = globalThis;
|
|
387
418
|
var _isDev3 = isDev();
|
|
388
419
|
function signal(initial, options) {
|
|
389
|
-
const state = {
|
|
420
|
+
const state = {
|
|
421
|
+
value: initial,
|
|
422
|
+
__v: 0,
|
|
423
|
+
__sc: 0,
|
|
424
|
+
subsHead: null,
|
|
425
|
+
subsTail: null,
|
|
426
|
+
__activeNode: null,
|
|
427
|
+
__name: void 0
|
|
428
|
+
};
|
|
390
429
|
const debugName = _isDev3 ? options?.name : void 0;
|
|
391
430
|
const equalsFn = options?.equals;
|
|
392
|
-
if (debugName)
|
|
393
|
-
state.__name = debugName;
|
|
394
|
-
}
|
|
431
|
+
if (debugName) state.__name = debugName;
|
|
395
432
|
function get() {
|
|
396
433
|
recordDependency(state);
|
|
397
434
|
return state.value;
|
|
398
435
|
}
|
|
399
436
|
get.__signal = state;
|
|
400
437
|
if (debugName) get.__name = debugName;
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
const
|
|
438
|
+
let set;
|
|
439
|
+
if (equalsFn) {
|
|
440
|
+
set = (next) => {
|
|
441
|
+
const prev = state.value;
|
|
442
|
+
const newValue = typeof next === "function" ? next(prev) : next;
|
|
443
|
+
if (equalsFn(prev, newValue)) return;
|
|
406
444
|
state.value = newValue;
|
|
445
|
+
state.__v++;
|
|
446
|
+
if (_isDev3) {
|
|
447
|
+
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
448
|
+
if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue: prev, newValue });
|
|
449
|
+
}
|
|
450
|
+
if (!enqueueBatchedSignal(state)) {
|
|
451
|
+
notifySubscribers(state);
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
} else if (_isDev3) {
|
|
455
|
+
set = (next) => {
|
|
456
|
+
const prev = state.value;
|
|
457
|
+
const newValue = typeof next === "function" ? next(prev) : next;
|
|
458
|
+
if (Object.is(newValue, prev)) return;
|
|
459
|
+
state.value = newValue;
|
|
460
|
+
state.__v++;
|
|
407
461
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
408
|
-
if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue, newValue });
|
|
409
|
-
|
|
462
|
+
if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue: prev, newValue });
|
|
463
|
+
if (!enqueueBatchedSignal(state)) {
|
|
464
|
+
notifySubscribers(state);
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
} else {
|
|
468
|
+
set = (next) => {
|
|
469
|
+
const prev = state.value;
|
|
470
|
+
const newValue = typeof next === "function" ? next(prev) : next;
|
|
471
|
+
if (Object.is(newValue, prev)) return;
|
|
410
472
|
state.value = newValue;
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
473
|
+
state.__v++;
|
|
474
|
+
if (!enqueueBatchedSignal(state)) {
|
|
475
|
+
notifySubscribers(state);
|
|
476
|
+
}
|
|
477
|
+
};
|
|
415
478
|
}
|
|
416
479
|
if (_isDev3) {
|
|
417
480
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
@@ -466,92 +529,122 @@ function isSSR() {
|
|
|
466
529
|
|
|
467
530
|
// src/core/signals/effect.ts
|
|
468
531
|
var _g2 = globalThis;
|
|
532
|
+
var MAX_RERUNS = 100;
|
|
533
|
+
function flushUserCleanups(ctx) {
|
|
534
|
+
const list = ctx.userCleanups;
|
|
535
|
+
if (list.length === 0) return;
|
|
536
|
+
ctx.userCleanups = [];
|
|
537
|
+
for (let i = list.length - 1; i >= 0; i--) {
|
|
538
|
+
try {
|
|
539
|
+
list[i]();
|
|
540
|
+
} catch (err) {
|
|
541
|
+
if (typeof console !== "undefined") console.warn("[SibuJS effect] onCleanup threw:", err);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
function drainReruns(ctx) {
|
|
546
|
+
let reruns = 1;
|
|
547
|
+
do {
|
|
548
|
+
ctx.rerunPending = false;
|
|
549
|
+
if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
|
|
550
|
+
retrack(ctx.bodyFn, ctx.subscriber);
|
|
551
|
+
} while (ctx.rerunPending && ++reruns <= MAX_RERUNS);
|
|
552
|
+
if (ctx.rerunPending) {
|
|
553
|
+
ctx.rerunPending = false;
|
|
554
|
+
if (_g2.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
|
|
555
|
+
console.error(
|
|
556
|
+
`[SibuJS] effect re-requested itself ${MAX_RERUNS}+ times \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
function disposeEffect(ctx) {
|
|
562
|
+
if (ctx.disposed) return;
|
|
563
|
+
ctx.disposed = true;
|
|
564
|
+
const h = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
565
|
+
if (h) {
|
|
566
|
+
try {
|
|
567
|
+
h.emit("effect:destroy", { effectFn: ctx.fn });
|
|
568
|
+
} catch {
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
try {
|
|
572
|
+
if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
|
|
573
|
+
} catch (err) {
|
|
574
|
+
if (typeof console !== "undefined") {
|
|
575
|
+
console.warn("[SibuJS effect] onCleanup threw during dispose:", err);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
try {
|
|
579
|
+
cleanup(ctx.subscriber);
|
|
580
|
+
} catch (err) {
|
|
581
|
+
if (typeof console !== "undefined") {
|
|
582
|
+
console.warn("[SibuJS effect] dispose threw:", err);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
}
|
|
469
586
|
function effect(effectFn, options) {
|
|
470
587
|
devAssert(typeof effectFn === "function", "effect: argument must be a function.");
|
|
471
588
|
if (isSSR()) return () => {
|
|
472
589
|
};
|
|
473
|
-
const
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
userCleanups
|
|
590
|
+
const ctx = {
|
|
591
|
+
fn: effectFn,
|
|
592
|
+
onError: options?.onError,
|
|
593
|
+
userCleanups: [],
|
|
594
|
+
running: false,
|
|
595
|
+
rerunPending: false,
|
|
596
|
+
disposed: false,
|
|
597
|
+
onCleanup: null,
|
|
598
|
+
subscriber: null,
|
|
599
|
+
bodyFn: null
|
|
477
600
|
};
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
const list = userCleanups;
|
|
481
|
-
userCleanups = [];
|
|
482
|
-
for (let i = list.length - 1; i >= 0; i--) {
|
|
483
|
-
try {
|
|
484
|
-
list[i]();
|
|
485
|
-
} catch (err) {
|
|
486
|
-
if (typeof console !== "undefined") {
|
|
487
|
-
console.warn("[SibuJS effect] onCleanup threw:", err);
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
}
|
|
601
|
+
ctx.onCleanup = (fn) => {
|
|
602
|
+
ctx.userCleanups.push(fn);
|
|
491
603
|
};
|
|
492
|
-
const
|
|
493
|
-
|
|
604
|
+
const onErrorCaptured = ctx.onError;
|
|
605
|
+
ctx.bodyFn = onErrorCaptured ? () => {
|
|
494
606
|
try {
|
|
495
|
-
|
|
607
|
+
ctx.fn(ctx.onCleanup);
|
|
496
608
|
} catch (err) {
|
|
497
|
-
|
|
609
|
+
onErrorCaptured(err);
|
|
498
610
|
}
|
|
499
|
-
} :
|
|
500
|
-
|
|
611
|
+
} : () => {
|
|
612
|
+
ctx.fn(ctx.onCleanup);
|
|
501
613
|
};
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
if (_g2.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
|
|
506
|
-
console.warn(
|
|
507
|
-
"[SibuJS] effect re-entered itself while running \u2014 the triggering update will be ignored. Wrap mutual writes in `batch()` or split the effect to avoid this."
|
|
508
|
-
);
|
|
509
|
-
}
|
|
614
|
+
const sub = (() => {
|
|
615
|
+
if (ctx.running) {
|
|
616
|
+
ctx.rerunPending = true;
|
|
510
617
|
return;
|
|
511
618
|
}
|
|
512
|
-
running = true;
|
|
619
|
+
ctx.running = true;
|
|
513
620
|
try {
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
621
|
+
ctx.rerunPending = false;
|
|
622
|
+
if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
|
|
623
|
+
retrack(ctx.bodyFn, sub);
|
|
624
|
+
if (ctx.rerunPending) drainReruns(ctx);
|
|
517
625
|
} finally {
|
|
518
|
-
running = false;
|
|
626
|
+
ctx.running = false;
|
|
627
|
+
ctx.rerunPending = false;
|
|
519
628
|
}
|
|
520
|
-
};
|
|
521
|
-
|
|
629
|
+
});
|
|
630
|
+
sub.depsHead = null;
|
|
631
|
+
sub.depsTail = null;
|
|
632
|
+
sub._epoch = 0;
|
|
633
|
+
sub._structDirty = false;
|
|
634
|
+
sub._runEpoch = 0;
|
|
635
|
+
sub._runs = 0;
|
|
636
|
+
ctx.subscriber = sub;
|
|
637
|
+
ctx.running = true;
|
|
522
638
|
try {
|
|
523
|
-
|
|
639
|
+
retrack(ctx.bodyFn, ctx.subscriber);
|
|
640
|
+
if (ctx.rerunPending) drainReruns(ctx);
|
|
524
641
|
} finally {
|
|
525
|
-
running = false;
|
|
642
|
+
ctx.running = false;
|
|
643
|
+
ctx.rerunPending = false;
|
|
526
644
|
}
|
|
527
645
|
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
528
646
|
if (hook) hook.emit("effect:create", { effectFn });
|
|
529
|
-
|
|
530
|
-
return () => {
|
|
531
|
-
if (disposed) return;
|
|
532
|
-
disposed = true;
|
|
533
|
-
const h = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
534
|
-
if (h) {
|
|
535
|
-
try {
|
|
536
|
-
h.emit("effect:destroy", { effectFn });
|
|
537
|
-
} catch {
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
try {
|
|
541
|
-
runUserCleanups();
|
|
542
|
-
} catch (err) {
|
|
543
|
-
if (typeof console !== "undefined") {
|
|
544
|
-
console.warn("[SibuJS effect] onCleanup threw during dispose:", err);
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
try {
|
|
548
|
-
cleanupHandle();
|
|
549
|
-
} catch (err) {
|
|
550
|
-
if (typeof console !== "undefined") {
|
|
551
|
-
console.warn("[SibuJS effect] dispose threw:", err);
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
};
|
|
647
|
+
return () => disposeEffect(ctx);
|
|
555
648
|
}
|
|
556
649
|
|
|
557
650
|
// src/browser/resize.ts
|