aoye 0.0.44 → 0.0.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/aoye.cjs.js CHANGED
@@ -18,12 +18,126 @@ function runWithPulling(fn, scope) {
18
18
  return ret;
19
19
  }
20
20
 
21
+ let ScheduleType = function (ScheduleType) {
22
+ ScheduleType[ScheduleType["Sync"] = 1] = "Sync";
23
+ ScheduleType[ScheduleType["Pre"] = 2] = "Pre";
24
+ ScheduleType[ScheduleType["Render"] = 4] = "Render";
25
+ ScheduleType[ScheduleType["Post"] = 8] = "Post";
26
+ return ScheduleType;
27
+ }({});
28
+ let ScheduleStatus = function (ScheduleStatus) {
29
+ ScheduleStatus[ScheduleStatus["Idle"] = 0] = "Idle";
30
+ ScheduleStatus[ScheduleStatus["Ready"] = 1] = "Ready";
31
+ ScheduleStatus[ScheduleStatus["Running"] = 2] = "Running";
32
+ return ScheduleStatus;
33
+ }({});
34
+
35
+ class MultiScheduler {
36
+ hasTask = 0;
37
+ taskMap = {};
38
+ constructor(queueCount) {
39
+ for (let i = 0; i < queueCount; i++) {
40
+ this.taskMap[1 << i] = {
41
+ head: null,
42
+ tail: null
43
+ };
44
+ }
45
+ }
46
+ addTask(queueId, task) {
47
+ const queue = this.taskMap[queueId];
48
+ const tail = queue.tail;
49
+ const item = {
50
+ value: task,
51
+ next: null
52
+ };
53
+ if (tail) {
54
+ tail.next = item;
55
+ } else {
56
+ queue.head = item;
57
+ }
58
+ queue.tail = item;
59
+ this.hasTask |= queueId;
60
+ }
61
+ flushAllTask() {
62
+ while (this.hasTask) {
63
+ const hasTask = this.hasTask;
64
+ const highest = hasTask & ~hasTask + 1;
65
+ const task = this.consumeTask(highest).value;
66
+ task.get();
67
+ }
68
+ }
69
+ consumeTask(queueId) {
70
+ const queue = this.taskMap[queueId];
71
+ const head = queue.head,
72
+ tail = queue.tail;
73
+ const next = head.next;
74
+ head.next = null;
75
+ if (head === tail) {
76
+ queue.head = null;
77
+ queue.tail = null;
78
+ this.hasTask &= ~queueId;
79
+ } else {
80
+ head.next = null;
81
+ queue.head = next;
82
+ }
83
+ return head;
84
+ }
85
+ }
86
+ const multiScheduler = new MultiScheduler(4);
87
+
88
+ let Keys = function (Keys) {
89
+ Keys["Iterator"] = "__AOYE_ITERATOR";
90
+ Keys["Raw"] = "__AOYE_RAW";
91
+ Keys["Meta"] = "__AOYE_META";
92
+ Keys["ProxyFreeObject"] = "__AOYE_PROXY_FREE_OBJECT";
93
+ return Keys;
94
+ }({});
95
+ const IsStore = Symbol('__AOYE_IS_STORE'),
96
+ StoreIgnoreKeys = Symbol('__AOYE_IGNORE_KEYS');
97
+
98
+ const ide = globalThis.requestIdleCallback || (globalThis.requestAnimationFrame ? fn => globalThis.requestAnimationFrame(() => {
99
+ setTimeout(() => {
100
+ fn();
101
+ });
102
+ }) : globalThis.setTimeout);
103
+ const now = () => {
104
+ const timer = globalThis.performance || globalThis.Date;
105
+ return timer.now();
106
+ };
107
+ let channel = globalThis.MessageChannel ? new MessageChannel() : null;
108
+ if (globalThis.MessageChannel) {
109
+ channel = new MessageChannel();
110
+ }
111
+ let msgId = 0;
112
+ const macro = fn => {
113
+ if (!channel) {
114
+ setTimeout(fn);
115
+ }
116
+ const memoId = msgId;
117
+ function onMessage(e) {
118
+ if (memoId === e.data) {
119
+ fn();
120
+ channel.port2.removeEventListener('message', onMessage);
121
+ }
122
+ }
123
+ channel.port2.addEventListener('message', onMessage);
124
+ channel.port1.postMessage(msgId++);
125
+ };
126
+ const p = Promise.resolve();
127
+ const micro = cb => {
128
+ p.then(cb);
129
+ };
130
+ const toRaw = a => {
131
+ if (typeof a === 'object' && a !== null && a[Keys.Raw]) {
132
+ return toRaw(a[Keys.Raw]);
133
+ }
134
+ return a;
135
+ };
136
+
21
137
  function mark(signal) {
22
138
  let line = signal.emitHead;
23
139
  while (line) {
24
- const _line = line,
25
- down = _line.down;
26
- _line.up;
140
+ const down = line.down;
27
141
  const scope = down.scope,
28
142
  emitHead = down.emitHead,
29
143
  state = down.state;
@@ -32,7 +146,11 @@ function mark(signal) {
32
146
  down.state |= notLocked ? 2 : 16;
33
147
  if (state & 32) {
34
148
  if (notLocked && state & 512) {
35
- addEffect(down);
149
+ if (down.type === ScheduleType.Sync) {
150
+ addEffect(down);
151
+ } else {
152
+ multiScheduler.addTask(down.type, down);
153
+ }
36
154
  }
37
155
  } else if (emitHead) {
38
156
  markUnknownDeep(emitHead);
@@ -49,9 +167,7 @@ function markUnknownDeep(initialLine) {
49
167
  let line = stack[--len];
50
168
  stack[len] = null;
51
169
  while (line) {
52
- const _line2 = line,
53
- down = _line2.down;
54
- _line2.up;
170
+ const down = line.down;
55
171
  const state = down.state,
56
172
  scope = down.scope;
57
173
  if (scope && scope.state & 128 || noPulling && state & 6) ; else {
@@ -59,7 +175,11 @@ function markUnknownDeep(initialLine) {
59
175
  down.state |= notLocked ? 4 : 8;
60
176
  if (state & 32) {
61
177
  if (notLocked && state & 512) {
62
- addEffect(down);
178
+ if (down.type === ScheduleType.Sync) {
179
+ addEffect(down);
180
+ } else {
181
+ multiScheduler.addTask(down.type, down);
182
+ }
63
183
  }
64
184
  } else if (down.emitHead) {
65
185
  stack[len++] = down.emitHead;
@@ -103,8 +223,8 @@ function pullDeep(root) {
103
223
  if (noGoSibling = value !== prevValue) {
104
224
  let line = node.emitHead;
105
225
  while (line) {
106
- const _line3 = line,
107
- down = _line3.down;
226
+ const _line = line,
227
+ down = _line.down;
108
228
  down.state &= -5;
109
229
  down.state |= 2;
110
230
  line = line.nextEmitLine;
@@ -148,7 +268,7 @@ let consumeI = -1,
148
268
  function addEffect(effect) {
149
269
  effectQueue[++produceI] = effect;
150
270
  }
151
- function flushEffect() {
271
+ function flushSyncEffect() {
152
272
  if (consumeI !== -1) {
153
273
  return;
154
274
  }
@@ -162,12 +282,24 @@ function flushEffect() {
162
282
  consumeI = -1;
163
283
  produceI = -1;
164
284
  }
285
+ let schedulerStatus = ScheduleStatus.Idle;
286
+ function flushMicroEffect() {
287
+ if (schedulerStatus === ScheduleStatus.Idle && multiScheduler.hasTask) {
288
+ schedulerStatus = ScheduleStatus.Ready;
289
+ micro(() => {
290
+ schedulerStatus = ScheduleStatus.Running;
291
+ multiScheduler.flushAllTask();
292
+ schedulerStatus = ScheduleStatus.Idle;
293
+ });
294
+ }
295
+ }
165
296
  let _batchDeep = 0;
166
297
  const batchStart = () => _batchDeep++;
167
298
  const batchEnd = () => {
168
299
  _batchDeep--;
169
300
  if (_batchDeep === 0) {
170
- flushEffect();
301
+ flushSyncEffect();
302
+ flushMicroEffect();
171
303
  }
172
304
  };
173
305
  const batchDeep = () => _batchDeep;
@@ -495,7 +627,8 @@ class Signal {
495
627
  if (this.emitHead) {
496
628
  mark(this);
497
629
  if (batchDeep() === 0) {
498
- flushEffect();
630
+ flushSyncEffect();
631
+ flushMicroEffect();
499
632
  }
500
633
  }
501
634
  }
@@ -511,8 +644,9 @@ class Effect {
511
644
  scope = getPulling();
512
645
  outLink = null;
513
646
  clean = null;
514
- constructor(callback) {
647
+ constructor(callback, type = ScheduleType.Sync) {
515
648
  this.callback = callback;
649
+ this.type = type;
516
650
  this.get();
517
651
  }
518
652
  get(shouldLink = true, notForceUpdate = true) {
@@ -579,16 +713,6 @@ class Scope {
579
713
  }
580
714
  Scope.prototype.dispose = dispose;
581
715
 
582
- let Keys = function (Keys) {
583
- Keys["Iterator"] = "__AOYE_ITERATOR";
584
- Keys["Raw"] = "__AOYE_RAW";
585
- Keys["Meta"] = "__AOYE_META";
586
- Keys["ProxyFreeObject"] = "__AOYE_PROXY_FREE_OBJECT";
587
- return Keys;
588
- }({});
589
- const IsStore = Symbol('__AOYE_IS_STORE'),
590
- StoreIgnoreKeys = Symbol('__AOYE_IGNORE_KEYS');
591
-
592
716
  const rawToProxy = new WeakMap();
593
717
  let State = function (State) {
594
718
  State[State["Clean"] = 0] = "Clean";
@@ -607,45 +731,6 @@ State.Unknown | State.Dirty;
607
731
  State.ScopeReady | State.ScopeAbort;
608
732
  State.ScopeAbort;
609
733
 
610
- const ide = globalThis.requestIdleCallback || (globalThis.requestAnimationFrame ? fn => globalThis.requestAnimationFrame(() => {
611
- setTimeout(() => {
612
- fn();
613
- });
614
- }) : globalThis.setTimeout);
615
- const now = () => {
616
- const timer = globalThis.performance || globalThis.Date;
617
- return timer.now();
618
- };
619
- let channel = globalThis.MessageChannel ? new MessageChannel() : null;
620
- if (globalThis.MessageChannel) {
621
- channel = new MessageChannel();
622
- }
623
- let msgId = 0;
624
- const macro = fn => {
625
- if (!channel) {
626
- setTimeout(fn);
627
- }
628
- const memoId = msgId;
629
- function onMessage(e) {
630
- if (memoId === e.data) {
631
- fn();
632
- channel.port2.removeEventListener('message', onMessage);
633
- }
634
- }
635
- channel.port2.addEventListener('message', onMessage);
636
- channel.port1.postMessage(msgId++);
637
- };
638
- const p = Promise.resolve();
639
- const micro = cb => {
640
- p.then(cb);
641
- };
642
- const toRaw = a => {
643
- if (typeof a === 'object' && a !== null && a[Keys.Raw]) {
644
- return toRaw(a[Keys.Raw]);
645
- }
646
- return a;
647
- };
648
-
649
734
  const deepSignal = (target, scope, deep = true) => {
650
735
  const isObj = typeof target === 'object' && target !== null;
651
736
  if (!isObj || target[Keys.Raw] || target[Keys.ProxyFreeObject]) return target;
@@ -1171,11 +1256,14 @@ function $(data) {
1171
1256
  };
1172
1257
  }
1173
1258
  }
1259
+ ({
1260
+ type: ScheduleType.Sync
1261
+ });
1174
1262
  function effectUt(callback, depOrOpt, opt) {
1175
1263
  const hasDep = Array.isArray(depOrOpt);
1176
1264
  opt = hasDep ? opt || {} : depOrOpt || {};
1177
1265
  if (!hasDep) {
1178
- const ef = new Effect(callback);
1266
+ const ef = new Effect(callback, opt.type);
1179
1267
  const run = ef.dispose.bind(ef);
1180
1268
  run.ins = ef;
1181
1269
  return run;
@@ -1189,19 +1277,19 @@ function effectUt(callback, depOrOpt, opt) {
1189
1277
  old: null,
1190
1278
  val: null
1191
1279
  }));
1192
- const ef = new Effect(() => {
1280
+ const ef = new Effect(eff => {
1193
1281
  for (let i = 0; i < deps.length; i++) {
1194
1282
  const value = deps[i].v;
1195
1283
  vs[i].old = vs[i].val;
1196
1284
  vs[i].val = value;
1197
1285
  }
1198
1286
  if (mounted || immediate) {
1199
- ef.state |= 256;
1287
+ eff.state |= 256;
1200
1288
  callback(...vs);
1201
- ef.state &= -257;
1289
+ eff.state &= -257;
1202
1290
  }
1203
1291
  mounted = true;
1204
- });
1292
+ }, opt.type);
1205
1293
  const run = ef.dispose.bind(ef);
1206
1294
  run.ins = ef;
1207
1295
  return run;
@@ -1210,7 +1298,7 @@ function effect(callback, depOrOpt, opt) {
1210
1298
  const hasDep = Array.isArray(depOrOpt);
1211
1299
  opt = hasDep ? opt || {} : depOrOpt || {};
1212
1300
  if (!hasDep) {
1213
- const ef = new Effect(callback);
1301
+ const ef = new Effect(callback, opt.type);
1214
1302
  return ef;
1215
1303
  }
1216
1304
  let mounted = false;
@@ -1234,7 +1322,7 @@ function effect(callback, depOrOpt, opt) {
1234
1322
  eff.state &= -257;
1235
1323
  }
1236
1324
  mounted = true;
1237
- });
1325
+ }, opt.type);
1238
1326
  return ef;
1239
1327
  }
1240
1328
  function scope(...args) {
@@ -1253,6 +1341,8 @@ exports.Computed = Computed;
1253
1341
  exports.Effect = Effect;
1254
1342
  exports.IsStore = IsStore;
1255
1343
  exports.Keys = Keys;
1344
+ exports.ScheduleStatus = ScheduleStatus;
1345
+ exports.ScheduleType = ScheduleType;
1256
1346
  exports.Scope = Scope;
1257
1347
  exports.Signal = Signal;
1258
1348
  exports.Store = Store;