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