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 +378 -800
- package/dist/aoye.cjs.js.map +1 -0
- package/dist/aoye.esm.js +372 -795
- package/dist/aoye.esm.js.map +1 -0
- package/dist/index.d.ts +203 -0
- package/dist/index.umd.js +860 -0
- package/dist/index.umd.js.map +1 -0
- package/package.json +14 -12
- package/dist/aoye.umd.js +0 -1211
- package/dist/shared/event.d.ts +0 -72
- package/dist/shared/util.d.ts +0 -22
- package/dist/signal/src/__test__/dep-str.d.ts +0 -8
- package/dist/signal/src/__test__/scope.test.d.ts +0 -1
- package/dist/signal/src/__test__/siganl.test.d.ts +0 -1
- package/dist/signal/src/__test__/watch.test.d.ts +0 -1
- package/dist/signal/src/dfs.d.ts +0 -14
- package/dist/signal/src/global.d.ts +0 -25
- package/dist/signal/src/index.d.ts +0 -28
- package/dist/signal/src/line.d.ts +0 -31
- package/dist/signal/src/priority-queue.d.ts +0 -44
- package/dist/signal/src/schedule.d.ts +0 -9
- package/dist/signal/src/scope.d.ts +0 -15
- package/dist/signal/src/signal.d.ts +0 -42
- package/dist/signal/src/task.d.ts +0 -12
- package/dist/signal/src/test-hidden-class-transfrom.d.ts +0 -17
- package/dist/signal/src/type.d.ts +0 -42
- package/dist/signal/src/util.d.ts +0 -4
package/dist/aoye.esm.js
CHANGED
|
@@ -1,186 +1,4 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
const
|
|
207
|
-
const
|
|
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(
|
|
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(
|
|
160
|
+
evt.emit("one", fn);
|
|
426
161
|
if (taskQueue.size() === 0) {
|
|
427
|
-
evt.emit(
|
|
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(
|
|
182
|
+
channel.port2.removeEventListener("message", onMessage);
|
|
458
183
|
}
|
|
459
184
|
}
|
|
460
|
-
channel.port2.addEventListener(
|
|
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
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
})(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
|
-
[
|
|
477
|
-
[
|
|
478
|
-
[
|
|
479
|
-
[
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
515
|
-
complete:
|
|
246
|
+
begin: null,
|
|
247
|
+
complete: null,
|
|
516
248
|
breakStack: [],
|
|
517
|
-
breakLine:
|
|
518
|
-
breakNode:
|
|
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 ?
|
|
534
|
-
const nodeKey = isUp ?
|
|
535
|
-
|
|
536
|
-
const
|
|
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
|
|
540
|
-
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
|
|
553
|
-
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
|
-
|
|
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] =
|
|
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
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
line.
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
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
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
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
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
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
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
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
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
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
|
|
889
|
-
|
|
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
|
-
|
|
895
|
-
|
|
896
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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.
|
|
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 =
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
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.
|
|
990
|
-
|
|
991
|
-
this.
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
740
|
+
this.state & (State.Unknown | State.Dirty) && this.v;
|
|
1130
741
|
}
|
|
1131
|
-
|
|
742
|
+
isDisabled() {
|
|
1132
743
|
return (
|
|
1133
744
|
// scope 被取消
|
|
1134
|
-
this.scope && this.scope.state & State.ScopeAbort ||
|
|
1135
|
-
|
|
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
|
-
|
|
1141
|
-
|
|
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
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
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
|
-
|
|
1153
|
-
|
|
769
|
+
({
|
|
770
|
+
scheduler: Scheduler.Sync});
|
|
771
|
+
const $ = (init) => {
|
|
772
|
+
let intiValue, customPull;
|
|
1154
773
|
if (init instanceof Function) {
|
|
1155
|
-
intiValue =
|
|
1156
|
-
|
|
774
|
+
intiValue = null;
|
|
775
|
+
customPull = init;
|
|
1157
776
|
} else {
|
|
1158
777
|
intiValue = init;
|
|
1159
778
|
}
|
|
1160
|
-
const
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
customPull
|
|
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
|
|
784
|
+
return s;
|
|
1177
785
|
};
|
|
1178
|
-
const
|
|
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
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
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 =
|
|
1193
|
-
const s = Signal.create(
|
|
1194
|
-
customPull
|
|
827
|
+
const scope = (customPull) => {
|
|
828
|
+
const s = Signal.create(null, {
|
|
829
|
+
customPull,
|
|
830
|
+
scheduler: Scheduler.Sync,
|
|
1195
831
|
isScope: true
|
|
1196
832
|
});
|
|
1197
|
-
s.
|
|
833
|
+
s.v;
|
|
1198
834
|
s.state |= State.ScopeReady;
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
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
|
-
|
|
1211
|
-
|
|
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,
|
|
845
|
+
export { $, Scheduler, TaskQueue, clean, customEffect, effect, runWithPulling, scheduler, scope };
|
|
846
|
+
//# sourceMappingURL=aoye.esm.js.map
|