@vobs/queue 1.2.1 → 1.2.2
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/index.cjs +61 -229
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +22 -212
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -1,218 +1,36 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
var __VOBS_CJS_FILE_URL = require("url").pathToFileURL(__filename).href;
|
|
2
|
+
"use strict";
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
7
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
var signalNames = /* @__PURE__ */ new WeakMap();
|
|
9
|
-
function hasDebugHooks() {
|
|
10
|
-
return activeDebugHooks !== null;
|
|
11
|
-
}
|
|
12
|
-
__name(hasDebugHooks, "hasDebugHooks");
|
|
13
|
-
function setSignalDebugName(signal, name) {
|
|
14
|
-
signalNames.set(signal, name);
|
|
15
|
-
invokeDebug("signalNamed", signal, name);
|
|
16
|
-
}
|
|
17
|
-
__name(setSignalDebugName, "setSignalDebugName");
|
|
18
|
-
function invokeDebug(name, ...args) {
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
__name(invokeDebug, "invokeDebug");
|
|
22
|
-
|
|
23
|
-
// packages/reactivity/src/owner.ts
|
|
24
|
-
var currentOwner = null;
|
|
25
|
-
function getCurrentOwner() {
|
|
26
|
-
return currentOwner;
|
|
27
|
-
}
|
|
28
|
-
__name(getCurrentOwner, "getCurrentOwner");
|
|
29
|
-
function onDispose(cleanup) {
|
|
30
|
-
throw new Error("Vobs: onDispose \u5FC5\u987B\u5728 Owner \u4F5C\u7528\u57DF\u5185\u8C03\u7528");
|
|
31
|
-
}
|
|
32
|
-
__name(onDispose, "onDispose");
|
|
33
|
-
|
|
34
|
-
// packages/reactivity/src/signal.ts
|
|
35
|
-
var currentSubscriber = null;
|
|
36
|
-
function getCurrentSubscriber() {
|
|
37
|
-
return currentSubscriber;
|
|
38
|
-
}
|
|
39
|
-
__name(getCurrentSubscriber, "getCurrentSubscriber");
|
|
40
|
-
function trackDependency(dependency) {
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
__name(trackDependency, "trackDependency");
|
|
44
|
-
function state(initialValue, debugName) {
|
|
45
|
-
let value = initialValue;
|
|
46
|
-
let disposed = false;
|
|
47
|
-
const subscribers = /* @__PURE__ */ new Set();
|
|
48
|
-
const signalInstance = {
|
|
49
|
-
get value() {
|
|
50
|
-
return value;
|
|
51
|
-
},
|
|
52
|
-
set value(nextValue) {
|
|
53
|
-
if (disposed || Object.is(value, nextValue)) return;
|
|
54
|
-
value = nextValue;
|
|
55
|
-
for (const subscriber of [...subscribers]) subscriber.notify();
|
|
56
|
-
},
|
|
57
|
-
unsubscribe(subscriber) {
|
|
58
|
-
subscribers.delete(subscriber);
|
|
59
|
-
},
|
|
60
|
-
// 与 `.value =` 赋值同一条路径:判等短路、debug hook、notify 全部一致。
|
|
61
|
-
// 以闭包实现,可安全地作为回调直接传递(无 this 绑定问题)。
|
|
62
|
-
set(next) {
|
|
63
|
-
signalInstance.value = next;
|
|
64
|
-
},
|
|
65
|
-
dispose() {
|
|
66
|
-
if (disposed) return;
|
|
67
|
-
disposed = true;
|
|
68
|
-
subscribers.clear();
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
if (debugName?.trim()) setSignalDebugName(signalInstance, debugName.trim());
|
|
72
|
-
return signalInstance;
|
|
73
|
-
}
|
|
74
|
-
__name(state, "state");
|
|
75
|
-
|
|
76
|
-
// packages/reactivity/src/scheduler.ts
|
|
77
|
-
var _Scheduler = class _Scheduler {
|
|
78
|
-
constructor() {
|
|
79
|
-
this.dirtyEffects = /* @__PURE__ */ new Set();
|
|
80
|
-
this.lowPriorityEffects = /* @__PURE__ */ new Set();
|
|
81
|
-
// flush 不可重入(flushing 标志保证),缓冲数组可在轮次间安全复用,避免每轮分配。
|
|
82
|
-
this.normalBuffer = [];
|
|
83
|
-
this.lowBuffer = [];
|
|
84
|
-
this.flushing = false;
|
|
85
|
-
this.scheduled = false;
|
|
86
|
-
this.batchDepth = 0;
|
|
87
|
-
}
|
|
88
|
-
schedule(effect2) {
|
|
89
|
-
if (effect2.disposed) return;
|
|
90
|
-
this.dirtyEffects.add(effect2);
|
|
91
|
-
this.lowPriorityEffects.delete(effect2);
|
|
92
|
-
this.ensureScheduled();
|
|
93
|
-
}
|
|
94
|
-
/** Queue an effect behind normal updates while preserving deterministic order. */
|
|
95
|
-
scheduleLow(effect2) {
|
|
96
|
-
if (effect2.disposed) return;
|
|
97
|
-
if (!this.dirtyEffects.has(effect2)) this.lowPriorityEffects.add(effect2);
|
|
98
|
-
this.ensureScheduled();
|
|
99
|
-
}
|
|
100
|
-
ensureScheduled() {
|
|
101
|
-
if (this.batchDepth === 0 && !this.flushing && !this.scheduled) {
|
|
102
|
-
this.scheduled = true;
|
|
103
|
-
queueMicrotask(() => {
|
|
104
|
-
this.scheduled = false;
|
|
105
|
-
this.flush();
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
remove(effect2) {
|
|
110
|
-
this.dirtyEffects.delete(effect2);
|
|
111
|
-
this.lowPriorityEffects.delete(effect2);
|
|
112
|
-
}
|
|
113
|
-
batch(fn) {
|
|
114
|
-
this.batchDepth++;
|
|
115
|
-
try {
|
|
116
|
-
return fn();
|
|
117
|
-
} finally {
|
|
118
|
-
this.batchDepth--;
|
|
119
|
-
if (this.batchDepth === 0) this.flush();
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
flush() {
|
|
123
|
-
if (this.flushing || this.batchDepth > 0) return;
|
|
124
|
-
this.flushing = true;
|
|
125
|
-
let rounds = 0;
|
|
126
|
-
let firstError;
|
|
127
|
-
let hasError = false;
|
|
128
|
-
try {
|
|
129
|
-
while (this.dirtyEffects.size > 0 || this.lowPriorityEffects.size > 0) {
|
|
130
|
-
if (++rounds > 100) {
|
|
131
|
-
this.dirtyEffects.clear();
|
|
132
|
-
this.lowPriorityEffects.clear();
|
|
133
|
-
throw new Error("Vobs: \u54CD\u5E94\u5F0F\u66F4\u65B0\u8D85\u8FC7 100 \u8F6E\uFF0C\u53EF\u80FD\u5B58\u5728\u5FAA\u73AF\u4F9D\u8D56");
|
|
134
|
-
}
|
|
135
|
-
this.collectRunnable(this.dirtyEffects, this.normalBuffer);
|
|
136
|
-
this.collectRunnable(this.lowPriorityEffects, this.lowBuffer);
|
|
137
|
-
sortEffects(this.normalBuffer);
|
|
138
|
-
sortEffects(this.lowBuffer);
|
|
139
|
-
for (const effect2 of this.normalBuffer) {
|
|
140
|
-
try {
|
|
141
|
-
effect2.run();
|
|
142
|
-
} catch (error) {
|
|
143
|
-
if (!hasError) {
|
|
144
|
-
firstError = error;
|
|
145
|
-
hasError = true;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
for (const effect2 of this.lowBuffer) {
|
|
150
|
-
try {
|
|
151
|
-
effect2.run();
|
|
152
|
-
} catch (error) {
|
|
153
|
-
if (!hasError) {
|
|
154
|
-
firstError = error;
|
|
155
|
-
hasError = true;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
this.normalBuffer.length = 0;
|
|
160
|
-
this.lowBuffer.length = 0;
|
|
161
|
-
}
|
|
162
|
-
} finally {
|
|
163
|
-
this.normalBuffer.length = 0;
|
|
164
|
-
this.lowBuffer.length = 0;
|
|
165
|
-
this.flushing = false;
|
|
166
|
-
}
|
|
167
|
-
if (hasError) throw firstError;
|
|
168
|
-
}
|
|
169
|
-
/** 收集未 disposed 的 effect 并清空源集合;run() 期间新调度的 effect 留给下一轮。 */
|
|
170
|
-
collectRunnable(source, target) {
|
|
171
|
-
for (const effect2 of source) {
|
|
172
|
-
if (!effect2.disposed) target.push(effect2);
|
|
173
|
-
}
|
|
174
|
-
source.clear();
|
|
175
|
-
}
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
176
11
|
};
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}
|
|
183
|
-
__name(sortEffects, "sortEffects");
|
|
184
|
-
|
|
185
|
-
// packages/runtime/src/hmr.ts
|
|
186
|
-
var globalTarget = globalThis;
|
|
187
|
-
var hmrGlobal = globalTarget.__VOBS_HMR__ ?? { modules: /* @__PURE__ */ new Map() };
|
|
188
|
-
globalTarget.__VOBS_HMR__ = hmrGlobal;
|
|
189
|
-
|
|
190
|
-
// packages/vobs/src/context.ts
|
|
191
|
-
var ownerProviders = /* @__PURE__ */ new WeakMap();
|
|
192
|
-
function inject(key, fallback) {
|
|
193
|
-
const owner = getCurrentOwner();
|
|
194
|
-
const value = owner ? injectFromOwner(owner, key) : void 0;
|
|
195
|
-
return value === void 0 ? fallback : value;
|
|
196
|
-
}
|
|
197
|
-
__name(inject, "inject");
|
|
198
|
-
function injectFromOwner(owner, key) {
|
|
199
|
-
let current = owner;
|
|
200
|
-
while (current) {
|
|
201
|
-
const providers = ownerProviders.get(current);
|
|
202
|
-
if (providers?.has(key)) return providers.get(key);
|
|
203
|
-
current = current.parent;
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
204
17
|
}
|
|
205
|
-
return
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
// packages/vobs/src/app.ts
|
|
210
|
-
function createInjectionKey(description) {
|
|
211
|
-
return Symbol(description);
|
|
212
|
-
}
|
|
213
|
-
__name(createInjectionKey, "createInjectionKey");
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
214
21
|
|
|
215
22
|
// packages/queue/src/index.ts
|
|
23
|
+
var src_exports = {};
|
|
24
|
+
__export(src_exports, {
|
|
25
|
+
QUEUE_KEY: () => QUEUE_KEY,
|
|
26
|
+
QueueError: () => QueueError,
|
|
27
|
+
createTaskQueue: () => createTaskQueue,
|
|
28
|
+
queuePlugin: () => queuePlugin,
|
|
29
|
+
useQueue: () => useQueue
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(src_exports);
|
|
32
|
+
var import_reactivity = require("@vobs/reactivity");
|
|
33
|
+
var import_vobs = require("@vobs/vobs");
|
|
216
34
|
var _QueueError = class _QueueError extends Error {
|
|
217
35
|
constructor(code, message, cause) {
|
|
218
36
|
super(message);
|
|
@@ -223,7 +41,7 @@ var _QueueError = class _QueueError extends Error {
|
|
|
223
41
|
};
|
|
224
42
|
__name(_QueueError, "QueueError");
|
|
225
43
|
var QueueError = _QueueError;
|
|
226
|
-
var QUEUE_KEY = createInjectionKey("vobs.queue");
|
|
44
|
+
var QUEUE_KEY = (0, import_vobs.createInjectionKey)("vobs.queue");
|
|
227
45
|
var PRIORITIES = {
|
|
228
46
|
low: 0,
|
|
229
47
|
normal: 1,
|
|
@@ -232,13 +50,13 @@ var PRIORITIES = {
|
|
|
232
50
|
};
|
|
233
51
|
function createTaskQueue(options = {}) {
|
|
234
52
|
const concurrency = resolveConcurrency(options);
|
|
235
|
-
const tasks = state([]);
|
|
236
|
-
const pending = state(0);
|
|
237
|
-
const processing = state(0);
|
|
238
|
-
const completed = state(0);
|
|
239
|
-
const failed = state(0);
|
|
240
|
-
const total = state(0);
|
|
241
|
-
const paused = state(false);
|
|
53
|
+
const tasks = (0, import_reactivity.state)([]);
|
|
54
|
+
const pending = (0, import_reactivity.state)(0);
|
|
55
|
+
const processing = (0, import_reactivity.state)(0);
|
|
56
|
+
const completed = (0, import_reactivity.state)(0);
|
|
57
|
+
const failed = (0, import_reactivity.state)(0);
|
|
58
|
+
const total = (0, import_reactivity.state)(0);
|
|
59
|
+
const paused = (0, import_reactivity.state)(false);
|
|
242
60
|
const queue = [];
|
|
243
61
|
const ownedTasks = /* @__PURE__ */ new Set();
|
|
244
62
|
let sequence = 0;
|
|
@@ -307,6 +125,7 @@ function createTaskQueue(options = {}) {
|
|
|
307
125
|
tasks.dispose();
|
|
308
126
|
}
|
|
309
127
|
};
|
|
128
|
+
if ((0, import_reactivity.getCurrentOwner)()) (0, import_reactivity.onDispose)(context.dispose);
|
|
310
129
|
return context;
|
|
311
130
|
function createTask(fn, id, taskOptions) {
|
|
312
131
|
const priority = taskOptions.priority ?? "normal";
|
|
@@ -319,10 +138,10 @@ function createTaskQueue(options = {}) {
|
|
|
319
138
|
}
|
|
320
139
|
const retryDelay = taskOptions.retryDelay ?? 0;
|
|
321
140
|
validateRetryDelay(retryDelay);
|
|
322
|
-
const status = state("pending");
|
|
323
|
-
const attempt = state(0);
|
|
324
|
-
const result = state(null);
|
|
325
|
-
const error = state(null);
|
|
141
|
+
const status = (0, import_reactivity.state)("pending");
|
|
142
|
+
const attempt = (0, import_reactivity.state)(0);
|
|
143
|
+
const result = (0, import_reactivity.state)(null);
|
|
144
|
+
const error = (0, import_reactivity.state)(null);
|
|
326
145
|
let promise;
|
|
327
146
|
const task = {
|
|
328
147
|
id,
|
|
@@ -401,6 +220,7 @@ function createTaskQueue(options = {}) {
|
|
|
401
220
|
task.reject = reject;
|
|
402
221
|
});
|
|
403
222
|
}
|
|
223
|
+
__name(createPromise, "createPromise");
|
|
404
224
|
function settleReject(reason) {
|
|
405
225
|
if (task.settled) return;
|
|
406
226
|
task.settled = true;
|
|
@@ -408,7 +228,9 @@ function createTaskQueue(options = {}) {
|
|
|
408
228
|
task.resolve = null;
|
|
409
229
|
task.reject = null;
|
|
410
230
|
}
|
|
231
|
+
__name(settleReject, "settleReject");
|
|
411
232
|
}
|
|
233
|
+
__name(createTask, "createTask");
|
|
412
234
|
async function execute(task) {
|
|
413
235
|
while (!disposed && (task.status.value === "pending" || task.status.value === "retrying")) {
|
|
414
236
|
if (task.status.value === "retrying") task.status.value = "pending";
|
|
@@ -473,6 +295,7 @@ function createTaskQueue(options = {}) {
|
|
|
473
295
|
}
|
|
474
296
|
}
|
|
475
297
|
}
|
|
298
|
+
__name(execute, "execute");
|
|
476
299
|
function drain() {
|
|
477
300
|
while (!disposed && !paused.value && active < concurrency && queue.length > 0) {
|
|
478
301
|
const task = queue.shift();
|
|
@@ -486,13 +309,16 @@ function createTaskQueue(options = {}) {
|
|
|
486
309
|
}
|
|
487
310
|
refreshStats();
|
|
488
311
|
}
|
|
312
|
+
__name(drain, "drain");
|
|
489
313
|
function sortQueue() {
|
|
490
314
|
queue.sort((left, right) => PRIORITIES[right.priority] - PRIORITIES[left.priority] || left.sequence - right.sequence);
|
|
491
315
|
}
|
|
316
|
+
__name(sortQueue, "sortQueue");
|
|
492
317
|
function removeFromQueue(task) {
|
|
493
318
|
const index = queue.indexOf(task);
|
|
494
319
|
if (index >= 0) queue.splice(index, 1);
|
|
495
320
|
}
|
|
321
|
+
__name(removeFromQueue, "removeFromQueue");
|
|
496
322
|
function refreshStats() {
|
|
497
323
|
let nextPending = 0;
|
|
498
324
|
let nextProcessing = 0;
|
|
@@ -510,6 +336,7 @@ function createTaskQueue(options = {}) {
|
|
|
510
336
|
failed.value = nextFailed;
|
|
511
337
|
total.value = tasks.value.length;
|
|
512
338
|
}
|
|
339
|
+
__name(refreshStats, "refreshStats");
|
|
513
340
|
function settleTask(task, value, reason) {
|
|
514
341
|
if (task.settled) return;
|
|
515
342
|
task.settled = true;
|
|
@@ -518,18 +345,22 @@ function createTaskQueue(options = {}) {
|
|
|
518
345
|
task.resolve = null;
|
|
519
346
|
task.reject = null;
|
|
520
347
|
}
|
|
348
|
+
__name(settleTask, "settleTask");
|
|
521
349
|
function report(queueError, task) {
|
|
522
350
|
try {
|
|
523
351
|
options.onError?.(queueError, task);
|
|
524
352
|
} catch {
|
|
525
353
|
}
|
|
526
354
|
}
|
|
355
|
+
__name(report, "report");
|
|
527
356
|
function ensureActive() {
|
|
528
357
|
if (disposed) throw new QueueError("QUEUE_CONTEXT_DISPOSED", "Vobs Queue: \u4E0A\u4E0B\u6587\u5DF2\u9500\u6BC1");
|
|
529
358
|
}
|
|
359
|
+
__name(ensureActive, "ensureActive");
|
|
530
360
|
function isCancelled(task) {
|
|
531
361
|
return task.status.value === "cancelled";
|
|
532
362
|
}
|
|
363
|
+
__name(isCancelled, "isCancelled");
|
|
533
364
|
}
|
|
534
365
|
__name(createTaskQueue, "createTaskQueue");
|
|
535
366
|
function queuePlugin(options = {}) {
|
|
@@ -545,7 +376,7 @@ function queuePlugin(options = {}) {
|
|
|
545
376
|
}
|
|
546
377
|
__name(queuePlugin, "queuePlugin");
|
|
547
378
|
function useQueue() {
|
|
548
|
-
const queue = inject(QUEUE_KEY);
|
|
379
|
+
const queue = (0, import_vobs.inject)(QUEUE_KEY);
|
|
549
380
|
if (!queue) throw new QueueError("QUEUE_CONTEXT_MISSING", "Vobs Queue: \u627E\u4E0D\u5230\u4E0A\u4E0B\u6587\uFF0C\u8BF7\u5B89\u88C5 queuePlugin");
|
|
550
381
|
return queue;
|
|
551
382
|
}
|
|
@@ -605,11 +436,12 @@ function isAbortError(value) {
|
|
|
605
436
|
return Boolean(value) && typeof value === "object" && value.name === "AbortError";
|
|
606
437
|
}
|
|
607
438
|
__name(isAbortError, "isAbortError");
|
|
608
|
-
|
|
609
|
-
exports
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
439
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
440
|
+
0 && (module.exports = {
|
|
441
|
+
QUEUE_KEY,
|
|
442
|
+
QueueError,
|
|
443
|
+
createTaskQueue,
|
|
444
|
+
queuePlugin,
|
|
445
|
+
useQueue
|
|
446
|
+
});
|
|
615
447
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../reactivity/src/debug.ts","../../reactivity/src/owner.ts","../../reactivity/src/signal.ts","../../reactivity/src/scheduler.ts","../../runtime/src/hmr.ts","../../vobs/src/context.ts","../../vobs/src/app.ts","../src/index.ts"],"names":["effect","task"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Effect } from './effect'\nimport type { Owner } from './owner'\nimport type { Dependency, ReadableSignal, Subscriber } from './signal'\n\nexport interface ReactivityDebugHooks {\n ownerCreated?(owner: Owner): void\n ownerNamed?(owner: Owner, name: string): void\n ownerDisposed?(owner: Owner): void\n signalCreated?(signal: ReadableSignal<unknown>, owner: Owner | null): void\n signalNamed?(signal: ReadableSignal<unknown>, name: string): void\n signalRead?(signal: ReadableSignal<unknown>, subscriber: Subscriber): void\n signalChanged?(signal: ReadableSignal<unknown>, previousValue: unknown, nextValue: unknown): void\n signalDisposed?(signal: ReadableSignal<unknown>): void\n dependencyTracked?(dependency: Dependency, subscriber: Subscriber): void\n dependencyUntracked?(dependency: Dependency, subscriber: Subscriber): void\n effectCreated?(effect: Effect, owner: Owner | null): void\n effectInvalidated?(effect: Effect): void\n effectRunStart?(effect: Effect): void\n effectRunEnd?(effect: Effect, error?: unknown, handled?: boolean): void\n effectDisposed?(effect: Effect): void\n memoCreated?(signal: ReadableSignal<unknown>, subscriber: Subscriber, owner: Owner | null): void\n memoInvalidated?(signal: ReadableSignal<unknown>): void\n flushStart?(): void\n flushEnd?(): void\n}\n\nlet activeDebugHooks: ReactivityDebugHooks | null = null\nconst signalNames = new WeakMap<object, string>()\n\nexport function setDebugHooks(hooks: ReactivityDebugHooks | null): ReactivityDebugHooks | null {\n const previous = activeDebugHooks\n activeDebugHooks = hooks\n return previous\n}\n\nexport function getDebugHooks(): ReactivityDebugHooks | null {\n return activeDebugHooks\n}\n\n/** 热路径守卫:无 hooks 时跳过 invokeDebug 调用,避免 rest 参数数组分配。 */\nexport function hasDebugHooks(): boolean {\n return activeDebugHooks !== null\n}\n\nexport function setSignalDebugName(signal: ReadableSignal<unknown>, name: string): void {\n signalNames.set(signal, name)\n invokeDebug('signalNamed', signal, name)\n}\n\nexport function getSignalDebugName(signal: ReadableSignal<unknown>): string | undefined {\n return signalNames.get(signal)\n}\n\nexport function invokeDebug<K extends keyof ReactivityDebugHooks>(\n name: K,\n ...args: Parameters<NonNullable<ReactivityDebugHooks[K]>>\n): void {\n const callback = activeDebugHooks?.[name] as ((...values: unknown[]) => void) | undefined\n if (!callback) return\n try {\n callback(...args)\n } catch {\n // Debug tooling must never change application behavior.\n }\n}\n","import { invokeDebug, hasDebugHooks } from './debug'\n\nexport interface Owner {\n readonly id: string\n readonly parent: Owner | null\n readonly children: readonly Owner[]\n readonly depth: number\n readonly disposed: boolean\n run<T>(fn: () => T): T\n addCleanup(cleanup: () => void): void\n onDispose(cleanup: () => void): void\n onError(handler: (error: unknown) => void): () => void\n handleError(error: unknown): boolean\n dispose(): void\n}\n\nlet currentOwner: Owner | null = null\nlet nextOwnerId = 1\nconst ownerNames = new WeakMap<Owner, string>()\n\nexport function createOwner(): Owner {\n const parent = currentOwner\n let disposed = parent?.disposed ?? false\n const children: Owner[] = []\n const cleanups: Array<() => void> = []\n const errorHandlers = new Set<(error: unknown) => void>()\n\n const owner: Owner = {\n id: `owner-${nextOwnerId++}`,\n parent,\n children,\n depth: (parent?.depth ?? -1) + 1,\n\n get disposed(): boolean {\n return disposed\n },\n\n run<T>(fn: () => T): T {\n if (disposed) throw new Error('Vobs: 已销毁的 Owner 不能继续运行')\n const previous = currentOwner\n currentOwner = owner\n try {\n return fn()\n } finally {\n currentOwner = previous\n }\n },\n\n addCleanup(cleanup: () => void): void {\n if (disposed) {\n cleanup()\n return\n }\n cleanups.push(cleanup)\n },\n\n onDispose(cleanup: () => void): void {\n owner.addCleanup(cleanup)\n },\n\n onError(handler: (error: unknown) => void): () => void {\n errorHandlers.add(handler)\n const remove = () => errorHandlers.delete(handler)\n owner.addCleanup(remove)\n return remove\n },\n\n handleError(error: unknown): boolean {\n for (const handler of [...errorHandlers].reverse()) {\n try {\n handler(error)\n return true\n } catch (handlerError) {\n return parent?.handleError(handlerError) ?? false\n }\n }\n return parent?.handleError(error) ?? false\n },\n\n dispose(): void {\n if (disposed) return\n disposed = true\n for (const child of [...children]) child.dispose()\n children.length = 0\n\n let firstError: unknown\n for (let index = cleanups.length - 1; index >= 0; index--) {\n try {\n cleanups[index]()\n } catch (error) {\n firstError ??= error\n }\n }\n cleanups.length = 0\n\n if (parent) {\n const index = parent.children.indexOf(owner)\n if (index >= 0) (parent.children as Owner[]).splice(index, 1)\n }\n if (hasDebugHooks()) invokeDebug('ownerDisposed', owner)\n if (firstError) throw firstError\n }\n }\n\n if (parent && !parent.disposed) (parent.children as Owner[]).push(owner)\n if (hasDebugHooks()) invokeDebug('ownerCreated', owner)\n return owner\n}\n\nexport function setOwnerDebugName(owner: Owner, name: string): void {\n ownerNames.set(owner, name)\n if (hasDebugHooks()) invokeDebug('ownerNamed', owner, name)\n}\n\nexport function getOwnerDebugName(owner: Owner): string | undefined {\n return ownerNames.get(owner)\n}\n\nexport function getCurrentOwner(): Owner | null {\n return currentOwner\n}\n\n/** Re-enter an Owner for an explicitly captured asynchronous continuation. */\nexport function runWithOwner<T>(owner: Owner, fn: () => T): T {\n return owner.run(fn)\n}\n\nexport function onDispose(cleanup: () => void): void {\n const owner = getCurrentOwner()\n if (!owner) throw new Error('Vobs: onDispose 必须在 Owner 作用域内调用')\n owner.onDispose(cleanup)\n}\n","import { getCurrentOwner } from './owner'\nimport { invokeDebug, hasDebugHooks, setSignalDebugName } from './debug'\n\nexport interface Dependency {\n unsubscribe(subscriber: Subscriber): void\n}\n\nexport interface Subscriber {\n readonly dependencies: Set<Dependency>\n readonly disposed: boolean\n notify(): void\n}\n\n/** 只读信号:派生值(memo)与只读上下文的最小契约,只能订阅与读取。 */\nexport interface ReadableSignal<T> extends Dependency {\n readonly value: T\n dispose(): void\n}\n\n/** 可写信号:state() 的返回类型。`set` 与 `.value =` 赋值语义完全一致。 */\nexport interface Signal<T> extends ReadableSignal<T> {\n value: T\n set(next: T): void\n}\n\nlet currentSubscriber: Subscriber | null = null\n\nexport function getCurrentSubscriber(): Subscriber | null {\n return currentSubscriber\n}\n\nexport function setCurrentSubscriber(subscriber: Subscriber | null): void {\n currentSubscriber = subscriber\n}\n\nexport function untrack<T>(fn: () => T): T {\n const previous = currentSubscriber\n currentSubscriber = null\n try {\n return fn()\n } finally {\n currentSubscriber = previous\n }\n}\n\nexport function trackDependency(dependency: Dependency): void {\n if (!currentSubscriber || currentSubscriber.disposed) return\n const added = !currentSubscriber.dependencies.has(dependency)\n currentSubscriber.dependencies.add(dependency)\n if (added && hasDebugHooks()) invokeDebug('dependencyTracked', dependency, currentSubscriber)\n}\n\n/**\n * Create a reactive state signal.\n *\n * State uses identity (`Object.is`) change detection. Objects and arrays are\n * intentionally shallow: mutating a nested property in place does not notify\n * subscribers; assign a new object/array to `value` to publish the change.\n *\n * The optional debug name is metadata for inspection tools only. It does not\n * affect subscriptions, scheduling, serialization, or the signal contract.\n */\nexport function state<T>(initialValue: T, debugName?: string): Signal<T> {\n let value = initialValue\n let disposed = false\n const subscribers = new Set<Subscriber>()\n\n const signalInstance: Signal<T> = {\n get value(): T {\n const subscriber = getCurrentSubscriber()\n if (subscriber && !subscriber.disposed) {\n subscribers.add(subscriber)\n if (hasDebugHooks()) invokeDebug('signalRead', signalInstance as Signal<unknown>, subscriber)\n trackDependency(signalInstance)\n }\n return value\n },\n\n set value(nextValue: T) {\n if (disposed || Object.is(value, nextValue)) return\n const previousValue = value\n value = nextValue\n if (hasDebugHooks()) invokeDebug('signalChanged', signalInstance as Signal<unknown>, previousValue, nextValue)\n for (const subscriber of [...subscribers]) subscriber.notify()\n },\n\n unsubscribe(subscriber: Subscriber): void {\n subscribers.delete(subscriber)\n },\n\n // 与 `.value =` 赋值同一条路径:判等短路、debug hook、notify 全部一致。\n // 以闭包实现,可安全地作为回调直接传递(无 this 绑定问题)。\n set(next: T): void {\n signalInstance.value = next\n },\n\n dispose(): void {\n if (disposed) return\n disposed = true\n subscribers.clear()\n if (hasDebugHooks()) invokeDebug('signalDisposed', signalInstance as Signal<unknown>)\n }\n }\n\n const owner = getCurrentOwner()\n owner?.addCleanup(signalInstance.dispose)\n if (hasDebugHooks()) invokeDebug('signalCreated', signalInstance as Signal<unknown>, owner)\n if (debugName?.trim()) setSignalDebugName(signalInstance as Signal<unknown>, debugName.trim())\n return signalInstance\n}\n","import type { Effect } from './effect'\nimport { hasDebugHooks, invokeDebug } from './debug'\n\nexport class Scheduler {\n private readonly dirtyEffects = new Set<Effect>()\n private readonly lowPriorityEffects = new Set<Effect>()\n // flush 不可重入(flushing 标志保证),缓冲数组可在轮次间安全复用,避免每轮分配。\n private readonly normalBuffer: Effect[] = []\n private readonly lowBuffer: Effect[] = []\n private flushing = false\n private scheduled = false\n private batchDepth = 0\n\n schedule(effect: Effect): void {\n if (effect.disposed) return\n this.dirtyEffects.add(effect)\n this.lowPriorityEffects.delete(effect)\n this.ensureScheduled()\n }\n\n /** Queue an effect behind normal updates while preserving deterministic order. */\n scheduleLow(effect: Effect): void {\n if (effect.disposed) return\n if (!this.dirtyEffects.has(effect)) this.lowPriorityEffects.add(effect)\n this.ensureScheduled()\n }\n\n private ensureScheduled(): void {\n if (this.batchDepth === 0 && !this.flushing && !this.scheduled) {\n this.scheduled = true\n queueMicrotask(() => {\n this.scheduled = false\n this.flush()\n })\n }\n }\n\n remove(effect: Effect): void {\n this.dirtyEffects.delete(effect)\n this.lowPriorityEffects.delete(effect)\n }\n\n batch<T>(fn: () => T): T {\n this.batchDepth++\n try {\n return fn()\n } finally {\n this.batchDepth--\n if (this.batchDepth === 0) this.flush()\n }\n }\n\n flush(): void {\n if (this.flushing || this.batchDepth > 0) return\n this.flushing = true\n const debugEnabled = hasDebugHooks()\n if (debugEnabled) invokeDebug('flushStart')\n let rounds = 0\n let firstError: unknown\n let hasError = false\n try {\n while (this.dirtyEffects.size > 0 || this.lowPriorityEffects.size > 0) {\n if (++rounds > 100) {\n this.dirtyEffects.clear()\n this.lowPriorityEffects.clear()\n throw new Error('Vobs: 响应式更新超过 100 轮,可能存在循环依赖')\n }\n\n // normal 先、low 后,两组分别排序:与旧的合并排序语义一致\n // (旧比较器里 low 优先级本就高于 depth),但消除了比较器内的 Set 查找。\n this.collectRunnable(this.dirtyEffects, this.normalBuffer)\n this.collectRunnable(this.lowPriorityEffects, this.lowBuffer)\n sortEffects(this.normalBuffer)\n sortEffects(this.lowBuffer)\n for (const effect of this.normalBuffer) {\n try {\n effect.run()\n } catch (error) {\n // Isolate one failed effect from the rest of the flush. Re-throw\n // the first error after all runnable effects have had a chance.\n if (!hasError) {\n firstError = error\n hasError = true\n }\n }\n }\n for (const effect of this.lowBuffer) {\n try {\n effect.run()\n } catch (error) {\n if (!hasError) {\n firstError = error\n hasError = true\n }\n }\n }\n this.normalBuffer.length = 0\n this.lowBuffer.length = 0\n }\n } finally {\n this.normalBuffer.length = 0\n this.lowBuffer.length = 0\n this.flushing = false\n if (debugEnabled) invokeDebug('flushEnd')\n }\n if (hasError) throw firstError\n }\n\n /** 收集未 disposed 的 effect 并清空源集合;run() 期间新调度的 effect 留给下一轮。 */\n private collectRunnable(source: Set<Effect>, target: Effect[]): void {\n for (const effect of source) {\n if (!effect.disposed) target.push(effect)\n }\n source.clear()\n }\n}\n\n/** depth 深的先跑(子 effect 先于父),同深度按创建顺序。 */\nfunction sortEffects(effects: Effect[]): void {\n if (effects.length > 1) {\n effects.sort((a, b) => b.depth - a.depth || a.order - b.order)\n }\n}\n\nexport const scheduler = new Scheduler()\n\nexport function batch<T>(fn: () => T): T {\n return scheduler.batch(fn)\n}\n\n/** Schedule a low-priority effect explicitly. */\nexport function scheduleLow(effect: Effect): void {\n effect.scheduleLow()\n}\n","import type { VobsNode } from './fragment'\n\nexport type HmrComponent<Props extends object = Record<string, unknown>> =\n (props: Props) => VobsNode\n\nexport interface HmrStateStore {\n get<T>(key: string, initial: T | (() => T)): T\n set<T>(key: string, value: T): void\n has(key: string): boolean\n delete(key: string): void\n clear(): void\n}\n\nexport interface HmrInstance {\n node: VobsNode\n parent: Node | null\n refresh(): void\n}\n\ninterface HmrModuleState {\n readonly components: Map<string, HmrComponent>\n readonly state: Map<string, unknown>\n readonly instances: Set<HmrInstance>\n}\n\ninterface HmrGlobal {\n modules: Map<string, HmrModuleState>\n}\n\nconst globalTarget = globalThis as typeof globalThis & { __VOBS_HMR__?: HmrGlobal }\nconst hmrGlobal = globalTarget.__VOBS_HMR__ ?? { modules: new Map<string, HmrModuleState>() }\nglobalTarget.__VOBS_HMR__ = hmrGlobal\n\nexport function resolveComponent<Props extends object>(\n component: HmrComponent<Props>,\n moduleId: string,\n exportName: string\n): HmrComponent<Props> {\n const module = getModule(moduleId)\n const existing = module.components.get(exportName)\n if (existing) return existing as HmrComponent<Props>\n\n const proxy = ((props: Props) => {\n const current = (proxy as HmrComponent<Props> & { current: HmrComponent<Props> }).current\n return current(props)\n }) as HmrComponent<Props> & { current: HmrComponent<Props> }\n proxy.current = component\n Object.defineProperties(proxy, {\n displayName: { configurable: true, value: component.name || exportName },\n hmrKey: { configurable: false, value: `${moduleId}:${exportName}` }\n })\n module.components.set(exportName, proxy as HmrComponent)\n return proxy\n}\n\nexport function updateHmrModule(_moduleId: string, nextModule: Record<string, unknown>): void {\n const modules = [...hmrGlobal.modules.values()]\n for (const module of modules) {\n let changed = false\n for (const [name, proxy] of module.components) {\n const next = nextModule[name]\n if (typeof next !== 'function') continue\n const hmrProxy = proxy as HmrComponent & { current: HmrComponent; displayName?: string }\n hmrProxy.current = next as HmrComponent\n Object.defineProperty(hmrProxy, 'displayName', { configurable: true, value: next.name || name })\n changed = true\n }\n if (!changed) continue\n for (const instance of module.instances) {\n try {\n instance.refresh()\n } catch {\n // HMR failures remain application errors on the next normal render.\n }\n }\n }\n}\n\nexport function disposeHmrModule(_moduleId: string): void {\n // State and component proxies intentionally survive module disposal.\n}\n\nexport function createHmrStateStore(moduleId: string): HmrStateStore {\n const state = getModule(moduleId).state\n return {\n get<T>(key: string, initial: T | (() => T)): T {\n if (!state.has(key)) state.set(key, typeof initial === 'function' ? (initial as () => T)() : initial)\n return state.get(key) as T\n },\n set<T>(key: string, value: T): void {\n state.set(key, value)\n },\n has: key => state.has(key),\n delete: key => { state.delete(key) },\n clear: () => { state.clear() }\n }\n}\n\nexport function registerHmrInstance(moduleId: string, instance: HmrInstance): () => void {\n const instances = getModule(moduleId).instances\n instances.add(instance)\n return () => instances.delete(instance)\n}\n\nexport function markHmrInstanceMounted(node: VobsNode, parent: Node): void {\n const instance = hmrInstances.get(node as object)\n if (instance) instance.parent = parent\n}\n\nfunction getModule(moduleId: string): HmrModuleState {\n let module = hmrGlobal.modules.get(moduleId)\n if (!module) {\n module = { components: new Map(), state: new Map(), instances: new Set() }\n hmrGlobal.modules.set(moduleId, module)\n }\n return module\n}\n\nconst hmrInstances = new WeakMap<object, HmrInstance>()\n\nexport function associateHmrInstance(node: VobsNode, instance: HmrInstance): void {\n hmrInstances.set(node as object, instance)\n}\n","import { getCurrentOwner, type Owner } from '@vobs/reactivity'\nimport type { InjectionKey, ProvideOptions } from './app'\n\nconst ownerProviders = new WeakMap<Owner, Map<InjectionKey<unknown>, unknown>>()\n\nexport function provide<T>(key: InjectionKey<T>, value: T, options: ProvideOptions = {}): void {\n const owner = getCurrentOwner()\n if (!owner) throw new Error('Vobs: provide 必须在组件或 Owner 作用域内调用')\n provideToOwner(owner, key, value, options)\n}\n\nexport function inject<T>(key: InjectionKey<T>): T | undefined\nexport function inject<T>(key: InjectionKey<T>, fallback: T): T\nexport function inject<T>(key: InjectionKey<T>, fallback?: T): T | undefined {\n const owner = getCurrentOwner()\n const value = owner ? injectFromOwner(owner, key) : undefined\n return value === undefined ? fallback : value\n}\n\nexport function injectRequired<T>(key: InjectionKey<T>, description?: string): T {\n const value = inject(key)\n if (value === undefined) {\n throw new Error(`Vobs: 找不到必需注入项${description ? ` ${description}` : ''}`)\n }\n return value\n}\n\nexport function provideToOwner<T>(\n owner: Owner,\n key: InjectionKey<T>,\n value: T,\n options: ProvideOptions = {}\n): void {\n let providers = ownerProviders.get(owner)\n if (!providers) {\n providers = new Map<InjectionKey<unknown>, unknown>()\n ownerProviders.set(owner, providers)\n owner.onDispose(() => ownerProviders.delete(owner))\n }\n if (providers.has(key) && !options.override) {\n throw new Error(`Vobs: 注入项 ${String(key)} 已存在;如需覆盖请传入 override: true`)\n }\n providers.set(key, value)\n}\n\nexport function injectFromOwner<T>(owner: Owner, key: InjectionKey<T>): T | undefined {\n let current: Owner | null = owner\n while (current) {\n const providers = ownerProviders.get(current)\n if (providers?.has(key)) return providers.get(key) as T\n current = current.parent\n }\n return undefined\n}\n","import { createOwner, scheduler, setOwnerDebugName, type Owner } from '@vobs/reactivity'\nimport { createDOMRenderer } from '@vobs/dom'\nimport { insertBefore as insertRuntimeNode, setRenderer, type VobsFragment, type VobsRenderer } from '@vobs/runtime'\nimport { injectFromOwner, provideToOwner } from './context'\n\nexport type InjectionKey<T> = symbol & {\n readonly __vobsType?: T\n}\n\nexport interface ProvideOptions {\n override?: boolean\n}\n\nexport interface VobsPlugin {\n name: string\n version?: string\n requires?: readonly VobsPlugin[]\n optional?: readonly VobsPlugin[]\n install?: (ctx: VobsContext) => void | (() => void)\n}\n\nexport interface VobsContext {\n readonly app: VobsApp\n provide<T>(key: InjectionKey<T>, value: T, options?: ProvideOptions): void\n inject<T>(key: InjectionKey<T>): T | undefined\n injectRequired<T>(key: InjectionKey<T>, description?: string): T\n onDestroy(cleanup: () => void): void\n onError(handler: (error: unknown) => void): () => void\n}\n\nexport interface VobsConfig<\n NodeType = Node,\n TextNode extends NodeType = NodeType,\n ElementNode extends NodeType = NodeType,\n CommentNode extends NodeType = NodeType\n> {\n render: () => NodeType | VobsFragment | Node | null | undefined\n renderer?: VobsRenderer<NodeType, TextNode, ElementNode, CommentNode>\n plugins?: VobsPlugin[]\n /** Optional application-level error observer. Observers are isolated from the app. */\n onError?: (error: unknown) => void\n}\n\nexport interface VobsApp<NodeType = Node> {\n readonly mounted: boolean\n readonly destroyed: boolean\n use(plugin: VobsPlugin): VobsApp<NodeType>\n mount(target: string | NodeType): void\n hydrate(target: string | NodeType): void\n update(): void\n destroy(): void\n}\n\nexport function createInjectionKey<T>(description: string): InjectionKey<T> {\n return Symbol(description) as InjectionKey<T>\n}\n\nexport function createVobs(\n config: VobsConfig<Node, Text, Element, Comment>\n): VobsApp<Node>\nexport function createVobs<\n NodeType = Node,\n TextNode extends NodeType = NodeType,\n ElementNode extends NodeType = NodeType,\n CommentNode extends NodeType = NodeType\n>(\n config: VobsConfig<NodeType, TextNode, ElementNode, CommentNode> & {\n renderer: VobsRenderer<NodeType, TextNode, ElementNode, CommentNode>\n }\n): VobsApp<NodeType>\nexport function createVobs(\n config: VobsConfig<any, any, any, any>\n): VobsApp<any> {\n if (!config.render) throw new Error('createVobs: render 不能为空')\n\n const renderer = config.renderer ?? createDOMRenderer()\n const rootOwner: Owner = createOwner()\n setOwnerDebugName(rootOwner, 'App')\n const cleanups: Array<() => void> = []\n const errorHandlers = new Set<(error: unknown) => void>()\n const installed = new Set<string>()\n const installing = new Set<string>()\n let mounted = false\n let destroyed = false\n let container: any = null\n let app!: VobsApp<any>\n\n if (config.onError) {\n errorHandlers.add(config.onError)\n cleanups.push(() => errorHandlers.delete(config.onError!))\n }\n\n const context: VobsContext = {\n get app(): VobsApp<any> {\n return app\n },\n\n provide<T>(key: InjectionKey<T>, value: T, options: ProvideOptions = {}): void {\n provideToOwner(rootOwner, key, value, options)\n },\n\n inject<T>(key: InjectionKey<T>): T | undefined {\n return injectFromOwner(rootOwner, key)\n },\n\n injectRequired<T>(key: InjectionKey<T>, description?: string): T {\n const value = injectFromOwner(rootOwner, key)\n if (value === undefined) {\n throw new Error(`Vobs: 找不到必需注入项${description ? ` ${description}` : ''}`)\n }\n return value\n },\n\n onDestroy(cleanup: () => void): void {\n cleanups.push(cleanup)\n },\n\n onError(handler: (error: unknown) => void): () => void {\n errorHandlers.add(handler)\n const remove = () => errorHandlers.delete(handler)\n cleanups.push(remove)\n return remove\n }\n }\n\n function notifyError(error: unknown): void {\n for (const handler of [...errorHandlers]) {\n try {\n handler(error)\n } catch {\n // 错误处理器不能覆盖触发它的原始错误。\n }\n }\n }\n\n function installPlugin(plugin: VobsPlugin): void {\n if (installed.has(plugin.name)) return\n if (installing.has(plugin.name)) {\n throw new Error(`Vobs: 插件依赖存在循环:${plugin.name}`)\n }\n\n installing.add(plugin.name)\n try {\n for (const dependency of plugin.requires ?? []) installPlugin(dependency)\n const cleanup = plugin.install?.(context)\n if (cleanup) cleanups.push(cleanup)\n installed.add(plugin.name)\n } finally {\n installing.delete(plugin.name)\n }\n }\n\n function cleanup(clearContainer = true): unknown {\n let firstError: unknown\n for (let index = cleanups.length - 1; index >= 0; index--) {\n try {\n cleanups[index]()\n } catch (error) {\n firstError ??= error\n }\n }\n cleanups.length = 0\n\n try {\n rootOwner.dispose()\n } catch (error) {\n firstError ??= error\n }\n\n if (container && clearContainer) {\n try {\n renderer.clear(container)\n } catch (error) {\n firstError ??= error\n }\n }\n return firstError\n }\n\n function start(target: string | any, hydrating: boolean): void {\n if (destroyed) throw new Error('Vobs: 已销毁的应用不能挂载')\n if (mounted) return\n\n container = typeof target === 'string' ? document.querySelector(target) : target\n if (!container) throw new Error(`mount: 目标不存在: ${target}`)\n if (hydrating && !renderer.beginHydration) {\n throw new Error('Vobs: 当前渲染器不支持 Hydration')\n }\n\n setRenderer(renderer)\n try {\n if (hydrating) renderer.beginHydration?.()\n const rootNode = rootOwner.run(config.render)\n if (!hydrating) renderer.clear(container)\n if (rootNode) insertRuntimeNode(container, rootNode as any, null)\n if (hydrating) renderer.completeHydration?.()\n mounted = true\n } catch (error) {\n notifyError(error)\n const cleanupError = cleanup(!hydrating)\n destroyed = true\n throw cleanupError ?? error\n }\n }\n\n app = {\n get mounted(): boolean {\n return mounted\n },\n\n get destroyed(): boolean {\n return destroyed\n },\n\n use(plugin: VobsPlugin): VobsApp<any> {\n if (destroyed) throw new Error('Vobs: 已销毁的应用不能安装插件')\n installPlugin(plugin)\n return app\n },\n\n mount(target: string | any): void {\n start(target, false)\n },\n\n hydrate(target: string | any): void {\n start(target, true)\n },\n\n update(): void {\n if (destroyed) throw new Error('Vobs: 已销毁的应用不能更新')\n try {\n scheduler.flush()\n } catch (error) {\n notifyError(error)\n throw error\n }\n },\n\n destroy(): void {\n if (destroyed) return\n try {\n const cleanupError = cleanup()\n if (cleanupError) {\n notifyError(cleanupError)\n throw cleanupError\n }\n } finally {\n mounted = false\n destroyed = true\n }\n }\n }\n\n try {\n for (const plugin of config.plugins ?? []) app.use(plugin)\n } catch (error) {\n notifyError(error)\n cleanup()\n destroyed = true\n throw error\n }\n\n return app\n}\n","import { getCurrentOwner, onDispose, state, type Signal } from '@vobs/reactivity'\nimport { createInjectionKey, inject, type InjectionKey, type VobsPlugin } from '@vobs/vobs'\n\nexport type TaskPriority = 'low' | 'normal' | 'high' | 'critical'\nexport type QueueTaskStatus = 'pending' | 'running' | 'retrying' | 'success' | 'error' | 'cancelled'\nexport type QueueRetryDelay = number | ((attempt: number, error: Error) => number)\n\nexport interface QueueTask<T = unknown> {\n readonly id: string\n readonly priority: TaskPriority\n readonly status: Signal<QueueTaskStatus>\n readonly attempt: Signal<number>\n readonly result: Signal<T | null>\n readonly error: Signal<Error | null>\n readonly promise: Promise<T>\n cancel(): void\n retry(): Promise<T>\n}\n\nexport interface QueueTaskOptions {\n readonly id?: string\n readonly priority?: TaskPriority\n readonly retry?: number\n readonly retryDelay?: QueueRetryDelay\n}\n\nexport type QueueTaskFunction<T> = (signal: AbortSignal) => T | PromiseLike<T>\n\nexport interface TaskQueueOptions {\n /** Maximum number of task functions running at once. */\n readonly concurrency?: number\n /** Alias retained for the terminology used in the design document. */\n readonly concurrent?: number\n readonly idFactory?: () => string\n readonly onError?: (error: QueueError, task: QueueTask) => void\n}\n\nexport interface QueuePluginOptions extends TaskQueueOptions {\n readonly queue?: TaskQueue\n}\n\nexport interface TaskQueue {\n readonly pending: Signal<number>\n readonly processing: Signal<number>\n readonly completed: Signal<number>\n readonly failed: Signal<number>\n readonly total: Signal<number>\n readonly paused: Signal<boolean>\n readonly tasks: Signal<readonly QueueTask[]>\n add<T>(fn: QueueTaskFunction<T>, options?: QueueTaskOptions): QueueTask<T>\n pause(): void\n resume(): void\n clear(): void\n dispose(): void\n}\n\nexport type QueueErrorCode =\n | 'QUEUE_CONTEXT_MISSING'\n | 'QUEUE_CONTEXT_DISPOSED'\n | 'INVALID_QUEUE_OPTIONS'\n | 'INVALID_TASK'\n | 'QUEUE_TASK_CANCELLED'\n | 'QUEUE_TASK_FAILED'\n\nexport class QueueError extends Error {\n readonly code: QueueErrorCode\n readonly cause: unknown\n\n constructor(code: QueueErrorCode, message: string, cause?: unknown) {\n super(message)\n this.name = 'QueueError'\n this.code = code\n this.cause = cause\n }\n}\n\nexport const QUEUE_KEY: InjectionKey<TaskQueue> = createInjectionKey<TaskQueue>('vobs.queue')\n\nconst PRIORITIES: Readonly<Record<TaskPriority, number>> = {\n low: 0,\n normal: 1,\n high: 2,\n critical: 3\n}\n\ninterface InternalTask<T> extends QueueTask<T> {\n readonly fn: QueueTaskFunction<T>\n readonly maxRetries: number\n readonly retryDelay: QueueRetryDelay\n readonly sequence: number\n controller: AbortController | null\n settled: boolean\n executing: boolean\n retryQueued: boolean\n resolve: ((value: T) => void) | null\n reject: ((reason: unknown) => void) | null\n run(): Promise<void>\n dispose(): void\n}\n\nexport function createTaskQueue(options: TaskQueueOptions = {}): TaskQueue {\n const concurrency = resolveConcurrency(options)\n const tasks = state<readonly QueueTask[]>([])\n const pending = state(0)\n const processing = state(0)\n const completed = state(0)\n const failed = state(0)\n const total = state(0)\n const paused = state(false)\n const queue: InternalTask<any>[] = []\n const ownedTasks = new Set<InternalTask<any>>()\n let sequence = 0\n let active = 0\n let nextId = 0\n let disposed = false\n\n const context: TaskQueue = {\n pending,\n processing,\n completed,\n failed,\n total,\n paused,\n tasks,\n\n add<T>(fn: QueueTaskFunction<T>, taskOptions: QueueTaskOptions = {}): QueueTask<T> {\n ensureActive()\n if (typeof fn !== 'function') {\n throw new QueueError('INVALID_TASK', 'Vobs Queue: task 必须是函数')\n }\n const id = taskOptions.id ?? options.idFactory?.() ?? `task-${++nextId}`\n if (typeof id !== 'string' || id.trim() === '') {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: task id 必须是非空字符串')\n }\n if (tasks.value.some(task => task.id === id)) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', `Vobs Queue: 已存在任务 ${id}`)\n }\n const task = createTask(fn, id, taskOptions)\n ownedTasks.add(task)\n tasks.value = Object.freeze([...tasks.value, task])\n queue.push(task)\n sortQueue()\n refreshStats()\n drain()\n return task\n },\n\n pause(): void {\n ensureActive()\n paused.value = true\n },\n\n resume(): void {\n ensureActive()\n if (!paused.value) return\n paused.value = false\n drain()\n },\n\n clear(): void {\n ensureActive()\n for (const task of [...queue]) task.cancel()\n queue.length = 0\n refreshStats()\n },\n\n dispose(): void {\n if (disposed) return\n disposed = true\n for (const task of [...ownedTasks]) task.cancel()\n queue.length = 0\n for (const task of ownedTasks) task.dispose()\n ownedTasks.clear()\n tasks.value = Object.freeze([])\n pending.dispose()\n processing.dispose()\n completed.dispose()\n failed.dispose()\n total.dispose()\n paused.dispose()\n tasks.dispose()\n }\n }\n\n if (getCurrentOwner()) onDispose(context.dispose)\n return context\n\n function createTask<T>(fn: QueueTaskFunction<T>, id: string, taskOptions: QueueTaskOptions): InternalTask<T> {\n const priority = taskOptions.priority ?? 'normal'\n if (!(priority in PRIORITIES)) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', `Vobs Queue: 不支持任务优先级 ${String(priority)}`)\n }\n const maxRetries = taskOptions.retry ?? 0\n if (!Number.isInteger(maxRetries) || maxRetries < 0) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: retry 必须是大于等于 0 的整数')\n }\n const retryDelay = taskOptions.retryDelay ?? 0\n validateRetryDelay(retryDelay)\n\n const status = state<QueueTaskStatus>('pending')\n const attempt = state(0)\n const result = state<T | null>(null)\n const error = state<Error | null>(null)\n let promise!: Promise<T>\n\n const task: InternalTask<T> = {\n id,\n priority,\n status,\n attempt,\n result,\n error,\n get promise(): Promise<T> { return promise },\n fn,\n maxRetries,\n retryDelay,\n sequence: sequence++,\n controller: null,\n settled: false,\n executing: false,\n retryQueued: false,\n resolve: null,\n reject: null,\n\n cancel(): void {\n if (status.value === 'success' || status.value === 'error' || status.value === 'cancelled') return\n task.controller?.abort()\n removeFromQueue(task)\n status.value = 'cancelled'\n const cancellation = new QueueError('QUEUE_TASK_CANCELLED', `Vobs Queue: 任务 ${id} 已取消`)\n error.value = cancellation\n settleReject(cancellation)\n refreshStats()\n },\n\n retry(): Promise<T> {\n ensureActive()\n if (status.value === 'pending' || status.value === 'running' || status.value === 'retrying') return promise\n if (status.value === 'success') return promise\n status.value = 'pending'\n attempt.value = 0\n result.value = null\n error.value = null\n task.controller = null\n task.settled = false\n task.retryQueued = true\n promise = createPromise()\n if (!task.executing) queue.push(task)\n sortQueue()\n refreshStats()\n drain()\n return promise\n },\n\n run(): Promise<void> {\n task.retryQueued = false\n task.executing = true\n return execute(task).finally(() => {\n task.executing = false\n if (task.retryQueued && task.status.value === 'pending' && !disposed) {\n task.retryQueued = false\n queue.push(task)\n sortQueue()\n drain()\n }\n })\n },\n\n dispose(): void {\n task.controller?.abort()\n status.dispose()\n attempt.dispose()\n result.dispose()\n error.dispose()\n }\n }\n promise = createPromise()\n return task\n\n function createPromise(): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n task.resolve = resolve\n task.reject = reject\n })\n }\n\n function settleReject(reason: unknown): void {\n if (task.settled) return\n task.settled = true\n task.reject?.(reason)\n task.resolve = null\n task.reject = null\n }\n }\n\n async function execute<T>(task: InternalTask<T>): Promise<void> {\n while (!disposed && (task.status.value === 'pending' || task.status.value === 'retrying')) {\n if (task.status.value === 'retrying') task.status.value = 'pending'\n task.status.value = 'running'\n task.attempt.value++\n const controller = new AbortController()\n task.controller = controller\n refreshStats()\n try {\n const value = await task.fn(controller.signal)\n if (isCancelled(task) || disposed) return\n task.result.value = value\n task.status.value = 'success'\n settleTask(task, value)\n refreshStats()\n return\n } catch (reason) {\n if (isCancelled(task) || disposed) return\n if (isAbortError(reason)) {\n const cancellation = new QueueError('QUEUE_TASK_CANCELLED', `Vobs Queue: 任务 ${task.id} 已取消`, reason)\n task.error.value = cancellation\n task.status.value = 'cancelled'\n settleTask(task, undefined, cancellation)\n refreshStats()\n return\n }\n const failure = toQueueError(reason, task.id)\n let delay: number | undefined\n try {\n if (task.attempt.value <= task.maxRetries) {\n delay = resolveRetryDelay(task.retryDelay, task.attempt.value, failure)\n }\n } catch (delayError) {\n const invalidDelay = toQueueError(delayError, task.id)\n task.error.value = invalidDelay\n task.status.value = 'error'\n settleTask(task, undefined, invalidDelay)\n report(invalidDelay, task)\n refreshStats()\n return\n }\n if (delay !== undefined) {\n task.status.value = 'retrying'\n refreshStats()\n try {\n await wait(delay, controller.signal)\n } catch (delayError) {\n if (isCancelled(task) || isAbortError(delayError)) return\n throw delayError\n }\n if (isCancelled(task) || disposed) return\n continue\n }\n task.error.value = failure\n task.status.value = 'error'\n settleTask(task, undefined, failure)\n report(failure, task)\n refreshStats()\n return\n } finally {\n if (task.controller === controller) task.controller = null\n }\n }\n }\n\n function drain(): void {\n while (!disposed && !paused.value && active < concurrency && queue.length > 0) {\n const task = queue.shift()!\n if (task.status.value !== 'pending') continue\n active++\n void task.run().finally(() => {\n active--\n refreshStats()\n drain()\n })\n }\n refreshStats()\n }\n\n function sortQueue(): void {\n queue.sort((left, right) => PRIORITIES[right.priority] - PRIORITIES[left.priority] || left.sequence - right.sequence)\n }\n\n function removeFromQueue(task: InternalTask<any>): void {\n const index = queue.indexOf(task)\n if (index >= 0) queue.splice(index, 1)\n }\n\n function refreshStats(): void {\n let nextPending = 0\n let nextProcessing = 0\n let nextCompleted = 0\n let nextFailed = 0\n for (const task of tasks.value) {\n if (task.status.value === 'pending') nextPending++\n else if (task.status.value === 'running' || task.status.value === 'retrying') nextProcessing++\n else if (task.status.value === 'success') nextCompleted++\n else if (task.status.value === 'error') nextFailed++\n }\n pending.value = nextPending\n processing.value = nextProcessing\n completed.value = nextCompleted\n failed.value = nextFailed\n total.value = tasks.value.length\n }\n\n function settleTask<T>(task: InternalTask<T>, value?: T, reason?: unknown): void {\n if (task.settled) return\n task.settled = true\n if (reason !== undefined) task.reject?.(reason)\n else task.resolve?.(value as T)\n task.resolve = null\n task.reject = null\n }\n\n function report(queueError: QueueError, task: QueueTask): void {\n try { options.onError?.(queueError, task) } catch { /* observers cannot break queue state */ }\n }\n\n function ensureActive(): void {\n if (disposed) throw new QueueError('QUEUE_CONTEXT_DISPOSED', 'Vobs Queue: 上下文已销毁')\n }\n\n function isCancelled(task: QueueTask): boolean {\n return task.status.value === 'cancelled'\n }\n}\n\nexport function queuePlugin(options: QueuePluginOptions = {}): VobsPlugin {\n return {\n name: '@vobs/queue',\n version: '0.1.0',\n install(context) {\n const ownedQueue = options.queue ? undefined : createTaskQueue(options)\n context.provide(QUEUE_KEY, options.queue ?? ownedQueue!)\n return () => ownedQueue?.dispose()\n }\n }\n}\n\nexport function useQueue(): TaskQueue {\n const queue = inject(QUEUE_KEY)\n if (!queue) throw new QueueError('QUEUE_CONTEXT_MISSING', 'Vobs Queue: 找不到上下文,请安装 queuePlugin')\n return queue\n}\n\nfunction resolveConcurrency(options: TaskQueueOptions): number {\n if (options.concurrency !== undefined && options.concurrent !== undefined && options.concurrency !== options.concurrent) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: concurrency 与 concurrent 不能设置为不同值')\n }\n const value = options.concurrency ?? options.concurrent ?? 3\n if (!Number.isInteger(value) || value <= 0) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: concurrency 必须是正整数')\n }\n return value\n}\n\nfunction validateRetryDelay(value: QueueRetryDelay): void {\n if (typeof value === 'number' && (!Number.isFinite(value) || value < 0)) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: retryDelay 必须是大于等于 0 的有限数字或函数')\n }\n if (typeof value !== 'number' && typeof value !== 'function') {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: retryDelay 必须是数字或函数')\n }\n}\n\nfunction resolveRetryDelay(value: QueueRetryDelay, attempt: number, error: Error): number {\n const delay = typeof value === 'function' ? value(attempt, error) : value\n if (!Number.isFinite(delay) || delay < 0) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: retryDelay 函数必须返回大于等于 0 的有限数字')\n }\n return delay\n}\n\nfunction wait(delay: number, signal: AbortSignal): Promise<void> {\n if (delay === 0) return Promise.resolve()\n return new Promise((resolve, reject) => {\n const timer = setTimeout(done, delay)\n signal.addEventListener('abort', abort, { once: true })\n function done(): void {\n signal.removeEventListener('abort', abort)\n resolve()\n }\n function abort(): void {\n clearTimeout(timer)\n reject(Object.assign(new Error('Aborted'), { name: 'AbortError' }))\n }\n })\n}\n\nfunction toQueueError(reason: unknown, id: string): QueueError {\n if (reason instanceof QueueError) return reason\n return new QueueError('QUEUE_TASK_FAILED', `Vobs Queue: 任务 ${id} 执行失败`, reason)\n}\n\nfunction isAbortError(value: unknown): boolean {\n return Boolean(value) && typeof value === 'object' && (value as { name?: unknown }).name === 'AbortError'\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { getCurrentOwner, onDispose, state, type Signal } from '@vobs/reactivity'\nimport { createInjectionKey, inject, type InjectionKey, type VobsPlugin } from '@vobs/vobs'\n\nexport type TaskPriority = 'low' | 'normal' | 'high' | 'critical'\nexport type QueueTaskStatus = 'pending' | 'running' | 'retrying' | 'success' | 'error' | 'cancelled'\nexport type QueueRetryDelay = number | ((attempt: number, error: Error) => number)\n\nexport interface QueueTask<T = unknown> {\n readonly id: string\n readonly priority: TaskPriority\n readonly status: Signal<QueueTaskStatus>\n readonly attempt: Signal<number>\n readonly result: Signal<T | null>\n readonly error: Signal<Error | null>\n readonly promise: Promise<T>\n cancel(): void\n retry(): Promise<T>\n}\n\nexport interface QueueTaskOptions {\n readonly id?: string\n readonly priority?: TaskPriority\n readonly retry?: number\n readonly retryDelay?: QueueRetryDelay\n}\n\nexport type QueueTaskFunction<T> = (signal: AbortSignal) => T | PromiseLike<T>\n\nexport interface TaskQueueOptions {\n /** Maximum number of task functions running at once. */\n readonly concurrency?: number\n /** Alias retained for the terminology used in the design document. */\n readonly concurrent?: number\n readonly idFactory?: () => string\n readonly onError?: (error: QueueError, task: QueueTask) => void\n}\n\nexport interface QueuePluginOptions extends TaskQueueOptions {\n readonly queue?: TaskQueue\n}\n\nexport interface TaskQueue {\n readonly pending: Signal<number>\n readonly processing: Signal<number>\n readonly completed: Signal<number>\n readonly failed: Signal<number>\n readonly total: Signal<number>\n readonly paused: Signal<boolean>\n readonly tasks: Signal<readonly QueueTask[]>\n add<T>(fn: QueueTaskFunction<T>, options?: QueueTaskOptions): QueueTask<T>\n pause(): void\n resume(): void\n clear(): void\n dispose(): void\n}\n\nexport type QueueErrorCode =\n | 'QUEUE_CONTEXT_MISSING'\n | 'QUEUE_CONTEXT_DISPOSED'\n | 'INVALID_QUEUE_OPTIONS'\n | 'INVALID_TASK'\n | 'QUEUE_TASK_CANCELLED'\n | 'QUEUE_TASK_FAILED'\n\nexport class QueueError extends Error {\n readonly code: QueueErrorCode\n readonly cause: unknown\n\n constructor(code: QueueErrorCode, message: string, cause?: unknown) {\n super(message)\n this.name = 'QueueError'\n this.code = code\n this.cause = cause\n }\n}\n\nexport const QUEUE_KEY: InjectionKey<TaskQueue> = createInjectionKey<TaskQueue>('vobs.queue')\n\nconst PRIORITIES: Readonly<Record<TaskPriority, number>> = {\n low: 0,\n normal: 1,\n high: 2,\n critical: 3\n}\n\ninterface InternalTask<T> extends QueueTask<T> {\n readonly fn: QueueTaskFunction<T>\n readonly maxRetries: number\n readonly retryDelay: QueueRetryDelay\n readonly sequence: number\n controller: AbortController | null\n settled: boolean\n executing: boolean\n retryQueued: boolean\n resolve: ((value: T) => void) | null\n reject: ((reason: unknown) => void) | null\n run(): Promise<void>\n dispose(): void\n}\n\nexport function createTaskQueue(options: TaskQueueOptions = {}): TaskQueue {\n const concurrency = resolveConcurrency(options)\n const tasks = state<readonly QueueTask[]>([])\n const pending = state(0)\n const processing = state(0)\n const completed = state(0)\n const failed = state(0)\n const total = state(0)\n const paused = state(false)\n const queue: InternalTask<any>[] = []\n const ownedTasks = new Set<InternalTask<any>>()\n let sequence = 0\n let active = 0\n let nextId = 0\n let disposed = false\n\n const context: TaskQueue = {\n pending,\n processing,\n completed,\n failed,\n total,\n paused,\n tasks,\n\n add<T>(fn: QueueTaskFunction<T>, taskOptions: QueueTaskOptions = {}): QueueTask<T> {\n ensureActive()\n if (typeof fn !== 'function') {\n throw new QueueError('INVALID_TASK', 'Vobs Queue: task 必须是函数')\n }\n const id = taskOptions.id ?? options.idFactory?.() ?? `task-${++nextId}`\n if (typeof id !== 'string' || id.trim() === '') {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: task id 必须是非空字符串')\n }\n if (tasks.value.some(task => task.id === id)) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', `Vobs Queue: 已存在任务 ${id}`)\n }\n const task = createTask(fn, id, taskOptions)\n ownedTasks.add(task)\n tasks.value = Object.freeze([...tasks.value, task])\n queue.push(task)\n sortQueue()\n refreshStats()\n drain()\n return task\n },\n\n pause(): void {\n ensureActive()\n paused.value = true\n },\n\n resume(): void {\n ensureActive()\n if (!paused.value) return\n paused.value = false\n drain()\n },\n\n clear(): void {\n ensureActive()\n for (const task of [...queue]) task.cancel()\n queue.length = 0\n refreshStats()\n },\n\n dispose(): void {\n if (disposed) return\n disposed = true\n for (const task of [...ownedTasks]) task.cancel()\n queue.length = 0\n for (const task of ownedTasks) task.dispose()\n ownedTasks.clear()\n tasks.value = Object.freeze([])\n pending.dispose()\n processing.dispose()\n completed.dispose()\n failed.dispose()\n total.dispose()\n paused.dispose()\n tasks.dispose()\n }\n }\n\n if (getCurrentOwner()) onDispose(context.dispose)\n return context\n\n function createTask<T>(fn: QueueTaskFunction<T>, id: string, taskOptions: QueueTaskOptions): InternalTask<T> {\n const priority = taskOptions.priority ?? 'normal'\n if (!(priority in PRIORITIES)) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', `Vobs Queue: 不支持任务优先级 ${String(priority)}`)\n }\n const maxRetries = taskOptions.retry ?? 0\n if (!Number.isInteger(maxRetries) || maxRetries < 0) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: retry 必须是大于等于 0 的整数')\n }\n const retryDelay = taskOptions.retryDelay ?? 0\n validateRetryDelay(retryDelay)\n\n const status = state<QueueTaskStatus>('pending')\n const attempt = state(0)\n const result = state<T | null>(null)\n const error = state<Error | null>(null)\n let promise!: Promise<T>\n\n const task: InternalTask<T> = {\n id,\n priority,\n status,\n attempt,\n result,\n error,\n get promise(): Promise<T> { return promise },\n fn,\n maxRetries,\n retryDelay,\n sequence: sequence++,\n controller: null,\n settled: false,\n executing: false,\n retryQueued: false,\n resolve: null,\n reject: null,\n\n cancel(): void {\n if (status.value === 'success' || status.value === 'error' || status.value === 'cancelled') return\n task.controller?.abort()\n removeFromQueue(task)\n status.value = 'cancelled'\n const cancellation = new QueueError('QUEUE_TASK_CANCELLED', `Vobs Queue: 任务 ${id} 已取消`)\n error.value = cancellation\n settleReject(cancellation)\n refreshStats()\n },\n\n retry(): Promise<T> {\n ensureActive()\n if (status.value === 'pending' || status.value === 'running' || status.value === 'retrying') return promise\n if (status.value === 'success') return promise\n status.value = 'pending'\n attempt.value = 0\n result.value = null\n error.value = null\n task.controller = null\n task.settled = false\n task.retryQueued = true\n promise = createPromise()\n if (!task.executing) queue.push(task)\n sortQueue()\n refreshStats()\n drain()\n return promise\n },\n\n run(): Promise<void> {\n task.retryQueued = false\n task.executing = true\n return execute(task).finally(() => {\n task.executing = false\n if (task.retryQueued && task.status.value === 'pending' && !disposed) {\n task.retryQueued = false\n queue.push(task)\n sortQueue()\n drain()\n }\n })\n },\n\n dispose(): void {\n task.controller?.abort()\n status.dispose()\n attempt.dispose()\n result.dispose()\n error.dispose()\n }\n }\n promise = createPromise()\n return task\n\n function createPromise(): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n task.resolve = resolve\n task.reject = reject\n })\n }\n\n function settleReject(reason: unknown): void {\n if (task.settled) return\n task.settled = true\n task.reject?.(reason)\n task.resolve = null\n task.reject = null\n }\n }\n\n async function execute<T>(task: InternalTask<T>): Promise<void> {\n while (!disposed && (task.status.value === 'pending' || task.status.value === 'retrying')) {\n if (task.status.value === 'retrying') task.status.value = 'pending'\n task.status.value = 'running'\n task.attempt.value++\n const controller = new AbortController()\n task.controller = controller\n refreshStats()\n try {\n const value = await task.fn(controller.signal)\n if (isCancelled(task) || disposed) return\n task.result.value = value\n task.status.value = 'success'\n settleTask(task, value)\n refreshStats()\n return\n } catch (reason) {\n if (isCancelled(task) || disposed) return\n if (isAbortError(reason)) {\n const cancellation = new QueueError('QUEUE_TASK_CANCELLED', `Vobs Queue: 任务 ${task.id} 已取消`, reason)\n task.error.value = cancellation\n task.status.value = 'cancelled'\n settleTask(task, undefined, cancellation)\n refreshStats()\n return\n }\n const failure = toQueueError(reason, task.id)\n let delay: number | undefined\n try {\n if (task.attempt.value <= task.maxRetries) {\n delay = resolveRetryDelay(task.retryDelay, task.attempt.value, failure)\n }\n } catch (delayError) {\n const invalidDelay = toQueueError(delayError, task.id)\n task.error.value = invalidDelay\n task.status.value = 'error'\n settleTask(task, undefined, invalidDelay)\n report(invalidDelay, task)\n refreshStats()\n return\n }\n if (delay !== undefined) {\n task.status.value = 'retrying'\n refreshStats()\n try {\n await wait(delay, controller.signal)\n } catch (delayError) {\n if (isCancelled(task) || isAbortError(delayError)) return\n throw delayError\n }\n if (isCancelled(task) || disposed) return\n continue\n }\n task.error.value = failure\n task.status.value = 'error'\n settleTask(task, undefined, failure)\n report(failure, task)\n refreshStats()\n return\n } finally {\n if (task.controller === controller) task.controller = null\n }\n }\n }\n\n function drain(): void {\n while (!disposed && !paused.value && active < concurrency && queue.length > 0) {\n const task = queue.shift()!\n if (task.status.value !== 'pending') continue\n active++\n void task.run().finally(() => {\n active--\n refreshStats()\n drain()\n })\n }\n refreshStats()\n }\n\n function sortQueue(): void {\n queue.sort((left, right) => PRIORITIES[right.priority] - PRIORITIES[left.priority] || left.sequence - right.sequence)\n }\n\n function removeFromQueue(task: InternalTask<any>): void {\n const index = queue.indexOf(task)\n if (index >= 0) queue.splice(index, 1)\n }\n\n function refreshStats(): void {\n let nextPending = 0\n let nextProcessing = 0\n let nextCompleted = 0\n let nextFailed = 0\n for (const task of tasks.value) {\n if (task.status.value === 'pending') nextPending++\n else if (task.status.value === 'running' || task.status.value === 'retrying') nextProcessing++\n else if (task.status.value === 'success') nextCompleted++\n else if (task.status.value === 'error') nextFailed++\n }\n pending.value = nextPending\n processing.value = nextProcessing\n completed.value = nextCompleted\n failed.value = nextFailed\n total.value = tasks.value.length\n }\n\n function settleTask<T>(task: InternalTask<T>, value?: T, reason?: unknown): void {\n if (task.settled) return\n task.settled = true\n if (reason !== undefined) task.reject?.(reason)\n else task.resolve?.(value as T)\n task.resolve = null\n task.reject = null\n }\n\n function report(queueError: QueueError, task: QueueTask): void {\n try { options.onError?.(queueError, task) } catch { /* observers cannot break queue state */ }\n }\n\n function ensureActive(): void {\n if (disposed) throw new QueueError('QUEUE_CONTEXT_DISPOSED', 'Vobs Queue: 上下文已销毁')\n }\n\n function isCancelled(task: QueueTask): boolean {\n return task.status.value === 'cancelled'\n }\n}\n\nexport function queuePlugin(options: QueuePluginOptions = {}): VobsPlugin {\n return {\n name: '@vobs/queue',\n version: '0.1.0',\n install(context) {\n const ownedQueue = options.queue ? undefined : createTaskQueue(options)\n context.provide(QUEUE_KEY, options.queue ?? ownedQueue!)\n return () => ownedQueue?.dispose()\n }\n }\n}\n\nexport function useQueue(): TaskQueue {\n const queue = inject(QUEUE_KEY)\n if (!queue) throw new QueueError('QUEUE_CONTEXT_MISSING', 'Vobs Queue: 找不到上下文,请安装 queuePlugin')\n return queue\n}\n\nfunction resolveConcurrency(options: TaskQueueOptions): number {\n if (options.concurrency !== undefined && options.concurrent !== undefined && options.concurrency !== options.concurrent) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: concurrency 与 concurrent 不能设置为不同值')\n }\n const value = options.concurrency ?? options.concurrent ?? 3\n if (!Number.isInteger(value) || value <= 0) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: concurrency 必须是正整数')\n }\n return value\n}\n\nfunction validateRetryDelay(value: QueueRetryDelay): void {\n if (typeof value === 'number' && (!Number.isFinite(value) || value < 0)) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: retryDelay 必须是大于等于 0 的有限数字或函数')\n }\n if (typeof value !== 'number' && typeof value !== 'function') {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: retryDelay 必须是数字或函数')\n }\n}\n\nfunction resolveRetryDelay(value: QueueRetryDelay, attempt: number, error: Error): number {\n const delay = typeof value === 'function' ? value(attempt, error) : value\n if (!Number.isFinite(delay) || delay < 0) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: retryDelay 函数必须返回大于等于 0 的有限数字')\n }\n return delay\n}\n\nfunction wait(delay: number, signal: AbortSignal): Promise<void> {\n if (delay === 0) return Promise.resolve()\n return new Promise((resolve, reject) => {\n const timer = setTimeout(done, delay)\n signal.addEventListener('abort', abort, { once: true })\n function done(): void {\n signal.removeEventListener('abort', abort)\n resolve()\n }\n function abort(): void {\n clearTimeout(timer)\n reject(Object.assign(new Error('Aborted'), { name: 'AbortError' }))\n }\n })\n}\n\nfunction toQueueError(reason: unknown, id: string): QueueError {\n if (reason instanceof QueueError) return reason\n return new QueueError('QUEUE_TASK_FAILED', `Vobs Queue: 任务 ${id} 执行失败`, reason)\n}\n\nfunction isAbortError(value: unknown): boolean {\n return Boolean(value) && typeof value === 'object' && (value as { name?: unknown }).name === 'AbortError'\n}\n"],"mappings":"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","names":["task"]}
|
package/dist/index.js
CHANGED
|
@@ -1,216 +1,9 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
|
|
4
|
-
// packages/reactivity/src/debug.ts
|
|
5
|
-
var activeDebugHooks = null;
|
|
6
|
-
var signalNames = /* @__PURE__ */ new WeakMap();
|
|
7
|
-
function hasDebugHooks() {
|
|
8
|
-
return activeDebugHooks !== null;
|
|
9
|
-
}
|
|
10
|
-
__name(hasDebugHooks, "hasDebugHooks");
|
|
11
|
-
function setSignalDebugName(signal, name) {
|
|
12
|
-
signalNames.set(signal, name);
|
|
13
|
-
invokeDebug("signalNamed", signal, name);
|
|
14
|
-
}
|
|
15
|
-
__name(setSignalDebugName, "setSignalDebugName");
|
|
16
|
-
function invokeDebug(name, ...args) {
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
__name(invokeDebug, "invokeDebug");
|
|
20
|
-
|
|
21
|
-
// packages/reactivity/src/owner.ts
|
|
22
|
-
var currentOwner = null;
|
|
23
|
-
function getCurrentOwner() {
|
|
24
|
-
return currentOwner;
|
|
25
|
-
}
|
|
26
|
-
__name(getCurrentOwner, "getCurrentOwner");
|
|
27
|
-
function onDispose(cleanup) {
|
|
28
|
-
throw new Error("Vobs: onDispose \u5FC5\u987B\u5728 Owner \u4F5C\u7528\u57DF\u5185\u8C03\u7528");
|
|
29
|
-
}
|
|
30
|
-
__name(onDispose, "onDispose");
|
|
31
|
-
|
|
32
|
-
// packages/reactivity/src/signal.ts
|
|
33
|
-
var currentSubscriber = null;
|
|
34
|
-
function getCurrentSubscriber() {
|
|
35
|
-
return currentSubscriber;
|
|
36
|
-
}
|
|
37
|
-
__name(getCurrentSubscriber, "getCurrentSubscriber");
|
|
38
|
-
function trackDependency(dependency) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
__name(trackDependency, "trackDependency");
|
|
42
|
-
function state(initialValue, debugName) {
|
|
43
|
-
let value = initialValue;
|
|
44
|
-
let disposed = false;
|
|
45
|
-
const subscribers = /* @__PURE__ */ new Set();
|
|
46
|
-
const signalInstance = {
|
|
47
|
-
get value() {
|
|
48
|
-
return value;
|
|
49
|
-
},
|
|
50
|
-
set value(nextValue) {
|
|
51
|
-
if (disposed || Object.is(value, nextValue)) return;
|
|
52
|
-
value = nextValue;
|
|
53
|
-
for (const subscriber of [...subscribers]) subscriber.notify();
|
|
54
|
-
},
|
|
55
|
-
unsubscribe(subscriber) {
|
|
56
|
-
subscribers.delete(subscriber);
|
|
57
|
-
},
|
|
58
|
-
// 与 `.value =` 赋值同一条路径:判等短路、debug hook、notify 全部一致。
|
|
59
|
-
// 以闭包实现,可安全地作为回调直接传递(无 this 绑定问题)。
|
|
60
|
-
set(next) {
|
|
61
|
-
signalInstance.value = next;
|
|
62
|
-
},
|
|
63
|
-
dispose() {
|
|
64
|
-
if (disposed) return;
|
|
65
|
-
disposed = true;
|
|
66
|
-
subscribers.clear();
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
if (debugName?.trim()) setSignalDebugName(signalInstance, debugName.trim());
|
|
70
|
-
return signalInstance;
|
|
71
|
-
}
|
|
72
|
-
__name(state, "state");
|
|
73
|
-
|
|
74
|
-
// packages/reactivity/src/scheduler.ts
|
|
75
|
-
var _Scheduler = class _Scheduler {
|
|
76
|
-
constructor() {
|
|
77
|
-
this.dirtyEffects = /* @__PURE__ */ new Set();
|
|
78
|
-
this.lowPriorityEffects = /* @__PURE__ */ new Set();
|
|
79
|
-
// flush 不可重入(flushing 标志保证),缓冲数组可在轮次间安全复用,避免每轮分配。
|
|
80
|
-
this.normalBuffer = [];
|
|
81
|
-
this.lowBuffer = [];
|
|
82
|
-
this.flushing = false;
|
|
83
|
-
this.scheduled = false;
|
|
84
|
-
this.batchDepth = 0;
|
|
85
|
-
}
|
|
86
|
-
schedule(effect2) {
|
|
87
|
-
if (effect2.disposed) return;
|
|
88
|
-
this.dirtyEffects.add(effect2);
|
|
89
|
-
this.lowPriorityEffects.delete(effect2);
|
|
90
|
-
this.ensureScheduled();
|
|
91
|
-
}
|
|
92
|
-
/** Queue an effect behind normal updates while preserving deterministic order. */
|
|
93
|
-
scheduleLow(effect2) {
|
|
94
|
-
if (effect2.disposed) return;
|
|
95
|
-
if (!this.dirtyEffects.has(effect2)) this.lowPriorityEffects.add(effect2);
|
|
96
|
-
this.ensureScheduled();
|
|
97
|
-
}
|
|
98
|
-
ensureScheduled() {
|
|
99
|
-
if (this.batchDepth === 0 && !this.flushing && !this.scheduled) {
|
|
100
|
-
this.scheduled = true;
|
|
101
|
-
queueMicrotask(() => {
|
|
102
|
-
this.scheduled = false;
|
|
103
|
-
this.flush();
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
remove(effect2) {
|
|
108
|
-
this.dirtyEffects.delete(effect2);
|
|
109
|
-
this.lowPriorityEffects.delete(effect2);
|
|
110
|
-
}
|
|
111
|
-
batch(fn) {
|
|
112
|
-
this.batchDepth++;
|
|
113
|
-
try {
|
|
114
|
-
return fn();
|
|
115
|
-
} finally {
|
|
116
|
-
this.batchDepth--;
|
|
117
|
-
if (this.batchDepth === 0) this.flush();
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
flush() {
|
|
121
|
-
if (this.flushing || this.batchDepth > 0) return;
|
|
122
|
-
this.flushing = true;
|
|
123
|
-
let rounds = 0;
|
|
124
|
-
let firstError;
|
|
125
|
-
let hasError = false;
|
|
126
|
-
try {
|
|
127
|
-
while (this.dirtyEffects.size > 0 || this.lowPriorityEffects.size > 0) {
|
|
128
|
-
if (++rounds > 100) {
|
|
129
|
-
this.dirtyEffects.clear();
|
|
130
|
-
this.lowPriorityEffects.clear();
|
|
131
|
-
throw new Error("Vobs: \u54CD\u5E94\u5F0F\u66F4\u65B0\u8D85\u8FC7 100 \u8F6E\uFF0C\u53EF\u80FD\u5B58\u5728\u5FAA\u73AF\u4F9D\u8D56");
|
|
132
|
-
}
|
|
133
|
-
this.collectRunnable(this.dirtyEffects, this.normalBuffer);
|
|
134
|
-
this.collectRunnable(this.lowPriorityEffects, this.lowBuffer);
|
|
135
|
-
sortEffects(this.normalBuffer);
|
|
136
|
-
sortEffects(this.lowBuffer);
|
|
137
|
-
for (const effect2 of this.normalBuffer) {
|
|
138
|
-
try {
|
|
139
|
-
effect2.run();
|
|
140
|
-
} catch (error) {
|
|
141
|
-
if (!hasError) {
|
|
142
|
-
firstError = error;
|
|
143
|
-
hasError = true;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
for (const effect2 of this.lowBuffer) {
|
|
148
|
-
try {
|
|
149
|
-
effect2.run();
|
|
150
|
-
} catch (error) {
|
|
151
|
-
if (!hasError) {
|
|
152
|
-
firstError = error;
|
|
153
|
-
hasError = true;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
this.normalBuffer.length = 0;
|
|
158
|
-
this.lowBuffer.length = 0;
|
|
159
|
-
}
|
|
160
|
-
} finally {
|
|
161
|
-
this.normalBuffer.length = 0;
|
|
162
|
-
this.lowBuffer.length = 0;
|
|
163
|
-
this.flushing = false;
|
|
164
|
-
}
|
|
165
|
-
if (hasError) throw firstError;
|
|
166
|
-
}
|
|
167
|
-
/** 收集未 disposed 的 effect 并清空源集合;run() 期间新调度的 effect 留给下一轮。 */
|
|
168
|
-
collectRunnable(source, target) {
|
|
169
|
-
for (const effect2 of source) {
|
|
170
|
-
if (!effect2.disposed) target.push(effect2);
|
|
171
|
-
}
|
|
172
|
-
source.clear();
|
|
173
|
-
}
|
|
174
|
-
};
|
|
175
|
-
__name(_Scheduler, "Scheduler");
|
|
176
|
-
function sortEffects(effects) {
|
|
177
|
-
if (effects.length > 1) {
|
|
178
|
-
effects.sort((a, b) => b.depth - a.depth || a.order - b.order);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
__name(sortEffects, "sortEffects");
|
|
182
|
-
|
|
183
|
-
// packages/runtime/src/hmr.ts
|
|
184
|
-
var globalTarget = globalThis;
|
|
185
|
-
var hmrGlobal = globalTarget.__VOBS_HMR__ ?? { modules: /* @__PURE__ */ new Map() };
|
|
186
|
-
globalTarget.__VOBS_HMR__ = hmrGlobal;
|
|
187
|
-
|
|
188
|
-
// packages/vobs/src/context.ts
|
|
189
|
-
var ownerProviders = /* @__PURE__ */ new WeakMap();
|
|
190
|
-
function inject(key, fallback) {
|
|
191
|
-
const owner = getCurrentOwner();
|
|
192
|
-
const value = owner ? injectFromOwner(owner, key) : void 0;
|
|
193
|
-
return value === void 0 ? fallback : value;
|
|
194
|
-
}
|
|
195
|
-
__name(inject, "inject");
|
|
196
|
-
function injectFromOwner(owner, key) {
|
|
197
|
-
let current = owner;
|
|
198
|
-
while (current) {
|
|
199
|
-
const providers = ownerProviders.get(current);
|
|
200
|
-
if (providers?.has(key)) return providers.get(key);
|
|
201
|
-
current = current.parent;
|
|
202
|
-
}
|
|
203
|
-
return void 0;
|
|
204
|
-
}
|
|
205
|
-
__name(injectFromOwner, "injectFromOwner");
|
|
206
|
-
|
|
207
|
-
// packages/vobs/src/app.ts
|
|
208
|
-
function createInjectionKey(description) {
|
|
209
|
-
return Symbol(description);
|
|
210
|
-
}
|
|
211
|
-
__name(createInjectionKey, "createInjectionKey");
|
|
212
|
-
|
|
213
4
|
// packages/queue/src/index.ts
|
|
5
|
+
import { getCurrentOwner, onDispose, state } from "@vobs/reactivity";
|
|
6
|
+
import { createInjectionKey, inject } from "@vobs/vobs";
|
|
214
7
|
var _QueueError = class _QueueError extends Error {
|
|
215
8
|
constructor(code, message, cause) {
|
|
216
9
|
super(message);
|
|
@@ -305,6 +98,7 @@ function createTaskQueue(options = {}) {
|
|
|
305
98
|
tasks.dispose();
|
|
306
99
|
}
|
|
307
100
|
};
|
|
101
|
+
if (getCurrentOwner()) onDispose(context.dispose);
|
|
308
102
|
return context;
|
|
309
103
|
function createTask(fn, id, taskOptions) {
|
|
310
104
|
const priority = taskOptions.priority ?? "normal";
|
|
@@ -399,6 +193,7 @@ function createTaskQueue(options = {}) {
|
|
|
399
193
|
task.reject = reject;
|
|
400
194
|
});
|
|
401
195
|
}
|
|
196
|
+
__name(createPromise, "createPromise");
|
|
402
197
|
function settleReject(reason) {
|
|
403
198
|
if (task.settled) return;
|
|
404
199
|
task.settled = true;
|
|
@@ -406,7 +201,9 @@ function createTaskQueue(options = {}) {
|
|
|
406
201
|
task.resolve = null;
|
|
407
202
|
task.reject = null;
|
|
408
203
|
}
|
|
204
|
+
__name(settleReject, "settleReject");
|
|
409
205
|
}
|
|
206
|
+
__name(createTask, "createTask");
|
|
410
207
|
async function execute(task) {
|
|
411
208
|
while (!disposed && (task.status.value === "pending" || task.status.value === "retrying")) {
|
|
412
209
|
if (task.status.value === "retrying") task.status.value = "pending";
|
|
@@ -471,6 +268,7 @@ function createTaskQueue(options = {}) {
|
|
|
471
268
|
}
|
|
472
269
|
}
|
|
473
270
|
}
|
|
271
|
+
__name(execute, "execute");
|
|
474
272
|
function drain() {
|
|
475
273
|
while (!disposed && !paused.value && active < concurrency && queue.length > 0) {
|
|
476
274
|
const task = queue.shift();
|
|
@@ -484,13 +282,16 @@ function createTaskQueue(options = {}) {
|
|
|
484
282
|
}
|
|
485
283
|
refreshStats();
|
|
486
284
|
}
|
|
285
|
+
__name(drain, "drain");
|
|
487
286
|
function sortQueue() {
|
|
488
287
|
queue.sort((left, right) => PRIORITIES[right.priority] - PRIORITIES[left.priority] || left.sequence - right.sequence);
|
|
489
288
|
}
|
|
289
|
+
__name(sortQueue, "sortQueue");
|
|
490
290
|
function removeFromQueue(task) {
|
|
491
291
|
const index = queue.indexOf(task);
|
|
492
292
|
if (index >= 0) queue.splice(index, 1);
|
|
493
293
|
}
|
|
294
|
+
__name(removeFromQueue, "removeFromQueue");
|
|
494
295
|
function refreshStats() {
|
|
495
296
|
let nextPending = 0;
|
|
496
297
|
let nextProcessing = 0;
|
|
@@ -508,6 +309,7 @@ function createTaskQueue(options = {}) {
|
|
|
508
309
|
failed.value = nextFailed;
|
|
509
310
|
total.value = tasks.value.length;
|
|
510
311
|
}
|
|
312
|
+
__name(refreshStats, "refreshStats");
|
|
511
313
|
function settleTask(task, value, reason) {
|
|
512
314
|
if (task.settled) return;
|
|
513
315
|
task.settled = true;
|
|
@@ -516,18 +318,22 @@ function createTaskQueue(options = {}) {
|
|
|
516
318
|
task.resolve = null;
|
|
517
319
|
task.reject = null;
|
|
518
320
|
}
|
|
321
|
+
__name(settleTask, "settleTask");
|
|
519
322
|
function report(queueError, task) {
|
|
520
323
|
try {
|
|
521
324
|
options.onError?.(queueError, task);
|
|
522
325
|
} catch {
|
|
523
326
|
}
|
|
524
327
|
}
|
|
328
|
+
__name(report, "report");
|
|
525
329
|
function ensureActive() {
|
|
526
330
|
if (disposed) throw new QueueError("QUEUE_CONTEXT_DISPOSED", "Vobs Queue: \u4E0A\u4E0B\u6587\u5DF2\u9500\u6BC1");
|
|
527
331
|
}
|
|
332
|
+
__name(ensureActive, "ensureActive");
|
|
528
333
|
function isCancelled(task) {
|
|
529
334
|
return task.status.value === "cancelled";
|
|
530
335
|
}
|
|
336
|
+
__name(isCancelled, "isCancelled");
|
|
531
337
|
}
|
|
532
338
|
__name(createTaskQueue, "createTaskQueue");
|
|
533
339
|
function queuePlugin(options = {}) {
|
|
@@ -603,7 +409,11 @@ function isAbortError(value) {
|
|
|
603
409
|
return Boolean(value) && typeof value === "object" && value.name === "AbortError";
|
|
604
410
|
}
|
|
605
411
|
__name(isAbortError, "isAbortError");
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
412
|
+
export {
|
|
413
|
+
QUEUE_KEY,
|
|
414
|
+
QueueError,
|
|
415
|
+
createTaskQueue,
|
|
416
|
+
queuePlugin,
|
|
417
|
+
useQueue
|
|
418
|
+
};
|
|
609
419
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../reactivity/src/debug.ts","../../reactivity/src/owner.ts","../../reactivity/src/signal.ts","../../reactivity/src/scheduler.ts","../../runtime/src/hmr.ts","../../vobs/src/context.ts","../../vobs/src/app.ts","../src/index.ts"],"names":["effect","task"],"mappings":"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","file":"index.js","sourcesContent":["import type { Effect } from './effect'\nimport type { Owner } from './owner'\nimport type { Dependency, ReadableSignal, Subscriber } from './signal'\n\nexport interface ReactivityDebugHooks {\n ownerCreated?(owner: Owner): void\n ownerNamed?(owner: Owner, name: string): void\n ownerDisposed?(owner: Owner): void\n signalCreated?(signal: ReadableSignal<unknown>, owner: Owner | null): void\n signalNamed?(signal: ReadableSignal<unknown>, name: string): void\n signalRead?(signal: ReadableSignal<unknown>, subscriber: Subscriber): void\n signalChanged?(signal: ReadableSignal<unknown>, previousValue: unknown, nextValue: unknown): void\n signalDisposed?(signal: ReadableSignal<unknown>): void\n dependencyTracked?(dependency: Dependency, subscriber: Subscriber): void\n dependencyUntracked?(dependency: Dependency, subscriber: Subscriber): void\n effectCreated?(effect: Effect, owner: Owner | null): void\n effectInvalidated?(effect: Effect): void\n effectRunStart?(effect: Effect): void\n effectRunEnd?(effect: Effect, error?: unknown, handled?: boolean): void\n effectDisposed?(effect: Effect): void\n memoCreated?(signal: ReadableSignal<unknown>, subscriber: Subscriber, owner: Owner | null): void\n memoInvalidated?(signal: ReadableSignal<unknown>): void\n flushStart?(): void\n flushEnd?(): void\n}\n\nlet activeDebugHooks: ReactivityDebugHooks | null = null\nconst signalNames = new WeakMap<object, string>()\n\nexport function setDebugHooks(hooks: ReactivityDebugHooks | null): ReactivityDebugHooks | null {\n const previous = activeDebugHooks\n activeDebugHooks = hooks\n return previous\n}\n\nexport function getDebugHooks(): ReactivityDebugHooks | null {\n return activeDebugHooks\n}\n\n/** 热路径守卫:无 hooks 时跳过 invokeDebug 调用,避免 rest 参数数组分配。 */\nexport function hasDebugHooks(): boolean {\n return activeDebugHooks !== null\n}\n\nexport function setSignalDebugName(signal: ReadableSignal<unknown>, name: string): void {\n signalNames.set(signal, name)\n invokeDebug('signalNamed', signal, name)\n}\n\nexport function getSignalDebugName(signal: ReadableSignal<unknown>): string | undefined {\n return signalNames.get(signal)\n}\n\nexport function invokeDebug<K extends keyof ReactivityDebugHooks>(\n name: K,\n ...args: Parameters<NonNullable<ReactivityDebugHooks[K]>>\n): void {\n const callback = activeDebugHooks?.[name] as ((...values: unknown[]) => void) | undefined\n if (!callback) return\n try {\n callback(...args)\n } catch {\n // Debug tooling must never change application behavior.\n }\n}\n","import { invokeDebug, hasDebugHooks } from './debug'\n\nexport interface Owner {\n readonly id: string\n readonly parent: Owner | null\n readonly children: readonly Owner[]\n readonly depth: number\n readonly disposed: boolean\n run<T>(fn: () => T): T\n addCleanup(cleanup: () => void): void\n onDispose(cleanup: () => void): void\n onError(handler: (error: unknown) => void): () => void\n handleError(error: unknown): boolean\n dispose(): void\n}\n\nlet currentOwner: Owner | null = null\nlet nextOwnerId = 1\nconst ownerNames = new WeakMap<Owner, string>()\n\nexport function createOwner(): Owner {\n const parent = currentOwner\n let disposed = parent?.disposed ?? false\n const children: Owner[] = []\n const cleanups: Array<() => void> = []\n const errorHandlers = new Set<(error: unknown) => void>()\n\n const owner: Owner = {\n id: `owner-${nextOwnerId++}`,\n parent,\n children,\n depth: (parent?.depth ?? -1) + 1,\n\n get disposed(): boolean {\n return disposed\n },\n\n run<T>(fn: () => T): T {\n if (disposed) throw new Error('Vobs: 已销毁的 Owner 不能继续运行')\n const previous = currentOwner\n currentOwner = owner\n try {\n return fn()\n } finally {\n currentOwner = previous\n }\n },\n\n addCleanup(cleanup: () => void): void {\n if (disposed) {\n cleanup()\n return\n }\n cleanups.push(cleanup)\n },\n\n onDispose(cleanup: () => void): void {\n owner.addCleanup(cleanup)\n },\n\n onError(handler: (error: unknown) => void): () => void {\n errorHandlers.add(handler)\n const remove = () => errorHandlers.delete(handler)\n owner.addCleanup(remove)\n return remove\n },\n\n handleError(error: unknown): boolean {\n for (const handler of [...errorHandlers].reverse()) {\n try {\n handler(error)\n return true\n } catch (handlerError) {\n return parent?.handleError(handlerError) ?? false\n }\n }\n return parent?.handleError(error) ?? false\n },\n\n dispose(): void {\n if (disposed) return\n disposed = true\n for (const child of [...children]) child.dispose()\n children.length = 0\n\n let firstError: unknown\n for (let index = cleanups.length - 1; index >= 0; index--) {\n try {\n cleanups[index]()\n } catch (error) {\n firstError ??= error\n }\n }\n cleanups.length = 0\n\n if (parent) {\n const index = parent.children.indexOf(owner)\n if (index >= 0) (parent.children as Owner[]).splice(index, 1)\n }\n if (hasDebugHooks()) invokeDebug('ownerDisposed', owner)\n if (firstError) throw firstError\n }\n }\n\n if (parent && !parent.disposed) (parent.children as Owner[]).push(owner)\n if (hasDebugHooks()) invokeDebug('ownerCreated', owner)\n return owner\n}\n\nexport function setOwnerDebugName(owner: Owner, name: string): void {\n ownerNames.set(owner, name)\n if (hasDebugHooks()) invokeDebug('ownerNamed', owner, name)\n}\n\nexport function getOwnerDebugName(owner: Owner): string | undefined {\n return ownerNames.get(owner)\n}\n\nexport function getCurrentOwner(): Owner | null {\n return currentOwner\n}\n\n/** Re-enter an Owner for an explicitly captured asynchronous continuation. */\nexport function runWithOwner<T>(owner: Owner, fn: () => T): T {\n return owner.run(fn)\n}\n\nexport function onDispose(cleanup: () => void): void {\n const owner = getCurrentOwner()\n if (!owner) throw new Error('Vobs: onDispose 必须在 Owner 作用域内调用')\n owner.onDispose(cleanup)\n}\n","import { getCurrentOwner } from './owner'\nimport { invokeDebug, hasDebugHooks, setSignalDebugName } from './debug'\n\nexport interface Dependency {\n unsubscribe(subscriber: Subscriber): void\n}\n\nexport interface Subscriber {\n readonly dependencies: Set<Dependency>\n readonly disposed: boolean\n notify(): void\n}\n\n/** 只读信号:派生值(memo)与只读上下文的最小契约,只能订阅与读取。 */\nexport interface ReadableSignal<T> extends Dependency {\n readonly value: T\n dispose(): void\n}\n\n/** 可写信号:state() 的返回类型。`set` 与 `.value =` 赋值语义完全一致。 */\nexport interface Signal<T> extends ReadableSignal<T> {\n value: T\n set(next: T): void\n}\n\nlet currentSubscriber: Subscriber | null = null\n\nexport function getCurrentSubscriber(): Subscriber | null {\n return currentSubscriber\n}\n\nexport function setCurrentSubscriber(subscriber: Subscriber | null): void {\n currentSubscriber = subscriber\n}\n\nexport function untrack<T>(fn: () => T): T {\n const previous = currentSubscriber\n currentSubscriber = null\n try {\n return fn()\n } finally {\n currentSubscriber = previous\n }\n}\n\nexport function trackDependency(dependency: Dependency): void {\n if (!currentSubscriber || currentSubscriber.disposed) return\n const added = !currentSubscriber.dependencies.has(dependency)\n currentSubscriber.dependencies.add(dependency)\n if (added && hasDebugHooks()) invokeDebug('dependencyTracked', dependency, currentSubscriber)\n}\n\n/**\n * Create a reactive state signal.\n *\n * State uses identity (`Object.is`) change detection. Objects and arrays are\n * intentionally shallow: mutating a nested property in place does not notify\n * subscribers; assign a new object/array to `value` to publish the change.\n *\n * The optional debug name is metadata for inspection tools only. It does not\n * affect subscriptions, scheduling, serialization, or the signal contract.\n */\nexport function state<T>(initialValue: T, debugName?: string): Signal<T> {\n let value = initialValue\n let disposed = false\n const subscribers = new Set<Subscriber>()\n\n const signalInstance: Signal<T> = {\n get value(): T {\n const subscriber = getCurrentSubscriber()\n if (subscriber && !subscriber.disposed) {\n subscribers.add(subscriber)\n if (hasDebugHooks()) invokeDebug('signalRead', signalInstance as Signal<unknown>, subscriber)\n trackDependency(signalInstance)\n }\n return value\n },\n\n set value(nextValue: T) {\n if (disposed || Object.is(value, nextValue)) return\n const previousValue = value\n value = nextValue\n if (hasDebugHooks()) invokeDebug('signalChanged', signalInstance as Signal<unknown>, previousValue, nextValue)\n for (const subscriber of [...subscribers]) subscriber.notify()\n },\n\n unsubscribe(subscriber: Subscriber): void {\n subscribers.delete(subscriber)\n },\n\n // 与 `.value =` 赋值同一条路径:判等短路、debug hook、notify 全部一致。\n // 以闭包实现,可安全地作为回调直接传递(无 this 绑定问题)。\n set(next: T): void {\n signalInstance.value = next\n },\n\n dispose(): void {\n if (disposed) return\n disposed = true\n subscribers.clear()\n if (hasDebugHooks()) invokeDebug('signalDisposed', signalInstance as Signal<unknown>)\n }\n }\n\n const owner = getCurrentOwner()\n owner?.addCleanup(signalInstance.dispose)\n if (hasDebugHooks()) invokeDebug('signalCreated', signalInstance as Signal<unknown>, owner)\n if (debugName?.trim()) setSignalDebugName(signalInstance as Signal<unknown>, debugName.trim())\n return signalInstance\n}\n","import type { Effect } from './effect'\nimport { hasDebugHooks, invokeDebug } from './debug'\n\nexport class Scheduler {\n private readonly dirtyEffects = new Set<Effect>()\n private readonly lowPriorityEffects = new Set<Effect>()\n // flush 不可重入(flushing 标志保证),缓冲数组可在轮次间安全复用,避免每轮分配。\n private readonly normalBuffer: Effect[] = []\n private readonly lowBuffer: Effect[] = []\n private flushing = false\n private scheduled = false\n private batchDepth = 0\n\n schedule(effect: Effect): void {\n if (effect.disposed) return\n this.dirtyEffects.add(effect)\n this.lowPriorityEffects.delete(effect)\n this.ensureScheduled()\n }\n\n /** Queue an effect behind normal updates while preserving deterministic order. */\n scheduleLow(effect: Effect): void {\n if (effect.disposed) return\n if (!this.dirtyEffects.has(effect)) this.lowPriorityEffects.add(effect)\n this.ensureScheduled()\n }\n\n private ensureScheduled(): void {\n if (this.batchDepth === 0 && !this.flushing && !this.scheduled) {\n this.scheduled = true\n queueMicrotask(() => {\n this.scheduled = false\n this.flush()\n })\n }\n }\n\n remove(effect: Effect): void {\n this.dirtyEffects.delete(effect)\n this.lowPriorityEffects.delete(effect)\n }\n\n batch<T>(fn: () => T): T {\n this.batchDepth++\n try {\n return fn()\n } finally {\n this.batchDepth--\n if (this.batchDepth === 0) this.flush()\n }\n }\n\n flush(): void {\n if (this.flushing || this.batchDepth > 0) return\n this.flushing = true\n const debugEnabled = hasDebugHooks()\n if (debugEnabled) invokeDebug('flushStart')\n let rounds = 0\n let firstError: unknown\n let hasError = false\n try {\n while (this.dirtyEffects.size > 0 || this.lowPriorityEffects.size > 0) {\n if (++rounds > 100) {\n this.dirtyEffects.clear()\n this.lowPriorityEffects.clear()\n throw new Error('Vobs: 响应式更新超过 100 轮,可能存在循环依赖')\n }\n\n // normal 先、low 后,两组分别排序:与旧的合并排序语义一致\n // (旧比较器里 low 优先级本就高于 depth),但消除了比较器内的 Set 查找。\n this.collectRunnable(this.dirtyEffects, this.normalBuffer)\n this.collectRunnable(this.lowPriorityEffects, this.lowBuffer)\n sortEffects(this.normalBuffer)\n sortEffects(this.lowBuffer)\n for (const effect of this.normalBuffer) {\n try {\n effect.run()\n } catch (error) {\n // Isolate one failed effect from the rest of the flush. Re-throw\n // the first error after all runnable effects have had a chance.\n if (!hasError) {\n firstError = error\n hasError = true\n }\n }\n }\n for (const effect of this.lowBuffer) {\n try {\n effect.run()\n } catch (error) {\n if (!hasError) {\n firstError = error\n hasError = true\n }\n }\n }\n this.normalBuffer.length = 0\n this.lowBuffer.length = 0\n }\n } finally {\n this.normalBuffer.length = 0\n this.lowBuffer.length = 0\n this.flushing = false\n if (debugEnabled) invokeDebug('flushEnd')\n }\n if (hasError) throw firstError\n }\n\n /** 收集未 disposed 的 effect 并清空源集合;run() 期间新调度的 effect 留给下一轮。 */\n private collectRunnable(source: Set<Effect>, target: Effect[]): void {\n for (const effect of source) {\n if (!effect.disposed) target.push(effect)\n }\n source.clear()\n }\n}\n\n/** depth 深的先跑(子 effect 先于父),同深度按创建顺序。 */\nfunction sortEffects(effects: Effect[]): void {\n if (effects.length > 1) {\n effects.sort((a, b) => b.depth - a.depth || a.order - b.order)\n }\n}\n\nexport const scheduler = new Scheduler()\n\nexport function batch<T>(fn: () => T): T {\n return scheduler.batch(fn)\n}\n\n/** Schedule a low-priority effect explicitly. */\nexport function scheduleLow(effect: Effect): void {\n effect.scheduleLow()\n}\n","import type { VobsNode } from './fragment'\n\nexport type HmrComponent<Props extends object = Record<string, unknown>> =\n (props: Props) => VobsNode\n\nexport interface HmrStateStore {\n get<T>(key: string, initial: T | (() => T)): T\n set<T>(key: string, value: T): void\n has(key: string): boolean\n delete(key: string): void\n clear(): void\n}\n\nexport interface HmrInstance {\n node: VobsNode\n parent: Node | null\n refresh(): void\n}\n\ninterface HmrModuleState {\n readonly components: Map<string, HmrComponent>\n readonly state: Map<string, unknown>\n readonly instances: Set<HmrInstance>\n}\n\ninterface HmrGlobal {\n modules: Map<string, HmrModuleState>\n}\n\nconst globalTarget = globalThis as typeof globalThis & { __VOBS_HMR__?: HmrGlobal }\nconst hmrGlobal = globalTarget.__VOBS_HMR__ ?? { modules: new Map<string, HmrModuleState>() }\nglobalTarget.__VOBS_HMR__ = hmrGlobal\n\nexport function resolveComponent<Props extends object>(\n component: HmrComponent<Props>,\n moduleId: string,\n exportName: string\n): HmrComponent<Props> {\n const module = getModule(moduleId)\n const existing = module.components.get(exportName)\n if (existing) return existing as HmrComponent<Props>\n\n const proxy = ((props: Props) => {\n const current = (proxy as HmrComponent<Props> & { current: HmrComponent<Props> }).current\n return current(props)\n }) as HmrComponent<Props> & { current: HmrComponent<Props> }\n proxy.current = component\n Object.defineProperties(proxy, {\n displayName: { configurable: true, value: component.name || exportName },\n hmrKey: { configurable: false, value: `${moduleId}:${exportName}` }\n })\n module.components.set(exportName, proxy as HmrComponent)\n return proxy\n}\n\nexport function updateHmrModule(_moduleId: string, nextModule: Record<string, unknown>): void {\n const modules = [...hmrGlobal.modules.values()]\n for (const module of modules) {\n let changed = false\n for (const [name, proxy] of module.components) {\n const next = nextModule[name]\n if (typeof next !== 'function') continue\n const hmrProxy = proxy as HmrComponent & { current: HmrComponent; displayName?: string }\n hmrProxy.current = next as HmrComponent\n Object.defineProperty(hmrProxy, 'displayName', { configurable: true, value: next.name || name })\n changed = true\n }\n if (!changed) continue\n for (const instance of module.instances) {\n try {\n instance.refresh()\n } catch {\n // HMR failures remain application errors on the next normal render.\n }\n }\n }\n}\n\nexport function disposeHmrModule(_moduleId: string): void {\n // State and component proxies intentionally survive module disposal.\n}\n\nexport function createHmrStateStore(moduleId: string): HmrStateStore {\n const state = getModule(moduleId).state\n return {\n get<T>(key: string, initial: T | (() => T)): T {\n if (!state.has(key)) state.set(key, typeof initial === 'function' ? (initial as () => T)() : initial)\n return state.get(key) as T\n },\n set<T>(key: string, value: T): void {\n state.set(key, value)\n },\n has: key => state.has(key),\n delete: key => { state.delete(key) },\n clear: () => { state.clear() }\n }\n}\n\nexport function registerHmrInstance(moduleId: string, instance: HmrInstance): () => void {\n const instances = getModule(moduleId).instances\n instances.add(instance)\n return () => instances.delete(instance)\n}\n\nexport function markHmrInstanceMounted(node: VobsNode, parent: Node): void {\n const instance = hmrInstances.get(node as object)\n if (instance) instance.parent = parent\n}\n\nfunction getModule(moduleId: string): HmrModuleState {\n let module = hmrGlobal.modules.get(moduleId)\n if (!module) {\n module = { components: new Map(), state: new Map(), instances: new Set() }\n hmrGlobal.modules.set(moduleId, module)\n }\n return module\n}\n\nconst hmrInstances = new WeakMap<object, HmrInstance>()\n\nexport function associateHmrInstance(node: VobsNode, instance: HmrInstance): void {\n hmrInstances.set(node as object, instance)\n}\n","import { getCurrentOwner, type Owner } from '@vobs/reactivity'\nimport type { InjectionKey, ProvideOptions } from './app'\n\nconst ownerProviders = new WeakMap<Owner, Map<InjectionKey<unknown>, unknown>>()\n\nexport function provide<T>(key: InjectionKey<T>, value: T, options: ProvideOptions = {}): void {\n const owner = getCurrentOwner()\n if (!owner) throw new Error('Vobs: provide 必须在组件或 Owner 作用域内调用')\n provideToOwner(owner, key, value, options)\n}\n\nexport function inject<T>(key: InjectionKey<T>): T | undefined\nexport function inject<T>(key: InjectionKey<T>, fallback: T): T\nexport function inject<T>(key: InjectionKey<T>, fallback?: T): T | undefined {\n const owner = getCurrentOwner()\n const value = owner ? injectFromOwner(owner, key) : undefined\n return value === undefined ? fallback : value\n}\n\nexport function injectRequired<T>(key: InjectionKey<T>, description?: string): T {\n const value = inject(key)\n if (value === undefined) {\n throw new Error(`Vobs: 找不到必需注入项${description ? ` ${description}` : ''}`)\n }\n return value\n}\n\nexport function provideToOwner<T>(\n owner: Owner,\n key: InjectionKey<T>,\n value: T,\n options: ProvideOptions = {}\n): void {\n let providers = ownerProviders.get(owner)\n if (!providers) {\n providers = new Map<InjectionKey<unknown>, unknown>()\n ownerProviders.set(owner, providers)\n owner.onDispose(() => ownerProviders.delete(owner))\n }\n if (providers.has(key) && !options.override) {\n throw new Error(`Vobs: 注入项 ${String(key)} 已存在;如需覆盖请传入 override: true`)\n }\n providers.set(key, value)\n}\n\nexport function injectFromOwner<T>(owner: Owner, key: InjectionKey<T>): T | undefined {\n let current: Owner | null = owner\n while (current) {\n const providers = ownerProviders.get(current)\n if (providers?.has(key)) return providers.get(key) as T\n current = current.parent\n }\n return undefined\n}\n","import { createOwner, scheduler, setOwnerDebugName, type Owner } from '@vobs/reactivity'\nimport { createDOMRenderer } from '@vobs/dom'\nimport { insertBefore as insertRuntimeNode, setRenderer, type VobsFragment, type VobsRenderer } from '@vobs/runtime'\nimport { injectFromOwner, provideToOwner } from './context'\n\nexport type InjectionKey<T> = symbol & {\n readonly __vobsType?: T\n}\n\nexport interface ProvideOptions {\n override?: boolean\n}\n\nexport interface VobsPlugin {\n name: string\n version?: string\n requires?: readonly VobsPlugin[]\n optional?: readonly VobsPlugin[]\n install?: (ctx: VobsContext) => void | (() => void)\n}\n\nexport interface VobsContext {\n readonly app: VobsApp\n provide<T>(key: InjectionKey<T>, value: T, options?: ProvideOptions): void\n inject<T>(key: InjectionKey<T>): T | undefined\n injectRequired<T>(key: InjectionKey<T>, description?: string): T\n onDestroy(cleanup: () => void): void\n onError(handler: (error: unknown) => void): () => void\n}\n\nexport interface VobsConfig<\n NodeType = Node,\n TextNode extends NodeType = NodeType,\n ElementNode extends NodeType = NodeType,\n CommentNode extends NodeType = NodeType\n> {\n render: () => NodeType | VobsFragment | Node | null | undefined\n renderer?: VobsRenderer<NodeType, TextNode, ElementNode, CommentNode>\n plugins?: VobsPlugin[]\n /** Optional application-level error observer. Observers are isolated from the app. */\n onError?: (error: unknown) => void\n}\n\nexport interface VobsApp<NodeType = Node> {\n readonly mounted: boolean\n readonly destroyed: boolean\n use(plugin: VobsPlugin): VobsApp<NodeType>\n mount(target: string | NodeType): void\n hydrate(target: string | NodeType): void\n update(): void\n destroy(): void\n}\n\nexport function createInjectionKey<T>(description: string): InjectionKey<T> {\n return Symbol(description) as InjectionKey<T>\n}\n\nexport function createVobs(\n config: VobsConfig<Node, Text, Element, Comment>\n): VobsApp<Node>\nexport function createVobs<\n NodeType = Node,\n TextNode extends NodeType = NodeType,\n ElementNode extends NodeType = NodeType,\n CommentNode extends NodeType = NodeType\n>(\n config: VobsConfig<NodeType, TextNode, ElementNode, CommentNode> & {\n renderer: VobsRenderer<NodeType, TextNode, ElementNode, CommentNode>\n }\n): VobsApp<NodeType>\nexport function createVobs(\n config: VobsConfig<any, any, any, any>\n): VobsApp<any> {\n if (!config.render) throw new Error('createVobs: render 不能为空')\n\n const renderer = config.renderer ?? createDOMRenderer()\n const rootOwner: Owner = createOwner()\n setOwnerDebugName(rootOwner, 'App')\n const cleanups: Array<() => void> = []\n const errorHandlers = new Set<(error: unknown) => void>()\n const installed = new Set<string>()\n const installing = new Set<string>()\n let mounted = false\n let destroyed = false\n let container: any = null\n let app!: VobsApp<any>\n\n if (config.onError) {\n errorHandlers.add(config.onError)\n cleanups.push(() => errorHandlers.delete(config.onError!))\n }\n\n const context: VobsContext = {\n get app(): VobsApp<any> {\n return app\n },\n\n provide<T>(key: InjectionKey<T>, value: T, options: ProvideOptions = {}): void {\n provideToOwner(rootOwner, key, value, options)\n },\n\n inject<T>(key: InjectionKey<T>): T | undefined {\n return injectFromOwner(rootOwner, key)\n },\n\n injectRequired<T>(key: InjectionKey<T>, description?: string): T {\n const value = injectFromOwner(rootOwner, key)\n if (value === undefined) {\n throw new Error(`Vobs: 找不到必需注入项${description ? ` ${description}` : ''}`)\n }\n return value\n },\n\n onDestroy(cleanup: () => void): void {\n cleanups.push(cleanup)\n },\n\n onError(handler: (error: unknown) => void): () => void {\n errorHandlers.add(handler)\n const remove = () => errorHandlers.delete(handler)\n cleanups.push(remove)\n return remove\n }\n }\n\n function notifyError(error: unknown): void {\n for (const handler of [...errorHandlers]) {\n try {\n handler(error)\n } catch {\n // 错误处理器不能覆盖触发它的原始错误。\n }\n }\n }\n\n function installPlugin(plugin: VobsPlugin): void {\n if (installed.has(plugin.name)) return\n if (installing.has(plugin.name)) {\n throw new Error(`Vobs: 插件依赖存在循环:${plugin.name}`)\n }\n\n installing.add(plugin.name)\n try {\n for (const dependency of plugin.requires ?? []) installPlugin(dependency)\n const cleanup = plugin.install?.(context)\n if (cleanup) cleanups.push(cleanup)\n installed.add(plugin.name)\n } finally {\n installing.delete(plugin.name)\n }\n }\n\n function cleanup(clearContainer = true): unknown {\n let firstError: unknown\n for (let index = cleanups.length - 1; index >= 0; index--) {\n try {\n cleanups[index]()\n } catch (error) {\n firstError ??= error\n }\n }\n cleanups.length = 0\n\n try {\n rootOwner.dispose()\n } catch (error) {\n firstError ??= error\n }\n\n if (container && clearContainer) {\n try {\n renderer.clear(container)\n } catch (error) {\n firstError ??= error\n }\n }\n return firstError\n }\n\n function start(target: string | any, hydrating: boolean): void {\n if (destroyed) throw new Error('Vobs: 已销毁的应用不能挂载')\n if (mounted) return\n\n container = typeof target === 'string' ? document.querySelector(target) : target\n if (!container) throw new Error(`mount: 目标不存在: ${target}`)\n if (hydrating && !renderer.beginHydration) {\n throw new Error('Vobs: 当前渲染器不支持 Hydration')\n }\n\n setRenderer(renderer)\n try {\n if (hydrating) renderer.beginHydration?.()\n const rootNode = rootOwner.run(config.render)\n if (!hydrating) renderer.clear(container)\n if (rootNode) insertRuntimeNode(container, rootNode as any, null)\n if (hydrating) renderer.completeHydration?.()\n mounted = true\n } catch (error) {\n notifyError(error)\n const cleanupError = cleanup(!hydrating)\n destroyed = true\n throw cleanupError ?? error\n }\n }\n\n app = {\n get mounted(): boolean {\n return mounted\n },\n\n get destroyed(): boolean {\n return destroyed\n },\n\n use(plugin: VobsPlugin): VobsApp<any> {\n if (destroyed) throw new Error('Vobs: 已销毁的应用不能安装插件')\n installPlugin(plugin)\n return app\n },\n\n mount(target: string | any): void {\n start(target, false)\n },\n\n hydrate(target: string | any): void {\n start(target, true)\n },\n\n update(): void {\n if (destroyed) throw new Error('Vobs: 已销毁的应用不能更新')\n try {\n scheduler.flush()\n } catch (error) {\n notifyError(error)\n throw error\n }\n },\n\n destroy(): void {\n if (destroyed) return\n try {\n const cleanupError = cleanup()\n if (cleanupError) {\n notifyError(cleanupError)\n throw cleanupError\n }\n } finally {\n mounted = false\n destroyed = true\n }\n }\n }\n\n try {\n for (const plugin of config.plugins ?? []) app.use(plugin)\n } catch (error) {\n notifyError(error)\n cleanup()\n destroyed = true\n throw error\n }\n\n return app\n}\n","import { getCurrentOwner, onDispose, state, type Signal } from '@vobs/reactivity'\nimport { createInjectionKey, inject, type InjectionKey, type VobsPlugin } from '@vobs/vobs'\n\nexport type TaskPriority = 'low' | 'normal' | 'high' | 'critical'\nexport type QueueTaskStatus = 'pending' | 'running' | 'retrying' | 'success' | 'error' | 'cancelled'\nexport type QueueRetryDelay = number | ((attempt: number, error: Error) => number)\n\nexport interface QueueTask<T = unknown> {\n readonly id: string\n readonly priority: TaskPriority\n readonly status: Signal<QueueTaskStatus>\n readonly attempt: Signal<number>\n readonly result: Signal<T | null>\n readonly error: Signal<Error | null>\n readonly promise: Promise<T>\n cancel(): void\n retry(): Promise<T>\n}\n\nexport interface QueueTaskOptions {\n readonly id?: string\n readonly priority?: TaskPriority\n readonly retry?: number\n readonly retryDelay?: QueueRetryDelay\n}\n\nexport type QueueTaskFunction<T> = (signal: AbortSignal) => T | PromiseLike<T>\n\nexport interface TaskQueueOptions {\n /** Maximum number of task functions running at once. */\n readonly concurrency?: number\n /** Alias retained for the terminology used in the design document. */\n readonly concurrent?: number\n readonly idFactory?: () => string\n readonly onError?: (error: QueueError, task: QueueTask) => void\n}\n\nexport interface QueuePluginOptions extends TaskQueueOptions {\n readonly queue?: TaskQueue\n}\n\nexport interface TaskQueue {\n readonly pending: Signal<number>\n readonly processing: Signal<number>\n readonly completed: Signal<number>\n readonly failed: Signal<number>\n readonly total: Signal<number>\n readonly paused: Signal<boolean>\n readonly tasks: Signal<readonly QueueTask[]>\n add<T>(fn: QueueTaskFunction<T>, options?: QueueTaskOptions): QueueTask<T>\n pause(): void\n resume(): void\n clear(): void\n dispose(): void\n}\n\nexport type QueueErrorCode =\n | 'QUEUE_CONTEXT_MISSING'\n | 'QUEUE_CONTEXT_DISPOSED'\n | 'INVALID_QUEUE_OPTIONS'\n | 'INVALID_TASK'\n | 'QUEUE_TASK_CANCELLED'\n | 'QUEUE_TASK_FAILED'\n\nexport class QueueError extends Error {\n readonly code: QueueErrorCode\n readonly cause: unknown\n\n constructor(code: QueueErrorCode, message: string, cause?: unknown) {\n super(message)\n this.name = 'QueueError'\n this.code = code\n this.cause = cause\n }\n}\n\nexport const QUEUE_KEY: InjectionKey<TaskQueue> = createInjectionKey<TaskQueue>('vobs.queue')\n\nconst PRIORITIES: Readonly<Record<TaskPriority, number>> = {\n low: 0,\n normal: 1,\n high: 2,\n critical: 3\n}\n\ninterface InternalTask<T> extends QueueTask<T> {\n readonly fn: QueueTaskFunction<T>\n readonly maxRetries: number\n readonly retryDelay: QueueRetryDelay\n readonly sequence: number\n controller: AbortController | null\n settled: boolean\n executing: boolean\n retryQueued: boolean\n resolve: ((value: T) => void) | null\n reject: ((reason: unknown) => void) | null\n run(): Promise<void>\n dispose(): void\n}\n\nexport function createTaskQueue(options: TaskQueueOptions = {}): TaskQueue {\n const concurrency = resolveConcurrency(options)\n const tasks = state<readonly QueueTask[]>([])\n const pending = state(0)\n const processing = state(0)\n const completed = state(0)\n const failed = state(0)\n const total = state(0)\n const paused = state(false)\n const queue: InternalTask<any>[] = []\n const ownedTasks = new Set<InternalTask<any>>()\n let sequence = 0\n let active = 0\n let nextId = 0\n let disposed = false\n\n const context: TaskQueue = {\n pending,\n processing,\n completed,\n failed,\n total,\n paused,\n tasks,\n\n add<T>(fn: QueueTaskFunction<T>, taskOptions: QueueTaskOptions = {}): QueueTask<T> {\n ensureActive()\n if (typeof fn !== 'function') {\n throw new QueueError('INVALID_TASK', 'Vobs Queue: task 必须是函数')\n }\n const id = taskOptions.id ?? options.idFactory?.() ?? `task-${++nextId}`\n if (typeof id !== 'string' || id.trim() === '') {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: task id 必须是非空字符串')\n }\n if (tasks.value.some(task => task.id === id)) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', `Vobs Queue: 已存在任务 ${id}`)\n }\n const task = createTask(fn, id, taskOptions)\n ownedTasks.add(task)\n tasks.value = Object.freeze([...tasks.value, task])\n queue.push(task)\n sortQueue()\n refreshStats()\n drain()\n return task\n },\n\n pause(): void {\n ensureActive()\n paused.value = true\n },\n\n resume(): void {\n ensureActive()\n if (!paused.value) return\n paused.value = false\n drain()\n },\n\n clear(): void {\n ensureActive()\n for (const task of [...queue]) task.cancel()\n queue.length = 0\n refreshStats()\n },\n\n dispose(): void {\n if (disposed) return\n disposed = true\n for (const task of [...ownedTasks]) task.cancel()\n queue.length = 0\n for (const task of ownedTasks) task.dispose()\n ownedTasks.clear()\n tasks.value = Object.freeze([])\n pending.dispose()\n processing.dispose()\n completed.dispose()\n failed.dispose()\n total.dispose()\n paused.dispose()\n tasks.dispose()\n }\n }\n\n if (getCurrentOwner()) onDispose(context.dispose)\n return context\n\n function createTask<T>(fn: QueueTaskFunction<T>, id: string, taskOptions: QueueTaskOptions): InternalTask<T> {\n const priority = taskOptions.priority ?? 'normal'\n if (!(priority in PRIORITIES)) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', `Vobs Queue: 不支持任务优先级 ${String(priority)}`)\n }\n const maxRetries = taskOptions.retry ?? 0\n if (!Number.isInteger(maxRetries) || maxRetries < 0) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: retry 必须是大于等于 0 的整数')\n }\n const retryDelay = taskOptions.retryDelay ?? 0\n validateRetryDelay(retryDelay)\n\n const status = state<QueueTaskStatus>('pending')\n const attempt = state(0)\n const result = state<T | null>(null)\n const error = state<Error | null>(null)\n let promise!: Promise<T>\n\n const task: InternalTask<T> = {\n id,\n priority,\n status,\n attempt,\n result,\n error,\n get promise(): Promise<T> { return promise },\n fn,\n maxRetries,\n retryDelay,\n sequence: sequence++,\n controller: null,\n settled: false,\n executing: false,\n retryQueued: false,\n resolve: null,\n reject: null,\n\n cancel(): void {\n if (status.value === 'success' || status.value === 'error' || status.value === 'cancelled') return\n task.controller?.abort()\n removeFromQueue(task)\n status.value = 'cancelled'\n const cancellation = new QueueError('QUEUE_TASK_CANCELLED', `Vobs Queue: 任务 ${id} 已取消`)\n error.value = cancellation\n settleReject(cancellation)\n refreshStats()\n },\n\n retry(): Promise<T> {\n ensureActive()\n if (status.value === 'pending' || status.value === 'running' || status.value === 'retrying') return promise\n if (status.value === 'success') return promise\n status.value = 'pending'\n attempt.value = 0\n result.value = null\n error.value = null\n task.controller = null\n task.settled = false\n task.retryQueued = true\n promise = createPromise()\n if (!task.executing) queue.push(task)\n sortQueue()\n refreshStats()\n drain()\n return promise\n },\n\n run(): Promise<void> {\n task.retryQueued = false\n task.executing = true\n return execute(task).finally(() => {\n task.executing = false\n if (task.retryQueued && task.status.value === 'pending' && !disposed) {\n task.retryQueued = false\n queue.push(task)\n sortQueue()\n drain()\n }\n })\n },\n\n dispose(): void {\n task.controller?.abort()\n status.dispose()\n attempt.dispose()\n result.dispose()\n error.dispose()\n }\n }\n promise = createPromise()\n return task\n\n function createPromise(): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n task.resolve = resolve\n task.reject = reject\n })\n }\n\n function settleReject(reason: unknown): void {\n if (task.settled) return\n task.settled = true\n task.reject?.(reason)\n task.resolve = null\n task.reject = null\n }\n }\n\n async function execute<T>(task: InternalTask<T>): Promise<void> {\n while (!disposed && (task.status.value === 'pending' || task.status.value === 'retrying')) {\n if (task.status.value === 'retrying') task.status.value = 'pending'\n task.status.value = 'running'\n task.attempt.value++\n const controller = new AbortController()\n task.controller = controller\n refreshStats()\n try {\n const value = await task.fn(controller.signal)\n if (isCancelled(task) || disposed) return\n task.result.value = value\n task.status.value = 'success'\n settleTask(task, value)\n refreshStats()\n return\n } catch (reason) {\n if (isCancelled(task) || disposed) return\n if (isAbortError(reason)) {\n const cancellation = new QueueError('QUEUE_TASK_CANCELLED', `Vobs Queue: 任务 ${task.id} 已取消`, reason)\n task.error.value = cancellation\n task.status.value = 'cancelled'\n settleTask(task, undefined, cancellation)\n refreshStats()\n return\n }\n const failure = toQueueError(reason, task.id)\n let delay: number | undefined\n try {\n if (task.attempt.value <= task.maxRetries) {\n delay = resolveRetryDelay(task.retryDelay, task.attempt.value, failure)\n }\n } catch (delayError) {\n const invalidDelay = toQueueError(delayError, task.id)\n task.error.value = invalidDelay\n task.status.value = 'error'\n settleTask(task, undefined, invalidDelay)\n report(invalidDelay, task)\n refreshStats()\n return\n }\n if (delay !== undefined) {\n task.status.value = 'retrying'\n refreshStats()\n try {\n await wait(delay, controller.signal)\n } catch (delayError) {\n if (isCancelled(task) || isAbortError(delayError)) return\n throw delayError\n }\n if (isCancelled(task) || disposed) return\n continue\n }\n task.error.value = failure\n task.status.value = 'error'\n settleTask(task, undefined, failure)\n report(failure, task)\n refreshStats()\n return\n } finally {\n if (task.controller === controller) task.controller = null\n }\n }\n }\n\n function drain(): void {\n while (!disposed && !paused.value && active < concurrency && queue.length > 0) {\n const task = queue.shift()!\n if (task.status.value !== 'pending') continue\n active++\n void task.run().finally(() => {\n active--\n refreshStats()\n drain()\n })\n }\n refreshStats()\n }\n\n function sortQueue(): void {\n queue.sort((left, right) => PRIORITIES[right.priority] - PRIORITIES[left.priority] || left.sequence - right.sequence)\n }\n\n function removeFromQueue(task: InternalTask<any>): void {\n const index = queue.indexOf(task)\n if (index >= 0) queue.splice(index, 1)\n }\n\n function refreshStats(): void {\n let nextPending = 0\n let nextProcessing = 0\n let nextCompleted = 0\n let nextFailed = 0\n for (const task of tasks.value) {\n if (task.status.value === 'pending') nextPending++\n else if (task.status.value === 'running' || task.status.value === 'retrying') nextProcessing++\n else if (task.status.value === 'success') nextCompleted++\n else if (task.status.value === 'error') nextFailed++\n }\n pending.value = nextPending\n processing.value = nextProcessing\n completed.value = nextCompleted\n failed.value = nextFailed\n total.value = tasks.value.length\n }\n\n function settleTask<T>(task: InternalTask<T>, value?: T, reason?: unknown): void {\n if (task.settled) return\n task.settled = true\n if (reason !== undefined) task.reject?.(reason)\n else task.resolve?.(value as T)\n task.resolve = null\n task.reject = null\n }\n\n function report(queueError: QueueError, task: QueueTask): void {\n try { options.onError?.(queueError, task) } catch { /* observers cannot break queue state */ }\n }\n\n function ensureActive(): void {\n if (disposed) throw new QueueError('QUEUE_CONTEXT_DISPOSED', 'Vobs Queue: 上下文已销毁')\n }\n\n function isCancelled(task: QueueTask): boolean {\n return task.status.value === 'cancelled'\n }\n}\n\nexport function queuePlugin(options: QueuePluginOptions = {}): VobsPlugin {\n return {\n name: '@vobs/queue',\n version: '0.1.0',\n install(context) {\n const ownedQueue = options.queue ? undefined : createTaskQueue(options)\n context.provide(QUEUE_KEY, options.queue ?? ownedQueue!)\n return () => ownedQueue?.dispose()\n }\n }\n}\n\nexport function useQueue(): TaskQueue {\n const queue = inject(QUEUE_KEY)\n if (!queue) throw new QueueError('QUEUE_CONTEXT_MISSING', 'Vobs Queue: 找不到上下文,请安装 queuePlugin')\n return queue\n}\n\nfunction resolveConcurrency(options: TaskQueueOptions): number {\n if (options.concurrency !== undefined && options.concurrent !== undefined && options.concurrency !== options.concurrent) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: concurrency 与 concurrent 不能设置为不同值')\n }\n const value = options.concurrency ?? options.concurrent ?? 3\n if (!Number.isInteger(value) || value <= 0) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: concurrency 必须是正整数')\n }\n return value\n}\n\nfunction validateRetryDelay(value: QueueRetryDelay): void {\n if (typeof value === 'number' && (!Number.isFinite(value) || value < 0)) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: retryDelay 必须是大于等于 0 的有限数字或函数')\n }\n if (typeof value !== 'number' && typeof value !== 'function') {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: retryDelay 必须是数字或函数')\n }\n}\n\nfunction resolveRetryDelay(value: QueueRetryDelay, attempt: number, error: Error): number {\n const delay = typeof value === 'function' ? value(attempt, error) : value\n if (!Number.isFinite(delay) || delay < 0) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: retryDelay 函数必须返回大于等于 0 的有限数字')\n }\n return delay\n}\n\nfunction wait(delay: number, signal: AbortSignal): Promise<void> {\n if (delay === 0) return Promise.resolve()\n return new Promise((resolve, reject) => {\n const timer = setTimeout(done, delay)\n signal.addEventListener('abort', abort, { once: true })\n function done(): void {\n signal.removeEventListener('abort', abort)\n resolve()\n }\n function abort(): void {\n clearTimeout(timer)\n reject(Object.assign(new Error('Aborted'), { name: 'AbortError' }))\n }\n })\n}\n\nfunction toQueueError(reason: unknown, id: string): QueueError {\n if (reason instanceof QueueError) return reason\n return new QueueError('QUEUE_TASK_FAILED', `Vobs Queue: 任务 ${id} 执行失败`, reason)\n}\n\nfunction isAbortError(value: unknown): boolean {\n return Boolean(value) && typeof value === 'object' && (value as { name?: unknown }).name === 'AbortError'\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { getCurrentOwner, onDispose, state, type Signal } from '@vobs/reactivity'\nimport { createInjectionKey, inject, type InjectionKey, type VobsPlugin } from '@vobs/vobs'\n\nexport type TaskPriority = 'low' | 'normal' | 'high' | 'critical'\nexport type QueueTaskStatus = 'pending' | 'running' | 'retrying' | 'success' | 'error' | 'cancelled'\nexport type QueueRetryDelay = number | ((attempt: number, error: Error) => number)\n\nexport interface QueueTask<T = unknown> {\n readonly id: string\n readonly priority: TaskPriority\n readonly status: Signal<QueueTaskStatus>\n readonly attempt: Signal<number>\n readonly result: Signal<T | null>\n readonly error: Signal<Error | null>\n readonly promise: Promise<T>\n cancel(): void\n retry(): Promise<T>\n}\n\nexport interface QueueTaskOptions {\n readonly id?: string\n readonly priority?: TaskPriority\n readonly retry?: number\n readonly retryDelay?: QueueRetryDelay\n}\n\nexport type QueueTaskFunction<T> = (signal: AbortSignal) => T | PromiseLike<T>\n\nexport interface TaskQueueOptions {\n /** Maximum number of task functions running at once. */\n readonly concurrency?: number\n /** Alias retained for the terminology used in the design document. */\n readonly concurrent?: number\n readonly idFactory?: () => string\n readonly onError?: (error: QueueError, task: QueueTask) => void\n}\n\nexport interface QueuePluginOptions extends TaskQueueOptions {\n readonly queue?: TaskQueue\n}\n\nexport interface TaskQueue {\n readonly pending: Signal<number>\n readonly processing: Signal<number>\n readonly completed: Signal<number>\n readonly failed: Signal<number>\n readonly total: Signal<number>\n readonly paused: Signal<boolean>\n readonly tasks: Signal<readonly QueueTask[]>\n add<T>(fn: QueueTaskFunction<T>, options?: QueueTaskOptions): QueueTask<T>\n pause(): void\n resume(): void\n clear(): void\n dispose(): void\n}\n\nexport type QueueErrorCode =\n | 'QUEUE_CONTEXT_MISSING'\n | 'QUEUE_CONTEXT_DISPOSED'\n | 'INVALID_QUEUE_OPTIONS'\n | 'INVALID_TASK'\n | 'QUEUE_TASK_CANCELLED'\n | 'QUEUE_TASK_FAILED'\n\nexport class QueueError extends Error {\n readonly code: QueueErrorCode\n readonly cause: unknown\n\n constructor(code: QueueErrorCode, message: string, cause?: unknown) {\n super(message)\n this.name = 'QueueError'\n this.code = code\n this.cause = cause\n }\n}\n\nexport const QUEUE_KEY: InjectionKey<TaskQueue> = createInjectionKey<TaskQueue>('vobs.queue')\n\nconst PRIORITIES: Readonly<Record<TaskPriority, number>> = {\n low: 0,\n normal: 1,\n high: 2,\n critical: 3\n}\n\ninterface InternalTask<T> extends QueueTask<T> {\n readonly fn: QueueTaskFunction<T>\n readonly maxRetries: number\n readonly retryDelay: QueueRetryDelay\n readonly sequence: number\n controller: AbortController | null\n settled: boolean\n executing: boolean\n retryQueued: boolean\n resolve: ((value: T) => void) | null\n reject: ((reason: unknown) => void) | null\n run(): Promise<void>\n dispose(): void\n}\n\nexport function createTaskQueue(options: TaskQueueOptions = {}): TaskQueue {\n const concurrency = resolveConcurrency(options)\n const tasks = state<readonly QueueTask[]>([])\n const pending = state(0)\n const processing = state(0)\n const completed = state(0)\n const failed = state(0)\n const total = state(0)\n const paused = state(false)\n const queue: InternalTask<any>[] = []\n const ownedTasks = new Set<InternalTask<any>>()\n let sequence = 0\n let active = 0\n let nextId = 0\n let disposed = false\n\n const context: TaskQueue = {\n pending,\n processing,\n completed,\n failed,\n total,\n paused,\n tasks,\n\n add<T>(fn: QueueTaskFunction<T>, taskOptions: QueueTaskOptions = {}): QueueTask<T> {\n ensureActive()\n if (typeof fn !== 'function') {\n throw new QueueError('INVALID_TASK', 'Vobs Queue: task 必须是函数')\n }\n const id = taskOptions.id ?? options.idFactory?.() ?? `task-${++nextId}`\n if (typeof id !== 'string' || id.trim() === '') {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: task id 必须是非空字符串')\n }\n if (tasks.value.some(task => task.id === id)) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', `Vobs Queue: 已存在任务 ${id}`)\n }\n const task = createTask(fn, id, taskOptions)\n ownedTasks.add(task)\n tasks.value = Object.freeze([...tasks.value, task])\n queue.push(task)\n sortQueue()\n refreshStats()\n drain()\n return task\n },\n\n pause(): void {\n ensureActive()\n paused.value = true\n },\n\n resume(): void {\n ensureActive()\n if (!paused.value) return\n paused.value = false\n drain()\n },\n\n clear(): void {\n ensureActive()\n for (const task of [...queue]) task.cancel()\n queue.length = 0\n refreshStats()\n },\n\n dispose(): void {\n if (disposed) return\n disposed = true\n for (const task of [...ownedTasks]) task.cancel()\n queue.length = 0\n for (const task of ownedTasks) task.dispose()\n ownedTasks.clear()\n tasks.value = Object.freeze([])\n pending.dispose()\n processing.dispose()\n completed.dispose()\n failed.dispose()\n total.dispose()\n paused.dispose()\n tasks.dispose()\n }\n }\n\n if (getCurrentOwner()) onDispose(context.dispose)\n return context\n\n function createTask<T>(fn: QueueTaskFunction<T>, id: string, taskOptions: QueueTaskOptions): InternalTask<T> {\n const priority = taskOptions.priority ?? 'normal'\n if (!(priority in PRIORITIES)) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', `Vobs Queue: 不支持任务优先级 ${String(priority)}`)\n }\n const maxRetries = taskOptions.retry ?? 0\n if (!Number.isInteger(maxRetries) || maxRetries < 0) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: retry 必须是大于等于 0 的整数')\n }\n const retryDelay = taskOptions.retryDelay ?? 0\n validateRetryDelay(retryDelay)\n\n const status = state<QueueTaskStatus>('pending')\n const attempt = state(0)\n const result = state<T | null>(null)\n const error = state<Error | null>(null)\n let promise!: Promise<T>\n\n const task: InternalTask<T> = {\n id,\n priority,\n status,\n attempt,\n result,\n error,\n get promise(): Promise<T> { return promise },\n fn,\n maxRetries,\n retryDelay,\n sequence: sequence++,\n controller: null,\n settled: false,\n executing: false,\n retryQueued: false,\n resolve: null,\n reject: null,\n\n cancel(): void {\n if (status.value === 'success' || status.value === 'error' || status.value === 'cancelled') return\n task.controller?.abort()\n removeFromQueue(task)\n status.value = 'cancelled'\n const cancellation = new QueueError('QUEUE_TASK_CANCELLED', `Vobs Queue: 任务 ${id} 已取消`)\n error.value = cancellation\n settleReject(cancellation)\n refreshStats()\n },\n\n retry(): Promise<T> {\n ensureActive()\n if (status.value === 'pending' || status.value === 'running' || status.value === 'retrying') return promise\n if (status.value === 'success') return promise\n status.value = 'pending'\n attempt.value = 0\n result.value = null\n error.value = null\n task.controller = null\n task.settled = false\n task.retryQueued = true\n promise = createPromise()\n if (!task.executing) queue.push(task)\n sortQueue()\n refreshStats()\n drain()\n return promise\n },\n\n run(): Promise<void> {\n task.retryQueued = false\n task.executing = true\n return execute(task).finally(() => {\n task.executing = false\n if (task.retryQueued && task.status.value === 'pending' && !disposed) {\n task.retryQueued = false\n queue.push(task)\n sortQueue()\n drain()\n }\n })\n },\n\n dispose(): void {\n task.controller?.abort()\n status.dispose()\n attempt.dispose()\n result.dispose()\n error.dispose()\n }\n }\n promise = createPromise()\n return task\n\n function createPromise(): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n task.resolve = resolve\n task.reject = reject\n })\n }\n\n function settleReject(reason: unknown): void {\n if (task.settled) return\n task.settled = true\n task.reject?.(reason)\n task.resolve = null\n task.reject = null\n }\n }\n\n async function execute<T>(task: InternalTask<T>): Promise<void> {\n while (!disposed && (task.status.value === 'pending' || task.status.value === 'retrying')) {\n if (task.status.value === 'retrying') task.status.value = 'pending'\n task.status.value = 'running'\n task.attempt.value++\n const controller = new AbortController()\n task.controller = controller\n refreshStats()\n try {\n const value = await task.fn(controller.signal)\n if (isCancelled(task) || disposed) return\n task.result.value = value\n task.status.value = 'success'\n settleTask(task, value)\n refreshStats()\n return\n } catch (reason) {\n if (isCancelled(task) || disposed) return\n if (isAbortError(reason)) {\n const cancellation = new QueueError('QUEUE_TASK_CANCELLED', `Vobs Queue: 任务 ${task.id} 已取消`, reason)\n task.error.value = cancellation\n task.status.value = 'cancelled'\n settleTask(task, undefined, cancellation)\n refreshStats()\n return\n }\n const failure = toQueueError(reason, task.id)\n let delay: number | undefined\n try {\n if (task.attempt.value <= task.maxRetries) {\n delay = resolveRetryDelay(task.retryDelay, task.attempt.value, failure)\n }\n } catch (delayError) {\n const invalidDelay = toQueueError(delayError, task.id)\n task.error.value = invalidDelay\n task.status.value = 'error'\n settleTask(task, undefined, invalidDelay)\n report(invalidDelay, task)\n refreshStats()\n return\n }\n if (delay !== undefined) {\n task.status.value = 'retrying'\n refreshStats()\n try {\n await wait(delay, controller.signal)\n } catch (delayError) {\n if (isCancelled(task) || isAbortError(delayError)) return\n throw delayError\n }\n if (isCancelled(task) || disposed) return\n continue\n }\n task.error.value = failure\n task.status.value = 'error'\n settleTask(task, undefined, failure)\n report(failure, task)\n refreshStats()\n return\n } finally {\n if (task.controller === controller) task.controller = null\n }\n }\n }\n\n function drain(): void {\n while (!disposed && !paused.value && active < concurrency && queue.length > 0) {\n const task = queue.shift()!\n if (task.status.value !== 'pending') continue\n active++\n void task.run().finally(() => {\n active--\n refreshStats()\n drain()\n })\n }\n refreshStats()\n }\n\n function sortQueue(): void {\n queue.sort((left, right) => PRIORITIES[right.priority] - PRIORITIES[left.priority] || left.sequence - right.sequence)\n }\n\n function removeFromQueue(task: InternalTask<any>): void {\n const index = queue.indexOf(task)\n if (index >= 0) queue.splice(index, 1)\n }\n\n function refreshStats(): void {\n let nextPending = 0\n let nextProcessing = 0\n let nextCompleted = 0\n let nextFailed = 0\n for (const task of tasks.value) {\n if (task.status.value === 'pending') nextPending++\n else if (task.status.value === 'running' || task.status.value === 'retrying') nextProcessing++\n else if (task.status.value === 'success') nextCompleted++\n else if (task.status.value === 'error') nextFailed++\n }\n pending.value = nextPending\n processing.value = nextProcessing\n completed.value = nextCompleted\n failed.value = nextFailed\n total.value = tasks.value.length\n }\n\n function settleTask<T>(task: InternalTask<T>, value?: T, reason?: unknown): void {\n if (task.settled) return\n task.settled = true\n if (reason !== undefined) task.reject?.(reason)\n else task.resolve?.(value as T)\n task.resolve = null\n task.reject = null\n }\n\n function report(queueError: QueueError, task: QueueTask): void {\n try { options.onError?.(queueError, task) } catch { /* observers cannot break queue state */ }\n }\n\n function ensureActive(): void {\n if (disposed) throw new QueueError('QUEUE_CONTEXT_DISPOSED', 'Vobs Queue: 上下文已销毁')\n }\n\n function isCancelled(task: QueueTask): boolean {\n return task.status.value === 'cancelled'\n }\n}\n\nexport function queuePlugin(options: QueuePluginOptions = {}): VobsPlugin {\n return {\n name: '@vobs/queue',\n version: '0.1.0',\n install(context) {\n const ownedQueue = options.queue ? undefined : createTaskQueue(options)\n context.provide(QUEUE_KEY, options.queue ?? ownedQueue!)\n return () => ownedQueue?.dispose()\n }\n }\n}\n\nexport function useQueue(): TaskQueue {\n const queue = inject(QUEUE_KEY)\n if (!queue) throw new QueueError('QUEUE_CONTEXT_MISSING', 'Vobs Queue: 找不到上下文,请安装 queuePlugin')\n return queue\n}\n\nfunction resolveConcurrency(options: TaskQueueOptions): number {\n if (options.concurrency !== undefined && options.concurrent !== undefined && options.concurrency !== options.concurrent) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: concurrency 与 concurrent 不能设置为不同值')\n }\n const value = options.concurrency ?? options.concurrent ?? 3\n if (!Number.isInteger(value) || value <= 0) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: concurrency 必须是正整数')\n }\n return value\n}\n\nfunction validateRetryDelay(value: QueueRetryDelay): void {\n if (typeof value === 'number' && (!Number.isFinite(value) || value < 0)) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: retryDelay 必须是大于等于 0 的有限数字或函数')\n }\n if (typeof value !== 'number' && typeof value !== 'function') {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: retryDelay 必须是数字或函数')\n }\n}\n\nfunction resolveRetryDelay(value: QueueRetryDelay, attempt: number, error: Error): number {\n const delay = typeof value === 'function' ? value(attempt, error) : value\n if (!Number.isFinite(delay) || delay < 0) {\n throw new QueueError('INVALID_QUEUE_OPTIONS', 'Vobs Queue: retryDelay 函数必须返回大于等于 0 的有限数字')\n }\n return delay\n}\n\nfunction wait(delay: number, signal: AbortSignal): Promise<void> {\n if (delay === 0) return Promise.resolve()\n return new Promise((resolve, reject) => {\n const timer = setTimeout(done, delay)\n signal.addEventListener('abort', abort, { once: true })\n function done(): void {\n signal.removeEventListener('abort', abort)\n resolve()\n }\n function abort(): void {\n clearTimeout(timer)\n reject(Object.assign(new Error('Aborted'), { name: 'AbortError' }))\n }\n })\n}\n\nfunction toQueueError(reason: unknown, id: string): QueueError {\n if (reason instanceof QueueError) return reason\n return new QueueError('QUEUE_TASK_FAILED', `Vobs Queue: 任务 ${id} 执行失败`, reason)\n}\n\nfunction isAbortError(value: unknown): boolean {\n return Boolean(value) && typeof value === 'object' && (value as { name?: unknown }).name === 'AbortError'\n}\n"],"mappings":"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","names":["task"]}
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"type": "git",
|
|
12
12
|
"url": "git+https://github.com/vobsjs/vobs.git"
|
|
13
13
|
},
|
|
14
|
-
"version": "1.2.
|
|
14
|
+
"version": "1.2.2",
|
|
15
15
|
"publishConfig": {
|
|
16
16
|
"access": "public"
|
|
17
17
|
},
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"./source/*": "./src/*"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@vobs/reactivity": "1.2.
|
|
39
|
-
"@vobs/vobs": "1.2.
|
|
38
|
+
"@vobs/reactivity": "1.2.2",
|
|
39
|
+
"@vobs/vobs": "1.2.2"
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
42
|
"test": "vitest --environment jsdom"
|