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