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/ecosystem.cjs
CHANGED
|
@@ -49,11 +49,88 @@ function devWarn(message) {
|
|
|
49
49
|
|
|
50
50
|
// src/reactivity/track.ts
|
|
51
51
|
var _isDev2 = isDev();
|
|
52
|
-
var
|
|
53
|
-
var
|
|
54
|
-
|
|
52
|
+
var POOL_MAX = 4096;
|
|
53
|
+
var nodePool = [];
|
|
54
|
+
function createNode() {
|
|
55
|
+
return {
|
|
56
|
+
sig: null,
|
|
57
|
+
sub: null,
|
|
58
|
+
epoch: 0,
|
|
59
|
+
sigPrev: null,
|
|
60
|
+
sigNext: null,
|
|
61
|
+
subPrev: null,
|
|
62
|
+
subNext: null,
|
|
63
|
+
prevActive: null
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function allocNode(sig, sub, epoch) {
|
|
67
|
+
const n = nodePool.pop();
|
|
68
|
+
if (n) {
|
|
69
|
+
n.sig = sig;
|
|
70
|
+
n.sub = sub;
|
|
71
|
+
n.epoch = epoch;
|
|
72
|
+
return n;
|
|
73
|
+
}
|
|
74
|
+
const fresh = createNode();
|
|
75
|
+
fresh.sig = sig;
|
|
76
|
+
fresh.sub = sub;
|
|
77
|
+
fresh.epoch = epoch;
|
|
78
|
+
return fresh;
|
|
79
|
+
}
|
|
80
|
+
function freeNode(node) {
|
|
81
|
+
node.sig = null;
|
|
82
|
+
node.sub = null;
|
|
83
|
+
node.sigPrev = null;
|
|
84
|
+
node.sigNext = null;
|
|
85
|
+
node.subPrev = null;
|
|
86
|
+
node.subNext = null;
|
|
87
|
+
node.prevActive = null;
|
|
88
|
+
if (nodePool.length < POOL_MAX) nodePool.push(node);
|
|
89
|
+
}
|
|
90
|
+
function linkSignal(sig, node) {
|
|
91
|
+
const oldHead = sig.subsHead ?? null;
|
|
92
|
+
node.sigPrev = null;
|
|
93
|
+
node.sigNext = oldHead;
|
|
94
|
+
if (oldHead) oldHead.sigPrev = node;
|
|
95
|
+
else sig.subsTail = node;
|
|
96
|
+
sig.subsHead = node;
|
|
97
|
+
sig.__sc = (sig.__sc ?? 0) + 1;
|
|
98
|
+
}
|
|
99
|
+
function unlinkSignal(node) {
|
|
100
|
+
const sig = node.sig;
|
|
101
|
+
if (!sig) return;
|
|
102
|
+
const prev = node.sigPrev;
|
|
103
|
+
const next = node.sigNext;
|
|
104
|
+
if (prev) prev.sigNext = next;
|
|
105
|
+
else sig.subsHead = next;
|
|
106
|
+
if (next) next.sigPrev = prev;
|
|
107
|
+
else sig.subsTail = prev;
|
|
108
|
+
sig.__sc = (sig.__sc ?? 1) - 1;
|
|
109
|
+
if (sig.__activeNode === node) sig.__activeNode = node.prevActive;
|
|
110
|
+
if (sig.__sc === 0) {
|
|
111
|
+
sig.subsHead = null;
|
|
112
|
+
sig.subsTail = null;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function linkSub(sub, node) {
|
|
116
|
+
const oldTail = sub.depsTail ?? null;
|
|
117
|
+
node.subPrev = oldTail;
|
|
118
|
+
node.subNext = null;
|
|
119
|
+
if (oldTail) oldTail.subNext = node;
|
|
120
|
+
else sub.depsHead = node;
|
|
121
|
+
sub.depsTail = node;
|
|
122
|
+
}
|
|
123
|
+
function unlinkSub(node) {
|
|
124
|
+
const sub = node.sub;
|
|
125
|
+
if (!sub) return;
|
|
126
|
+
const prev = node.subPrev;
|
|
127
|
+
const next = node.subNext;
|
|
128
|
+
if (prev) prev.subNext = next;
|
|
129
|
+
else sub.depsHead = next;
|
|
130
|
+
if (next) next.subPrev = prev;
|
|
131
|
+
else sub.depsTail = prev;
|
|
132
|
+
}
|
|
55
133
|
var currentSubscriber = null;
|
|
56
|
-
var SUBS = "__s";
|
|
57
134
|
var notifyDepth = 0;
|
|
58
135
|
var pendingQueue = [];
|
|
59
136
|
var pendingSet = /* @__PURE__ */ new Set();
|
|
@@ -66,92 +143,136 @@ function safeInvoke(sub) {
|
|
|
66
143
|
}
|
|
67
144
|
}
|
|
68
145
|
var trackingSuspended = false;
|
|
146
|
+
var subscriberEpochCounter = 0;
|
|
69
147
|
function retrack(effectFn, subscriber) {
|
|
70
148
|
const prev = currentSubscriber;
|
|
71
149
|
currentSubscriber = subscriber;
|
|
150
|
+
const sub = subscriber;
|
|
151
|
+
const epoch = ++subscriberEpochCounter;
|
|
152
|
+
sub._epoch = epoch;
|
|
153
|
+
sub._structDirty = false;
|
|
154
|
+
for (let n = sub.depsHead ?? null; n !== null; n = n.subNext) {
|
|
155
|
+
const sig = n.sig;
|
|
156
|
+
n.prevActive = sig.__activeNode ?? null;
|
|
157
|
+
sig.__activeNode = n;
|
|
158
|
+
}
|
|
72
159
|
try {
|
|
73
160
|
effectFn();
|
|
74
161
|
} finally {
|
|
75
162
|
currentSubscriber = prev;
|
|
163
|
+
let node = sub.depsHead ?? null;
|
|
164
|
+
while (node !== null) {
|
|
165
|
+
const next = node.subNext;
|
|
166
|
+
const sig = node.sig;
|
|
167
|
+
sig.__activeNode = node.prevActive;
|
|
168
|
+
node.prevActive = null;
|
|
169
|
+
if (node.epoch !== epoch) {
|
|
170
|
+
unlinkSub(node);
|
|
171
|
+
unlinkSignal(node);
|
|
172
|
+
freeNode(node);
|
|
173
|
+
}
|
|
174
|
+
node = next;
|
|
175
|
+
}
|
|
76
176
|
}
|
|
77
177
|
}
|
|
78
178
|
function track(effectFn, subscriber) {
|
|
79
179
|
if (!subscriber) subscriber = effectFn;
|
|
80
180
|
cleanup(subscriber);
|
|
81
|
-
|
|
82
|
-
if (stackTop >= stackCapacity) {
|
|
83
|
-
stackCapacity *= 2;
|
|
84
|
-
subscriberStack.length = stackCapacity;
|
|
85
|
-
}
|
|
86
|
-
subscriberStack[stackTop] = subscriber;
|
|
181
|
+
const prev = currentSubscriber;
|
|
87
182
|
currentSubscriber = subscriber;
|
|
88
183
|
try {
|
|
89
184
|
effectFn();
|
|
90
185
|
} finally {
|
|
91
|
-
|
|
92
|
-
|
|
186
|
+
currentSubscriber = prev;
|
|
187
|
+
const sub2 = subscriber;
|
|
188
|
+
for (let n = sub2.depsHead ?? null; n !== null; n = n.subNext) {
|
|
189
|
+
const sig = n.sig;
|
|
190
|
+
sig.__activeNode = n.prevActive;
|
|
191
|
+
n.prevActive = null;
|
|
192
|
+
}
|
|
93
193
|
}
|
|
94
|
-
|
|
194
|
+
const sub = subscriber;
|
|
195
|
+
return sub._dispose ?? (sub._dispose = () => cleanup(subscriber));
|
|
95
196
|
}
|
|
96
197
|
function recordDependency(signal2) {
|
|
97
198
|
if (!currentSubscriber) return;
|
|
98
199
|
const sub = currentSubscriber;
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const set = /* @__PURE__ */ new Set();
|
|
106
|
-
set.add(sub._dep);
|
|
107
|
-
set.add(signal2);
|
|
108
|
-
sub._deps = set;
|
|
109
|
-
sub._dep = void 0;
|
|
110
|
-
} else {
|
|
111
|
-
sub._dep = signal2;
|
|
200
|
+
const sig = signal2;
|
|
201
|
+
const epoch = sub._epoch ?? 0;
|
|
202
|
+
const active = sig.__activeNode ?? null;
|
|
203
|
+
if (active !== null && active.sub === sub) {
|
|
204
|
+
active.epoch = epoch;
|
|
205
|
+
return;
|
|
112
206
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
207
|
+
const node = allocNode(signal2, sub, epoch);
|
|
208
|
+
node.prevActive = active;
|
|
209
|
+
sig.__activeNode = node;
|
|
210
|
+
linkSub(sub, node);
|
|
211
|
+
linkSignal(sig, node);
|
|
212
|
+
sub._structDirty = true;
|
|
213
|
+
}
|
|
214
|
+
function cleanup(subscriber) {
|
|
215
|
+
const sub = subscriber;
|
|
216
|
+
let node = sub.depsHead ?? null;
|
|
217
|
+
sub.depsHead = null;
|
|
218
|
+
sub.depsTail = null;
|
|
219
|
+
while (node) {
|
|
220
|
+
const next = node.subNext;
|
|
221
|
+
unlinkSignal(node);
|
|
222
|
+
freeNode(node);
|
|
223
|
+
node = next;
|
|
117
224
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
225
|
+
}
|
|
226
|
+
var maxSubscriberRepeats = 50;
|
|
227
|
+
var maxDrainIterations = 1e6;
|
|
228
|
+
var drainEpoch = 0;
|
|
229
|
+
function tickRepeat(sub) {
|
|
230
|
+
const s = sub;
|
|
231
|
+
if (s._runEpoch !== drainEpoch) {
|
|
232
|
+
s._runEpoch = drainEpoch;
|
|
233
|
+
s._runs = 1;
|
|
234
|
+
return false;
|
|
123
235
|
}
|
|
236
|
+
s._runs = (s._runs ?? 0) + 1;
|
|
237
|
+
return s._runs > maxSubscriberRepeats;
|
|
124
238
|
}
|
|
125
|
-
function
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
239
|
+
function cycleError(sub) {
|
|
240
|
+
if (typeof console !== "undefined") {
|
|
241
|
+
const name = sub.__name ?? "<unnamed>";
|
|
242
|
+
console.error(
|
|
243
|
+
`[SibuJS] subscriber "${name}" fired more than ${maxSubscriberRepeats} times \u2014 likely a write-reads-self cycle between effects/signals. Breaking to prevent infinite loop.`
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
function absoluteDrainError() {
|
|
248
|
+
if (typeof console !== "undefined") {
|
|
249
|
+
console.error(
|
|
250
|
+
`[SibuJS] Notification drain exceeded ${maxDrainIterations} iterations \u2014 absolute safety net tripped. Breaking to prevent infinite loop.`
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
function drainQueue() {
|
|
255
|
+
let i = 0;
|
|
256
|
+
while (i < pendingQueue.length) {
|
|
257
|
+
if (i >= maxDrainIterations) {
|
|
258
|
+
absoluteDrainError();
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
const sub = pendingQueue[i++];
|
|
262
|
+
if (tickRepeat(sub)) {
|
|
263
|
+
cycleError(sub);
|
|
264
|
+
break;
|
|
134
265
|
}
|
|
266
|
+
pendingSet.delete(sub);
|
|
267
|
+
safeInvoke(sub);
|
|
135
268
|
}
|
|
136
269
|
}
|
|
137
|
-
var maxDrainIterations = 1e5;
|
|
138
270
|
function drainNotificationQueue() {
|
|
139
271
|
if (notifyDepth > 0) return;
|
|
140
272
|
notifyDepth++;
|
|
273
|
+
drainEpoch++;
|
|
141
274
|
try {
|
|
142
|
-
|
|
143
|
-
while (i < pendingQueue.length) {
|
|
144
|
-
if (i >= maxDrainIterations) {
|
|
145
|
-
if (typeof console !== "undefined") {
|
|
146
|
-
console.error(
|
|
147
|
-
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
break;
|
|
151
|
-
}
|
|
152
|
-
safeInvoke(pendingQueue[i]);
|
|
153
|
-
i++;
|
|
154
|
-
}
|
|
275
|
+
drainQueue();
|
|
155
276
|
} finally {
|
|
156
277
|
notifyDepth--;
|
|
157
278
|
if (notifyDepth === 0) {
|
|
@@ -169,131 +290,82 @@ function propagateDirty(sub) {
|
|
|
169
290
|
stack.push(rootSig);
|
|
170
291
|
while (stack.length > baseLen) {
|
|
171
292
|
const sig = stack.pop();
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
if (
|
|
177
|
-
nSig
|
|
178
|
-
|
|
293
|
+
let node = sig.subsHead ?? null;
|
|
294
|
+
while (node) {
|
|
295
|
+
const s = node.sub;
|
|
296
|
+
if (s) {
|
|
297
|
+
if (s._c) {
|
|
298
|
+
const nSig = s._sig;
|
|
299
|
+
if (nSig) {
|
|
300
|
+
if (!nSig._d) {
|
|
301
|
+
nSig._d = true;
|
|
302
|
+
stack.push(nSig);
|
|
303
|
+
}
|
|
304
|
+
} else {
|
|
305
|
+
s();
|
|
306
|
+
}
|
|
307
|
+
} else if (!pendingSet.has(s)) {
|
|
308
|
+
pendingSet.add(s);
|
|
309
|
+
pendingQueue.push(s);
|
|
179
310
|
}
|
|
180
|
-
} else if (!pendingSet.has(first)) {
|
|
181
|
-
pendingSet.add(first);
|
|
182
|
-
pendingQueue.push(first);
|
|
183
311
|
}
|
|
184
|
-
|
|
312
|
+
node = node.sigNext;
|
|
185
313
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
function queueSignalNotification(signal2) {
|
|
317
|
+
const sig = signal2;
|
|
318
|
+
let node = sig.subsHead ?? null;
|
|
319
|
+
while (node) {
|
|
320
|
+
const s = node.sub;
|
|
321
|
+
if (s) {
|
|
189
322
|
if (s._c) {
|
|
190
|
-
|
|
191
|
-
if (nSig && !nSig._d) {
|
|
192
|
-
nSig._d = true;
|
|
193
|
-
stack.push(nSig);
|
|
194
|
-
} else if (!nSig) {
|
|
195
|
-
s();
|
|
196
|
-
}
|
|
323
|
+
propagateDirty(s);
|
|
197
324
|
} else if (!pendingSet.has(s)) {
|
|
198
325
|
pendingSet.add(s);
|
|
199
326
|
pendingQueue.push(s);
|
|
200
327
|
}
|
|
201
328
|
}
|
|
329
|
+
node = node.sigNext;
|
|
202
330
|
}
|
|
203
331
|
}
|
|
204
332
|
function notifySubscribers(signal2) {
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
if (first._c) {
|
|
209
|
-
propagateDirty(first);
|
|
210
|
-
} else if (!pendingSet.has(first)) {
|
|
211
|
-
pendingSet.add(first);
|
|
212
|
-
pendingQueue.push(first);
|
|
213
|
-
}
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
notifyDepth++;
|
|
217
|
-
try {
|
|
218
|
-
if (first._c) {
|
|
219
|
-
propagateDirty(first);
|
|
220
|
-
} else {
|
|
221
|
-
safeInvoke(first);
|
|
222
|
-
}
|
|
223
|
-
let i = 0;
|
|
224
|
-
while (i < pendingQueue.length) {
|
|
225
|
-
if (i >= maxDrainIterations) {
|
|
226
|
-
if (typeof console !== "undefined") {
|
|
227
|
-
console.error(
|
|
228
|
-
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
229
|
-
);
|
|
230
|
-
}
|
|
231
|
-
break;
|
|
232
|
-
}
|
|
233
|
-
safeInvoke(pendingQueue[i]);
|
|
234
|
-
i++;
|
|
235
|
-
}
|
|
236
|
-
} finally {
|
|
237
|
-
notifyDepth--;
|
|
238
|
-
if (notifyDepth === 0) {
|
|
239
|
-
pendingQueue.length = 0;
|
|
240
|
-
pendingSet.clear();
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
const subs = signal2[SUBS];
|
|
246
|
-
if (!subs || subs.size === 0) return;
|
|
333
|
+
const sig = signal2;
|
|
334
|
+
const head = sig.subsHead;
|
|
335
|
+
if (!head) return;
|
|
247
336
|
if (notifyDepth > 0) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
337
|
+
let node = head;
|
|
338
|
+
while (node) {
|
|
339
|
+
const s = node.sub;
|
|
340
|
+
if (s) {
|
|
341
|
+
if (s._c) {
|
|
342
|
+
propagateDirty(s);
|
|
343
|
+
} else if (!pendingSet.has(s)) {
|
|
344
|
+
pendingSet.add(s);
|
|
345
|
+
pendingQueue.push(s);
|
|
346
|
+
}
|
|
254
347
|
}
|
|
348
|
+
node = node.sigNext;
|
|
255
349
|
}
|
|
256
350
|
return;
|
|
257
351
|
}
|
|
258
352
|
notifyDepth++;
|
|
353
|
+
drainEpoch++;
|
|
259
354
|
try {
|
|
260
|
-
let
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
if (
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
}
|
|
270
|
-
} else {
|
|
271
|
-
for (let i2 = 0; i2 < directCount; i2++) {
|
|
272
|
-
if (pendingQueue[i2]._c) {
|
|
273
|
-
propagateDirty(pendingQueue[i2]);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
for (let i2 = 0; i2 < directCount; i2++) {
|
|
277
|
-
const sub = pendingQueue[i2];
|
|
278
|
-
if (!sub._c && !pendingSet.has(sub)) {
|
|
279
|
-
pendingSet.add(sub);
|
|
280
|
-
safeInvoke(sub);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
let i = directCount;
|
|
285
|
-
while (i < pendingQueue.length) {
|
|
286
|
-
if (i - directCount >= maxDrainIterations) {
|
|
287
|
-
if (typeof console !== "undefined") {
|
|
288
|
-
console.error(
|
|
289
|
-
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
290
|
-
);
|
|
355
|
+
let node = head;
|
|
356
|
+
while (node) {
|
|
357
|
+
const s = node.sub;
|
|
358
|
+
if (s) {
|
|
359
|
+
if (s._c) {
|
|
360
|
+
propagateDirty(s);
|
|
361
|
+
} else if (!pendingSet.has(s)) {
|
|
362
|
+
pendingSet.add(s);
|
|
363
|
+
pendingQueue.push(s);
|
|
291
364
|
}
|
|
292
|
-
break;
|
|
293
365
|
}
|
|
294
|
-
|
|
295
|
-
i++;
|
|
366
|
+
node = node.sigNext;
|
|
296
367
|
}
|
|
368
|
+
drainQueue();
|
|
297
369
|
} finally {
|
|
298
370
|
notifyDepth--;
|
|
299
371
|
if (notifyDepth === 0) {
|
|
@@ -302,37 +374,6 @@ function notifySubscribers(signal2) {
|
|
|
302
374
|
}
|
|
303
375
|
}
|
|
304
376
|
}
|
|
305
|
-
function cleanup(subscriber) {
|
|
306
|
-
const sub = subscriber;
|
|
307
|
-
const singleDep = sub._dep;
|
|
308
|
-
if (singleDep !== void 0) {
|
|
309
|
-
const subs = singleDep[SUBS];
|
|
310
|
-
if (subs) {
|
|
311
|
-
subs.delete(subscriber);
|
|
312
|
-
if (singleDep.__f === subscriber) {
|
|
313
|
-
singleDep.__f = subs.size === 1 ? subs.values().next().value : void 0;
|
|
314
|
-
} else if (subs.size === 1 && singleDep.__f === void 0) {
|
|
315
|
-
singleDep.__f = subs.values().next().value;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
sub._dep = void 0;
|
|
319
|
-
return;
|
|
320
|
-
}
|
|
321
|
-
const deps = sub._deps;
|
|
322
|
-
if (!deps || deps.size === 0) return;
|
|
323
|
-
for (const signal2 of deps) {
|
|
324
|
-
const subs = signal2[SUBS];
|
|
325
|
-
if (subs) {
|
|
326
|
-
subs.delete(subscriber);
|
|
327
|
-
if (signal2.__f === subscriber) {
|
|
328
|
-
signal2.__f = subs.size === 1 ? subs.values().next().value : void 0;
|
|
329
|
-
} else if (subs.size === 1 && signal2.__f === void 0) {
|
|
330
|
-
signal2.__f = subs.values().next().value;
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
deps.clear();
|
|
335
|
-
}
|
|
336
377
|
|
|
337
378
|
// src/core/ssr-context.ts
|
|
338
379
|
var als = null;
|
|
@@ -361,92 +402,122 @@ function isSSR() {
|
|
|
361
402
|
|
|
362
403
|
// src/core/signals/effect.ts
|
|
363
404
|
var _g = globalThis;
|
|
405
|
+
var MAX_RERUNS = 100;
|
|
406
|
+
function flushUserCleanups(ctx) {
|
|
407
|
+
const list = ctx.userCleanups;
|
|
408
|
+
if (list.length === 0) return;
|
|
409
|
+
ctx.userCleanups = [];
|
|
410
|
+
for (let i = list.length - 1; i >= 0; i--) {
|
|
411
|
+
try {
|
|
412
|
+
list[i]();
|
|
413
|
+
} catch (err) {
|
|
414
|
+
if (typeof console !== "undefined") console.warn("[SibuJS effect] onCleanup threw:", err);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
function drainReruns(ctx) {
|
|
419
|
+
let reruns = 1;
|
|
420
|
+
do {
|
|
421
|
+
ctx.rerunPending = false;
|
|
422
|
+
if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
|
|
423
|
+
retrack(ctx.bodyFn, ctx.subscriber);
|
|
424
|
+
} while (ctx.rerunPending && ++reruns <= MAX_RERUNS);
|
|
425
|
+
if (ctx.rerunPending) {
|
|
426
|
+
ctx.rerunPending = false;
|
|
427
|
+
if (_g.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
|
|
428
|
+
console.error(
|
|
429
|
+
`[SibuJS] effect re-requested itself ${MAX_RERUNS}+ times \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
function disposeEffect(ctx) {
|
|
435
|
+
if (ctx.disposed) return;
|
|
436
|
+
ctx.disposed = true;
|
|
437
|
+
const h = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
438
|
+
if (h) {
|
|
439
|
+
try {
|
|
440
|
+
h.emit("effect:destroy", { effectFn: ctx.fn });
|
|
441
|
+
} catch {
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
try {
|
|
445
|
+
if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
|
|
446
|
+
} catch (err) {
|
|
447
|
+
if (typeof console !== "undefined") {
|
|
448
|
+
console.warn("[SibuJS effect] onCleanup threw during dispose:", err);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
try {
|
|
452
|
+
cleanup(ctx.subscriber);
|
|
453
|
+
} catch (err) {
|
|
454
|
+
if (typeof console !== "undefined") {
|
|
455
|
+
console.warn("[SibuJS effect] dispose threw:", err);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
364
459
|
function effect(effectFn, options) {
|
|
365
460
|
devAssert(typeof effectFn === "function", "effect: argument must be a function.");
|
|
366
461
|
if (isSSR()) return () => {
|
|
367
462
|
};
|
|
368
|
-
const
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
userCleanups
|
|
463
|
+
const ctx = {
|
|
464
|
+
fn: effectFn,
|
|
465
|
+
onError: options?.onError,
|
|
466
|
+
userCleanups: [],
|
|
467
|
+
running: false,
|
|
468
|
+
rerunPending: false,
|
|
469
|
+
disposed: false,
|
|
470
|
+
onCleanup: null,
|
|
471
|
+
subscriber: null,
|
|
472
|
+
bodyFn: null
|
|
372
473
|
};
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
const list = userCleanups;
|
|
376
|
-
userCleanups = [];
|
|
377
|
-
for (let i = list.length - 1; i >= 0; i--) {
|
|
378
|
-
try {
|
|
379
|
-
list[i]();
|
|
380
|
-
} catch (err) {
|
|
381
|
-
if (typeof console !== "undefined") {
|
|
382
|
-
console.warn("[SibuJS effect] onCleanup threw:", err);
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
}
|
|
474
|
+
ctx.onCleanup = (fn) => {
|
|
475
|
+
ctx.userCleanups.push(fn);
|
|
386
476
|
};
|
|
387
|
-
const
|
|
388
|
-
|
|
477
|
+
const onErrorCaptured = ctx.onError;
|
|
478
|
+
ctx.bodyFn = onErrorCaptured ? () => {
|
|
389
479
|
try {
|
|
390
|
-
|
|
480
|
+
ctx.fn(ctx.onCleanup);
|
|
391
481
|
} catch (err) {
|
|
392
|
-
|
|
482
|
+
onErrorCaptured(err);
|
|
393
483
|
}
|
|
394
|
-
} :
|
|
395
|
-
|
|
484
|
+
} : () => {
|
|
485
|
+
ctx.fn(ctx.onCleanup);
|
|
396
486
|
};
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
if (_g.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
|
|
401
|
-
console.warn(
|
|
402
|
-
"[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."
|
|
403
|
-
);
|
|
404
|
-
}
|
|
487
|
+
const sub = (() => {
|
|
488
|
+
if (ctx.running) {
|
|
489
|
+
ctx.rerunPending = true;
|
|
405
490
|
return;
|
|
406
491
|
}
|
|
407
|
-
running = true;
|
|
492
|
+
ctx.running = true;
|
|
408
493
|
try {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
494
|
+
ctx.rerunPending = false;
|
|
495
|
+
if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
|
|
496
|
+
retrack(ctx.bodyFn, sub);
|
|
497
|
+
if (ctx.rerunPending) drainReruns(ctx);
|
|
412
498
|
} finally {
|
|
413
|
-
running = false;
|
|
499
|
+
ctx.running = false;
|
|
500
|
+
ctx.rerunPending = false;
|
|
414
501
|
}
|
|
415
|
-
};
|
|
416
|
-
|
|
502
|
+
});
|
|
503
|
+
sub.depsHead = null;
|
|
504
|
+
sub.depsTail = null;
|
|
505
|
+
sub._epoch = 0;
|
|
506
|
+
sub._structDirty = false;
|
|
507
|
+
sub._runEpoch = 0;
|
|
508
|
+
sub._runs = 0;
|
|
509
|
+
ctx.subscriber = sub;
|
|
510
|
+
ctx.running = true;
|
|
417
511
|
try {
|
|
418
|
-
|
|
512
|
+
retrack(ctx.bodyFn, ctx.subscriber);
|
|
513
|
+
if (ctx.rerunPending) drainReruns(ctx);
|
|
419
514
|
} finally {
|
|
420
|
-
running = false;
|
|
515
|
+
ctx.running = false;
|
|
516
|
+
ctx.rerunPending = false;
|
|
421
517
|
}
|
|
422
518
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
423
519
|
if (hook) hook.emit("effect:create", { effectFn });
|
|
424
|
-
|
|
425
|
-
return () => {
|
|
426
|
-
if (disposed) return;
|
|
427
|
-
disposed = true;
|
|
428
|
-
const h = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
429
|
-
if (h) {
|
|
430
|
-
try {
|
|
431
|
-
h.emit("effect:destroy", { effectFn });
|
|
432
|
-
} catch {
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
try {
|
|
436
|
-
runUserCleanups();
|
|
437
|
-
} catch (err) {
|
|
438
|
-
if (typeof console !== "undefined") {
|
|
439
|
-
console.warn("[SibuJS effect] onCleanup threw during dispose:", err);
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
try {
|
|
443
|
-
cleanupHandle();
|
|
444
|
-
} catch (err) {
|
|
445
|
-
if (typeof console !== "undefined") {
|
|
446
|
-
console.warn("[SibuJS effect] dispose threw:", err);
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
};
|
|
520
|
+
return () => disposeEffect(ctx);
|
|
450
521
|
}
|
|
451
522
|
|
|
452
523
|
// src/reactivity/batch.ts
|
|
@@ -483,32 +554,64 @@ function flushBatch() {
|
|
|
483
554
|
var _g2 = globalThis;
|
|
484
555
|
var _isDev3 = isDev();
|
|
485
556
|
function signal(initial, options) {
|
|
486
|
-
const state = {
|
|
557
|
+
const state = {
|
|
558
|
+
value: initial,
|
|
559
|
+
__v: 0,
|
|
560
|
+
__sc: 0,
|
|
561
|
+
subsHead: null,
|
|
562
|
+
subsTail: null,
|
|
563
|
+
__activeNode: null,
|
|
564
|
+
__name: void 0
|
|
565
|
+
};
|
|
487
566
|
const debugName = _isDev3 ? options?.name : void 0;
|
|
488
567
|
const equalsFn = options?.equals;
|
|
489
|
-
if (debugName)
|
|
490
|
-
state.__name = debugName;
|
|
491
|
-
}
|
|
568
|
+
if (debugName) state.__name = debugName;
|
|
492
569
|
function get() {
|
|
493
570
|
recordDependency(state);
|
|
494
571
|
return state.value;
|
|
495
572
|
}
|
|
496
573
|
get.__signal = state;
|
|
497
574
|
if (debugName) get.__name = debugName;
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
const
|
|
575
|
+
let set;
|
|
576
|
+
if (equalsFn) {
|
|
577
|
+
set = (next) => {
|
|
578
|
+
const prev = state.value;
|
|
579
|
+
const newValue = typeof next === "function" ? next(prev) : next;
|
|
580
|
+
if (equalsFn(prev, newValue)) return;
|
|
581
|
+
state.value = newValue;
|
|
582
|
+
state.__v++;
|
|
583
|
+
if (_isDev3) {
|
|
584
|
+
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
585
|
+
if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue: prev, newValue });
|
|
586
|
+
}
|
|
587
|
+
if (!enqueueBatchedSignal(state)) {
|
|
588
|
+
notifySubscribers(state);
|
|
589
|
+
}
|
|
590
|
+
};
|
|
591
|
+
} else if (_isDev3) {
|
|
592
|
+
set = (next) => {
|
|
593
|
+
const prev = state.value;
|
|
594
|
+
const newValue = typeof next === "function" ? next(prev) : next;
|
|
595
|
+
if (Object.is(newValue, prev)) return;
|
|
503
596
|
state.value = newValue;
|
|
597
|
+
state.__v++;
|
|
504
598
|
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
505
|
-
if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue, newValue });
|
|
506
|
-
|
|
599
|
+
if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue: prev, newValue });
|
|
600
|
+
if (!enqueueBatchedSignal(state)) {
|
|
601
|
+
notifySubscribers(state);
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
} else {
|
|
605
|
+
set = (next) => {
|
|
606
|
+
const prev = state.value;
|
|
607
|
+
const newValue = typeof next === "function" ? next(prev) : next;
|
|
608
|
+
if (Object.is(newValue, prev)) return;
|
|
507
609
|
state.value = newValue;
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
610
|
+
state.__v++;
|
|
611
|
+
if (!enqueueBatchedSignal(state)) {
|
|
612
|
+
notifySubscribers(state);
|
|
613
|
+
}
|
|
614
|
+
};
|
|
512
615
|
}
|
|
513
616
|
if (_isDev3) {
|
|
514
617
|
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
@@ -647,6 +750,7 @@ function derived(getter, options) {
|
|
|
647
750
|
const cs = {};
|
|
648
751
|
cs._d = false;
|
|
649
752
|
cs._g = getter;
|
|
753
|
+
cs.__v = 0;
|
|
650
754
|
const markDirty = () => {
|
|
651
755
|
if (cs._d) return;
|
|
652
756
|
cs._d = true;
|
|
@@ -676,11 +780,14 @@ function derived(getter, options) {
|
|
|
676
780
|
evaluating = true;
|
|
677
781
|
let threw = true;
|
|
678
782
|
try {
|
|
783
|
+
const prev = cs._v;
|
|
679
784
|
retrack(() => {
|
|
680
|
-
|
|
785
|
+
const next = getter();
|
|
786
|
+
cs._v = equals && cs._v !== void 0 ? equals(cs._v, next) ? cs._v : next : next;
|
|
681
787
|
cs._d = false;
|
|
682
788
|
threw = false;
|
|
683
789
|
}, markDirty);
|
|
790
|
+
if (!Object.is(prev, cs._v)) cs.__v++;
|
|
684
791
|
} finally {
|
|
685
792
|
evaluating = false;
|
|
686
793
|
if (threw) cs._d = true;
|
|
@@ -700,6 +807,7 @@ function derived(getter, options) {
|
|
|
700
807
|
cs._d = false;
|
|
701
808
|
threw = false;
|
|
702
809
|
}, markDirty);
|
|
810
|
+
if (!Object.is(oldValue, cs._v)) cs.__v++;
|
|
703
811
|
} finally {
|
|
704
812
|
evaluating = false;
|
|
705
813
|
if (threw) cs._d = true;
|