aoye 0.0.2 → 0.0.4

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
@@ -1,249 +1,32 @@
1
1
  'use strict';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
3
+ var bobeShared = require('bobe-shared');
4
4
 
5
- class SortMap {
6
- constructor() {
7
- this.data = {};
8
- }
9
- clear() {
10
- this.data = {};
11
- }
12
- add(key, value) {
13
- const {
14
- data
15
- } = this;
16
- let list = data[key];
17
- if (!list) {
18
- list = [];
19
- data[key] = list;
20
- }
21
- list.push(value);
22
- }
23
- }
24
- // const queue = new Queue([1,2,3,4]);
25
- // queue.shift()
26
- // queue.pop()
27
- // // @ts-ignore
28
- // queue.unshift('a')
29
- // // @ts-ignore
30
- // queue.push('b')
31
- // queue.shift()
32
- // queue.pop()
33
- // queue.shift()
34
- // queue.pop()
35
- // queue.shift()
36
- // queue.pop()
37
- // queue.push(10)
38
- // queue.array();
39
-
40
- const timestamp = globalThis.performance ? globalThis.performance.now.bind(globalThis.performance) : Date.now;
41
- var EventMode;
42
- (function (EventMode) {
43
- EventMode[EventMode["Immediate"] = 0] = "Immediate";
44
- EventMode[EventMode["Queue"] = 1] = "Queue";
45
- })(EventMode || (EventMode = {}));
46
- var ProcessStatus;
47
- (function (ProcessStatus) {
48
- ProcessStatus[ProcessStatus["None"] = 0] = "None";
49
- ProcessStatus[ProcessStatus["Processing"] = 1] = "Processing";
50
- ProcessStatus[ProcessStatus["Paused"] = 2] = "Paused";
51
- })(ProcessStatus || (ProcessStatus = {}));
52
- const DefaultEventOpt = {
53
- mode: EventMode.Immediate
54
- };
55
- const ALL = '__ALL_KEY';
56
- class BaseEvent {
57
- constructor(opt = {}) {
58
- this.opt = opt;
59
- this.eventQueue = [];
60
- this.status = ProcessStatus.None;
61
- this.subMap = new Map();
62
- this.on = (type, fn) => {
63
- if (type == null) type = ALL;
64
- const suber = this.subMap.get(type) || new Set();
65
- suber.add(fn);
66
- this.subMap.set(type, suber);
67
- };
68
- this.off = (type, fn) => {
69
- const suber = this.subMap.get(type !== null && type !== void 0 ? type : ALL);
70
- if (!suber) return;
71
- suber.delete(fn);
72
- };
73
- this.once = (type, fn) => {
74
- fn['once'] = true;
75
- this.on(type, fn);
76
- };
77
- this.promiseOnce = type => {
78
- return new Promise(resolve => {
79
- this.once(type, (...args) => {
80
- resolve(args);
81
- });
82
- });
83
- };
84
- this.setScheduler = (type, scheduler) => {
85
- if (typeof type !== 'string') {
86
- this.scheduler = type;
87
- return;
88
- }
89
- const set = this.subMap.get(type) || new Set();
90
- set['scheduler'] = scheduler;
91
- this.subMap.set(type, set);
92
- };
93
- // construct 会初始化为下面其中一种
94
- this.emit = (type, ...args) => {
95
- this.opt.mode === EventMode.Immediate ? this.emitImmediate(type, ...args) : this.emitQueue(type, ...args);
96
- };
97
- this.pause = () => this.status = ProcessStatus.Paused;
98
- this.unPause = () => this.status = ProcessStatus.None;
99
- this.start = () => {
100
- this.status = ProcessStatus.None;
101
- this.processQueue();
102
- };
103
- this.process = () => {
104
- if (this.scheduler) {
105
- return this.scheduler(this.recallScheduler);
106
- }
107
- return this.processQueue();
108
- };
109
- this.recallScheduler = () => {
110
- this.scheduler(this.recallScheduler);
111
- };
112
- this.processQueue = () => {
113
- // 如果是挂起状态则直接结束
114
- if (this.status === ProcessStatus.Paused) return;
115
- this.status = ProcessStatus.Processing;
116
- let {
117
- type,
118
- args
119
- } = this.eventQueue.shift() || {};
120
- if (type) {
121
- // 在此过程中用户可通过 pause 和 start 同步控制事件处理
122
- const fns = this.subMap.get(type);
123
- const allSub = this.subMap.get(ALL);
124
- fns === null || fns === void 0 ? void 0 : fns.forEach(it => this.callSub(it, fns, args));
125
- allSub === null || allSub === void 0 ? void 0 : allSub.forEach(it => this.callSub(it, allSub, args));
126
- if (this.eventQueue.length > 0) {
127
- this.processQueue();
128
- }
129
- }
130
- //@ts-ignore 队列全部处理完成,如果执行过程中被 pause
131
- if (this.status !== ProcessStatus.Paused) {
132
- this.status = ProcessStatus.None;
133
- }
134
- };
135
- this.dispatchEvent = iList => {
136
- // 从大到小排序
137
- iList.sort((a, b) => b - a);
138
- iList.forEach(idx => {
139
- const [item] = this.eventQueue.splice(idx, 1);
140
- const {
141
- type,
142
- args
143
- } = item || {};
144
- if (type && args) {
145
- this.emitImmediate(type, ...args);
146
- }
147
- });
148
- };
149
- this.clear = () => {
150
- this.subMap.clear();
151
- this.eventQueue = [];
152
- this.scheduler = undefined;
153
- };
154
- this.opt = {
155
- ...DefaultEventOpt,
156
- ...opt
157
- };
158
- }
159
- callSub(it, fns, args) {
160
- const doCall = (...args) => {
161
- it(...args);
162
- if (it['once'] === true) fns.delete(it);
163
- };
164
- const scheduler = it['scheduler'] || fns['scheduler'];
165
- if (scheduler) {
166
- scheduler(doCall, ...args);
167
- } else {
168
- it(...args);
169
- if (it['once'] === true) fns.delete(it);
170
- }
171
- }
172
- emitImmediate(type, ...args) {
173
- const fns = this.subMap.get(type);
174
- const allSub = this.subMap.get(ALL);
175
- fns === null || fns === void 0 ? void 0 : fns.forEach(it => this.callSub(it, fns, args));
176
- allSub === null || allSub === void 0 ? void 0 : allSub.forEach(it => this.callSub(it, allSub, args));
177
- }
178
- emitQueue(type, ...args) {
179
- this.eventQueue.push({
180
- type,
181
- args,
182
- time: timestamp()
183
- });
184
- this.process();
185
- }
186
- }
187
- BaseEvent.a = 19;
188
-
189
- const evt = new BaseEvent();
5
+ const evt = new bobeShared.BaseEvent();
190
6
  const G = {
191
7
  /** 原子 signal 更新次数 */
192
8
  version: 0,
193
9
  id: 0,
194
10
  /** scope 销毁任务序号 */
195
- scopeDisposeI: 0
11
+ scopeDisposeI: 0,
12
+ PullingSignal: null
196
13
  };
