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