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