197
- const dirtyLeafs = new SortMap();
198
- var State;
199
- (function (State) {
200
- State[State["Clean"] = 0] = "Clean";
201
- /** 仅用于 scope 节点是否 abort */
202
- State[State["ScopeAborted"] = 64] = "ScopeAborted";
203
- State[State["ScopeAbort"] = 32] = "ScopeAbort";
204
- State[State["OutLink"] = 16] = "OutLink";
205
- State[State["Unknown"] = 8] = "Unknown";
206
- State[State["Dirty"] = 4] = "Dirty";
207
- State[State["Check"] = 2] = "Check";
208
- State[State["ScopeReady"] = 1] = "ScopeReady";
209
- })(State || (State = {}));
210
- const DirtyState = State.Unknown | State.Dirty;
211
- const ScopeExecuted = State.ScopeReady | State.ScopeAbort | State.ScopeAborted;
14
+ const dirtyLeafs = new bobeShared.SortMap();
15
+ var State = /* @__PURE__ */ ((State2) => {
16
+ State2[State2["Clean"] = 0] = "Clean";
17
+ State2[State2["LinkScopeOnly"] = 64] = "LinkScopeOnly";
18
+ State2[State2["ScopeAbort"] = 32] = "ScopeAbort";
19
+ State2[State2["ScopeReady"] = 16] = "ScopeReady";
20
+ State2[State2["IsScope"] = 8] = "IsScope";
21
+ State2[State2["Unknown"] = 4] = "Unknown";
22
+ State2[State2["Dirty"] = 2] = "Dirty";
23
+ State2[State2["Check"] = 1] = "Check";
24
+ return State2;
25
+ })(State || {});
26
+ const DirtyState = 4 /* Unknown */ | 2 /* Dirty */;
27
+ const ScopeExecuted = 16 /* ScopeReady */ | 32 /* ScopeAbort */;
28
+ const ScopeAbort = 32 /* ScopeAbort */;
212
29
 
213
- /**
214
- * 这是一个优先队列 (满足子节点总是比父节点大)
215
- * 1
216
- *
217
- * 10 20
218
- *
219
- * 15 30 25 30
220
- *
221
- * 17
222
- * 现在插入 7 , 会按广度优先的顺序插入在数组尾部
223
- * 1
224
- *
225
- * 10 20
226
- *
227
- * 15 30 25 30
228
- *
229
- * 17 7
230
- * 接着我们只需要将 7 逐层与上门的父节点比较, 7 较小则两者交互,一直让 7 上浮到适合的位置
231
- *
232
- * 0
233
- *
234
- * 1 2 2^0 得到第二层第一个索引
235
- *
236
- * 3 4 5 6 2^0 + 2^1 。。。 + 2^n + x = y
237
- *
238
- * 7 8
239
- * 上浮后我们得到以上的树
240
- */
241
- // 父子节点的关系
242
- // 计算一个节点的 index 公式 ① 2^0 + 2^1 。。。 + 2^n + y = x 已知
243
- // 节点的左子节点 index ② 2^0 + 2^1 。。。 + 2^n + 2^(n+1) + z = res 求 res
244
- // ② - ① 得到 2^(n+1) + (z-y) = res - x
245
- // 2^(n+1) + (z-y) + x = res
246
- // 而 z 和 y 的关系是,③ z = 2y
247
30
  const leakI = (y, max) => y < 0 || y >= max ? null : y;
248
31
  const getLeft = (x, max) => leakI(x * 2 + 1, max);
249
32
  const getRight = (x, max) => leakI(x * 2 + 2, max);
@@ -262,12 +45,9 @@ class PriorityQueue {
262
45
  const pI = getParent(i, len);
263
46
  const parent = arr[pI];
264
47
  if (this.aIsUrgent(item, parent)) {
265
- // console.log(`交换 parent:${parent} -> child:${item} `);
266
48
  exchange(arr, i, pI);
267
- // this.logTree();
268
49
  i = pI;
269
50
  } else {
270
- // console.log(`parent:${parent} child:${item} 不需要交换 \n`);
271
51
  break;
272
52
  }
273
53
  }
@@ -288,33 +68,26 @@ class PriorityQueue {
288
68
  if (point === i) {
289
69
  break;
290
70
  }
291
- // console.log(`交换 parent:${arr[i]} -> child:${arr[point]} `);
292
71
  exchange(arr, i, point);
293
- // this.logTree();
294
72
  i = point;
295
73
  }
296
74
  };
297
75
  }
298
76
  // 添加一个元素
299
77
  _add(current) {
300
- // console.log(`加入 ${current}`);
301
78
  this.arr.push(current);
302
79
  const len = this.size();
303
- // this.logTree();
304
80
  if (len === 1) {
305
81
  return;
306
82
  }
307
83
  this.goUp(this.arr, current, len);
308
84
  }
309
85
  add(...items) {
310
- items.forEach(it => this._add(it));
86
+ items.forEach((it) => this._add(it));
311
87
  }
312
88
  // 去除头元素并返回
