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