aoye 0.0.22 → 0.0.24

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/index.umd.js CHANGED
@@ -4,996 +4,654 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Aoye = {}, global.BobeShared));
5
5
  })(this, (function (exports, bobeShared) { 'use strict';
6
6
 
7
- const rawToProxy = /* @__PURE__ */new WeakMap();
8
- new bobeShared.BaseEvent();
9
- const G = {
10
- /** 原子 signal 更新次数 */
11
- version: 0,
12
- id: 0,
13
- /** scope 销毁任务序号 */
14
- scopeDisposeI: 0,
15
- PullingSignal: null,
16
- /** 表示当前处于 pull 递归中 */
17
- PullingRecurseDeep: 0
18
- };
19
- var State = /* @__PURE__ */(State2 => {
20
- State2[State2["Clean"] = 0] = "Clean";
21
- State2[State2["LinkScopeOnly"] = 256] = "LinkScopeOnly";
22
- State2[State2["ScopeAbort"] = 128] = "ScopeAbort";
23
- State2[State2["ScopeReady"] = 64] = "ScopeReady";
24
- State2[State2["IsScope"] = 32] = "IsScope";
25
- State2[State2["PullingDirty"] = 16] = "PullingDirty";
26
- State2[State2["PullingUnknown"] = 8] = "PullingUnknown";
27
- State2[State2["Unknown"] = 4] = "Unknown";
28
- State2[State2["Dirty"] = 2] = "Dirty";
29
- State2[State2["Pulling"] = 1] = "Pulling";
30
- return State2;
31
- })(State || {});
32
- const DirtyState = 4 /* Unknown */ | 2 /* Dirty */;
33
- const ScopeExecuted = 64 /* ScopeReady */ | 128 /* ScopeAbort */;
34
- const ScopeAbort = 128 /* ScopeAbort */;
7
+ let _execId = 0;
8
+ let currentExecId = 0;
9
+ const execIdInc = () => ++_execId;
10
+ const execId = () => currentExecId;
11
+ const setExecId = v => currentExecId = v;
12
+ let pulling = null;
13
+ const setPulling = v => pulling = v;
14
+ const getPulling = () => pulling;
15
+ function runWithPulling(fn, scope) {
16
+ const oldPulling = pulling;
17
+ pulling = scope;
18
+ const ret = fn();
19
+ pulling = oldPulling;
20
+ return ret;
21
+ }
35
22
 
36
- const leakI = (y, max) => y < 0 || y >= max ? null : y;
37
- const getLeft = (x, max) => leakI(x * 2 + 1, max);
38
- const getRight = (x, max) => leakI(x * 2 + 2, max);
39
- const getParent = (x, max) => leakI(x - 1 >>> 1, max);
40
- const exchange = (arr, i, j) => {
41
- var _ref = [arr[j], arr[i]];
42
- arr[i] = _ref[0];
43
- arr[j] = _ref[1];
44
- return _ref;
45
- };
46
- class PriorityQueue {
47
- // 构造函数接受一个compare函数
48
- // compare返回的-1, 0, 1决定元素是否优先被去除
49
- constructor(aIsUrgent) {
50
- this.aIsUrgent = aIsUrgent;
51
- this.arr = [];
52
- this.goUp = (arr, current, len) => {
53
- let i = len - 1;
54
- while (i > 0) {
55
- const item = arr[i];
56
- const pI = getParent(i, len);
57
- const parent = arr[pI];
58
- if (this.aIsUrgent(item, parent)) {
59
- exchange(arr, i, pI);
60
- i = pI;
61
- } else {
62
- break;
23
+ function mark(signal) {
24
+ let line = signal.emitHead;
25
+ while (line) {
26
+ const _line = line,
27
+ down = _line.down;
28
+ _line.up;
29
+ const scope = down.scope,
30
+ emitHead = down.emitHead,
31
+ state = down.state;
32
+ if (scope && scope.state & 128) ; else {
33
+ const notLocked = (state & 1) === 0;
34
+ down.state |= notLocked ? 2 : 16;
35
+ if (state & 32) {
36
+ if (notLocked && state & 512) {
37
+ addEffect(down);
63
38
  }
39
+ } else if (emitHead) {
40
+ markUnknownDeep(emitHead);
64
41
  }
65
- };
66
- this.goDown = (arr, i) => {
67
- const len = this.size();
68
- const half = len >>> 1;
69
- while (i < half) {
70
- const lI = getLeft(i, len);
71
- const rI = getRight(i, len);
72
- let point = i;
73
- if (lI != null && this.aIsUrgent(arr[lI], arr[point])) {
74
- point = lI;
75
- }
76
- if (rI != null && this.aIsUrgent(arr[rI], arr[point])) {
77
- point = rI;
78
- }
79
- if (point === i) {
80
- break;
42
+ }
43
+ line = line.nextEmitLine;
44
+ }
45
+ }
46
+ function markUnknownDeep(initialLine) {
47
+ const noPulling = !getPulling();
48
+ const stack = [initialLine];
49
+ let len = 1;
50
+ while (len > 0) {
51
+ let line = stack[--len];
52
+ stack[len] = null;
53
+ while (line) {
54
+ const _line2 = line,
55
+ down = _line2.down;
56
+ _line2.up;
57
+ const state = down.state,
58
+ scope = down.scope;
59
+ if (scope && scope.state & 128 || noPulling && state & 6) ; else {
60
+ const notLocked = (state & 1) === 0;
61
+ down.state |= notLocked ? 4 : 8;
62
+ if (state & 32) {
63
+ if (notLocked && state & 512) {
64
+ addEffect(down);
65
+ }
66
+ } else if (down.emitHead) {
67
+ stack[len++] = down.emitHead;
81
68
  }
82
- exchange(arr, i, point);
83
- i = point;
84
69
  }
85
- };
86
- }
87
- // 添加一个元素
88
- _add(current) {
89
- this.arr.push(current);
90
- const len = this.size();
91
- if (len === 1) {
92
- return;
70
+ line = line.nextEmitLine;
93
71
  }
94
- this.goUp(this.arr, current, len);
95
72
  }
96
- add(...items) {
97
- items.forEach(it => this._add(it));
98
- }
99
- // 去除头元素并返回
100
- poll() {
101
- const arr = this.arr;
102
- const len = this.size();
103
- if (len <= 2) {
104
- return arr.shift();
73
+ }
74
+ function pullDeep(root) {
75
+ let node = root,
76
+ top = null,
77
+ i = -1;
78
+ const lineStack = [];
79
+ do {
80
+ const _node = node,
81
+ state = _node.state,
82
+ scope = _node.scope;
83
+ let noSkipSelf = !(state & 193 || (state & 6) === 0 || scope && scope.state & 128);
84
+ const firstLine = node.recHead;
85
+ if (noSkipSelf) {
86
+ node.state |= 1;
87
+ if ((state & 2) === 0 && firstLine) {
88
+ node = firstLine.up;
89
+ lineStack[++i] = top;
90
+ top = firstLine;
91
+ continue;
92
+ }
105
93
  }
106
- const last = arr.pop();
107
- const first = arr[0];
108
- arr[0] = last;
109
- this.goDown(this.arr, 0);
110
- return first;
111
- }
112
- // 取得头元素
113
- peek() {
114
- return this.arr[0];
115
- }
116
- // 取得元素数量
117
- size() {
118
- return this.arr.length;
119
- }
120
- logTree() {
121
- const arr = this.arr;
122
- let i = 0;
123
- let j = 1;
124
- let level = 0;
125
- const matrix = [];
126
94
  do {
127
- matrix.push(arr.slice(i, j));
128
- i = i * 2 + 1;
129
- j = i + Math.pow(2, level) + 1;
130
- level++;
131
- } while (i < arr.length);
132
- const last = Math.pow(2, matrix.length - 1);
133
- const arrStr = JSON.stringify(last);
134
- const halfLen = arrStr.length >>> 1;
135
- matrix.forEach(it => {
136
- const str = JSON.stringify(it);
137
- const halfIt = str.length >>> 1;
138
- console.log(str.padStart(halfLen + halfIt, " "));
139
- });
140
- console.log("\n");
141
- }
95
+ const _node2 = node,
96
+ state = _node2.state;
97
+ let noGoSibling = false;
98
+ if (noSkipSelf) {
99
+ if (state & 2) {
100
+ const prevValue = node.value;
101
+ const prevPulling = getPulling();
102
+ setPulling(node);
103
+ const value = node.get(false, false);
104
+ setPulling(prevPulling);
105
+ if (noGoSibling = value !== prevValue) {
106
+ let line = node.emitHead;
107
+ while (line) {
108
+ const _line3 = line,
109
+ down = _line3.down;
110
+ down.state &= -5;
111
+ down.state |= 2;
112
+ line = line.nextEmitLine;
113
+ }
114
+ }
115
+ } else {
116
+ transferDirtyState(node, state);
117
+ }
118
+ node.state &= -2;
119
+ }
120
+ if (node === root) {
121
+ return node.value;
122
+ }
123
+ if (!noGoSibling && top.nextRecLine) {
124
+ top = top.nextRecLine;
125
+ node = top.up;
126
+ break;
127
+ }
128
+ noSkipSelf = true;
129
+ node = top.down;
130
+ top = lineStack[i];
131
+ lineStack[i--] = null;
132
+ } while (true);
133
+ } while (true);
142
134
  }
143
-
144
- const DefaultTaskControlReturn = {
145
- finished: true,
146
- startNewCallbackAble: true
147
- };
148
- class TaskQueue {
149
- constructor(callbackAble, aIsUrgent) {
150
- this.callbackAble = callbackAble;
151
- this.aIsUrgent = aIsUrgent;
152
- this.isScheduling = false;
153
- }
154
- static create({
155
- callbackAble,
156
- aIsUrgent
157
- }) {
158
- const queue = new TaskQueue(callbackAble, aIsUrgent);
159
- queue.taskQueue = new PriorityQueue(aIsUrgent);
160
- return queue;
161
- }
162
- pushTask(task) {
163
- const taskQueue = this.taskQueue,
164
- isScheduling = this.isScheduling;
165
- taskQueue._add(task);
166
- if (!isScheduling) {
167
- this.callbackAble(this.scheduleTask.bind(this));
168
- this.isScheduling = true;
169
- }
135
+ function transferDirtyState(node, state) {
136
+ if (state & 8) {
137
+ node.state = state & -9 | 4;
138
+ } else {
139
+ node.state &= -5;
170
140
  }
171
- scheduleTask() {
172
- const taskQueue = this.taskQueue;
173
- const fn = taskQueue.peek();
174
- if (!fn) return this.isScheduling = false;
175
- let info = fn() || {};
176
- info = {
177
- ...DefaultTaskControlReturn,
178
- ...info
179
- };
180
- if (info.finished) {
181
- taskQueue.poll();
182
- if (taskQueue.size() === 0) {
183
- return this.isScheduling = false;
184
- }
185
- }
186
- if (info.startNewCallbackAble) {
187
- this.callbackAble(this.scheduleTask.bind(this));
188
- } else {
189
- this.scheduleTask();
190
- }
141
+ if (state & 16) {
142
+ node.state = state & -17 | 2;
143
+ } else {
144
+ node.state &= -3;
191
145
  }
192
146
  }
193
-
194
- var Keys = /* @__PURE__ */(Keys2 => {
195
- Keys2["Iterator"] = "__AOYE_ITERATOR";
196
- Keys2["Raw"] = "__AOYE_RAW";
197
- Keys2["Meta"] = "__AOYE_META";
198
- return Keys2;
199
- })(Keys || {});
200
- const IsStore = /* @__PURE__ */Symbol("__AOYE_IS_STORE"),
201
- StoreIgnoreKeys = /* @__PURE__ */Symbol("__AOYE_IGNORE_KEYS");
202
-
203
- let channel = globalThis.MessageChannel ? new MessageChannel() : null;
204
- if (globalThis.MessageChannel) {
205
- channel = new MessageChannel();
147
+ const effectQueue = [];
148
+ let consumeI = -1,
149
+ produceI = -1;
150
+ function addEffect(effect) {
151
+ effectQueue[++produceI] = effect;
206
152
  }
207
- let msgId = 0;
208
- const macro = fn => {
209
- if (!channel) {
210
- setTimeout(fn);
153
+ function flushEffect() {
154
+ if (consumeI !== -1) {
155
+ return;
211
156
  }
212
- const memoId = msgId;
213
- function onMessage(e) {
214
- if (memoId === e.data) {
215
- fn();
216
- channel.port2.removeEventListener("message", onMessage);
157
+ while (++consumeI <= produceI) {
158
+ const effect = effectQueue[consumeI];
159
+ if (effect.state | 6) {
160
+ effect.get();
217
161
  }
162
+ effectQueue[consumeI] = null;
218
163
  }
219
- channel.port2.addEventListener("message", onMessage);
220
- channel.port1.postMessage(msgId++);
221
- };
222
- const p = Promise.resolve();
223
- const micro = cb => {
224
- p.then(cb);
225
- };
226
- const toRaw = a => {
227
- if (typeof a === "object" && a !== null && a[Keys.Raw]) {
228
- return toRaw(a[Keys.Raw]);
164
+ consumeI = -1;
165
+ produceI = -1;
166
+ }
167
+ let _batchDeep = 0;
168
+ const batchStart = () => _batchDeep++;
169
+ const batchEnd = () => {
170
+ _batchDeep--;
171
+ if (_batchDeep === 0) {
172
+ flushEffect();
229
173
  }
230
- return a;
231
174
  };
232
-
233
- class Scheduler {
234
- constructor() {
235
- this.effectQueue = new bobeShared.Queue();
236
- /** 每当 Set 或 BatchSet 开始时标记 */
237
- this.firstEffectItem = null;
238
- /** 记录 Set 或 BatchSet 产生的最后一个 Effect */
239
- this.lastEffectItem = null;
240
- }
241
- static {
242
- this.Sync = "__Sync_";
243
- }
244
- static {
245
- this.Layout = "__Layout_";
246
- }
247
- static {
248
- this.Micro = "__Micro_";
249
- }
250
- static {
251
- this.Macro = "__Macro_";
175
+ const batchDeep = () => _batchDeep;
176
+ function unlink(line, deep) {
177
+ const nextEmitLine = line.nextEmitLine,
178
+ prevEmitLine = line.prevEmitLine,
179
+ nextRecLine = line.nextRecLine,
180
+ prevRecLine = line.prevRecLine,
181
+ up = line.up,
182
+ down = line.down,
183
+ prevOutLink = line.prevOutLink,
184
+ nextOutLink = line.nextOutLink;
185
+ const scope = down.scope;
186
+ if (prevEmitLine) {
187
+ prevEmitLine.nextEmitLine = nextEmitLine;
188
+ } else {
189
+ up.emitHead = nextEmitLine;
252
190
  }
253
- endSet() {
254
- if (!this.firstEffectItem) return;
255
- const subQueue = this.effectQueue.subRef(this.firstEffectItem, this.lastEffectItem);
256
- this.firstEffectItem = null;
257
- this.lastEffectItem = null;
258
- this.onOneSetEffectsAdded?.(subQueue, this.effectQueue);
191
+ if (nextEmitLine) {
192
+ nextEmitLine.prevEmitLine = prevEmitLine;
193
+ } else {
194
+ up.emitTail = prevEmitLine;
259
195
  }
260
- addEffect(effect) {
261
- const item = this.effectQueue.push(effect);
262
- this.onEffectAdded?.(effect, item, this.effectQueue);
263
- return item;
196
+ if (prevRecLine) {
197
+ prevRecLine.nextRecLine = nextRecLine;
198
+ } else {
199
+ down.recHead = nextRecLine;
264
200
  }
265
- }
266
- class SyncScheduler extends Scheduler {
267
- onOneSetEffectsAdded(subQueue, queue) {
268
- subQueue.forEach((effect, item) => {
269
- queue.delete(item);
270
- effect.runIfDirty();
271
- });
201
+ if (nextRecLine) {
202
+ nextRecLine.prevRecLine = prevRecLine;
203
+ } else {
204
+ down.recTail = prevRecLine;
205
+ }
206
+ if (prevOutLink) {
207
+ prevOutLink.nextOutLink = nextOutLink;
208
+ }
209
+ if (nextOutLink) {
210
+ nextOutLink.prevOutLink = prevOutLink;
211
+ }
212
+ if (scope && scope.outLink === line) {
213
+ scope.outLink = nextOutLink;
214
+ }
215
+ if (up.state & 32) {
216
+ up.dispose();
217
+ } else if (deep && !prevEmitLine && !nextEmitLine) {
218
+ let _ref = up,
219
+ line = _ref.recHead;
220
+ while (line) {
221
+ const next = line.nextRecLine;
222
+ unlink(line, true);
223
+ line = next;
224
+ }
272
225
  }
273
226
  }
274
- class MicroScheduler extends Scheduler {
275
- constructor() {
276
- super(...arguments);
277
- this.taskQueue = TaskQueue.create({
278
- callbackAble: micro,
279
- aIsUrgent: (a, b) => a.time < b.time
280
- });
281
- }
282
- onOneSetEffectsAdded(subQueue, queue) {
283
- const task = () => {
284
- subQueue.forEach((effect, item) => {
285
- queue.delete(item);
286
- effect.runIfDirty();
287
- });
288
- return {
289
- finished: true,
290
- startNewCallbackAble: false
291
- };
292
- };
293
- task.time = Date.now();
294
- this.taskQueue.pushTask(task);
227
+ function dispose() {
228
+ let toDel = this.recHead,
229
+ emitHead = this.emitHead;
230
+ while (toDel) {
231
+ const _toDel = toDel,
232
+ up = _toDel.up,
233
+ nextRecLine = _toDel.nextRecLine;
234
+ if ((up.state & 32) === 0) {
235
+ unlink(toDel, true);
236
+ toDel = nextRecLine;
237
+ continue;
238
+ }
239
+ let node = up,
240
+ top = null,
241
+ i = -1;
242
+ const lineStack = [];
243
+ outer: do {
244
+ let noSkipSelf = node.state & 32 && (node.state & 128) === 0;
245
+ const firstLine = node.recHead;
246
+ if (noSkipSelf && firstLine) {
247
+ node = firstLine.up;
248
+ lineStack[++i] = top;
249
+ top = firstLine;
250
+ continue;
251
+ }
252
+ do {
253
+ if (noSkipSelf) {
254
+ releaseScope(node);
255
+ }
256
+ if (node === up) {
257
+ break outer;
258
+ }
259
+ if (top.nextRecLine) {
260
+ top = top.nextRecLine;
261
+ node = top.up;
262
+ break;
263
+ }
264
+ noSkipSelf = true;
265
+ node = top.down;
266
+ top = lineStack[i];
267
+ lineStack[i--] = null;
268
+ } while (true);
269
+ } while (true);
270
+ toDel = nextRecLine;
295
271
  }
272
+ releaseScope(this);
273
+ if (emitHead) unlink(emitHead, false);
296
274
  }
297
- class MacroScheduler extends Scheduler {
298
- constructor() {
299
- super(...arguments);
300
- this.taskQueue = TaskQueue.create({
301
- callbackAble: macro,
302
- aIsUrgent: (a, b) => a.time < b.time
303
- });
304
- }
305
- onOneSetEffectsAdded(subQueue, queue) {
306
- const task = () => {
307
- subQueue.forEach((effect, item) => {
308
- queue.delete(item);
309
- effect.runIfDirty();
310
- });
311
- };
312
- task.time = Date.now();
313
- this.taskQueue.pushTask(task);
314
- }
275
+ function clean(onClean) {
276
+ const current = getPulling();
277
+ current.clean = onClean;
315
278
  }
316
- class LayoutScheduler extends Scheduler {
317
- constructor() {
318
- super(...arguments);
319
- this.taskQueue = TaskQueue.create({
320
- callbackAble: macro,
321
- aIsUrgent: (a, b) => a.time < b.time
322
- });
323
- }
324
- onOneSetEffectsAdded(subQueue, queue) {
325
- const task = () => {
326
- subQueue.forEach((effect, item) => {
327
- queue.delete(item);
328
- effect.runIfDirty();
329
- });
330
- };
331
- task.time = Date.now();
332
- this.taskQueue.pushTask(task);
279
+ function releaseScope(scope) {
280
+ let outLink = scope.outLink;
281
+ while (outLink) {
282
+ const next = outLink.nextOutLink;
283
+ unlink(outLink, true);
284
+ outLink = next;
333
285
  }
286
+ scope.state |= 128;
287
+ scope.clean?.();
288
+ scope.clean = null;
334
289
  }
335
- const _scheduler = {
336
- [Scheduler.Sync]: new SyncScheduler(),
337
- [Scheduler.Micro]: new MicroScheduler(),
338
- [Scheduler.Macro]: new MacroScheduler(),
339
- [Scheduler.Layout]: new LayoutScheduler()
340
- };
341
- globalThis["sche"] = _scheduler[Scheduler.Sync];
342
- const registerScheduler = (key, Ctor) => _scheduler[key] = new Ctor();
343
290
 
344
- const DefaultDFSOpt = {
345
- isUp: false,
346
- begin: null,
347
- complete: null,
348
- breakStack: [],
349
- breakLine: null,
350
- breakNode: null
351
- };
352
- function dfs(root, opt = {}) {
353
- const _DefaultDFSOpt$opt = {
354
- ...DefaultDFSOpt,
355
- ...opt
356
- },
357
- isUp = _DefaultDFSOpt$opt.isUp,
358
- begin = _DefaultDFSOpt$opt.begin,
359
- complete = _DefaultDFSOpt$opt.complete,
360
- lineStack = _DefaultDFSOpt$opt.breakStack,
361
- breakLine = _DefaultDFSOpt$opt.breakLine;
362
- let node = opt.breakNode || root;
363
- let line = breakLine;
364
- const listKey = isUp ? "recStart" : "emitStart";
365
- const nodeKey = isUp ? "upstream" : "downstream";
366
- const nextLineKey = isUp ? "nextRecLine" : "nextEmitLine";
367
- const reverseNodeKey = isUp ? "downstream" : "upstream";
368
- while (true) {
369
- let notGoDeep = begin?.({
370
- node,
371
- lineFromUp: line,
372
- walkedLine: lineStack
373
- });
374
- lineStack.push(line);
375
- line = node[listKey];
376
- if (line && !notGoDeep) {
377
- const firstChild = line[nodeKey];
378
- node = firstChild;
379
- continue;
380
- }
381
- while (true) {
382
- const noGoSibling = complete?.({
383
- node,
384
- lineToDeep: line,
385
- walkedLine: lineStack,
386
- notGoDeep
387
- });
388
- line = lineStack.pop();
389
- if (node === root) {
390
- return;
391
- }
392
- notGoDeep = false;
393
- const nextLine = line[nextLineKey];
394
- if (!noGoSibling && nextLine) {
395
- line = nextLine;
396
- node = nextLine[nodeKey];
397
- break;
398
- }
399
- node = line[reverseNodeKey];
400
- }
291
+ function link(up = null, down = null) {
292
+ const prevEmitLine = up.emitTail,
293
+ scopeUp = up.scope;
294
+ let recHead = down.recHead,
295
+ recTail = down.recTail,
296
+ scopeDown = down.scope;
297
+ if (scopeDown && scopeDown !== scopeUp && (up.state & 32) === 0) {
298
+ outLink(up, down);
299
+ return;
401
300
  }
402
- }
403
-
404
- class Line {
405
- constructor() {
406
- /** 上游顶点 */
407
- this.upstream = null;
408
- /** 上游节点 发出的上一条线 */
409
- this.prevEmitLine = null;
410
- /** 上游节点 发出的下一条线 */
411
- this.nextEmitLine = null;
412
- /** 下游顶点 */
413
- this.downstream = null;
414
- /** 下游节点 接收的上一条线 */
415
- this.prevRecLine = null;
416
- /** 下游节点 接收的下一条线 */
417
- this.nextRecLine = null;
418
- /** 表示 scope 当前存在的 外部 link */
419
- this.prevOutLink = null;
420
- this.nextOutLink = null;
421
- }
422
- static link(v1, v2) {
423
- let emitEnd = v1.emitEnd,
424
- recEnd = v2.recEnd,
425
- recStart = v2.recStart,
426
- noRecEnd = !recEnd,
427
- head = {
428
- nextRecLine: recStart
429
- },
430
- line;
431
- recEnd = recEnd || head;
432
- const _ref = recEnd || {},
433
- nextRecLine = _ref.nextRecLine;
434
- if (!nextRecLine) {
435
- line = new Line();
436
- Line.emit_line(v1, line);
437
- Line.rec_line(v2, line);
438
- emitEnd && Line.line_line_emit(emitEnd, line);
439
- !noRecEnd && Line.line_line_rec(recEnd, line);
440
- } else if (nextRecLine.upstream === v1) {
441
- v2.recEnd = nextRecLine;
442
- } else {
443
- line = new Line();
444
- Line.emit_line(v1, line);
445
- Line.rec_line(v2, line);
446
- emitEnd && Line.line_line_emit(emitEnd, line);
447
- Line.insert_line_rec(recEnd, nextRecLine, line);
448
- }
449
- for (const key in head) {
450
- head[key] = null;
451
- }
452
- if (line && v2.scope && v1.scope !== v2.scope && (v1.state & State.IsScope) === 0) {
453
- const first = v2.scope.outLink;
454
- if (!first) {
455
- v2.scope.outLink = line;
456
- } else {
457
- first.prevOutLink = line;
458
- line.nextOutLink = first;
459
- v2.scope.outLink = line;
460
- }
461
- }
301
+ const nextRec = recTail ? recTail.nextRecLine : recHead;
302
+ const eid = execId();
303
+ if (prevEmitLine && prevEmitLine.down === down && prevEmitLine.execId === eid) {
304
+ return;
462
305
  }
463
- static unlink(line) {
464
- let prevEmitLine = line.prevEmitLine,
465
- nextEmitLine = line.nextEmitLine,
466
- prevRecLine = line.prevRecLine,
467
- nextRecLine = line.nextRecLine,
468
- upstream = line.upstream,
469
- downstream = line.downstream,
470
- nextOutLink = line.nextOutLink,
471
- prevOutLink = line.prevOutLink;
472
- line.prevEmitLine = null;
473
- line.nextEmitLine = null;
474
- line.prevRecLine = null;
475
- line.nextRecLine = null;
476
- line.upstream = null;
477
- line.downstream = null;
478
- line.prevOutLink = null;
479
- line.nextOutLink = null;
480
- const downNode = downstream;
481
- if (prevOutLink) {
482
- prevOutLink.nextOutLink = nextOutLink;
483
- }
484
- if (nextOutLink) {
485
- nextOutLink.prevOutLink = prevOutLink;
486
- }
487
- if (downNode.scope && downNode.scope.outLink === line) {
488
- downNode.scope.outLink = nextOutLink;
489
- }
306
+ if (!nextRec) {
307
+ const line = {
308
+ execId: eid,
309
+ up,
310
+ down,
311
+ prevEmitLine,
312
+ nextEmitLine: null,
313
+ prevRecLine: recTail,
314
+ nextRecLine: null
315
+ };
490
316
  if (prevEmitLine) {
491
- prevEmitLine.nextEmitLine = nextEmitLine;
317
+ prevEmitLine.nextEmitLine = line;
492
318
  } else {
493
- upstream.emitStart = nextEmitLine;
319
+ up.emitHead = line;
494
320
  }
495
- if (nextEmitLine) {
496
- nextEmitLine.prevEmitLine = prevEmitLine;
321
+ up.emitTail = line;
322
+ if (recTail) {
323
+ recTail.nextRecLine = line;
497
324
  } else {
498
- upstream.emitEnd = prevEmitLine;
499
- }
500
- if (prevRecLine) {
501
- prevRecLine.nextRecLine = nextRecLine;
502
- } else {
503
- downstream.recStart = nextRecLine;
504
- }
505
- if (nextRecLine) {
506
- nextRecLine.prevRecLine = prevRecLine;
507
- } else {
508
- downstream.recEnd = prevRecLine;
509
- }
510
- }
511
- static unlinkRec(line) {
512
- let toDel = line;
513
- while (toDel) {
514
- const memoNext = toDel.nextRecLine;
515
- Line.unlink(toDel);
516
- toDel = memoNext;
325
+ down.recHead = line;
517
326
  }
327
+ down.recTail = line;
328
+ return;
518
329
  }
519
- static unlinkEmit(line) {
520
- let toDel = line;
521
- while (toDel) {
522
- const memoNext = toDel.nextEmitLine;
523
- Line.unlink(toDel);
524
- toDel = memoNext;
525
- }
330
+ if (nextRec.up === up) {
331
+ nextRec.execId = eid;
332
+ down.recTail = nextRec;
333
+ return;
526
334
  }
527
- /** 上游节点 link */
528
- static emit_line(upstream, line) {
529
- if (!upstream.emitStart) {
530
- upstream.emitStart = line;
531
- }
532
- upstream.emitEnd = line;
533
- line.upstream = upstream;
335
+ const line = {
336
+ execId: eid,
337
+ up,
338
+ down,
339
+ prevEmitLine,
340
+ nextEmitLine: null,
341
+ prevRecLine: recTail,
342
+ nextRecLine: nextRec
343
+ };
344
+ if (prevEmitLine) {
345
+ prevEmitLine.nextEmitLine = line;
346
+ } else {
347
+ up.emitHead = line;
534
348
  }
535
- /** 下游节点 连 link */
536
- static rec_line(downstream, line) {
537
- if (!downstream.recStart) {
538
- downstream.recStart = line;
539
- }
540
- downstream.recEnd = line;
541
- line.downstream = downstream;
542
- }
543
- /** 同一节点发出的 两个条线 相连 */
544
- static line_line_emit(l1, l2) {
545
- if (!l1 || !l2) return;
546
- l1.nextEmitLine = l2;
547
- l2.prevEmitLine = l1;
548
- }
549
- /** 同一节点接收的 两个条线 相连 */
550
- static line_line_rec(l1, l2) {
551
- if (!l1 || !l2) return;
552
- l1.nextRecLine = l2;
553
- l2.prevRecLine = l1;
554
- }
555
- static insert_line_emit(l1, l2, ins) {
556
- l1.nextEmitLine = ins;
557
- ins.prevEmitLine = l1;
558
- l2.prevEmitLine = ins;
559
- ins.nextEmitLine = l2;
560
- }
561
- static insert_line_rec(l1, l2, ins) {
562
- l1.nextRecLine = ins;
563
- ins.prevRecLine = l1;
564
- l2.prevRecLine = ins;
565
- ins.nextRecLine = l2;
349
+ up.emitTail = line;
350
+ if (recHead) {
351
+ recTail.nextRecLine = line;
352
+ } else {
353
+ down.recHead = line;
566
354
  }
355
+ down.recTail = line;
356
+ if (recTail) recTail.nextRecLine = line;
357
+ nextRec.prevRecLine = line;
567
358
  }
568
-
569
- function unlinkRecWithScope(line) {
570
- let toDel = line;
571
- while (toDel) {
572
- const memoNext = toDel.nextRecLine;
573
- const upstream = toDel.upstream;
574
- if (upstream.state & State.IsScope) {
575
- dispose.call(upstream);
359
+ function outLink(up = null, down = null) {
360
+ const prevEmitLine = up.emitTail;
361
+ let recHead = down.recHead,
362
+ recTail = down.recTail,
363
+ scopeDown = down.scope;
364
+ const nextRec = recTail ? recTail.nextRecLine : recHead;
365
+ if (!nextRec) {
366
+ const line = {
367
+ execId: execId(),
368
+ up,
369
+ down,
370
+ prevEmitLine,
371
+ nextEmitLine: null,
372
+ prevRecLine: recTail,
373
+ nextRecLine: null,
374
+ nextOutLink: null,
375
+ prevOutLink: null
376
+ };
377
+ if (prevEmitLine) {
378
+ prevEmitLine.nextEmitLine = line;
576
379
  } else {
577
- unlinkSingleLine(toDel);
380
+ up.emitHead = line;
578
381
  }
579
- toDel = memoNext;
580
- }
581
- }
582
- function unlinkSingleLine(line) {
583
- const upstream = line.upstream;
584
- if (upstream.emitStart === upstream.emitEnd) {
585
- unlinkSingleRefedNode(upstream);
586
- } else {
587
- Line.unlink(line);
588
- }
589
- }
590
- function unlinkSingleRefedNode(delRoot) {
591
- let toUnlink;
592
- dfs(delRoot, {
593
- isUp: true,
594
- begin: ({
595
- node
596
- }) => {
597
- doUnlink(toUnlink);
598
- toUnlink = null;
599
- if (node.emitStart !== node.emitEnd) {
600
- return true;
601
- }
602
- },
603
- complete: ({
604
- node,
605
- notGoDeep
606
- }) => {
607
- doUnlink(toUnlink);
608
- toUnlink = null;
609
- const isSingleRefed = !notGoDeep;
610
- if (isSingleRefed) {
611
- toUnlink = node.emitStart;
612
- }
382
+ up.emitTail = line;
383
+ if (recTail) {
384
+ recTail.nextRecLine = line;
385
+ } else {
386
+ down.recHead = line;
613
387
  }
614
- });
615
- doUnlink(toUnlink);
616
- }
617
- function doUnlink(line) {
618
- if (!line) {
388
+ down.recTail = line;
389
+ makeOutLink(scopeDown, line);
619
390
  return;
620
391
  }
621
- Line.unlink(line);
622
- }
623
- function dispose() {
624
- let toDel = this.recStart;
625
- while (toDel) {
626
- const memoNext = toDel.nextRecLine;
627
- const upstream = toDel.upstream;
628
- if (upstream.state & State.IsScope) {
629
- dfs(upstream, {
630
- isUp: true,
631
- begin: ({
632
- node
633
- }) => {
634
- if ((node.state & State.IsScope) === 0 || node.state & ScopeAbort) return true;
635
- },
636
- complete: ({
637
- node: scope,
638
- notGoDeep
639
- }) => {
640
- const shouldAbort = !notGoDeep;
641
- if (shouldAbort) {
642
- releaseScope(scope);
643
- }
644
- }
645
- });
646
- } else {
647
- unlinkSingleLine(toDel);
648
- }
649
- toDel = memoNext;
392
+ if (nextRec.up === up) {
393
+ down.recTail = nextRec;
394
+ return;
650
395
  }
651
- releaseScope(this);
652
- doUnlink(this.emitStart);
653
- }
654
- function releaseScope(scope) {
655
- let outLink = scope.outLink;
656
- while (outLink) {
657
- const memoNext = outLink.nextOutLink;
658
- unlinkSingleLine(outLink);
659
- outLink = memoNext;
396
+ const line = {
397
+ execId: execId(),
398
+ up,
399
+ down,
400
+ prevEmitLine,
401
+ nextEmitLine: null,
402
+ prevRecLine: recTail,
403
+ nextRecLine: nextRec,
404
+ nextOutLink: null,
405
+ prevOutLink: null
406
+ };
407
+ if (prevEmitLine) {
408
+ prevEmitLine.nextEmitLine = line;
409
+ } else {
410
+ up.emitHead = line;
660
411
  }
661
- scope.state |= State.ScopeAbort;
662
- scope.clean?.();
663
- scope.clean = null;
664
- }
665
- function clean(cb) {
666
- G.PullingSignal.clean = () => runWithPulling(cb, null);
667
- }
668
- function runWithPulling(fn, signal) {
669
- const prevPulling = G.PullingSignal;
670
- G.PullingSignal = signal;
671
- const res = fn();
672
- G.PullingSignal = prevPulling;
673
- return res;
674
- }
675
- function getPulling() {
676
- return G.PullingSignal;
412
+ up.emitTail = line;
413
+ if (recHead) {
414
+ recTail.nextRecLine = line;
415
+ } else {
416
+ down.recHead = line;
417
+ }
418
+ down.recTail = line;
419
+ if (recTail) recTail.nextRecLine = line;
420
+ nextRec.prevRecLine = line;
421
+ makeOutLink(scopeDown, line);
677
422
  }
678
- function setPulling(pulling) {
679
- G.PullingSignal = pulling;
423
+ function makeOutLink(scopeDown, line) {
424
+ const first = scopeDown.outLink;
425
+ if (first) {
426
+ first.prevOutLink = line;
427
+ line.nextOutLink = first;
428
+ }
429
+ scopeDown.outLink = line;
680
430
  }
681
431
 
682
- const markDeep = root => {
683
- let node = root,
684
- i = -1,
685
- parent;
686
- const stack = [];
687
- outer: do {
688
- let noGoDeep = false;
689
- const state = node.state,
690
- emitStart = node.emitStart,
691
- scheduler = node.scheduler;
692
- if (node.scope && node.scope.state & State.ScopeAbort ||
693
- // scope 节点,且处于 ready 状态,不需要重复执行
694
- node.state & ScopeExecuted) {
695
- noGoDeep = true;
696
- } else {
697
- const inPullingArea = state & State.Pulling;
698
- const isEffect = parent !== void 0;
699
- const isLeaf = !emitStart || emitStart.downstream === node.scope;
700
- if (isEffect) {
701
- node.state |= inPullingArea ? State.PullingUnknown : State.Unknown;
702
- } else if (!isLeaf) {
703
- node.state |= State.Dirty;
432
+ class Computed {
433
+ emitHead = null;
434
+ emitTail = null;
435
+ recHead = null;
436
+ recTail = null;
437
+ state = 0;
438
+ scope = getPulling();
439
+ value = null;
440
+ constructor(callback) {
441
+ this.callback = callback;
442
+ }
443
+ get(shouldLink = true, notForceUpdate = true) {
444
+ const scope = this.scope;
445
+ if (scope && scope.state & 128) return this.value;
446
+ const down = getPulling();
447
+ if (this.recHead && notForceUpdate) {
448
+ if (this.state & 6) {
449
+ this.value = pullDeep(this);
704
450
  }
705
- if (isLeaf) {
706
- noGoDeep = true;
707
- if (isEffect && !inPullingArea) {
708
- const instance = _scheduler[scheduler];
709
- const item = instance.addEffect(node);
710
- instance.firstEffectItem ??= item;
711
- instance.lastEffectItem = item;
712
- }
451
+ } else {
452
+ this.state |= 1;
453
+ const nextId = execIdInc();
454
+ const prevId = execId();
455
+ setExecId(nextId);
456
+ setPulling(this);
457
+ this.recTail = null;
458
+ this.value = this.callback(this);
459
+ this.state &= -2;
460
+ setPulling(down);
461
+ setExecId(prevId);
462
+ transferDirtyState(this, this.state);
463
+ let line = this.recTail?.nextRecLine;
464
+ while (line) {
465
+ const nextLine = line.nextRecLine;
466
+ unlink(line, true);
467
+ line = nextLine;
713
468
  }
714
469
  }
715
- if (emitStart && !noGoDeep) {
716
- stack[++i] = emitStart;
717
- parent = node;
718
- node = emitStart.downstream;
719
- noGoDeep = false;
720
- continue;
470
+ if (shouldLink && down && (down.state & 256) === 0) {
471
+ link(this, down);
721
472
  }
722
- while (true) {
723
- if (i === -1) {
724
- break outer;
725
- }
726
- const backLine = stack[i];
727
- const nextLine = backLine.nextEmitLine;
728
- if (nextLine) {
729
- node = nextLine.downstream;
730
- stack[i] = nextLine;
731
- break;
732
- }
733
- node = parent;
734
- if (--i !== -1) {
735
- parent = stack[i].upstream;
736
- }
737
- }
738
- } while (true);
739
- };
740
- const pullingPostprocess = node => {
741
- let s = node.state;
742
- s &= ~State.Pulling;
743
- if (s & State.PullingUnknown) {
744
- s = s & ~State.PullingUnknown | State.Unknown;
473
+ return this.value;
745
474
  }
746
- node.state = s;
747
- };
475
+ }
476
+
748
477
  class Signal {
749
- constructor(nextValue, customPull) {
750
- this.nextValue = nextValue;
751
- this.customPull = customPull;
752
- this.version = -1;
753
- this.id = G.id++;
754
- this.state = State.Clean;
755
- /** 当前节点创建时处于的 effect 就是 scope */
756
- this.scope = G.PullingSignal;
757
- this.recEnd = null;
758
- this.recStart = null;
759
- this.emitStart = null;
760
- this.emitEnd = null;
761
- this.scheduler = null;
762
- this.value = null;
763
- this.outLink = null;
764
- this.pull = null;
765
- /** 记录当前 effect 中 clean */
766
- this.clean = null;
767
- }
768
- static {
769
- this.Pulling = null;
770
- }
771
- static create(nextValue, {
772
- customPull,
773
- isScope,
774
- scope,
775
- immediate,
776
- ...rest
777
- }) {
778
- const s = new Signal(nextValue, customPull);
779
- s.pull = s.customPull || s.DEFAULT_PULL;
780
- Object.assign(s, rest);
781
- if (isScope) {
782
- s.state |= State.IsScope;
783
- }
784
- if (scope !== void 0) {
785
- s.scope = scope;
786
- }
787
- return s;
788
- }
789
- DEFAULT_PULL() {
790
- return this.nextValue;
791
- }
792
- /**
793
- * 递归拉取负责建立以来链
794
- */
795
- pullRecurse(shouldLink = true) {
796
- G.PullingRecurseDeep++;
797
- const downstream = G.PullingSignal;
798
- this.linkWhenPull(downstream, shouldLink);
799
- try {
800
- if (this.version === G.version) {
801
- return this.value;
802
- }
803
- if (this.pull !== this.DEFAULT_PULL) this.recEnd = null;
804
- this.state |= State.Pulling;
805
- G.PullingSignal = this;
806
- this.clean?.();
807
- this.clean = null;
808
- let v = this.pull();
809
- if (this.state & State.IsScope && typeof v === "function") {
810
- const fn = v;
811
- this.clean = () => runWithPulling(fn, null);
812
- v = this.value;
478
+ scope = getPulling();
479
+ emitHead = null;
480
+ emitTail = null;
481
+ state = 0;
482
+ constructor(value) {
483
+ this.value = value;
484
+ }
485
+ get(shouldLink = true) {
486
+ if (shouldLink) {
487
+ const down = getPulling();
488
+ if (down && (down.state & 256) === 0) {
489
+ link(this, down);
813
490
  }
814
- this.value = v;
815
- this.version = G.version;
816
- return this.value;
817
- } catch (error) {
818
- console.error("\u8BA1\u7B97\u5C5E\u6027\u62A5\u9519\u8FD9\u6B21\u4E0D\u89E6\u53D1\uFF0C\u540E\u7EED\u72B6\u6001\u53EF\u80FD\u51FA\u9519", error);
819
- return this.value;
820
- } finally {
821
- this.pull = this.customPull || this.DEFAULT_PULL;
822
- pullingPostprocess(this);
823
- const toDel = this.recEnd?.nextRecLine;
824
- unlinkRecWithScope(toDel);
825
- G.PullingSignal = downstream;
826
- G.PullingRecurseDeep--;
827
491
  }
828
- }
829
- linkWhenPull(downstream, shouldLink) {
830
- const isScope = this.state & State.IsScope;
831
- if (
832
- // 2. 有下游
833
- downstream && shouldLink && (
834
- // 3. 下游是 watcher 不是 watch,或 是watcher 但 当前是 scope
835
- (downstream.state & State.LinkScopeOnly) === 0 || isScope) && (
836
- /**4. scope 只能被一个下游节点管理,就是初始化它的那个下游节点
837
- * 发生在 outEffect(() => scope(() => innerEffect(), null))
838
- * 虽然通过 scope 让 innerEffect 被管理,
839
- * 如果 innerEffect 在 outEffect 中被再次触发,就导致其被 outEffect 管理,
840
- * 若 outEffect 后续重新触发, 则导致 innerEffect 被销毁
841
- */
842
- !isScope || !this.emitStart)) {
843
- Line.link(this, downstream);
844
- }
845
- }
846
- pullDeep() {
847
- const signal = this;
848
- if (signal.state & DirtyState) {
849
- let node = signal,
850
- i = -1,
851
- parent;
852
- const stack = [];
853
- outer: do {
854
- let noGoDeep = false;
855
- if (node.state & (State.Pulling | State.Dirty) || (node.state & DirtyState) === 0 || node.isDisabled()) {
856
- noGoDeep = true;
857
- } else {
858
- node.state |= State.Pulling;
859
- }
860
- const recStart = node.recStart;
861
- if (recStart && !noGoDeep) {
862
- stack[++i] = recStart;
863
- parent = node;
864
- node = recStart.upstream;
865
- continue;
866
- }
867
- while (true) {
868
- const isDirty = node.state & State.Dirty;
869
- let currentClean = noGoDeep && !isDirty;
870
- if (noGoDeep && node.state & State.Pulling) {
871
- currentClean = true;
872
- }
873
- let noGoSibling = false;
874
- const downstream2 = parent;
875
- const isEmitter = node.pull === node.DEFAULT_PULL;
876
- if (currentClean) ; else if (isDirty) {
877
- if (isEmitter && node.value !== node.nextValue) {
878
- node.markDownStreamsDirty();
879
- node.state &= ~State.Dirty;
880
- } else {
881
- const prevPulling = G.PullingSignal;
882
- G.PullingSignal = downstream2;
883
- const prevValue = node.value;
884
- node.pullRecurse(false);
885
- if (prevValue !== node.value) {
886
- node.markDownStreamsDirty();
887
- }
888
- node.state &= ~State.Dirty;
889
- G.PullingSignal = prevPulling;
890
- noGoSibling = true;
891
- }
892
- } else if (node.state & State.Unknown) {
893
- node.state &= ~State.Unknown;
894
- }
895
- if (!isEmitter) {
896
- node.version = G.version;
897
- }
898
- pullingPostprocess(node);
899
- noGoDeep = false;
900
- if (i === -1) {
901
- break outer;
902
- }
903
- const backLine = stack[i];
904
- const nextLine = backLine.nextRecLine;
905
- if (!noGoSibling && nextLine) {
906
- node = nextLine.upstream;
907
- stack[i] = nextLine;
908
- break;
909
- } else {
910
- node = parent;
911
- if (--i !== -1) {
912
- parent = stack[i].downstream;
913
- }
914
- }
915
- }
916
- } while (true);
917
- }
918
- const downstream = G.PullingSignal;
919
- this.linkWhenPull(downstream, true);
920
492
  return this.value;
921
493
  }
922
- get v() {
923
- if (this.isDisabled()) {
924
- return this.value;
925
- }
926
- if (!this.recStart || this.pull === this.DEFAULT_PULL) {
927
- return this.pullRecurse(true);
928
- }
929
- return this.pullDeep();
930
- }
931
- // pause() {
932
- // this.state |= State.SelfPaused;
933
- // }
934
- // resume() {
935
- // this.state &= ~State.SelfPaused;
936
- // }
937
- markDownStreamsDirty() {
938
- let point = this.emitStart;
939
- while (point != null) {
940
- const downstream = point.downstream;
941
- downstream.state |= State.Dirty;
942
- downstream.state &= ~State.Unknown;
943
- point = point.nextEmitLine;
494
+ set(v) {
495
+ if (this.value === v) return;
496
+ this.value = v;
497
+ if (this.emitHead) {
498
+ mark(this);
499
+ if (batchDeep() === 0) {
500
+ flushEffect();
501
+ }
944
502
  }
945
503
  }
946
- set v(v) {
947
- if (this.isDisabled() || this.nextValue === v) {
948
- return;
949
- }
950
- this.nextValue = v;
951
- this.pull = this.DEFAULT_PULL;
952
- G.version++;
953
- if (this.emitStart) {
954
- markDeep(this);
955
- if (batchDeep === 0) {
956
- this.scheduleEffect();
504
+ }
505
+
506
+ const EffectState = 512 | 32;
507
+ class Effect {
508
+ emitHead = null;
509
+ emitTail = null;
510
+ recHead = null;
511
+ recTail = null;
512
+ state = EffectState;
513
+ scope = getPulling();
514
+ outLink = null;
515
+ clean = null;
516
+ constructor(callback) {
517
+ this.callback = callback;
518
+ this.get();
519
+ }
520
+ get(shouldLink = true, notForceUpdate = true) {
521
+ if (this.state & 128) return;
522
+ const down = getPulling();
523
+ if (this.recHead && notForceUpdate) {
524
+ pullDeep(this);
525
+ } else {
526
+ this.state |= 1;
527
+ setPulling(null);
528
+ this.clean?.();
529
+ this.clean = null;
530
+ const nextId = execIdInc();
531
+ const prevId = execId();
532
+ setExecId(nextId);
533
+ setPulling(this);
534
+ this.recTail = null;
535
+ const res = this.callback(this);
536
+ typeof res === 'function' && (this.clean = res);
537
+ this.state &= -2;
538
+ setPulling(down);
539
+ setExecId(prevId);
540
+ transferDirtyState(this, this.state);
541
+ let line = this.recTail?.nextRecLine;
542
+ while (line) {
543
+ const nextLine = line.nextRecLine;
544
+ unlink(line, true);
545
+ line = nextLine;
957
546
  }
958
547
  }
959
- }
960
- scheduleEffect() {
961
- for (const key in _scheduler) {
962
- const instance = _scheduler[key];
963
- instance.endSet();
548
+ if (!this.emitHead && shouldLink && down) {
549
+ link(this, down);
964
550
  }
965
551
  }
966
- /** 返回值为 true 表示已处理 */
967
- runIfDirty() {
968
- this.state & (State.Unknown | State.Dirty) && this.v;
969
- }
970
- isDisabled() {
971
- return (
972
- // scope 被取消
973
- this.scope && this.scope.state & State.ScopeAbort ||
974
- // scope 节点,且处于 ready 状态,不需要重复执行
975
- this.state & ScopeExecuted
976
- );
552
+ }
553
+ Effect.prototype.dispose = dispose;
554
+
555
+ const ScopeAndLinkScopeOnly = 32 | 256;
556
+ class Scope {
557
+ emitHead = null;
558
+ emitTail = null;
559
+ recHead = null;
560
+ recTail = null;
561
+ state = ScopeAndLinkScopeOnly;
562
+ scope = getPulling();
563
+ outLink = null;
564
+ constructor(callback) {
565
+ this.callback = callback;
566
+ }
567
+ get(shouldLink = true) {
568
+ const scope = this.scope;
569
+ this.state |= 1;
570
+ setPulling(this);
571
+ this.recTail = null;
572
+ const res = this.callback();
573
+ typeof res === 'function' && (this.clean = res);
574
+ this.state &= -2;
575
+ setPulling(scope);
576
+ if (!this.emitHead && shouldLink && scope) {
577
+ link(this, scope);
578
+ }
977
579
  }
978
580
  }
979
- let batchDeep = 0;
980
- function batchStart() {
981
- batchDeep++;
581
+ Scope.prototype.dispose = dispose;
582
+
583
+ const rawToProxy = new WeakMap();
584
+ let State = function (State) {
585
+ State[State["Clean"] = 0] = "Clean";
586
+ State[State["LinkScopeOnly"] = 256] = "LinkScopeOnly";
587
+ State[State["ScopeAbort"] = 128] = "ScopeAbort";
588
+ State[State["ScopeReady"] = 64] = "ScopeReady";
589
+ State[State["IsScope"] = 32] = "IsScope";
590
+ State[State["PullingDirty"] = 16] = "PullingDirty";
591
+ State[State["PullingUnknown"] = 8] = "PullingUnknown";
592
+ State[State["Unknown"] = 4] = "Unknown";
593
+ State[State["Dirty"] = 2] = "Dirty";
594
+ State[State["Pulling"] = 1] = "Pulling";
595
+ return State;
596
+ }({});
597
+ State.Unknown | State.Dirty;
598
+ State.ScopeReady | State.ScopeAbort;
599
+ State.ScopeAbort;
600
+
601
+ let Keys = function (Keys) {
602
+ Keys["Iterator"] = "__AOYE_ITERATOR";
603
+ Keys["Raw"] = "__AOYE_RAW";
604
+ Keys["Meta"] = "__AOYE_META";
605
+ return Keys;
606
+ }({});
607
+ const IsStore = Symbol('__AOYE_IS_STORE'),
608
+ StoreIgnoreKeys = Symbol('__AOYE_IGNORE_KEYS');
609
+
610
+ const ide = globalThis.requestIdleCallback || (globalThis.requestAnimationFrame ? fn => globalThis.requestAnimationFrame(() => {
611
+ setTimeout(() => {
612
+ fn();
613
+ });
614
+ }) : globalThis.setTimeout);
615
+ const now = () => {
616
+ const timer = globalThis.performance || globalThis.Date;
617
+ return timer.now();
618
+ };
619
+ let channel = globalThis.MessageChannel ? new MessageChannel() : null;
620
+ if (globalThis.MessageChannel) {
621
+ channel = new MessageChannel();
982
622
  }
983
- function batchEnd() {
984
- if (--batchDeep) return;
985
- for (const key in _scheduler) {
986
- const instance = _scheduler[key];
987
- instance.endSet();
623
+ let msgId = 0;
624
+ const macro = fn => {
625
+ if (!channel) {
626
+ setTimeout(fn);
988
627
  }
989
- }
628
+ const memoId = msgId;
629
+ function onMessage(e) {
630
+ if (memoId === e.data) {
631
+ fn();
632
+ channel.port2.removeEventListener('message', onMessage);
633
+ }
634
+ }
635
+ channel.port2.addEventListener('message', onMessage);
636
+ channel.port1.postMessage(msgId++);
637
+ };
638
+ const p = Promise.resolve();
639
+ const micro = cb => {
640
+ p.then(cb);
641
+ };
642
+ const toRaw = a => {
643
+ if (typeof a === 'object' && a !== null && a[Keys.Raw]) {
644
+ return toRaw(a[Keys.Raw]);
645
+ }
646
+ return a;
647
+ };
990
648
 
991
649
  const deepSignal = (target, scope, deep = true) => {
992
- const isObj = typeof target === "object" && target !== null;
650
+ const isObj = typeof target === 'object' && target !== null;
993
651
  if (!isObj || target[Keys.Raw]) return target;
994
652
  const p = rawToProxy.get(target);
995
653
  if (p) return p;
996
- const cells = /* @__PURE__ */new Map();
654
+ const cells = new Map();
997
655
  const targetIsArray = Array.isArray(target);
998
656
  const targetIsStore = Boolean(target.constructor?.[IsStore]);
999
657
  const meta = {
@@ -1014,12 +672,12 @@
1014
672
  return Reflect.get(obj, prop, receiver);
1015
673
  }
1016
674
  const desc = Reflect.getOwnPropertyDescriptor(obj, prop);
1017
- const isGetter = desc && typeof desc.get === "function";
675
+ const isGetter = desc && typeof desc.get === 'function';
1018
676
  if (isGetter) {
1019
677
  return handleGetterAsComputed(obj, prop, receiver, cells, scope);
1020
678
  }
1021
679
  const value = Reflect.get(obj, prop, receiver);
1022
- const valueIsFn = typeof value === "function";
680
+ const valueIsFn = typeof value === 'function';
1023
681
  if (valueIsFn) {
1024
682
  if (targetIsArray) {
1025
683
  return arrayMethodReWrites[prop] || value;
@@ -1029,26 +687,22 @@
1029
687
  }
1030
688
  let s = cells.get(prop);
1031
689
  if (s) {
1032
- return s.v;
690
+ return s.get();
1033
691
  }
1034
692
  const wrappedValue = deep ? deepSignal(value, scope) : value;
1035
- s = Signal.create(wrappedValue, {
1036
- scheduler: Scheduler.Sync,
1037
- isScope: false,
1038
- scope
1039
- });
693
+ s = new Signal(wrappedValue);
1040
694
  cells.set(prop, s);
1041
- return s.v;
695
+ return s.get();
1042
696
  },
1043
697
  set(obj, prop, value, receiver) {
1044
- if (targetIsStore && isIgnoreKey(obj.constructor[StoreIgnoreKeys], prop) || typeof value === "function") {
698
+ if (targetIsStore && isIgnoreKey(obj.constructor[StoreIgnoreKeys], prop) || typeof value === 'function') {
1045
699
  return Reflect.set(obj, prop, value, receiver);
1046
700
  }
1047
701
  batchStart();
1048
702
  const success = Reflect.set(obj, prop, value, receiver);
1049
703
  const cell = cells.get(prop);
1050
704
  if (cell) {
1051
- cell.v = deep ? deepSignal(value, scope) : value;
705
+ cell.set(deep ? deepSignal(value, scope) : value);
1052
706
  }
1053
707
  if (targetIsArray) {
1054
708
  handleArraySet(obj, prop, value, receiver);
@@ -1058,13 +712,12 @@
1058
712
  batchEnd();
1059
713
  return success;
1060
714
  },
1061
- // 【核心修改】拦截 delete 操作
1062
715
  deleteProperty(obj, prop) {
1063
- if (targetIsStore && isIgnoreKey(obj.constructor[StoreIgnoreKeys], prop) || typeof obj[prop] === "function") {
716
+ if (targetIsStore && isIgnoreKey(obj.constructor[StoreIgnoreKeys], prop) || typeof obj[prop] === 'function') {
1064
717
  return Reflect.deleteProperty(obj, prop);
1065
718
  }
1066
719
  cells.delete(prop);
1067
- triggerIter(obj, prop, void 0, proxy);
720
+ triggerIter(obj, prop, undefined, proxy);
1068
721
  return Reflect.deleteProperty(obj, prop);
1069
722
  },
1070
723
  ownKeys(obj) {
@@ -1081,8 +734,8 @@
1081
734
  };
1082
735
  const shareSignal = (from, fromPath, to, toPath) => {
1083
736
  try {
1084
- const toPaths = toPath.split(".");
1085
- const formPaths = Array.isArray(fromPath) ? fromPath : fromPath.split(".");
737
+ const toPaths = toPath.split('.');
738
+ const formPaths = Array.isArray(fromPath) ? fromPath : fromPath.split('.');
1086
739
  runWithPulling(() => {
1087
740
  const _getTargetAndKey = getTargetAndKey(from, formPaths),
1088
741
  fromTarget = _getTargetAndKey.target,
@@ -1096,13 +749,13 @@
1096
749
  toTarget[Keys.Raw][toKey] = val;
1097
750
  }, null);
1098
751
  } catch (error) {
1099
- console.error("\u6620\u5C04\u4E86\u4E0D\u5B58\u5728\u7684Key\uFF01");
752
+ console.error('映射了不存在的Key!');
1100
753
  throw error;
1101
754
  }
1102
755
  };
1103
756
  function getTargetAndKey(obj, paths) {
1104
757
  let target = obj;
1105
- let key = "";
758
+ let key = '';
1106
759
  const len = paths.length;
1107
760
  for (let i = 0; i < len; i++) {
1108
761
  key = paths[i];
@@ -1116,27 +769,23 @@
1116
769
  };
1117
770
  }
1118
771
  function isIgnoreKey(ignores, key) {
1119
- if (typeof key !== "string") {
772
+ if (typeof key !== 'string') {
1120
773
  return ignores.includes(key);
1121
774
  }
1122
- return ignores.some(it => typeof it === "string" && key.startsWith(it));
775
+ return ignores.some(it => typeof it === 'string' && key.startsWith(it));
1123
776
  }
1124
777
  function handleGetterAsComputed(obj, prop, receiver, cells, scope) {
1125
778
  let s = cells.get(prop);
1126
779
  if (s) {
1127
- return s.v;
780
+ return s.get();
1128
781
  }
1129
- s = Signal.create(null, {
1130
- customPull: () => Reflect.get(obj, prop, receiver),
1131
- scheduler: Scheduler.Sync,
1132
- isScope: false,
1133
- scope
1134
- });
782
+ s = new Computed(() => Reflect.get(obj, prop, receiver));
783
+ s.scope = scope;
1135
784
  cells.set(prop, s);
1136
- return s.v;
785
+ return s.get();
1137
786
  }
1138
787
  function handleArraySet(arr, prop, value, receiver) {
1139
- if (prop === "length") ; else if (bobeShared.isNatureNumStr(prop)) {
788
+ if (prop === 'length') ; else if (bobeShared.isNatureNumStr(prop)) {
1140
789
  receiver[Keys.Iterator] = (arr[Keys.Iterator] || 0) + 1;
1141
790
  } else {
1142
791
  triggerIter(arr, prop, value, receiver);
@@ -1144,11 +793,11 @@
1144
793
  }
1145
794
  function triggerIter(obj, prop, value, receiver) {
1146
795
  if (!Reflect.has(obj, prop)) {
1147
- receiver[Keys.Iterator] = receiver[Keys.Raw][Keys.Iterator] + 1;
796
+ receiver[Keys.Iterator] = (receiver[Keys.Raw][Keys.Iterator] || 0) + 1;
1148
797
  }
1149
798
  }
1150
799
  const arrayMethodReWrites = {};
1151
- ["pop", "push", "shift", "splice", "unshift", "copyWithin", "reverse", "fill"].forEach(key => {
800
+ ['pop', 'push', 'shift', 'splice', 'unshift', 'copyWithin', 'reverse', 'fill'].forEach(key => {
1152
801
  arrayMethodReWrites[key] = function (...args) {
1153
802
  batchStart();
1154
803
  const fn = Array.prototype[key];
@@ -1158,13 +807,13 @@
1158
807
  return res;
1159
808
  };
1160
809
  });
1161
- ["includes", "indexOf", "lastIndexOf"].forEach(key => {
810
+ ['includes', 'indexOf', 'lastIndexOf'].forEach(key => {
1162
811
  arrayMethodReWrites[key] = function (...args) {
1163
812
  const fn = Array.prototype[key];
1164
813
  const that = toRaw(this);
1165
814
  let result = fn.call(that, ...args);
1166
815
  const value = args[0];
1167
- if ((result === false || result === -1) && typeof value === "object" && value !== null) {
816
+ if ((result === false || result === -1) && typeof value === 'object' && value !== null) {
1168
817
  if (value[Keys.Raw]) {
1169
818
  args[0] = value[Keys.Raw];
1170
819
  result = fn.call(that, ...args);
@@ -1179,8 +828,8 @@
1179
828
  return result;
1180
829
  };
1181
830
  });
1182
- [Symbol.iterator, "values", "entries"].forEach(key => {
1183
- const isEntries = key === "entries";
831
+ [Symbol.iterator, 'values', 'entries'].forEach(key => {
832
+ const isEntries = key === 'entries';
1184
833
  arrayMethodReWrites[key] = function (...args) {
1185
834
  const fn = Array.prototype[key];
1186
835
  const rawArray = toRaw(this);
@@ -1238,7 +887,7 @@
1238
887
  } else {
1239
888
  k = Math.min(k, len);
1240
889
  }
1241
- let final = end === void 0 ? len : end;
890
+ let final = end === undefined ? len : end;
1242
891
  if (final < 0) {
1243
892
  final = Math.max(len + final, 0);
1244
893
  } else {
@@ -1366,42 +1015,42 @@
1366
1015
  };
1367
1016
  const GetMethodConf = {
1368
1017
  wrapReturn: false,
1369
- wrapArgs: 1
1018
+ wrapArgs: 0b01
1370
1019
  };
1371
1020
  [{
1372
- key: "every",
1021
+ key: 'every',
1373
1022
  ...GetMethodConf
1374
1023
  }, {
1375
- key: "find",
1024
+ key: 'find',
1376
1025
  wrapReturn: true,
1377
1026
  ...GetMethodConf
1378
1027
  }, {
1379
- key: "findLast",
1028
+ key: 'findLast',
1380
1029
  ...GetMethodConf,
1381
1030
  wrapReturn: true
1382
1031
  }, {
1383
- key: "findIndex",
1032
+ key: 'findIndex',
1384
1033
  ...GetMethodConf
1385
1034
  }, {
1386
- key: "findLastIndex",
1035
+ key: 'findLastIndex',
1387
1036
  ...GetMethodConf
1388
1037
  }, {
1389
- key: "forEach",
1038
+ key: 'forEach',
1390
1039
  ...GetMethodConf
1391
1040
  }, {
1392
- key: "map",
1041
+ key: 'map',
1393
1042
  ...GetMethodConf
1394
1043
  }, {
1395
- key: "some",
1044
+ key: 'some',
1396
1045
  ...GetMethodConf
1397
1046
  }, {
1398
- key: "reduce",
1047
+ key: 'reduce',
1399
1048
  ...GetMethodConf,
1400
- wrapArgs: 2
1049
+ wrapArgs: 0b10
1401
1050
  }, {
1402
- key: "reduceRight",
1051
+ key: 'reduceRight',
1403
1052
  ...GetMethodConf,
1404
- wrapArgs: 2
1053
+ wrapArgs: 0b10
1405
1054
  }].forEach(({
1406
1055
  key,
1407
1056
  wrapReturn,
@@ -1423,17 +1072,17 @@
1423
1072
  };
1424
1073
  });
1425
1074
  arrayMethodReWrites.toSorted = function (...args) {
1426
- const fn = Array.prototype["toSorted"];
1075
+ const fn = Array.prototype['toSorted'];
1427
1076
  const meta = this[Keys.Meta];
1428
1077
  const isDeep = meta.deep,
1429
1078
  scope = meta.scope;
1430
1079
  const that = toRaw(this);
1431
- warpCallbackArgs(isDeep, args, scope, 3);
1080
+ warpCallbackArgs(isDeep, args, scope, 0b11);
1432
1081
  let result = fn.call(that, ...args);
1433
1082
  this[Keys.Iterator];
1434
1083
  return isDeep ? result.map(it => deepSignal(it, scope)) : result;
1435
1084
  };
1436
- ["join", "toString", "toLocaleString"].forEach(key => {
1085
+ ['join', 'toString', 'toLocaleString'].forEach(key => {
1437
1086
  arrayMethodReWrites[key] = function (...args) {
1438
1087
  const fn = Array.prototype[key];
1439
1088
  const that = toRaw(this);
@@ -1442,38 +1091,30 @@
1442
1091
  return result;
1443
1092
  };
1444
1093
  });
1445
- function warpCallbackArgs(isDeep, args, scope, wrapArgs = 1) {
1094
+ function warpCallbackArgs(isDeep, args, scope, wrapArgs = 0b01) {
1446
1095
  const callback = args[0];
1447
1096
  const wrapCb = function (...cbArgs) {
1448
1097
  if (isDeep) {
1449
- if (wrapArgs & 1) cbArgs[0] = deepSignal(cbArgs[0], scope);
1450
- if (wrapArgs & 2) cbArgs[1] = deepSignal(cbArgs[1], scope);
1098
+ if (wrapArgs & 0b01) cbArgs[0] = deepSignal(cbArgs[0], scope);
1099
+ if (wrapArgs & 0b10) cbArgs[1] = deepSignal(cbArgs[1], scope);
1451
1100
  }
1452
1101
  return callback.call(this, ...cbArgs);
1453
1102
  };
1454
1103
  args[0] = wrapCb;
1455
1104
  }
1456
1105
 
1457
- var _a, _b;
1458
- _b = IsStore, _a = StoreIgnoreKeys;
1459
- const _Store = class _Store {
1106
+ class Store {
1107
+ static [IsStore] = true;
1108
+ static [StoreIgnoreKeys] = ['ui', 'raw'];
1109
+ static Current = null;
1460
1110
  constructor() {
1461
- this.parent = () => null;
1462
- const proxy = deepSignal(this, G.PullingSignal, true);
1463
- _Store.Current = proxy;
1111
+ const proxy = deepSignal(this, getPulling(), true);
1112
+ Store.Current = proxy;
1464
1113
  return proxy;
1465
1114
  }
1466
- static {
1467
- this[_b] = true;
1468
- }
1469
- static {
1470
- this[_a] = ["ui", "raw"];
1471
- }
1472
- static {
1473
- this.Current = null;
1474
- }
1115
+ parent = () => null;
1475
1116
  static new(keyMap = {}, staticMap = {}) {
1476
- const parentStore = _Store.Current;
1117
+ const parentStore = Store.Current;
1477
1118
  const child = new this();
1478
1119
  if (parentStore) {
1479
1120
  for (const childKey in keyMap) {
@@ -1486,7 +1127,7 @@
1486
1127
  child[key] = value;
1487
1128
  }
1488
1129
  child.parent = () => parentStore;
1489
- _Store.Current = parentStore;
1130
+ Store.Current = parentStore;
1490
1131
  return child;
1491
1132
  }
1492
1133
  map(keyMap = {}) {
@@ -1499,56 +1140,44 @@
1499
1140
  }
1500
1141
  this.parent = null;
1501
1142
  }
1502
- };
1503
- let Store = _Store;
1143
+ }
1504
1144
 
1505
- const DefaultCustomSignalOpt = {
1506
- /** 三种模式
1507
- * 1. auto: 根据值类型自动判断 默认
1508
- * 2. ref: 对任何值使用 {v: xxx} 进行包装
1509
- * 3. proxy: 使用 proxy 进行包装
1510
- */
1511
- mode: "auto",
1512
- /** 是否深度响应式 */
1513
- deep: true
1514
- };
1515
- ({
1516
- scheduler: Scheduler.Sync});
1517
- const $ = (init, opt = {}) => {
1518
- opt = {
1519
- ...DefaultCustomSignalOpt,
1520
- ...opt
1521
- };
1522
- let intiValue, customPull;
1523
- if (typeof init === "function") {
1524
- intiValue = null;
1525
- customPull = init;
1526
- } else if (opt.mode !== "ref" && typeof init === "object" && init !== null) {
1527
- return deepSignal(init, G.PullingSignal, opt.deep);
1145
+ function $(data) {
1146
+ if (typeof data === 'object' && data !== null) {
1147
+ return deepSignal(data, getPulling());
1148
+ }
1149
+ if (typeof data === 'function') {
1150
+ const s = new Computed(data),
1151
+ get = s.get.bind(s);
1152
+ return {
1153
+ ins: s,
1154
+ get v() {
1155
+ return get();
1156
+ }
1157
+ };
1528
1158
  } else {
1529
- intiValue = init;
1159
+ const s = new Signal(data),
1160
+ set = s.set.bind(s),
1161
+ get = s.get.bind(s);
1162
+ return {
1163
+ ins: s,
1164
+ get v() {
1165
+ return get();
1166
+ },
1167
+ set v(v) {
1168
+ set(v);
1169
+ }
1170
+ };
1530
1171
  }
1531
- const s = Signal.create(intiValue, {
1532
- scheduler: Scheduler.Sync,
1533
- isScope: false,
1534
- customPull
1535
- });
1536
- return s;
1537
- };
1538
- const effect = (customPull, depOrOpt, opt) => {
1172
+ }
1173
+ function effectUt(callback, depOrOpt, opt) {
1539
1174
  const hasDep = Array.isArray(depOrOpt);
1540
1175
  opt = hasDep ? opt || {} : depOrOpt || {};
1541
1176
  if (!hasDep) {
1542
- const s2 = Signal.create(null, {
1543
- customPull,
1544
- scheduler: Scheduler.Sync,
1545
- isScope: true,
1546
- ...opt
1547
- });
1548
- s2.v;
1549
- const bound2 = dispose.bind(s2);
1550
- bound2.ins = s2;
1551
- return bound2;
1177
+ const ef = new Effect(callback);
1178
+ const run = ef.dispose.bind(ef);
1179
+ run.ins = ef;
1180
+ return run;
1552
1181
  }
1553
1182
  let mounted = false;
1554
1183
  const deps = depOrOpt;
@@ -1559,84 +1188,94 @@
1559
1188
  old: null,
1560
1189
  val: null
1561
1190
  }));
1562
- const s = Signal.create(null, {
1563
- customPull() {
1564
- for (let i = 0; i < deps.length; i++) {
1565
- const value = deps[i].v;
1566
- vs[i].old = vs[i].val;
1567
- vs[i].val = value;
1568
- }
1569
- if (mounted || immediate) {
1570
- s.state |= State.LinkScopeOnly;
1571
- customPull(...vs);
1572
- s.state &= ~State.LinkScopeOnly;
1573
- }
1574
- mounted = true;
1575
- },
1576
- scheduler: Scheduler.Sync,
1577
- isScope: true,
1578
- ...opt
1579
- });
1580
- s.v;
1581
- const bound = dispose.bind(s);
1582
- bound.ins = s;
1583
- return bound;
1584
- };
1585
- const scope = (...args) => {
1586
- const hasScope = args.length > 1;
1587
- const s = Signal.create(null, {
1588
- customPull: args[0],
1589
- scheduler: Scheduler.Sync,
1590
- isScope: true,
1591
- scope: hasScope ? args[1] : G.PullingSignal
1191
+ const ef = new Effect(() => {
1192
+ for (let i = 0; i < deps.length; i++) {
1193
+ const value = deps[i].v;
1194
+ vs[i].old = vs[i].val;
1195
+ vs[i].val = value;
1196
+ }
1197
+ if (mounted || immediate) {
1198
+ ef.state |= 256;
1199
+ callback(...vs);
1200
+ ef.state &= -257;
1201
+ }
1202
+ mounted = true;
1592
1203
  });
1593
- if (hasScope) {
1594
- runWithPulling(() => {
1595
- s.v;
1596
- }, args[1]);
1597
- } else {
1598
- s.v;
1204
+ const run = ef.dispose.bind(ef);
1205
+ run.ins = ef;
1206
+ return run;
1207
+ }
1208
+ function effect(callback, depOrOpt, opt) {
1209
+ const hasDep = Array.isArray(depOrOpt);
1210
+ opt = hasDep ? opt || {} : depOrOpt || {};
1211
+ if (!hasDep) {
1212
+ const ef = new Effect(callback);
1213
+ const run = ef.dispose.bind(ef);
1214
+ run.ins = ef;
1215
+ return run;
1599
1216
  }
1600
- s.state |= State.ScopeReady;
1601
- const bound = dispose.bind(s);
1602
- bound.ins = s;
1603
- return bound;
1604
- };
1605
- const customEffect = opt => {
1606
- return (init, innerOpt = {}) => {
1607
- return effect(init, {
1608
- ...opt,
1609
- ...innerOpt
1610
- });
1611
- };
1612
- };
1613
- const isSignal = value => {
1614
- return value instanceof Signal;
1615
- };
1616
- const isScope = value => {
1617
- return value instanceof Signal;
1618
- };
1217
+ let mounted = false;
1218
+ const deps = depOrOpt;
1219
+ const immediate = deps.length === 0 ? true : opt.immediate ?? true;
1220
+ const vs = Array.from({
1221
+ length: deps.length
1222
+ }, () => ({
1223
+ old: null,
1224
+ val: null
1225
+ }));
1226
+ const ef = new Effect(eff => {
1227
+ for (let i = 0; i < deps.length; i++) {
1228
+ const value = deps[i].get();
1229
+ vs[i].old = vs[i].val;
1230
+ vs[i].val = value;
1231
+ }
1232
+ if (mounted || immediate) {
1233
+ eff.state |= 256;
1234
+ callback(...vs);
1235
+ eff.state &= -257;
1236
+ }
1237
+ mounted = true;
1238
+ });
1239
+ const run = ef.dispose.bind(ef);
1240
+ run.ins = ef;
1241
+ return run;
1242
+ }
1243
+ function scope(...args) {
1244
+ const ins = new Scope(args[0]);
1245
+ if (args.length === 2) {
1246
+ ins.scope = args[1];
1247
+ }
1248
+ ins.get();
1249
+ const run = ins.dispose.bind(ins);
1250
+ run.ins = ins;
1251
+ return run;
1252
+ }
1619
1253
 
1620
1254
  exports.$ = $;
1255
+ exports.Computed = Computed;
1256
+ exports.Effect = Effect;
1621
1257
  exports.IsStore = IsStore;
1622
1258
  exports.Keys = Keys;
1623
- exports.Scheduler = Scheduler;
1259
+ exports.Scope = Scope;
1624
1260
  exports.Signal = Signal;
1625
1261
  exports.Store = Store;
1626
1262
  exports.StoreIgnoreKeys = StoreIgnoreKeys;
1627
- exports.TaskQueue = TaskQueue;
1628
1263
  exports.batchEnd = batchEnd;
1629
1264
  exports.batchStart = batchStart;
1630
1265
  exports.clean = clean;
1631
- exports.customEffect = customEffect;
1632
1266
  exports.deepSignal = deepSignal;
1633
1267
  exports.effect = effect;
1268
+ exports.effectUt = effectUt;
1269
+ exports.execId = execId;
1270
+ exports.execIdInc = execIdInc;
1634
1271
  exports.getPulling = getPulling;
1635
- exports.isScope = isScope;
1636
- exports.isSignal = isSignal;
1637
- exports.registerScheduler = registerScheduler;
1272
+ exports.ide = ide;
1273
+ exports.macro = macro;
1274
+ exports.micro = micro;
1275
+ exports.now = now;
1638
1276
  exports.runWithPulling = runWithPulling;
1639
1277
  exports.scope = scope;
1278
+ exports.setExecId = setExecId;
1640
1279
  exports.setPulling = setPulling;
1641
1280
  exports.shareSignal = shareSignal;
1642
1281
  exports.toRaw = toRaw;