313
89
  poll() {
314
- const {
315
- arr
316
- } = this;
317
- // console.log(`弹出 ${arr[0]} 把 ${arr[arr.length - 1]} 放置到队头 `);
90
+ const { arr } = this;
318
91
  const len = this.size();
319
92
  if (len <= 2) {
320
93
  return arr.shift();
@@ -322,7 +95,6 @@ class PriorityQueue {
322
95
  const last = arr.pop();
323
96
  const first = arr[0];
324
97
  arr[0] = last;
325
- // this.logTree();
326
98
  this.goDown(this.arr, 0);
327
99
  return first;
328
100
  }
@@ -335,9 +107,7 @@ class PriorityQueue {
335
107
  return this.arr.length;
336
108
  }
337
109
  logTree() {
338
- const {
339
- arr
340
- } = this;
110
+ const { arr } = this;
341
111
  let i = 0;
342
112
  let j = 1;
343
113
  let level = 0;
@@ -351,40 +121,14 @@ class PriorityQueue {
351
121
  const last = Math.pow(2, matrix.length - 1);
352
122
  const arrStr = JSON.stringify(last);
353
123
  const halfLen = arrStr.length >>> 1;
354
- matrix.forEach(it => {
124
+ matrix.forEach((it) => {
355
125
  const str = JSON.stringify(it);
356
126
  const halfIt = str.length >>> 1;
357
- console.log(str.padStart(halfLen + halfIt, ' '));
127
+ console.log(str.padStart(halfLen + halfIt, " "));
358
128
  });
359
- console.log('\n');
129
+ console.log("\n");
360
130
  }
361
131
  }
362
- // case 1
363
- // const pq = new PriorityQueue((a, b) => a - b)
364
- // pq.add(5)
365
- // pq.add(3)
366
- // pq.add(1)
367
- // pq.add(4)
368
- // pq.add(2)
369
- // const result = []
370
- // while (pq.size() > 0) {
371
- // result.push(pq.poll())
372
- // }
373
- // console.log(result);
374
- // [1,2,3,4,5]
375
- // case 2
376
- // const pq = new PriorityQueue((a, b) => b - a)
377
- // pq.add(1)
378
- // pq.add(3)
379
- // pq.add(4)
380
- // pq.add(5)
381
- // pq.add(2)
382
- // const result = []
383
- // while (pq.size() > 0) {
384
- // result.push(pq.poll())
385
- // }
386
- // console.log(result);
387
- // [5,4,3,2,1]
388
132
 
389
133
  class TaskQueue {
390
134
  constructor(callbackAble, aIsUrgent) {
@@ -392,19 +136,13 @@ class TaskQueue {
392
136
  this.aIsUrgent = aIsUrgent;
393
137
  this.isScheduling = false;
394
138
  }
395
- static create({
396
- callbackAble,
397
- aIsUrgent
398
- }) {
139
+ static create({ callbackAble, aIsUrgent }) {
399
140
  const queue = new TaskQueue(callbackAble, aIsUrgent);
400
141
  queue.taskQueue = new PriorityQueue(aIsUrgent);
401
142
  return queue;
402
143
  }
403
144
  pushTask(task) {
404
- const {
405
- taskQueue,
406
- isScheduling
407
- } = this;
145
+ const { taskQueue, isScheduling } = this;
408
146
  taskQueue._add(task);
409
147
  if (!isScheduling) {
410
148
  this.callbackAble(this.scheduleTask.bind(this));
@@ -412,45 +150,30 @@ class TaskQueue {
412
150
  }
413
151
  }
414
152
  scheduleTask() {
415
- const {
416
- taskQueue
417
- } = this;
418
- // console.log('调度 dispose');
153
+ const { taskQueue } = this;
419
154
  const fn = taskQueue.peek();
420
155
  if (!fn) return this.isScheduling = false;
421
156
  const hasRemain = fn();
422
- // 未完成
423
157
  if (hasRemain) {
424
158
  this.callbackAble(this.scheduleTask.bind(this));
425
159
  return;
426
160
  }
427
- // 完成
428
161
  taskQueue.poll();
429
- evt.emit('one', fn);
162
+ evt.emit("one", fn);
430
163
  if (taskQueue.size() === 0) {
431
- evt.emit('done', fn);
164
+ evt.emit("done", fn);
432
165
  return this.isScheduling = false;
433
166
  }
434
- // 任务列表中还有任务
435
167
  this.callbackAble(this.scheduleTask.bind(this));
436
168
  }
437
169
  }
438
170
 
439
- const ide = globalThis.requestIdleCallback || (globalThis.requestAnimationFrame ? fn => globalThis.requestAnimationFrame(() => {
440
- setTimeout(() => {
441
- fn();
442
- });
443
- }) : globalThis.setTimeout);
444
- const now = () => {
445
- const timer = globalThis.performance || globalThis.Date;
446
- return timer.now();
447
- };
448
171
  let channel = globalThis.MessageChannel ? new MessageChannel() : null;
449
172
  if (globalThis.MessageChannel) {
450
173
  channel = new MessageChannel();
451
174
  }
452
175
  let msgId = 0;
453
- const macro = fn => {
176
+ const macro = (fn) => {
454
177
  if (!channel) {
455
178
  setTimeout(fn);
456
179
  }
@@ -458,29 +181,29 @@ const macro = fn => {
458
181
  function onMessage(e) {
459
182
  if (memoId === e.data) {
460
183
  fn();
461
- channel.port2.removeEventListener('message', onMessage);
184
+ channel.port2.removeEventListener("message", onMessage);
462
185
  }
463
186
  }
464
- channel.port2.addEventListener('message', onMessage);
187
+ channel.port2.addEventListener("message", onMessage);
465
188
  channel.port1.postMessage(msgId++);
466
189
  };
467
190
  const p = Promise.resolve();
468
- const micro = cb => {
191
+ const micro = (cb) => {
469
192
  p.then(cb);
470
193
  };
471
194
 
472
- exports.Scheduler = void 0;
473
- (function (Scheduler) {
474
- Scheduler["Sync"] = "__Sync_";
475
- Scheduler["Layout"] = "__Layout_";
476
- Scheduler["Micro"] = "__Micro_";
477
- Scheduler["Macro"] = "__Macro_";
478
- })(exports.Scheduler || (exports.Scheduler = {}));
195
+ var Scheduler = /* @__PURE__ */ ((Scheduler2) => {
196
+ Scheduler2["Sync"] = "__Sync_";
197
+ Scheduler2["Layout"] = "__Layout_";
198
+ Scheduler2["Micro"] = "__Micro_";
199
+ Scheduler2["Macro"] = "__Macro_";
200
+ return Scheduler2;
201
+ })(Scheduler || {});
479
202
  const _scheduler = {
480
- [exports.Scheduler.Sync]: defaultScheduler,
481
- [exports.Scheduler.Micro]: microScheduler,
482
- [exports.Scheduler.Macro]: macroScheduler,
483
- [exports.Scheduler.Layout]: layoutScheduler
203
+ ["__Sync_" /* Sync */]: defaultScheduler,
204
+ ["__Micro_" /* Micro */]: microScheduler,
205
+ ["__Macro_" /* Macro */]: macroScheduler,
206
+ ["__Layout_" /* Layout */]: layoutScheduler
484
207
  };
485
208
  const scheduler = (key, value) => _scheduler[key] = value;
486
209
  function defaultScheduler(effects) {
@@ -492,56 +215,53 @@ let microSTaskQueue;
492
215
  let macroSTaskQueue;
493
216
  let layoutSTaskQueue;
494
217
  function microScheduler(effects) {
495
- microSTaskQueue = microSTaskQueue || TaskQueue.create({
496
- callbackAble: micro,
497
- aIsUrgent: (a, b) => a.time < b.time
498
- });
499
- microSTaskQueue.pushTask(defaultScheduler.bind(undefined, effects));
218
+ microSTaskQueue = microSTaskQueue || TaskQueue.create({ callbackAble: micro, aIsUrgent: (a, b) => a.time < b.time });
219
+ microSTaskQueue.pushTask(defaultScheduler.bind(null, effects));
500
220
  }
501
221
  function macroScheduler(effects) {
502
- macroSTaskQueue = macroSTaskQueue || TaskQueue.create({
503
- callbackAble: macro,
504
- aIsUrgent: (a, b) => a.time < b.time
505
- });
506
- macroSTaskQueue.pushTask(defaultScheduler.bind(undefined, effects));
222
+ macroSTaskQueue = macroSTaskQueue || TaskQueue.create({ callbackAble: macro, aIsUrgent: (a, b) => a.time < b.time });
223
+ macroSTaskQueue.pushTask(defaultScheduler.bind(null, effects));
507
224
  }
508
225
  function layoutScheduler(effects) {
509
- layoutSTaskQueue = layoutSTaskQueue || TaskQueue.create({
510
- callbackAble: macro,
511
- aIsUrgent: (a, b) => a.time < b.time
512
- });
513
- layoutSTaskQueue.pushTask(defaultScheduler.bind(undefined, effects));
226
+ layoutSTaskQueue = layoutSTaskQueue || TaskQueue.create({ callbackAble: macro, aIsUrgent: (a, b) => a.time < b.time });
227
+ layoutSTaskQueue.pushTask(defaultScheduler.bind(null, effects));
514
228
  }
515
229
 
230
+ var __defProp$1 = Object.defineProperty;
231
+ var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols;
232
+ var __hasOwnProp$2 = Object.prototype.hasOwnProperty;
233
+ var __propIsEnum$2 = Object.prototype.propertyIsEnumerable;
234
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
235
+ var __spreadValues$1 = (a, b) => {
236
+ for (var prop in b || (b = {}))
237
+ if (__hasOwnProp$2.call(b, prop))
238
+ __defNormalProp$1(a, prop, b[prop]);
239
+ if (__getOwnPropSymbols$2)
240
+ for (var prop of __getOwnPropSymbols$2(b)) {
241
+ if (__propIsEnum$2.call(b, prop))
242
+ __defNormalProp$1(a, prop, b[prop]);
243
+ }
244
+ return a;
245
+ };
516
246
  const DefaultDFSOpt = {
517
247
  isUp: false,
518
- begin: undefined,
519
- complete: undefined,
248
+ begin: null,
249
+ complete: null,
520
250
  breakStack: [],
521
- breakLine: undefined,
522
- breakNode: undefined
251
+ breakLine: null,
252
+ breakNode: null
523
253
  };
524
254
  function dfs(root, opt = {}) {
525
- const {
526
- isUp,
527
- begin,
528
- complete,
529
- breakStack: lineStack,
530
- breakLine
531
- } = {
532
- ...DefaultDFSOpt,
533
- ...opt
534
- };
255
+ const { isUp, begin, complete, breakStack: lineStack, breakLine } = __spreadValues$1(__spreadValues$1({}, DefaultDFSOpt), opt);
535
256
  let node = opt.breakNode || root;
536
257
  let line = breakLine;
537
- const listKey = isUp ? 'recStart' : 'emitStart';
538
- const nodeKey = isUp ? 'upstream' : 'downstream';
539
- // 向上意味着要找所有节点的入度
540
- const nextLineKey = isUp ? 'nextRecLine' : 'nextEmitLine';
541
- const reverseNodeKey = isUp ? 'downstream' : 'upstream';
258
+ const listKey = isUp ? "recStart" : "emitStart";
259
+ const nodeKey = isUp ? "upstream" : "downstream";
260
+ const nextLineKey = isUp ? "nextRecLine" : "nextEmitLine";
261
+ const reverseNodeKey = isUp ? "downstream" : "upstream";
542
262
  while (1) {
543
- let notGoDeep = begin === null || begin === void 0 ? void 0 : begin({
544
- node: node,
263
+ let notGoDeep = begin == null ? void 0 : begin({
264
+ node,
545
265
  lineFromUp: line,
546
266
  walkedLine: lineStack
547
267
  });
@@ -553,128 +273,121 @@ function dfs(root, opt = {}) {
553
273
  continue;
554
274
  }
555
275
  while (1) {
556
- const noGoSibling = complete === null || complete === void 0 ? void 0 : complete({
557
- node: node,
276
+ const noGoSibling = complete == null ? void 0 : complete({
277
+ node,
558
278
  lineToDeep: line,
559
279
  walkedLine: lineStack,
560
280
  notGoDeep
561
281
  });
562
- // 只对当前不下钻的节点生效
563
- // notGoDeep = false;
564
282
  line = lineStack.pop();
565
- // 递归出口,回到起点
566
283
  if (node === root) {
567
284
  return;
568
285
  }
569
286
  notGoDeep = false;
570
287
  const nextLine = line[nextLineKey];
571
- // 有兄弟节点, 进入外循环,向下遍历兄弟节点
572
288
  if (!noGoSibling && nextLine) {
573
- // 外层循环后会把 sibling line 入栈,这里不需要处理
574
289
  line = nextLine;
575
290
  node = nextLine[nodeKey];
576
291
  break;
577
292
  }
578
- // 没有兄弟节点就上浮
579
293
  node = line[reverseNodeKey];
580
294
  }
581
295
  }
582
296
  }
583
297
 
584
298
  class Line {
299
+ constructor() {
300
+ /** 上游顶点 */
301
+ this.upstream = null;
302
+ /** 上游节点 发出的上一条线 */
303
+ this.prevEmitLine = null;
304
+ /** 上游节点 发出的下一条线 */
305
+ this.nextEmitLine = null;
306
+ /** 下游顶点 */
307
+ this.downstream = null;
308
+ /** 下游节点 接收的上一条线 */
309
+ this.prevRecLine = null;
310
+ /** 下游节点 接收的下一条线 */
311
+ this.nextRecLine = null;
312
+ /** 表示 scope 当前存在的 外部 link */
313
+ this.prevOutLink = null;
314
+ this.nextOutLink = null;
315
+ }
585
316
  static link(v1, v2) {
586
- let {
587
- emitEnd
588
- } = v1,
589
- {
590
- recEnd,
591
- recStart
592
- } = v2,
593
- noRecEnd = !recEnd,
594
- /** 模拟头节点 */
595
- head = {
596
- nextRecLine: recStart
597
- },
598
- line;
317
+ let { emitEnd } = v1, { recEnd, recStart } = v2, noRecEnd = !recEnd, head = { nextRecLine: recStart }, line;
599
318
  recEnd = recEnd || head;
600
- const {
601
- nextRecLine
602
- } = recEnd || {};
603
- // 没有下一个收到的线
319
+ const { nextRecLine } = recEnd || {};
604
320
  if (!nextRecLine) {
605
321
  line = new Line();
606
- // 内部会处理空链表的情况,即同步头部
607
322
  Line.emit_line(v1, line);
608
323
  Line.rec_line(v2, line);
609
324
  emitEnd && Line.line_line_emit(emitEnd, line);
610
325
  !noRecEnd && Line.line_line_rec(recEnd, line);
611
- }
612
- // 复用
613
- else if (nextRecLine.upstream === v1) {
326
+ } else if (nextRecLine.upstream === v1) {
614
327
  v2.recEnd = nextRecLine;
615
- // TODO: link 版本标记
616
- }
617
- // 插入(这么做): v1 和 下一个 入度(订阅)节点不同
618
- // TODO: v2上次真依赖了 v1 只是没检查出来,需要删除原依赖
619
- else {
328
+ } else {
620
329
  line = new Line();
621
330
  Line.emit_line(v1, line);
622
331
  Line.rec_line(v2, line);
623
332
  emitEnd && Line.line_line_emit(emitEnd, line);
624
333
  Line.insert_line_rec(recEnd, nextRecLine, line);
625
334
  }
626
- // 消除 head
627
335
  for (const key in head) {
628
- head[key] = undefined;
336
+ head[key] = null;
337
+ }
338
+ if (line && v2.scope && v1.scope !== v2.scope && !(v1.state & State.IsScope)) {
339
+ const first = v2.scope.outLink;
340
+ if (!first) {
341
+ v2.scope.outLink = line;
342
+ } else {
343
+ first.prevOutLink = line;
344
+ line.nextOutLink = first;
345
+ v2.scope.outLink = line;
346
+ }
629
347
  }
630
348
  }
631
349
  static unlink(line) {
632
- let {
633
- prevEmitLine,
634
- nextEmitLine,
635
- prevRecLine,
636
- nextRecLine,
637
- upstream,
638
- downstream
639
- } = line;
640
- line.prevEmitLine = undefined;
641
- line.nextEmitLine = undefined;
642
- line.prevRecLine = undefined;
643
- line.nextRecLine = undefined;
644
- line.upstream = undefined;
645
- line.downstream = undefined;
646
- /** 上游节点发出的线 前一条 关联 后一条 */
350
+ let { prevEmitLine, nextEmitLine, prevRecLine, nextRecLine, upstream, downstream, nextOutLink, prevOutLink } = line;
351
+ line.prevEmitLine = null;
352
+ line.nextEmitLine = null;
353
+ line.prevRecLine = null;
354
+ line.nextRecLine = null;
355
+ line.upstream = null;
356
+ line.downstream = null;
357
+ line.prevOutLink = null;
358
+ line.nextOutLink = null;
359
+ const downNode = downstream;
360
+ if (prevOutLink) {
361
+ prevOutLink.nextOutLink = nextOutLink;
362
+ }
363
+ if (nextOutLink) {
364
+ nextOutLink.prevOutLink = prevOutLink;
365
+ }
366
+ if (downNode.scope && downNode.scope.outLink === line) {
367
+ downNode.scope.outLink = nextOutLink;
368
+ }
647
369
  if (prevEmitLine) {
648
370
  prevEmitLine.nextEmitLine = nextEmitLine;
649
371
  } else {
650
- // 删除的是首个节点
651
372
  upstream.emitStart = nextEmitLine;
652
373
  }
653
374
  if (nextEmitLine) {
654
375
  nextEmitLine.prevEmitLine = prevEmitLine;
655
376
  } else {
656
- // 删除尾节点
657
377
  upstream.emitEnd = prevEmitLine;
658
378
  }
659
- /** 下游节点接收的线,我们从 recEnd 开始删除的,
660
- * 接收信息,不需要设置 recEnd ,
661
- * 因为 recStart ~ recEnd 是经过上级 get 确认的有用依赖
662
- * */
663
379
  if (prevRecLine) {
664
380
  prevRecLine.nextRecLine = nextRecLine;
665
381
  } else {
666
- // 删除的是首个节点,大概率不可能从有依赖 变成无依赖
667
382
  downstream.recStart = nextRecLine;
668
383
  }
669
384
  if (nextRecLine) {
670
385
  nextRecLine.prevRecLine = prevRecLine;
671
386
  } else {
672
- // 删除尾节点
673
387
  downstream.recEnd = prevRecLine;
674
388
  }
675
389
  }
676
390
  static unlinkRec(line) {
677
- // 作为下游,执行完 get 上游节点已经完成了依赖更新,把 recEnd 后的依赖删除即可
678
391
  let toDel = line;
679
392
  while (toDel) {
680
393
  const memoNext = toDel.nextRecLine;
@@ -683,7 +396,6 @@ class Line {
683
396
  }
684
397
  }
685
398
  static unlinkEmit(line) {
686
- // 作为下游,执行完 get 上游节点已经完成了依赖更新,把 recEnd 后的依赖删除即可
687
399
  let toDel = line;
688
400
  while (toDel) {
689
401
  const memoNext = toDel.nextEmitLine;
@@ -731,198 +443,133 @@ class Line {
731
443
  l2.prevRecLine = ins;
732
444
  ins.nextRecLine = l2;
733
445
  }
734
- constructor() {
735
- /** 上游顶点 */
736
- this.upstream = null;
737
- /** 上游节点 发出的上一条线 */
738
- this.prevEmitLine = null;
739
- /** 上游节点 发出的下一条线 */
740
- this.nextEmitLine = null;
741
- /** 下游顶点 */
742
- this.downstream = null;
743
- /** 下游节点 接收的上一条线 */
744
- this.prevRecLine = null;
745
- /** 下游节点 接收的下一条线 */
746
- this.nextRecLine = null;
747
- }
748
446
  }
749
447
 
750
- /** scope 捕获,引用外部 signal 孤岛 */
751
- const unTrackIsland = signal => {
752
- // 原来是孤岛,且被 scope 管理的要恢复
753
- if (signal.emitStart && signal.emitStart.downstream === signal.scope) {
754
- Line.unlink(signal.emitStart);
755
- }
756
- };
757
- /** scope 释放,被重新连接的孤岛 */
758
- const trackIsland = signal => {
759
- const line = new Line();
760
- // 上游节点处于孤岛状态,切有引用外部信号,需要被 scope 管理来删除外部依赖
761
- if (!signal.emitStart && signal.state & State.OutLink) {
762
- const {
763
- recEnd
764
- } = signal.scope;
765
- Line.emit_line(signal, line);
766
- Line.rec_line(signal.scope, line);
767
- Line.line_line_rec(recEnd, line);
768
- }
769
- };
770
- /** 子 scope 释放,把其 only 被其持有的 signal 挂回其属于的 scope */
771
- const trackByOtherScopeDispose = signal => {
772
- const line = new Line();
773
- const {
774
- recEnd
775
- } = signal.scope;
776
- Line.emit_line(signal, line);
777
- Line.rec_line(signal.scope, line);
778
- Line.line_line_rec(recEnd, line);
779
- };
780
- const markOutLink = (signal, downstream) => {
781
- // 上游是外部节点,或者上游引用了外部节点的, 做传播
782
- if (signal.scope !== downstream.scope || signal.state & State.OutLink) {
783
- downstream.state |= State.OutLink;
784
- }
785
- // else {
786
- // downstream.state &= ~State.OutLink;
787
- // }
788
- };
789
- const BreakErr = '_ERR_BREAK_';
790
- let remain = {
791
- stack: null,
792
- node: null,
793
- line: null
794
- };
795
- const ideScheduler = TaskQueue.create({
796
- callbackAble: ide,
797
- aIsUrgent(a, b) {
798
- return a.index < b.index;
448
+ function unlinkRecWithScope(line) {
449
+ let toDel = line;
450
+ while (toDel) {
451
+ const memoNext = toDel.nextRecLine;
452
+ const upstream = toDel.upstream;
453
+ if (upstream.state & State.IsScope) {
454
+ dispose.call(upstream);
455
+ } else {
456
+ unlinkSingleLine(toDel);
457
+ }
458
+ toDel = memoNext;
799
459
  }
800
- });
801
- function handleOneTask(scope, breakStack) {
802
- breakStack = remain.stack || breakStack;
803
- // s 同步到 remainRoot
804
- let lineToRemove = null;
805
- const startTime = now();
806
- if (scope.emitStart) {
807
- Line.unlink(scope.emitStart);
460
+ }
461
+ function unlinkSingleLine(line) {
462
+ const upstream = line.upstream;
463
+ if (upstream.emitStart === upstream.emitEnd) {
464
+ unlinkSingleRefedNode(upstream);
465
+ } else {
466
+ Line.unlink(line);
808
467
  }
809
- try {
810
- dfs(scope, {
811
- breakStack,
812
- breakNode: remain.node,
813
- breakLine: remain.line,
814
- isUp: true,
815
- begin: ({
816
- walkedLine,
817
- node,
818
- lineFromUp
819
- }) => {
820
- if (lineToRemove) {
821
- Line.unlink(lineToRemove);
822
- lineToRemove = null;
823
- }
824
- if (now() - startTime > 5) {
825
- remain = {
826
- stack: walkedLine,
827
- node: node,
828
- line: lineFromUp
829
- };
830
- throw BreakErr;
831
- }
832
- // 1. 未标记的节点,是外部节点
833
- if (!(node.state & State.OutLink)) {
834
- return true;
835
- }
836
- // 2. 标记的节点,但是 scope 不一样,说明外部节点也引用了 另一 scope 的节点
837
- if (lineFromUp && node.scope !== lineFromUp.downstream['scope']) {
838
- // 是仅被 node 引用的外部节点
839
- if (node.emitStart === node.emitEnd) {
840
- // 已经 abort 只能继续释放
841
- if (scope.state & State.ScopeAborted) {
842
- const bound = handleOneTask.bind(undefined, node, []);
843
- bound.index = G.scopeDisposeI++;
844
- ideScheduler.pushTask(bound);
845
- }
846
- // 可以将其交给 原 scope 释放
847
- else {
848
- trackByOtherScopeDispose(node);
849
- }
850
- }
851
- // 任何外部引用都应该被断开
852
- return true;
853
- }
854
- // 对于嵌套作用域不允许重复进入
855
- node.state &= ~State.OutLink;
856
- },
857
- complete: ({
858
- node,
859
- notGoDeep,
860
- walkedLine
861
- }) => {
862
- if (lineToRemove) {
863
- Line.unlink(lineToRemove);
864
- lineToRemove = null;
865
- }
866
- if (notGoDeep) {
867
- const last = walkedLine[walkedLine.length - 1];
868
- const downstream = last === null || last === void 0 ? void 0 : last.downstream;
869
- // 节点没被标记 OutLink 但是发现与下游节点的 scope 不一致,是需要解除 link 的位置
870
- if (downstream && downstream.scope !== node.scope) {
871
- lineToRemove = last;
872
- }
873
- }
468
+ }
469
+ function unlinkSingleRefedNode(delRoot) {
470
+ let toUnlink;
471
+ dfs(delRoot, {
472
+ isUp: true,
473
+ begin: ({ node }) => {
474
+ doUnlink(toUnlink);
475
+ toUnlink = null;
476
+ if (node.emitStart !== node.emitEnd) {
477
+ return true;
874
478
  }
875
- });
876
- remain = {
877
- stack: null,
878
- node: null,
879
- line: null
880
- };
881
- scope.state |= State.ScopeAborted;
882
- } catch (error) {
883
- if (error === BreakErr) return true;
884
- remain = {
885
- stack: null,
886
- node: null,
887
- line: null
888
- };
889
- throw error;
479
+ },
480
+ complete: ({ node, notGoDeep }) => {
481
+ doUnlink(toUnlink);
482
+ toUnlink = null;
483
+ const isSingleRefed = !notGoDeep;
484
+ if (isSingleRefed) {
485
+ toUnlink = node.emitStart;
486
+ }
487
+ }
488
+ });
489
+ doUnlink(toUnlink);
490
+ }
491
+ function doUnlink(line) {
492
+ if (!line) {
493
+ return;
890
494
  }
495
+ Line.unlink(line);
891
496
  }
892
- function unlinkRecWithScope(line) {
893
- // 作为下游,执行完 get 上游节点已经完成了依赖更新,把 recEnd 后的依赖删除即可
894
- let toDel = line;
497
+ function dispose() {
498
+ let toDel = this.recStart;
895
499
  while (toDel) {
896
500
  const memoNext = toDel.nextRecLine;
897
501
  const upstream = toDel.upstream;
898
- Line.unlink(toDel);
899
- // 删除完后看看是否要被 scope 管理
900
- trackIsland(upstream);
502
+ if (upstream.state & State.IsScope) {
503
+ dfs(upstream, {
504
+ isUp: true,
505
+ begin: ({ node }) => {
506
+ if (!(node.state & State.IsScope) || node.state & ScopeAbort) return true;
507
+ },
508
+ complete: ({ node: scope, notGoDeep }) => {
509
+ const shouldAbort = !notGoDeep;
510
+ if (shouldAbort) {
511
+ releaseScope(scope);
512
+ }
513
+ }
514
+ });
515
+ } else {
516
+ unlinkSingleLine(toDel);
517
+ }
901
518
  toDel = memoNext;
902
519
  }
520
+ releaseScope(this);
521
+ doUnlink(this.emitStart);
522
+ }
523
+ function releaseScope(scope) {
524
+ var _a;
525
+ let outLink = scope.outLink;
526
+ while (outLink) {
527
+ const memoNext = outLink.nextOutLink;
528
+ unlinkSingleLine(outLink);
529
+ outLink = memoNext;
530
+ }
531
+ scope.state |= State.ScopeAbort;
532
+ (_a = scope.clean) == null ? void 0 : _a.call(scope);
533
+ scope.clean = null;
534
+ }
535
+ function clean(cb) {
536
+ G.PullingSignal.clean = () => runWithPulling(cb, null);
537
+ }
538
+ function runWithPulling(fn, signal) {
539
+ const prevPulling = G.PullingSignal;
540
+ G.PullingSignal = signal;
541
+ fn();
542
+ G.PullingSignal = prevPulling;
903
543
  }
904
544
 
905
- const markDeep = signal => {
545
+ var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
546
+ var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
547
+ var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
548
+ var __objRest = (source, exclude) => {
549
+ var target = {};
550
+ for (var prop in source)
551
+ if (__hasOwnProp$1.call(source, prop) && exclude.indexOf(prop) < 0)
552
+ target[prop] = source[prop];
553
+ if (source != null && __getOwnPropSymbols$1)
554
+ for (var prop of __getOwnPropSymbols$1(source)) {
555
+ if (exclude.indexOf(prop) < 0 && __propIsEnum$1.call(source, prop))
556
+ target[prop] = source[prop];
557
+ }
558
+ return target;
559
+ };
560
+ const markDeep = (signal) => {
906
561
  let level = 0;
907
562
  dfs(signal, {
908
563
  isUp: false,
909
- begin: ({
910
- node
911
- }) => {
912
- /**
913
- * 1. 当前节点在预检 应该跳过
914
- * 2. 当前节点 已标记
915
- * 3. 当前节点 已放弃
916
- */
917
- // console.log('markBegin', node.id);
918
- if (node.state & (State.Check | State.Unknown | State.Dirty) || node.isAbort()) {
564
+ begin: ({ node }) => {
565
+ if (node.state & (State.Check | State.Unknown | State.Dirty) || node.isDisabled()) {
919
566
  return true;
920
567
  }
921
568
  const isEffect = level > 0;
922
- const isLeaf = !node.emitStart || node.emitStart.downstream['scope'] === node.emitStart.downstream;
569
+ const isLeaf = !node.emitStart || node.emitStart.downstream === node.scope;
923
570
  if (isEffect) {
924
571
  node.state |= State.Unknown;
925
- } else {
572
+ } else if (!isLeaf) {
926
573
  node.state |= State.Dirty;
927
574
  }
928
575
  if (isLeaf && isEffect) {
@@ -938,37 +585,33 @@ const markDeep = signal => {
938
585
  }
939
586
  dirtyLeafs.clear();
940
587
  };
941
- class Signal {
942
- constructor(nextValue,
943
- /** 为什么是 shallow,因为 pullDeep 会把
944
- * 上游节点 get 执行完成,让其可以直接拿到缓存值
945
- */
946
- customPull) {
588
+ const _Signal = class _Signal {
589
+ constructor(nextValue, customPull) {
947
590
  this.nextValue = nextValue;
948
591
  this.customPull = customPull;
949
592
  this.version = -1;
950
593
  this.id = G.id++;
951
594
  this.state = State.Clean;
952
595
  /** 当前节点创建时处于的 effect 就是 scope */
953
- this.scope = Signal.Pulling;
596
+ this.scope = G.PullingSignal;
954
597
  this.recEnd = null;
955
598
  this.recStart = null;
956
599
  this.emitStart = null;
957
600
  this.emitEnd = null;
958
601
  this.scheduler = null;
959
602
  this.value = null;
603
+ this.outLink = null;
960
604
  this.pull = null;
605
+ /** 记录当前 effect 中 clean */
606
+ this.clean = null;
961
607
  }
962
- static create(nextValue, {
963
- customPull,
964
- isScope,
965
- ...rest
966
- }) {
967
- const s = new Signal(nextValue, customPull);
608
+ static create(nextValue, _a) {
609
+ var _b = _a, { customPull, isScope, immediate } = _b, rest = __objRest(_b, ["customPull", "isScope", "immediate"]);
610
+ const s = new _Signal(nextValue, customPull);
968
611
  s.pull = s.customPull || s.DEFAULT_PULL;
969
612
  Object.assign(s, rest);
970
613
  if (isScope) {
971
- s.scope = s;
614
+ s.state |= State.IsScope;
972
615
  }
973
616
  return s;
974
617
  }
@@ -979,131 +622,104 @@ class Signal {
979
622
  * 递归拉取负责建立以来链
980
623
  */
981
624
  pullRecurse(shouldLink = true) {
982
- var _a;
983
- let downstream = Signal.Pulling;
984
- if (shouldLink && downstream) {
985
- // 如果上游节点被 scope 管理了,解除管理
986
- unTrackIsland(this);
625
+ var _a, _b;
626
+ let downstream = G.PullingSignal;
627
+ const isScope = this.state & State.IsScope;
628
+ if (
629
+ // 1. 外部支持 link
630
+ shouldLink && // 2. 有下游
631
+ downstream && // 3. 下游是 watcher,不链接非 scope
632
+ !(downstream.state & State.LinkScopeOnly && !isScope)
633
+ ) {
987
634
  Line.link(this, downstream);
988
635
  }
989
636
  try {
990
637
  if (this.version === G.version) {
991
638
  return this.value;
992
639
  }
993
- this.state &= ~State.OutLink;
994
- // pullShallow 前重置 recEnd,让子 getter 重构订阅链表
995
- this.recEnd = undefined;
996
- Signal.Pulling = this;
997
- const v = this.pull();
998
- // 如果使用了 DEFAULT_PULL,处理一次 set 的取值后,替换回 customPull,如果有的话
640
+ this.recEnd = null;
641
+ G.PullingSignal = this;
642
+ (_a = this.clean) == null ? void 0 : _a.call(this);
643
+ this.clean = null;
644
+ let v = this.pull();
645
+ if (isScope && typeof v === "function") {
646
+ const fn = v;
647
+ this.clean = () => runWithPulling(fn, null);
648
+ v = this.value;
649
+ }
999
650
  this.pull = this.customPull || this.DEFAULT_PULL;
1000
651
  this.value = v;
1001
- // 依赖上游的 版本号
1002
652
  this.version = G.version;
1003
- // if (this.value !== v) {
1004
- // }
1005
653
  return this.value;
1006
654
  } catch (error) {
1007
- console.error('计算属性报错这次不触发,后续状态可能出错', error);
655
+ console.error("\u8BA1\u7B97\u5C5E\u6027\u62A5\u9519\u8FD9\u6B21\u4E0D\u89E6\u53D1\uFF0C\u540E\u7EED\u72B6\u6001\u53EF\u80FD\u51FA\u9519", error);
1008
656
  return this.value;
1009
657
  } finally {
1010
- // getter 执行完成时上游 getter 通过 link,完成对下游 recLines 的更新
1011
- const toDel = (_a = this.recEnd) === null || _a === void 0 ? void 0 : _a.nextRecLine;
658
+ const toDel = (_b = this.recEnd) == null ? void 0 : _b.nextRecLine;
1012
659
  unlinkRecWithScope(toDel);
1013
- if (shouldLink && downstream) {
1014
- // 用于 scope 指示哪些节点依赖 scope 外部
1015
- markOutLink(this, downstream);
1016
- }
1017
- Signal.Pulling = downstream;
660
+ G.PullingSignal = downstream;
1018
661
  }
1019
662
  }
1020
663
  pullDeep() {
1021
- /*----------------- 有上游节点,通过 dfs 重新计算结果 -----------------*/
1022
664
  const signal = this;
1023
- // 优化执行
1024
665
  if (!(signal.state & DirtyState)) {
1025
666
  return this.value;
1026
667
  }
1027
668
  dfs(signal, {
1028
669
  isUp: true,
1029
- begin: ({
1030
- node
1031
- }) => {
1032
- // console.log('begin', node.id);
1033
- /**
1034
- * 不需要检查
1035
- * 1. 正在查
1036
- * 2. 干净
1037
- * 3. 放弃 或者为 scope 节点
1038
- */
1039
- if (node.state & State.Check || !(node.state & DirtyState) || node.isAbort()) {
670
+ begin: ({ node }) => {
671
+ if (node.state & State.Check || !(node.state & DirtyState) || node.isDisabled()) {
1040
672
  return true;
1041
673
  }
1042
674
  node.state |= State.Check;
1043
- // 交给下游重新计算是否 引用外部节点
1044
- node.state &= ~State.OutLink;
1045
675
  },
1046
- complete: ({
1047
- node,
1048
- notGoDeep: currentClean,
1049
- walkedLine
1050
- }) => {
676
+ complete: ({ node, notGoDeep: currentClean, walkedLine }) => {
1051
677
  let noGoSibling = false;
1052
678
  const last = walkedLine[walkedLine.length - 1];
1053
- const downstream = last === null || last === void 0 ? void 0 : last.downstream;
1054
- // 当前正在检查,生成检查屏障,同时避免重新标记
1055
- if (currentClean) ;
1056
- // 当前节点需要重新计算
1057
- else if (node.state & State.Dirty) {
1058
- // 优化:源节点变化,直接让下游节点重新计算
679
+ const downstream = last == null ? void 0 : last.downstream;
680
+ if (currentClean) ; else if (node.state & State.Dirty) {
1059
681
  if (!node.recStart && node.value !== node.nextValue) {
1060
682
  node.markDownStreamsDirty();
1061
683
  node.state &= ~State.Dirty;
1062
684
  node.state &= ~State.Check;
1063
685
  return;
1064
- }
1065
- // 预检数据
1066
- else {
1067
- const prevPulling = Signal.Pulling;
1068
- Signal.Pulling = downstream;
686
+ } else {
687
+ const prevPulling = G.PullingSignal;
688
+ G.PullingSignal = downstream;
1069
689
  const prevValue = node.value;
1070
- // 递归转用递归拉取,且不需要重建 link 因为dfs的前提就是上游节点依赖于 本节点
1071
690
  node.pullRecurse(false);
1072
- // dirty 传播, 由于本节点值已被计算出,因此消除 dirty
1073
691
  if (prevValue !== node.value) {
1074
692
  node.markDownStreamsDirty();
1075
693
  }
1076
694
  node.state &= ~State.Dirty;
1077
- Signal.Pulling = prevPulling;
1078
- // 立刻返回父节点重新计算
695
+ G.PullingSignal = prevPulling;
1079
696
  noGoSibling = true;
1080
697
  }
1081
- }
1082
- // 没被上游节点标记为 Dirty,说明是干净的
1083
- else if (node.state & State.Unknown) {
698
+ } else if (node.state & State.Unknown) {
1084
699
  node.state &= ~State.Unknown;
1085
700
  }
1086
701
  node.version = G.version;
1087
702
  node.state &= ~State.Check;
1088
- if (downstream) {
1089
- markOutLink(node, downstream);
1090
- }
1091
703
  return noGoSibling;
1092
704
  }
1093
705
  });
1094
706
  return this.value;
1095
707
  }
1096
- get() {
1097
- if (this.isAbort()) {
708
+ get v() {
709
+ if (this.isDisabled()) {
1098
710
  return this.value;
1099
711
  }
1100
- // 没有上游节点,应该通过递归重新建立
1101
712
  if (!this.recStart) {
1102
713
  return this.pullRecurse(true);
1103
714
  }
1104
- // 有上游节点则采用 dfs 直接遍历,查看情况
1105
715
  return this.pullDeep();
1106
716
  }
717
+ // pause() {
718
+ // this.state |= State.SelfPaused;
719
+ // }
720
+ // resume() {
721
+ // this.state &= ~State.SelfPaused;
722
+ // }
1107
723
  markDownStreamsDirty() {
1108
724
  let point = this.emitStart;
1109
725
  while (point != null) {
@@ -1113,166 +729,128 @@ class Signal {
1113
729
  point = point.nextEmitLine;
1114
730
  }
1115
731
  }
1116
- set(v) {
1117
- if (this.isAbort() || this.nextValue === v) {
732
+ set v(v) {
733
+ if (this.isDisabled() || this.nextValue === v) {
1118
734
  return;
1119
735
  }
1120
736
  this.nextValue = v;
1121
- // 手动设值后,采用默认拉取,能拉取到设置的值,拉取完成后在替换回 customPull
1122
737
  this.pull = this.DEFAULT_PULL;
1123
738
  G.version++;
1124
739
  markDeep(this);
1125
740
  }
1126
- run(...args) {
1127
- if (args.length) {
1128
- return this.set(args[0]);
1129
- }
1130
- return this.get();
1131
- }
1132
741
  runIfDirty() {
1133
- this.state & (State.Unknown | State.Dirty) && this.run();
742
+ this.state & (State.Unknown | State.Dirty) && this.v;
1134
743
  }
1135
- isAbort() {
744
+ isDisabled() {
1136
745
  return (
1137
746
  // scope 被取消
1138
- this.scope && this.scope.state & State.ScopeAbort ||
1139
- // scope 节点,且处于 ready 状态,不需要重复执行
1140
- this === this.scope && this.state & ScopeExecuted
747
+ this.scope && this.scope.state & State.ScopeAbort || // 是 scope 节点,且处于 ready 状态,不需要重复执行
748
+ this.state & State.IsScope && this.state & ScopeExecuted
1141
749
  );
1142
750
  }
1143
- }
1144
- Signal.Pulling = null;
1145
- function runWithPulling(fn, signal) {
1146
- const prevPulling = Signal.Pulling;
1147
- Signal.Pulling = signal;
1148
- fn();
1149
- Signal.Pulling = prevPulling;
1150
- }
751
+ };
752
+ _Signal.Pulling = null;
753
+ let Signal = _Signal;
1151
754
 
1152
- const DefaultCustomSignalOpt = {
1153
- scheduler: exports.Scheduler.Sync,
1154
- isScope: false
755
+ var __defProp = Object.defineProperty;
756
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
757
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
758
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
759
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
760
+ var __spreadValues = (a, b) => {
761
+ for (var prop in b || (b = {}))
762
+ if (__hasOwnProp.call(b, prop))
763
+ __defNormalProp(a, prop, b[prop]);
764
+ if (__getOwnPropSymbols)
765
+ for (var prop of __getOwnPropSymbols(b)) {
766
+ if (__propIsEnum.call(b, prop))
767
+ __defNormalProp(a, prop, b[prop]);
768
+ }
769
+ return a;
1155
770
  };
1156
- const $ = (init, opt = {}) => {
1157
- let intiValue, pull;
771
+ ({
772
+ scheduler: Scheduler.Sync});
773
+ const $ = (init) => {
774
+ let intiValue, customPull;
1158
775
  if (init instanceof Function) {
1159
- intiValue = undefined;
1160
- pull = init;
776
+ intiValue = null;
777
+ customPull = init;
1161
778
  } else {
1162
779
  intiValue = init;
1163
780
  }
1164
- const signalOpt = {
1165
- ...DefaultCustomSignalOpt,
1166
- ...opt,
1167
- customPull: pull
1168
- };
1169
- const s = Signal.create(intiValue, signalOpt);
1170
- const bound = s.run.bind(s);
1171
- bound.ins = s;
1172
- Object.defineProperty(bound, 'v', {
1173
- get() {
1174
- return s.get();
1175
- },
1176
- set(v) {
1177
- return s.set(v);
1178
- }
781
+ const s = Signal.create(intiValue, {
782
+ scheduler: Scheduler.Sync,
783
+ isScope: false,
784
+ customPull
1179
785
  });
1180
- return bound;
786
+ return s;
1181
787
  };
1182
- const watch = (values, watcher, opt) => {
788
+ const effect = (customPull, depOrOpt, opt) => {
789
+ var _a;
790
+ const hasDep = Array.isArray(depOrOpt);
791
+ opt = hasDep ? opt || {} : depOrOpt || {};
792
+ if (!hasDep) {
793
+ const s2 = Signal.create(null, __spreadValues({
794
+ customPull,
795
+ scheduler: Scheduler.Sync,
796
+ isScope: true
797
+ }, opt));
798
+ s2.v;
799
+ const bound2 = dispose.bind(s2);
800
+ bound2.ins = s2;
801
+ return bound2;
802
+ }
1183
803
  let mounted = false;
1184
- const get = $(() => {
1185
- for (const get of values) {
1186
- get();
1187
- }
1188
- if (mounted) {
1189
- runWithPulling(watcher, undefined);
1190
- }
1191
- mounted = true;
1192
- }, opt);
1193
- get();
1194
- return get;
804
+ const deps = depOrOpt;
805
+ const immediate = deps.length === 0 ? true : (_a = opt.immediate) != null ? _a : true;
806
+ const vs = Array.from({ length: deps.length }, () => ({ old: null, val: null }));
807
+ const s = Signal.create(null, __spreadValues({
808
+ customPull() {
809
+ for (let i = 0; i < deps.length; i++) {
810
+ const value = deps[i].v;
811
+ vs[i].old = vs[i].val;
812
+ vs[i].val = value;
813
+ }
814
+ if (mounted || immediate) {
815
+ s.state |= State.LinkScopeOnly;
816
+ customPull(...vs);
817
+ s.state &= ~State.LinkScopeOnly;
818
+ }
819
+ mounted = true;
820
+ },
821
+ scheduler: Scheduler.Sync,
822
+ isScope: true
823
+ }, opt));
824
+ s.v;
825
+ const bound = dispose.bind(s);
826
+ bound.ins = s;
827
+ return bound;
1195
828
  };
1196
- const scope = fn => {
1197
- const s = Signal.create(undefined, {
1198
- customPull: fn,
829
+ const scope = (customPull) => {
830
+ const s = Signal.create(null, {
831
+ customPull,
832
+ scheduler: Scheduler.Sync,
1199
833
  isScope: true
1200
834
  });
1201
- s.get();
835
+ s.v;
1202
836
  s.state |= State.ScopeReady;
1203
- function dispose() {
1204
- s.state |= State.ScopeAbort;
1205
- const bound = handleOneTask.bind(undefined, s, []);
1206
- bound.index = G.scopeDisposeI++;
1207
- ideScheduler.pushTask(bound);
1208
- }
1209
- dispose.ins = s;
1210
- return dispose;
837
+ const bound = dispose.bind(s);
838
+ bound.ins = s;
839
+ return bound;
1211
840
  };
1212
- /**
1213
- * 数据变化时,自定义 触发订阅函数的时机
1214
- * @param {CustomSignalOpt} opt 配置如下:
1215
- * @prop scheduler: (runIfDirty, effect) => void 执行 runIfDirty 定制触发 effect 时机
1216
- * @prop scope: 用于统一释放 effect link 的作用域 默认是 defaultScope 可以全局获取
1217
- */
1218
- const customSignal = opt => {
1219
- return (init, innerOpt = {}) => {
1220
- const s = $(init, {
1221
- ...opt,
1222
- ...innerOpt
1223
- });
1224
- return s;
1225
- };
841
+ const customEffect = (opt) => {
842
+ return ((init, innerOpt = {}) => {
843
+ return effect(init, __spreadValues(__spreadValues({}, opt), innerOpt));
844
+ });
1226
845
  };
1227
- // const globalSignal = $(10);
1228
- // let outerA, outerB, innerX, innerY, outerResult, innerResult, innerDispose;
1229
- // const outerDispose = scope(() => {
1230
- // outerA = $(1);
1231
- // outerB = $(2);
1232
- // // 外层计算信号
1233
- // outerResult = $(() => {
1234
- // const res = globalSignal.v + outerA.v + outerB.v;
1235
- // return res;
1236
- // });
1237
- // innerDispose = scope(() => {
1238
- // innerX = $(3);
1239
- // innerY = $(4);
1240
- // // 内层计算信号,既依赖内层也依赖外层信号
1241
- // innerResult = $(() => {
1242
- // const res = outerA.v + innerX.v + innerY.v;
1243
- // return res;
1244
- // });
1245
- // // 访问信号以建立依赖关系
1246
- // innerResult();
1247
- // });
1248
- // // 访问外层信号
1249
- // outerResult();
1250
- // // 将内层dispose函数绑定到外层scope,这样可以测试嵌套行为
1251
- // (outerResult as any).innerDispose = innerDispose;
1252
- // });
1253
- // outerA.v = 5;
1254
- // innerX.v = 6;
1255
- // globalSignal.v = 20;
1256
- // // 先释放内层scope
1257
- // innerDispose();
1258
- // innerX.v = 7;
1259
- // outerA.v = 8;
1260
- // outerDispose();
1261
- // evt.on('one', ({ index }) => {
1262
- // switch (index) {
1263
- // case 0:
1264
- // console.log({ index });
1265
- // break;
1266
- // case 1:
1267
- // console.log({ index });
1268
- // default:
1269
- // break;
1270
- // }
1271
- // });
1272
846
 
1273
847
  exports.$ = $;
848
+ exports.Scheduler = Scheduler;
1274
849
  exports.TaskQueue = TaskQueue;
1275
- exports.customSignal = customSignal;
850
+ exports.clean = clean;
851
+ exports.customEffect = customEffect;
852
+ exports.effect = effect;
853
+ exports.runWithPulling = runWithPulling;
1276
854
  exports.scheduler = scheduler;
1277
855
  exports.scope = scope;
1278
- exports.watch = watch;
856
+ //# sourceMappingURL=aoye.cjs.js.map