@vielzeug/familiar 2.1.0 → 3.0.0
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/README.md +4 -11
- package/dist/_dev.cjs +2 -0
- package/dist/_dev.cjs.map +1 -0
- package/dist/_dev.js +6 -0
- package/dist/_dev.js.map +1 -0
- package/dist/_pool-core.cjs +2 -0
- package/dist/_pool-core.cjs.map +1 -0
- package/dist/_pool-core.d.ts +41 -0
- package/dist/_pool-core.d.ts.map +1 -0
- package/dist/_pool-core.js +118 -0
- package/dist/_pool-core.js.map +1 -0
- package/dist/_pool.cjs +1 -1
- package/dist/_pool.cjs.map +1 -1
- package/dist/_pool.d.ts +8 -9
- package/dist/_pool.d.ts.map +1 -1
- package/dist/_pool.js +117 -164
- package/dist/_pool.js.map +1 -1
- package/dist/_queue.cjs +1 -1
- package/dist/_queue.cjs.map +1 -1
- package/dist/_queue.d.ts +1 -1
- package/dist/_queue.d.ts.map +1 -1
- package/dist/_queue.js +10 -7
- package/dist/_queue.js.map +1 -1
- package/dist/_stream-pool.cjs +1 -1
- package/dist/_stream-pool.cjs.map +1 -1
- package/dist/_stream-pool.d.ts +3 -4
- package/dist/_stream-pool.d.ts.map +1 -1
- package/dist/_stream-pool.js +84 -118
- package/dist/_stream-pool.js.map +1 -1
- package/dist/errors.cjs +1 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.ts +8 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +16 -6
- package/dist/errors.js.map +1 -1
- package/dist/familiar.cjs +1 -1
- package/dist/familiar.cjs.map +1 -1
- package/dist/familiar.iife.js +1 -1
- package/dist/familiar.iife.js.map +1 -1
- package/dist/familiar.js +1 -1
- package/dist/familiar.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/protocol.cjs +1 -1
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.d.ts +1 -0
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +16 -5
- package/dist/protocol.js.map +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/testing.cjs +1 -1
- package/dist/testing/testing.cjs.map +1 -1
- package/dist/testing/testing.d.ts +3 -3
- package/dist/testing/testing.d.ts.map +1 -1
- package/dist/testing/testing.js +25 -24
- package/dist/testing/testing.js.map +1 -1
- package/dist/types.d.ts +7 -28
- package/dist/types.d.ts.map +1 -1
- package/dist/worker.cjs +1 -1
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.d.ts +5 -4
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +49 -38
- package/dist/worker.js.map +1 -1
- package/package.json +10 -8
package/dist/_stream-pool.js
CHANGED
|
@@ -1,152 +1,118 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { abortError as
|
|
1
|
+
import { FamiliarQueueFullError as e, FamiliarRuntimeError as t, FamiliarTerminatedError as n } from "./errors.js";
|
|
2
|
+
import { createPoolCore as r, validatePriority as i, validateTimeout as a } from "./_pool-core.js";
|
|
3
|
+
import { abortError as o } from "@vielzeug/arsenal";
|
|
4
4
|
//#region src/_stream-pool.ts
|
|
5
|
-
function
|
|
6
|
-
let
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}, t.timeout);
|
|
20
|
-
e(a);
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
function x() {
|
|
25
|
-
l.shift()?.resolve();
|
|
26
|
-
}
|
|
27
|
-
function S(e) {
|
|
28
|
-
for (let t of l.splice(0)) t.reject(e);
|
|
29
|
-
}
|
|
30
|
-
function C(e) {
|
|
31
|
-
return e?.aborted ? Promise.reject(i(e)) : new Promise((t, n) => {
|
|
32
|
-
let r = !1, a = {
|
|
33
|
-
cleanup() {
|
|
34
|
-
e?.removeEventListener("abort", o);
|
|
35
|
-
},
|
|
36
|
-
reject(e) {
|
|
37
|
-
if (r) return;
|
|
38
|
-
r = !0, a.cleanup();
|
|
39
|
-
let t = l.indexOf(a);
|
|
40
|
-
t !== -1 && l.splice(t, 1), n(e);
|
|
41
|
-
},
|
|
42
|
-
resolve() {
|
|
43
|
-
r || (r = !0, a.cleanup(), t());
|
|
44
|
-
}
|
|
45
|
-
}, o = () => a.reject(i(e));
|
|
46
|
-
e?.addEventListener("abort", o, { once: !0 }), l.push(a);
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
function w(e) {
|
|
50
|
-
let t = c.shift();
|
|
51
|
-
t ? (t.resolve(e), x()) : s.push(e);
|
|
5
|
+
function s(s, c) {
|
|
6
|
+
let l = [...s], u = [], d = 0, f = r({
|
|
7
|
+
isIdle: () => l.length === s.length && u.length === 0,
|
|
8
|
+
onDispose() {
|
|
9
|
+
for (let e of s) e.terminate();
|
|
10
|
+
for (let e of u.splice(0)) e.reject(new n());
|
|
11
|
+
},
|
|
12
|
+
onDrainStart() {
|
|
13
|
+
for (let e of u.splice(0)) e.reject(new n("Worker is draining"));
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
function p(e) {
|
|
17
|
+
let t = u.shift();
|
|
18
|
+
t ? (t.resolve(e), f.releaseCapacity()) : l.push(e);
|
|
52
19
|
}
|
|
53
|
-
async function
|
|
54
|
-
if (
|
|
55
|
-
if (
|
|
56
|
-
if (
|
|
57
|
-
for (;
|
|
58
|
-
if (
|
|
59
|
-
if (await
|
|
60
|
-
if (
|
|
61
|
-
if (
|
|
20
|
+
async function m(t) {
|
|
21
|
+
if (f.disposed) throw new n();
|
|
22
|
+
if (f.drainPromise) throw new n("Worker is draining");
|
|
23
|
+
if (t.signal?.aborted) throw o(t.signal);
|
|
24
|
+
for (; c.maxQueue !== void 0 && u.length >= c.maxQueue;) {
|
|
25
|
+
if (c.onFull === "reject") throw new e(c.maxQueue);
|
|
26
|
+
if (await f.waitForCapacity(t.signal, t.priority ?? 0), f.disposed) throw new n();
|
|
27
|
+
if (f.drainPromise) throw new n("Worker is draining");
|
|
28
|
+
if (t.signal?.aborted) throw f.releaseCapacity(), o(t.signal);
|
|
62
29
|
}
|
|
63
|
-
return
|
|
30
|
+
return l.pop() || new Promise((e, n) => {
|
|
64
31
|
let r = {
|
|
65
32
|
cleanup() {
|
|
66
|
-
r.signal?.removeEventListener("abort",
|
|
33
|
+
r.signal?.removeEventListener("abort", i);
|
|
67
34
|
},
|
|
68
|
-
priority:
|
|
35
|
+
priority: t.priority ?? 0,
|
|
69
36
|
reject(e) {
|
|
70
37
|
r.cleanup();
|
|
71
|
-
let t =
|
|
72
|
-
t !== -1 && (
|
|
38
|
+
let t = u.indexOf(r);
|
|
39
|
+
t !== -1 && (u.splice(t, 1), f.releaseCapacity()), n(e), f.settleIdle();
|
|
73
40
|
},
|
|
74
|
-
resolve(
|
|
75
|
-
r.cleanup(), t
|
|
41
|
+
resolve(t) {
|
|
42
|
+
r.cleanup(), e(t);
|
|
76
43
|
},
|
|
77
|
-
sequence:
|
|
78
|
-
signal:
|
|
79
|
-
},
|
|
80
|
-
r.signal?.addEventListener("abort",
|
|
44
|
+
sequence: d++,
|
|
45
|
+
signal: t.signal
|
|
46
|
+
}, i = () => r.reject(o(r.signal));
|
|
47
|
+
r.signal?.addEventListener("abort", i, { once: !0 }), u.push(r), u.sort((e, t) => t.priority - e.priority || e.sequence - t.sequence);
|
|
81
48
|
});
|
|
82
49
|
}
|
|
83
|
-
function E() {
|
|
84
|
-
if (!g) {
|
|
85
|
-
g = !0, u.abort();
|
|
86
|
-
for (let e of a) e.terminate();
|
|
87
|
-
for (let e of c.splice(0)) e.reject(new n());
|
|
88
|
-
S(new n()), y();
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
function D(e = {}) {
|
|
92
|
-
if (g) return Promise.resolve();
|
|
93
|
-
if (_) return _;
|
|
94
|
-
for (let e of c.splice(0)) e.reject(new n("Worker is draining"));
|
|
95
|
-
return S(new n("Worker is draining")), _ = b(e).then(() => E(), (e) => {
|
|
96
|
-
throw E(), e;
|
|
97
|
-
}), _;
|
|
98
|
-
}
|
|
99
50
|
return {
|
|
100
51
|
get disposalSignal() {
|
|
101
|
-
return
|
|
52
|
+
return f.disposalSignal;
|
|
102
53
|
},
|
|
103
|
-
dispose:
|
|
54
|
+
dispose: f.dispose,
|
|
104
55
|
get disposed() {
|
|
105
|
-
return
|
|
106
|
-
},
|
|
107
|
-
drain: D,
|
|
108
|
-
async prime() {
|
|
109
|
-
await Promise.all(a.map((e) => e.prime()));
|
|
56
|
+
return f.disposed;
|
|
110
57
|
},
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
let
|
|
58
|
+
drain: f.drain,
|
|
59
|
+
runStream(e, r = {}) {
|
|
60
|
+
let s = i(r.priority ?? 0), l = a(r.timeout) ?? c.defaultTimeout, u = [...r.transferables ?? []], d, h = async function* (t) {
|
|
61
|
+
let i = () => t.abort(r.signal?.reason), a, c;
|
|
62
|
+
r.signal?.aborted ? t.abort(r.signal.reason) : r.signal?.addEventListener("abort", i, { once: !0 });
|
|
115
63
|
try {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
signal:
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
64
|
+
a = await m({
|
|
65
|
+
priority: s,
|
|
66
|
+
signal: t.signal,
|
|
67
|
+
timeout: l,
|
|
68
|
+
transferables: u
|
|
69
|
+
}), f.trackActive(1), c = () => a?.cancel(o(t.signal)), t.signal.addEventListener("abort", c, { once: !0 });
|
|
70
|
+
let n = a.stream(e, {
|
|
71
|
+
priority: s,
|
|
72
|
+
signal: t.signal,
|
|
73
|
+
timeout: l,
|
|
74
|
+
transferables: u
|
|
124
75
|
});
|
|
125
76
|
for await (let e of n.iterable) yield e;
|
|
126
|
-
await n.done,
|
|
77
|
+
await n.done, f.trackCompleted();
|
|
127
78
|
} catch (e) {
|
|
128
|
-
throw
|
|
79
|
+
throw a && !t.signal.aborted && !(e instanceof n) && f.trackFailed(), e;
|
|
129
80
|
} finally {
|
|
130
|
-
|
|
81
|
+
r.signal?.removeEventListener("abort", i), a && (c && t.signal.removeEventListener("abort", c), f.trackActive(-1), p(a), f.settleIdle());
|
|
131
82
|
}
|
|
83
|
+
};
|
|
84
|
+
return { [Symbol.asyncIterator]() {
|
|
85
|
+
let e = {}, r = new AbortController(), i, a = () => {
|
|
86
|
+
if (d ??= e, d === e) return i ??= h(r), i;
|
|
87
|
+
};
|
|
88
|
+
return {
|
|
89
|
+
next: () => a()?.next() ?? Promise.reject(new t("Worker streams can only be consumed once")),
|
|
90
|
+
return: async (t) => !d || d !== e ? {
|
|
91
|
+
done: !0,
|
|
92
|
+
value: t
|
|
93
|
+
} : (r.abort(new n("Stream consumer stopped")), i?.return(t) ?? {
|
|
94
|
+
done: !0,
|
|
95
|
+
value: t
|
|
96
|
+
}),
|
|
97
|
+
throw: async (e) => {
|
|
98
|
+
let n = a();
|
|
99
|
+
if (!n) throw new t("Worker streams can only be consumed once");
|
|
100
|
+
return r.abort(e), n.throw(e);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
132
103
|
} };
|
|
133
104
|
},
|
|
134
105
|
get stats() {
|
|
135
|
-
return
|
|
136
|
-
active: f,
|
|
137
|
-
completed: p,
|
|
138
|
-
failed: m,
|
|
139
|
-
queued: c.length
|
|
140
|
-
};
|
|
106
|
+
return f.stats(u.length);
|
|
141
107
|
},
|
|
142
108
|
get status() {
|
|
143
|
-
return
|
|
109
|
+
return f.status();
|
|
144
110
|
},
|
|
145
|
-
[Symbol.asyncDispose]: () =>
|
|
146
|
-
[Symbol.dispose]:
|
|
111
|
+
[Symbol.asyncDispose]: () => f.drain({}),
|
|
112
|
+
[Symbol.dispose]: f.dispose
|
|
147
113
|
};
|
|
148
114
|
}
|
|
149
115
|
//#endregion
|
|
150
|
-
export {
|
|
116
|
+
export { s as createStreamPool };
|
|
151
117
|
|
|
152
118
|
//# sourceMappingURL=_stream-pool.js.map
|
package/dist/_stream-pool.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_stream-pool.js","names":[],"sources":["../src/_stream-pool.ts"],"sourcesContent":["import { abortError } from '@vielzeug/arsenal/async';\n\nimport type { PoolOptions } from './_pool';\nimport { unrefTimer } from './_timers';\nimport { FamiliarQueueFullError, FamiliarTerminatedError, FamiliarTimeoutError } from './errors';\nimport type { DrainOptions, RunOptions, StreamWorkerPool, WorkerStats, WorkerStatus } from './types';\nimport type { RunningStream } from './worker';\n\nexport type StreamSlot<TInput, TChunk> = {\n cancel(reason: unknown): void;\n prime(): Promise<void>;\n stream(input: TInput, options: RunOptions): RunningStream<TChunk>;\n terminate(): void;\n};\n\ntype CapacityWaiter = {\n cleanup(): void;\n reject(reason: unknown): void;\n resolve(): void;\n};\n\ntype Waiter<TSlot> = {\n cleanup(): void;\n priority: number;\n reject(reason: unknown): void;\n resolve(slot: TSlot): void;\n sequence: number;\n signal?: AbortSignal;\n};\n\nexport function createStreamPool<TInput, TChunk>(\n slots: StreamSlot<TInput, TChunk>[],\n options: PoolOptions,\n): StreamWorkerPool<TInput, TChunk> {\n const freeSlots = [...slots];\n const waiters: Waiter<StreamSlot<TInput, TChunk>>[] = [];\n const capacityWaiters: CapacityWaiter[] = [];\n const disposalController = new AbortController();\n const idleWaiters: Array<() => void> = [];\n let active = 0;\n let completed = 0;\n let failed = 0;\n let sequence = 0;\n let terminated = false;\n let drainPromise: Promise<void> | undefined;\n\n function idle(): boolean {\n return active === 0 && waiters.length === 0;\n }\n\n function settleIdle(): void {\n if (!idle()) return;\n\n for (const resolve of idleWaiters.splice(0)) resolve();\n }\n\n function waitForIdle(options: DrainOptions): Promise<void> {\n if (idle()) return Promise.resolve();\n\n return new Promise<void>((resolve, reject) => {\n idleWaiters.push(resolve);\n\n if (options.timeout !== undefined) {\n const timer = setTimeout(() => {\n const index = idleWaiters.indexOf(resolve);\n\n if (index !== -1) idleWaiters.splice(index, 1);\n\n reject(new FamiliarTimeoutError(options.timeout!));\n }, options.timeout);\n\n unrefTimer(timer);\n }\n });\n }\n\n function releaseCapacity(): void {\n capacityWaiters.shift()?.resolve();\n }\n\n function rejectCapacity(reason: unknown): void {\n for (const waiter of capacityWaiters.splice(0)) waiter.reject(reason);\n }\n\n function waitForCapacity(signal: AbortSignal | undefined): Promise<void> {\n if (signal?.aborted) return Promise.reject(abortError(signal));\n\n return new Promise<void>((resolve, reject) => {\n let settled = false;\n const waiter: CapacityWaiter = {\n cleanup() {\n signal?.removeEventListener('abort', onAbort);\n },\n reject(reason) {\n if (settled) return;\n\n settled = true;\n waiter.cleanup();\n\n const index = capacityWaiters.indexOf(waiter);\n\n if (index !== -1) capacityWaiters.splice(index, 1);\n\n reject(reason);\n },\n resolve() {\n if (settled) return;\n\n settled = true;\n waiter.cleanup();\n resolve();\n },\n };\n const onAbort = () => waiter.reject(abortError(signal!));\n\n signal?.addEventListener('abort', onAbort, { once: true });\n capacityWaiters.push(waiter);\n });\n }\n\n function release(slot: StreamSlot<TInput, TChunk>): void {\n const next = waiters.shift();\n\n if (next) {\n next.resolve(slot);\n releaseCapacity();\n } else {\n freeSlots.push(slot);\n }\n }\n\n async function acquire(runOptions: RunOptions): Promise<StreamSlot<TInput, TChunk>> {\n if (terminated) throw new FamiliarTerminatedError();\n\n if (drainPromise) throw new FamiliarTerminatedError('Worker is draining');\n\n if (runOptions.signal?.aborted) throw abortError(runOptions.signal);\n\n while (options.maxQueue !== undefined && waiters.length >= options.maxQueue) {\n if (options.onFull === 'reject') throw new FamiliarQueueFullError(options.maxQueue);\n\n await waitForCapacity(runOptions.signal);\n\n if (terminated) throw new FamiliarTerminatedError();\n\n if (drainPromise) throw new FamiliarTerminatedError('Worker is draining');\n\n if (runOptions.signal?.aborted) throw abortError(runOptions.signal);\n }\n\n const free = freeSlots.pop();\n\n if (free) return free;\n\n return new Promise<StreamSlot<TInput, TChunk>>((resolve, reject) => {\n const waiter: Waiter<StreamSlot<TInput, TChunk>> = {\n cleanup() {\n waiter.signal?.removeEventListener('abort', onAbort);\n },\n priority: runOptions.priority ?? 0,\n reject(reason) {\n waiter.cleanup();\n\n const index = waiters.indexOf(waiter);\n\n if (index !== -1) {\n waiters.splice(index, 1);\n releaseCapacity();\n }\n\n reject(reason);\n settleIdle();\n },\n resolve(slot) {\n waiter.cleanup();\n resolve(slot);\n },\n sequence: sequence++,\n signal: runOptions.signal,\n };\n const onAbort = () => waiter.reject(abortError(waiter.signal!));\n\n waiter.signal?.addEventListener('abort', onAbort, { once: true });\n waiters.push(waiter);\n waiters.sort((a, b) => b.priority - a.priority || a.sequence - b.sequence);\n });\n }\n\n function dispose(): void {\n if (terminated) return;\n\n terminated = true;\n disposalController.abort();\n for (const slot of slots) slot.terminate();\n for (const waiter of waiters.splice(0)) waiter.reject(new FamiliarTerminatedError());\n rejectCapacity(new FamiliarTerminatedError());\n settleIdle();\n }\n\n function drain(drainOptions: DrainOptions = {}): Promise<void> {\n if (terminated) return Promise.resolve();\n\n if (drainPromise) return drainPromise;\n\n for (const waiter of waiters.splice(0)) waiter.reject(new FamiliarTerminatedError('Worker is draining'));\n rejectCapacity(new FamiliarTerminatedError('Worker is draining'));\n drainPromise = waitForIdle(drainOptions).then(\n () => dispose(),\n (error: unknown) => {\n dispose();\n throw error;\n },\n );\n\n return drainPromise;\n }\n\n return {\n get disposalSignal() {\n return disposalController.signal;\n },\n dispose,\n get disposed() {\n return terminated;\n },\n drain,\n async prime(): Promise<void> {\n await Promise.all(slots.map((slot) => slot.prime()));\n },\n runStream(input, runOptions = {}): AsyncIterable<TChunk> {\n const controller = new AbortController();\n const onAbort = () => controller.abort(runOptions.signal?.reason);\n\n runOptions.signal?.addEventListener('abort', onAbort, { once: true });\n\n return {\n [Symbol.asyncIterator]: async function* () {\n let slot: StreamSlot<TInput, TChunk> | undefined;\n let onCancel: (() => void) | undefined;\n\n try {\n slot = await acquire({ ...runOptions, signal: controller.signal });\n active += 1;\n onCancel = () => slot?.cancel(abortError(controller.signal));\n controller.signal.addEventListener('abort', onCancel, { once: true });\n\n const running = slot.stream(input, {\n ...runOptions,\n signal: controller.signal,\n timeout: runOptions.timeout ?? options.defaultTimeout,\n });\n\n for await (const value of running.iterable) yield value;\n await running.done;\n completed += 1;\n } catch (error) {\n if (error?.constructor?.name !== 'AbortError' && !(error instanceof FamiliarTerminatedError)) failed += 1;\n\n throw error;\n } finally {\n runOptions.signal?.removeEventListener('abort', onAbort);\n\n if (slot) {\n if (onCancel) controller.signal.removeEventListener('abort', onCancel);\n\n active -= 1;\n release(slot);\n settleIdle();\n }\n }\n },\n };\n },\n get stats(): WorkerStats {\n return { active, completed, failed, queued: waiters.length };\n },\n get status(): WorkerStatus {\n if (terminated) return 'terminated';\n\n return active === 0 ? 'idle' : 'running';\n },\n [Symbol.asyncDispose]: () => drain(),\n [Symbol.dispose]: dispose,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"_stream-pool.js","names":[],"sources":["../src/_stream-pool.ts"],"sourcesContent":["import { abortError } from '@vielzeug/arsenal';\nimport { createPoolCore, type PoolCore, type PoolOptions, validatePriority, validateTimeout } from './_pool-core.js';\nimport { FamiliarQueueFullError, FamiliarRuntimeError, FamiliarTerminatedError } from './errors.js';\nimport type { RunOptions, StreamWorkerPool } from './types.js';\nimport type { RunningStream } from './worker.js';\n\nexport type StreamSlot<TInput, TChunk> = {\n cancel(reason: unknown): void;\n stream(input: TInput, options: RunOptions): RunningStream<TChunk>;\n terminate(): void;\n};\n\ntype Waiter<TSlot> = {\n cleanup(): void;\n priority: number;\n reject(reason: unknown): void;\n resolve(slot: TSlot): void;\n sequence: number;\n signal?: AbortSignal;\n};\n\nexport function createStreamPool<TInput, TChunk>(\n slots: StreamSlot<TInput, TChunk>[],\n options: PoolOptions,\n): StreamWorkerPool<TInput, TChunk> {\n const freeSlots = [...slots];\n const waiters: Waiter<StreamSlot<TInput, TChunk>>[] = [];\n let sequence = 0;\n\n const isIdle = (): boolean => freeSlots.length === slots.length && waiters.length === 0;\n\n const core: PoolCore = createPoolCore({\n isIdle,\n onDispose() {\n for (const slot of slots) slot.terminate();\n for (const waiter of waiters.splice(0)) waiter.reject(new FamiliarTerminatedError());\n },\n onDrainStart() {\n for (const waiter of waiters.splice(0)) waiter.reject(new FamiliarTerminatedError('Worker is draining'));\n },\n });\n\n function release(slot: StreamSlot<TInput, TChunk>): void {\n const next = waiters.shift();\n\n if (next) {\n next.resolve(slot);\n core.releaseCapacity();\n } else {\n freeSlots.push(slot);\n }\n }\n\n async function acquire(runOptions: RunOptions): Promise<StreamSlot<TInput, TChunk>> {\n if (core.disposed) throw new FamiliarTerminatedError();\n\n if (core.drainPromise) throw new FamiliarTerminatedError('Worker is draining');\n\n if (runOptions.signal?.aborted) throw abortError(runOptions.signal);\n\n while (options.maxQueue !== undefined && waiters.length >= options.maxQueue) {\n if (options.onFull === 'reject') throw new FamiliarQueueFullError(options.maxQueue);\n\n await core.waitForCapacity(runOptions.signal, runOptions.priority ?? 0);\n\n if (core.disposed) throw new FamiliarTerminatedError();\n\n if (core.drainPromise) throw new FamiliarTerminatedError('Worker is draining');\n\n if (runOptions.signal?.aborted) {\n core.releaseCapacity();\n throw abortError(runOptions.signal);\n }\n }\n\n const free = freeSlots.pop();\n\n if (free) return free;\n\n return new Promise<StreamSlot<TInput, TChunk>>((resolve, reject) => {\n const waiter: Waiter<StreamSlot<TInput, TChunk>> = {\n cleanup() {\n waiter.signal?.removeEventListener('abort', onAbort);\n },\n priority: runOptions.priority ?? 0,\n reject(reason) {\n waiter.cleanup();\n\n const index = waiters.indexOf(waiter);\n\n if (index !== -1) {\n waiters.splice(index, 1);\n core.releaseCapacity();\n }\n\n reject(reason);\n core.settleIdle();\n },\n resolve(slot) {\n waiter.cleanup();\n resolve(slot);\n },\n sequence: sequence++,\n signal: runOptions.signal,\n };\n const onAbort = () => waiter.reject(abortError(waiter.signal!));\n\n waiter.signal?.addEventListener('abort', onAbort, { once: true });\n waiters.push(waiter);\n waiters.sort((a, b) => b.priority - a.priority || a.sequence - b.sequence);\n });\n }\n\n return {\n get disposalSignal() {\n return core.disposalSignal;\n },\n dispose: core.dispose,\n get disposed() {\n return core.disposed;\n },\n drain: core.drain,\n runStream(input, runOptions = {}): AsyncIterable<TChunk> {\n const priority = validatePriority(runOptions.priority ?? 0);\n const timeout = validateTimeout(runOptions.timeout) ?? options.defaultTimeout;\n const transferables = [...(runOptions.transferables ?? [])];\n let owner: object | undefined;\n\n const iterate = async function* (controller: AbortController): AsyncGenerator<TChunk> {\n const onAbort = () => controller.abort(runOptions.signal?.reason);\n let slot: StreamSlot<TInput, TChunk> | undefined;\n let onCancel: (() => void) | undefined;\n\n if (runOptions.signal?.aborted) controller.abort(runOptions.signal.reason);\n else runOptions.signal?.addEventListener('abort', onAbort, { once: true });\n\n try {\n slot = await acquire({ priority, signal: controller.signal, timeout, transferables });\n core.trackActive(1);\n onCancel = () => slot?.cancel(abortError(controller.signal));\n controller.signal.addEventListener('abort', onCancel, { once: true });\n\n const running = slot.stream(input, { priority, signal: controller.signal, timeout, transferables });\n\n for await (const value of running.iterable) yield value;\n await running.done;\n core.trackCompleted();\n } catch (error) {\n if (slot && !controller.signal.aborted && !(error instanceof FamiliarTerminatedError)) core.trackFailed();\n throw error;\n } finally {\n runOptions.signal?.removeEventListener('abort', onAbort);\n\n if (slot) {\n if (onCancel) controller.signal.removeEventListener('abort', onCancel);\n\n core.trackActive(-1);\n release(slot);\n core.settleIdle();\n }\n }\n };\n\n return {\n [Symbol.asyncIterator]() {\n const token = {};\n const controller = new AbortController();\n let iterator: AsyncGenerator<TChunk> | undefined;\n const start = (): AsyncGenerator<TChunk> | undefined => {\n owner ??= token;\n if (owner !== token) return undefined;\n iterator ??= iterate(controller);\n return iterator;\n };\n\n return {\n next: () =>\n start()?.next() ?? Promise.reject(new FamiliarRuntimeError('Worker streams can only be consumed once')),\n return: async (value?: unknown) => {\n if (!owner) return { done: true, value: value as TChunk };\n if (owner !== token) return { done: true, value: value as TChunk };\n controller.abort(new FamiliarTerminatedError('Stream consumer stopped'));\n return iterator?.return(value as TChunk) ?? { done: true, value: value as TChunk };\n },\n throw: async (error?: unknown) => {\n const active = start();\n if (!active) throw new FamiliarRuntimeError('Worker streams can only be consumed once');\n controller.abort(error);\n return active.throw(error);\n },\n };\n },\n };\n },\n get stats() {\n return core.stats(waiters.length);\n },\n get status() {\n return core.status();\n },\n [Symbol.asyncDispose]: () => core.drain({}),\n [Symbol.dispose]: core.dispose,\n };\n}\n"],"mappings":"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"}
|
package/dist/errors.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=class extends Error{constructor(e,t){super(e,t),this.name=new.target.
|
|
1
|
+
var e=class extends Error{static errorName=`FamiliarError`;constructor(e,t){super(e,t),this.name=new.target.errorName,Object.setPrototypeOf(this,new.target.prototype)}},t=class extends e{static errorName=`FamiliarInvalidOptionsError`},n=class extends e{static errorName=`FamiliarQueueFullError`;maxQueue;constructor(e){super(`Queue is full (maxQueue=${e})`),this.maxQueue=e}},r=class extends e{static errorName=`FamiliarTaskError`},i=class extends e{static errorName=`FamiliarTerminatedError`;constructor(e=`Worker was terminated`){super(e)}},a=class extends e{static errorName=`FamiliarTimeoutError`;timeoutMs;constructor(e,t=`Task`){super(`${t} timed out after ${e}ms`),this.timeoutMs=e}},o=class extends e{static errorName=`FamiliarRuntimeError`};exports.FamiliarError=e,exports.FamiliarInvalidOptionsError=t,exports.FamiliarQueueFullError=n,exports.FamiliarRuntimeError=o,exports.FamiliarTaskError=r,exports.FamiliarTerminatedError=i,exports.FamiliarTimeoutError=a;
|
|
2
2
|
//# sourceMappingURL=errors.cjs.map
|
package/dist/errors.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all familiar errors. Use `instanceof FamiliarError` to catch any familiar-originated error. */\nexport class FamiliarError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.
|
|
1
|
+
{"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all familiar errors. Use `instanceof FamiliarError` to catch any familiar-originated error. */\nexport class FamiliarError extends Error {\n protected static readonly errorName: string = 'FamiliarError';\n\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = (new.target as typeof FamiliarError).errorName;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when invalid options are passed to a Familiar pool factory. */\nexport class FamiliarInvalidOptionsError extends FamiliarError {\n protected static override readonly errorName = 'FamiliarInvalidOptionsError';\n}\n\n/** Thrown when run() is called and the queue is full (`onFull='reject'`). */\nexport class FamiliarQueueFullError extends FamiliarError {\n protected static override readonly errorName = 'FamiliarQueueFullError';\n /** The configured `maxQueue` value. */\n readonly maxQueue: number;\n\n constructor(maxQueue: number) {\n super(`Queue is full (maxQueue=${maxQueue})`);\n this.maxQueue = maxQueue;\n }\n}\n\n/** Thrown when the task function throws. The original error is available as `.cause`. */\nexport class FamiliarTaskError extends FamiliarError {\n protected static override readonly errorName = 'FamiliarTaskError';\n}\n\n/** Thrown when a task or operation is rejected because the worker was terminated. */\nexport class FamiliarTerminatedError extends FamiliarError {\n protected static override readonly errorName = 'FamiliarTerminatedError';\n\n constructor(message = 'Worker was terminated') {\n super(message);\n }\n}\n\n/** Thrown when a task exceeds its timeout or `drain()` times out. */\nexport class FamiliarTimeoutError extends FamiliarError {\n protected static override readonly errorName = 'FamiliarTimeoutError';\n /** The configured timeout in milliseconds. */\n readonly timeoutMs: number;\n\n constructor(timeoutMs: number, operation = 'Task') {\n super(`${operation} timed out after ${timeoutMs}ms`);\n this.timeoutMs = timeoutMs;\n }\n}\n\n/** Thrown when the Worker API is unavailable or an unhandled error occurs in the worker thread. */\nexport class FamiliarRuntimeError extends FamiliarError {\n protected static override readonly errorName = 'FamiliarRuntimeError';\n}\n"],"mappings":"AACA,IAAa,EAAb,cAAmC,KAAM,CACvC,OAA0B,UAAoB,gBAE9C,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAQ,WAAoC,UACjD,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAGa,EAAb,cAAiD,CAAc,CAC7D,OAAmC,UAAY,6BACjD,EAGa,EAAb,cAA4C,CAAc,CACxD,OAAmC,UAAY,yBAE/C,SAEA,YAAY,EAAkB,CAC5B,MAAM,2BAA2B,EAAS,EAAE,EAC5C,KAAK,SAAW,CAClB,CACF,EAGa,EAAb,cAAuC,CAAc,CACnD,OAAmC,UAAY,mBACjD,EAGa,EAAb,cAA6C,CAAc,CACzD,OAAmC,UAAY,0BAE/C,YAAY,EAAU,wBAAyB,CAC7C,MAAM,CAAO,CACf,CACF,EAGa,EAAb,cAA0C,CAAc,CACtD,OAAmC,UAAY,uBAE/C,UAEA,YAAY,EAAmB,EAAY,OAAQ,CACjD,MAAM,GAAG,EAAU,mBAAmB,EAAU,GAAG,EACnD,KAAK,UAAY,CACnB,CACF,EAGa,EAAb,cAA0C,CAAc,CACtD,OAAmC,UAAY,sBACjD"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,30 +1,37 @@
|
|
|
1
1
|
/** Base class for all familiar errors. Use `instanceof FamiliarError` to catch any familiar-originated error. */
|
|
2
2
|
export declare class FamiliarError extends Error {
|
|
3
|
+
protected static readonly errorName: string;
|
|
3
4
|
constructor(message: string, opts?: ErrorOptions);
|
|
4
5
|
}
|
|
5
6
|
/** Thrown when invalid options are passed to a Familiar pool factory. */
|
|
6
7
|
export declare class FamiliarInvalidOptionsError extends FamiliarError {
|
|
8
|
+
protected static readonly errorName = "FamiliarInvalidOptionsError";
|
|
7
9
|
}
|
|
8
10
|
/** Thrown when run() is called and the queue is full (`onFull='reject'`). */
|
|
9
11
|
export declare class FamiliarQueueFullError extends FamiliarError {
|
|
12
|
+
protected static readonly errorName = "FamiliarQueueFullError";
|
|
10
13
|
/** The configured `maxQueue` value. */
|
|
11
14
|
readonly maxQueue: number;
|
|
12
15
|
constructor(maxQueue: number);
|
|
13
16
|
}
|
|
14
17
|
/** Thrown when the task function throws. The original error is available as `.cause`. */
|
|
15
18
|
export declare class FamiliarTaskError extends FamiliarError {
|
|
19
|
+
protected static readonly errorName = "FamiliarTaskError";
|
|
16
20
|
}
|
|
17
21
|
/** Thrown when a task or operation is rejected because the worker was terminated. */
|
|
18
22
|
export declare class FamiliarTerminatedError extends FamiliarError {
|
|
23
|
+
protected static readonly errorName = "FamiliarTerminatedError";
|
|
19
24
|
constructor(message?: string);
|
|
20
25
|
}
|
|
21
26
|
/** Thrown when a task exceeds its timeout or `drain()` times out. */
|
|
22
27
|
export declare class FamiliarTimeoutError extends FamiliarError {
|
|
28
|
+
protected static readonly errorName = "FamiliarTimeoutError";
|
|
23
29
|
/** The configured timeout in milliseconds. */
|
|
24
30
|
readonly timeoutMs: number;
|
|
25
|
-
constructor(timeoutMs: number);
|
|
31
|
+
constructor(timeoutMs: number, operation?: string);
|
|
26
32
|
}
|
|
27
33
|
/** Thrown when the Worker API is unavailable or an unhandled error occurs in the worker thread. */
|
|
28
34
|
export declare class FamiliarRuntimeError extends FamiliarError {
|
|
35
|
+
protected static readonly errorName = "FamiliarRuntimeError";
|
|
29
36
|
}
|
|
30
37
|
//# sourceMappingURL=errors.d.ts.map
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,iHAAiH;AACjH,qBAAa,aAAc,SAAQ,KAAK;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,iHAAiH;AACjH,qBAAa,aAAc,SAAQ,KAAK;IACtC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAmB;gBAElD,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;CAKjD;AAED,yEAAyE;AACzE,qBAAa,2BAA4B,SAAQ,aAAa;IAC5D,0BAAmC,SAAS,iCAAiC;CAC9E;AAED,6EAA6E;AAC7E,qBAAa,sBAAuB,SAAQ,aAAa;IACvD,0BAAmC,SAAS,4BAA4B;IACxE,uCAAuC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,QAAQ,EAAE,MAAM;CAI7B;AAED,yFAAyF;AACzF,qBAAa,iBAAkB,SAAQ,aAAa;IAClD,0BAAmC,SAAS,uBAAuB;CACpE;AAED,qFAAqF;AACrF,qBAAa,uBAAwB,SAAQ,aAAa;IACxD,0BAAmC,SAAS,6BAA6B;gBAE7D,OAAO,SAA0B;CAG9C;AAED,qEAAqE;AACrE,qBAAa,oBAAqB,SAAQ,aAAa;IACrD,0BAAmC,SAAS,0BAA0B;IACtE,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,SAAS,EAAE,MAAM,EAAE,SAAS,SAAS;CAIlD;AAED,mGAAmG;AACnG,qBAAa,oBAAqB,SAAQ,aAAa;IACrD,0BAAmC,SAAS,0BAA0B;CACvE"}
|
package/dist/errors.js
CHANGED
|
@@ -1,23 +1,33 @@
|
|
|
1
1
|
//#region src/errors.ts
|
|
2
2
|
var e = class extends Error {
|
|
3
|
+
static errorName = "FamiliarError";
|
|
3
4
|
constructor(e, t) {
|
|
4
|
-
super(e, t), this.name = new.target.
|
|
5
|
+
super(e, t), this.name = new.target.errorName, Object.setPrototypeOf(this, new.target.prototype);
|
|
5
6
|
}
|
|
6
|
-
}, t = class extends e {
|
|
7
|
+
}, t = class extends e {
|
|
8
|
+
static errorName = "FamiliarInvalidOptionsError";
|
|
9
|
+
}, n = class extends e {
|
|
10
|
+
static errorName = "FamiliarQueueFullError";
|
|
7
11
|
maxQueue;
|
|
8
12
|
constructor(e) {
|
|
9
13
|
super(`Queue is full (maxQueue=${e})`), this.maxQueue = e;
|
|
10
14
|
}
|
|
11
|
-
}, r = class extends e {
|
|
15
|
+
}, r = class extends e {
|
|
16
|
+
static errorName = "FamiliarTaskError";
|
|
17
|
+
}, i = class extends e {
|
|
18
|
+
static errorName = "FamiliarTerminatedError";
|
|
12
19
|
constructor(e = "Worker was terminated") {
|
|
13
20
|
super(e);
|
|
14
21
|
}
|
|
15
22
|
}, a = class extends e {
|
|
23
|
+
static errorName = "FamiliarTimeoutError";
|
|
16
24
|
timeoutMs;
|
|
17
|
-
constructor(e) {
|
|
18
|
-
super(
|
|
25
|
+
constructor(e, t = "Task") {
|
|
26
|
+
super(`${t} timed out after ${e}ms`), this.timeoutMs = e;
|
|
19
27
|
}
|
|
20
|
-
}, o = class extends e {
|
|
28
|
+
}, o = class extends e {
|
|
29
|
+
static errorName = "FamiliarRuntimeError";
|
|
30
|
+
};
|
|
21
31
|
//#endregion
|
|
22
32
|
export { e as FamiliarError, t as FamiliarInvalidOptionsError, n as FamiliarQueueFullError, o as FamiliarRuntimeError, r as FamiliarTaskError, i as FamiliarTerminatedError, a as FamiliarTimeoutError };
|
|
23
33
|
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all familiar errors. Use `instanceof FamiliarError` to catch any familiar-originated error. */\nexport class FamiliarError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.
|
|
1
|
+
{"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all familiar errors. Use `instanceof FamiliarError` to catch any familiar-originated error. */\nexport class FamiliarError extends Error {\n protected static readonly errorName: string = 'FamiliarError';\n\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = (new.target as typeof FamiliarError).errorName;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when invalid options are passed to a Familiar pool factory. */\nexport class FamiliarInvalidOptionsError extends FamiliarError {\n protected static override readonly errorName = 'FamiliarInvalidOptionsError';\n}\n\n/** Thrown when run() is called and the queue is full (`onFull='reject'`). */\nexport class FamiliarQueueFullError extends FamiliarError {\n protected static override readonly errorName = 'FamiliarQueueFullError';\n /** The configured `maxQueue` value. */\n readonly maxQueue: number;\n\n constructor(maxQueue: number) {\n super(`Queue is full (maxQueue=${maxQueue})`);\n this.maxQueue = maxQueue;\n }\n}\n\n/** Thrown when the task function throws. The original error is available as `.cause`. */\nexport class FamiliarTaskError extends FamiliarError {\n protected static override readonly errorName = 'FamiliarTaskError';\n}\n\n/** Thrown when a task or operation is rejected because the worker was terminated. */\nexport class FamiliarTerminatedError extends FamiliarError {\n protected static override readonly errorName = 'FamiliarTerminatedError';\n\n constructor(message = 'Worker was terminated') {\n super(message);\n }\n}\n\n/** Thrown when a task exceeds its timeout or `drain()` times out. */\nexport class FamiliarTimeoutError extends FamiliarError {\n protected static override readonly errorName = 'FamiliarTimeoutError';\n /** The configured timeout in milliseconds. */\n readonly timeoutMs: number;\n\n constructor(timeoutMs: number, operation = 'Task') {\n super(`${operation} timed out after ${timeoutMs}ms`);\n this.timeoutMs = timeoutMs;\n }\n}\n\n/** Thrown when the Worker API is unavailable or an unhandled error occurs in the worker thread. */\nexport class FamiliarRuntimeError extends FamiliarError {\n protected static override readonly errorName = 'FamiliarRuntimeError';\n}\n"],"mappings":";AACA,IAAa,IAAb,cAAmC,MAAM;CACvC,OAA0B,YAAoB;CAE9C,YAAY,GAAiB,GAAqB;EAGhD,AAFA,MAAM,GAAS,CAAI,GACnB,KAAK,OAAQ,WAAoC,WACjD,OAAO,eAAe,MAAM,WAAW,SAAS;CAClD;AACF,GAGa,IAAb,cAAiD,EAAc;CAC7D,OAAmC,YAAY;AACjD,GAGa,IAAb,cAA4C,EAAc;CACxD,OAAmC,YAAY;CAE/C;CAEA,YAAY,GAAkB;EAE5B,AADA,MAAM,2BAA2B,EAAS,EAAE,GAC5C,KAAK,WAAW;CAClB;AACF,GAGa,IAAb,cAAuC,EAAc;CACnD,OAAmC,YAAY;AACjD,GAGa,IAAb,cAA6C,EAAc;CACzD,OAAmC,YAAY;CAE/C,YAAY,IAAU,yBAAyB;EAC7C,MAAM,CAAO;CACf;AACF,GAGa,IAAb,cAA0C,EAAc;CACtD,OAAmC,YAAY;CAE/C;CAEA,YAAY,GAAmB,IAAY,QAAQ;EAEjD,AADA,MAAM,GAAG,EAAU,mBAAmB,EAAU,GAAG,GACnD,KAAK,YAAY;CACnB;AACF,GAGa,IAAb,cAA0C,EAAc;CACtD,OAAmC,YAAY;AACjD"}
|
package/dist/familiar.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e){return e?.reason??new DOMException(`Aborted`,`AbortError`)}var t=class{#e=[];#t=0;#n=0;get size(){return this.#t}enqueue(e,t){return t!==void 0&&this.#t>=t?!1:(this.#e.push({item:e,sequence:this.#n++}),this.#a(this.#e.length-1),this.#t+=1,!0)}remove(e){if(e.cancelled)return!1;for(let t of this.#e)if(t.item===e)return e.cancelled=!0,--this.#t,!0;return!1}shift(){for(;this.#e.length>0;){let e=this.#r().item;if(!e.cancelled)return--this.#t,e}}#r(){let e=this.#e[0],t=this.#e.pop();return this.#e.length>0&&(this.#e[0]=t,this.#o(0)),e}#i(e,t){return e.item.priority===t.item.priority?e.sequence<t.sequence:e.item.priority>t.item.priority}#a(e){for(;e>0;){let t=e-1>>1;if(!this.#i(this.#e[e],this.#e[t]))return;[this.#e[e],this.#e[t]]=[this.#e[t],this.#e[e]],e=t}}#o(e){for(;;){let t=e*2+1,n=t+1,r=e;if(t<this.#e.length&&this.#i(this.#e[t],this.#e[r])&&(r=t),n<this.#e.length&&this.#i(this.#e[n],this.#e[r])&&(r=n),r===e)return;[this.#e[e],this.#e[r]]=[this.#e[r],this.#e[e]],e=r}}};function n(e){typeof e==`object`&&e&&`unref`in e&&e.unref()}var r=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},i=class extends r{},a=class extends r{maxQueue;constructor(e){super(`Queue is full (maxQueue=${e})`),this.maxQueue=e}},o=class extends r{},s=class extends r{constructor(e=`Worker was terminated`){super(e)}},c=class extends r{timeoutMs;constructor(e){super(`Task timed out after ${e}ms`),this.timeoutMs=e}},l=class extends r{};function u(r,i){let o=[...r],l=new t,u=new AbortController,d=[],f=[],p=0,m=0,h=0,g,_=!1,v=!1;function y(){return p===0&&l.size===0}function b(){if(y())for(let e of d.splice(0))e.timer&&clearTimeout(e.timer),e.resolve()}function x(e={}){return y()?Promise.resolve():new Promise((t,r)=>{let i={reject:r,resolve:t};e.timeout!==void 0&&(i.timer=setTimeout(()=>{let t=d.indexOf(i);t!==-1&&d.splice(t,1),r(new c(e.timeout))},e.timeout),n(i.timer)),d.push(i)})}function S(){f.shift()?.resolve()}function C(e){for(let t of f.splice(0))t.reject(e)}function w(t){return t?.aborted?Promise.reject(e(t)):new Promise((n,r)=>{let i=!1,a={cleanup(){t?.removeEventListener(`abort`,o)},reject(e){if(i)return;i=!0,a.cleanup();let t=f.indexOf(a);t!==-1&&f.splice(t,1),r(e)},resolve(){i||(i=!0,a.cleanup(),n())}},o=()=>a.reject(e(t));t?.addEventListener(`abort`,o,{once:!0}),f.push(a)})}function T(){for(;l.size>0;){let t=l.shift();if(!t)break;if(t.signal?.aborted){t.cleanupAbort?.(),t.reject(e(t.signal)),S();continue}return t}b()}function E(){if(!(_||v)){for(_=!0;!v&&o.length>0&&l.size>0;){let r=T();if(!r)break;let a=r,c=o.pop(),l=a.timeout??i.defaultTimeout;p+=1,S();let u=()=>c.cancel(e(a.signal));a.cleanupAbort=()=>{a.signal?.removeEventListener(`abort`,u),a.cleanupAbort=void 0},a.signal?.addEventListener(`abort`,u,{once:!0}),c.run(a.input,a.transferables,l).then(e=>t(e),e=>n(e));function t(e){a.cleanupAbort?.(),o.push(c),--p,m+=1,a.resolve(e),E(),b()}function n(e){a.cleanupAbort?.(),o.push(c),--p,!(e instanceof s)&&e?.constructor?.name!==`AbortError`&&(h+=1),a.reject(e),E(),b()}}_=!1}}async function D(t,n={}){let{priority:r=0,signal:o,timeout:c,transferables:u=[]}=n;if(v)throw new s;if(g)throw new s(`Worker is draining`);if(o?.aborted)throw e(o);for(;i.onFull===`wait`&&i.maxQueue!==void 0&&l.size>=i.maxQueue;){if(await w(o),v)throw new s;if(g)throw new s(`Worker is draining`);if(o?.aborted)throw e(o)}let d,f,p=new Promise((e,t)=>{d=e,f=t}),m={input:t,priority:r,reject:f,resolve:d,signal:o,timeout:c,transferables:u};if(!l.enqueue(m,i.onFull===`wait`?void 0:i.maxQueue))throw new a(i.maxQueue);if(o){let t=()=>{l.remove(m)&&(m.cleanupAbort?.(),f(e(o)),S(),b())};m.cleanupAbort=()=>{o.removeEventListener(`abort`,t),m.cleanupAbort=void 0},o.addEventListener(`abort`,t,{once:!0})}return E(),p}function O(){if(!v){v=!0,u.abort();for(let e of r)e.terminate();for(;l.size>0;){let e=l.shift();if(!e)break;e.cleanupAbort?.(),e.reject(new s)}C(new s),b()}}function k(e={}){return v?Promise.resolve():g||(C(new s(`Worker is draining`)),g=x(e).then(()=>O(),e=>{throw O(),e}),g)}return{get disposalSignal(){return u.signal},dispose:O,get disposed(){return v},drain:k,async prime(){await Promise.all(r.map(e=>e.prime()))},run:D,get stats(){return{active:p,completed:m,failed:h,queued:l.size}},get status(){return v?`terminated`:p===0?`idle`:`running`},[Symbol.asyncDispose]:()=>k(),[Symbol.dispose]:O}}async function*d(e,t,n={}){let r=new AbortController,i=()=>r.abort(n.signal?.reason);n.signal?.addEventListener(`abort`,i,{once:!0});let a=t.map(t=>e.run(t,{...n,signal:r.signal}));try{for(let e of a)yield await e}catch(e){throw r.abort(e),await Promise.allSettled(a),e}finally{n.signal?.removeEventListener(`abort`,i),r.abort(),await Promise.allSettled(a)}}function f(e,t=void 0,n={}){let r=new AbortController,i=new Set,a=0;return n.signal?.addEventListener(`abort`,()=>r.abort(n.signal?.reason),{once:!0}),{abort(e){r.abort(e)},async drain(){return Promise.allSettled([...i])},get name(){return t},get pending(){return i.size},run(t,n={}){let o=e.run(t,{...n,signal:r.signal});return a+=1,i.add(o),o.finally(()=>i.delete(o)),o},get size(){return a}}}function p(t,r){let i=[...t],o=[],l=[],u=new AbortController,d=[],f=0,p=0,m=0,h=0,g=!1,_;function v(){return f===0&&o.length===0}function y(){if(v())for(let e of d.splice(0))e()}function b(e){return v()?Promise.resolve():new Promise((t,r)=>{d.push(t),e.timeout!==void 0&&n(setTimeout(()=>{let n=d.indexOf(t);n!==-1&&d.splice(n,1),r(new c(e.timeout))},e.timeout))})}function x(){l.shift()?.resolve()}function S(e){for(let t of l.splice(0))t.reject(e)}function C(t){return t?.aborted?Promise.reject(e(t)):new Promise((n,r)=>{let i=!1,a={cleanup(){t?.removeEventListener(`abort`,o)},reject(e){if(i)return;i=!0,a.cleanup();let t=l.indexOf(a);t!==-1&&l.splice(t,1),r(e)},resolve(){i||(i=!0,a.cleanup(),n())}},o=()=>a.reject(e(t));t?.addEventListener(`abort`,o,{once:!0}),l.push(a)})}function w(e){let t=o.shift();t?(t.resolve(e),x()):i.push(e)}async function T(t){if(g)throw new s;if(_)throw new s(`Worker is draining`);if(t.signal?.aborted)throw e(t.signal);for(;r.maxQueue!==void 0&&o.length>=r.maxQueue;){if(r.onFull===`reject`)throw new a(r.maxQueue);if(await C(t.signal),g)throw new s;if(_)throw new s(`Worker is draining`);if(t.signal?.aborted)throw e(t.signal)}return i.pop()||new Promise((n,r)=>{let i={cleanup(){i.signal?.removeEventListener(`abort`,a)},priority:t.priority??0,reject(e){i.cleanup();let t=o.indexOf(i);t!==-1&&(o.splice(t,1),x()),r(e),y()},resolve(e){i.cleanup(),n(e)},sequence:h++,signal:t.signal},a=()=>i.reject(e(i.signal));i.signal?.addEventListener(`abort`,a,{once:!0}),o.push(i),o.sort((e,t)=>t.priority-e.priority||e.sequence-t.sequence)})}function E(){if(!g){g=!0,u.abort();for(let e of t)e.terminate();for(let e of o.splice(0))e.reject(new s);S(new s),y()}}function D(e={}){if(g)return Promise.resolve();if(_)return _;for(let e of o.splice(0))e.reject(new s(`Worker is draining`));return S(new s(`Worker is draining`)),_=b(e).then(()=>E(),e=>{throw E(),e}),_}return{get disposalSignal(){return u.signal},dispose:E,get disposed(){return g},drain:D,async prime(){await Promise.all(t.map(e=>e.prime()))},runStream(t,n={}){let i=new AbortController,a=()=>i.abort(n.signal?.reason);return n.signal?.addEventListener(`abort`,a,{once:!0}),{[Symbol.asyncIterator]:async function*(){let o,c;try{o=await T({...n,signal:i.signal}),f+=1,c=()=>o?.cancel(e(i.signal)),i.signal.addEventListener(`abort`,c,{once:!0});let a=o.stream(t,{...n,signal:i.signal,timeout:n.timeout??r.defaultTimeout});for await(let e of a.iterable)yield e;await a.done,p+=1}catch(e){throw e?.constructor?.name!==`AbortError`&&!(e instanceof s)&&(m+=1),e}finally{n.signal?.removeEventListener(`abort`,a),o&&(c&&i.signal.removeEventListener(`abort`,c),--f,w(o),y())}}}},get stats(){return{active:f,completed:p,failed:m,queued:o.length}},get status(){return g?`terminated`:f===0?`idle`:`running`},[Symbol.asyncDispose]:()=>D(),[Symbol.dispose]:E}}var m=512;function h(e={}){let{concurrency:t=1,maxQueue:n,onFull:r=`reject`,onSlotError:a,timeout:o}=e,s=t===`auto`?Math.max(1,globalThis.navigator?.hardwareConcurrency??1):t;if(!Number.isInteger(s)||s<1||s>m)throw new i(`\`concurrency\` must be a positive integer ≤ ${m} or "auto"`);if(n!==void 0&&(!Number.isInteger(n)||n<1))throw new i("`maxQueue` must be a positive integer");if(o!==void 0&&(!Number.isFinite(o)||o<=0))throw new i("`timeout` must be a finite number greater than 0");return{concurrency:s,maxQueue:n,onFull:r,onSlotError:a,timeout:o}}function g(e){if(typeof e!=`object`||!e)return!1;let t=e;return t.version===1&&typeof t.id==`number`&&(t.kind===`chunk`||t.kind===`error`||t.kind===`result`)}function _(e){let t=Error(e.message);return t.name=e.name,t.stack=e.stack,new o(e.message,{cause:t})}var v=class{#e;#t;#n=!1;#r;#i=0;#a;constructor(e,t){this.#t=e,this.#e=t}cancel(e){this.#a?.terminate(),this.#a=void 0,this.#l(`reject`,e)}prime(){return this.#n||this.#s(),Promise.resolve()}run(e,t,n){return this.#o(e,t,n,`run`)}stream(e,t){let n=()=>this.cancel(new s(`Stream consumer stopped`)),r=[],i=[],a=!1,o,c=e=>{let t=i.shift();t?t({done:!1,value:e}):r.push(e)},l=e=>{for(a=!0,o=e;i.length>0;)i.shift()(e===void 0?{done:!0,value:void 0}:Promise.reject(e))};return{done:this.#o(e,t.transferables??[],t.timeout,`stream`,c).then(()=>l(),e=>l(e)),iterable:{[Symbol.asyncIterator]:()=>({async next(){if(r.length>0)return{done:!1,value:r.shift()};if(o!==void 0)throw o;return a?{done:!0,value:void 0}:new Promise((e,t)=>{i.push(n=>{n instanceof Promise?n.then(e,t):e(n)})})},async return(){return n(),{done:!0,value:void 0}}})}}}terminate(){this.#n=!0,this.cancel(new s)}#o(e,t,r,i,a){if(this.#n)return Promise.reject(new s);if(this.#r)return Promise.reject(new l(`Worker slot is already busy`));try{let o=this.#s(),s=this.#i++;return new Promise((u,d)=>{let f={emit:a,id:s,reject:d,resolve:u};this.#r=f,r!==void 0&&(f.timer=setTimeout(()=>this.cancel(new c(r)),r),n(f.timer));try{o.postMessage({id:s,input:e,kind:i,version:1},t)}catch(e){this.cancel(new l(`Failed to post message to worker`,{cause:e}))}})}catch(e){return Promise.reject(e)}}#s(){if(this.#a)return this.#a;if(typeof Worker>`u`)throw new l(`Worker API is unavailable in this runtime`);try{let e=new Worker(this.#t,{type:`module`});return e.onmessage=e=>this.#c(e.data),e.onerror=e=>{let t=new l(e.message||`Worker failed`);this.#a=void 0,this.#e?.(t),this.#l(`reject`,t)},this.#a=e,e}catch(e){throw new l(`Failed to create Worker`,{cause:e})}}#c(e){if(this.#r){if(!g(e)||e.id!==this.#r.id){this.cancel(new l(`Worker returned an incompatible protocol response`));return}if(e.kind===`chunk`){this.#r.emit?.(e.value);return}if(e.kind===`error`){this.#l(`reject`,_(e.error));return}this.#l(`resolve`,e.value)}}#l(e,t){let n=this.#r;n&&(this.#r=void 0,n.timer&&clearTimeout(n.timer),e===`resolve`?n.resolve(t):n.reject(t))}};function y(e,t){return Array.from({length:t.concurrency},()=>new v(e,t.onSlotError))}function b(e,t={}){let n=h(t);return u(y(e,n),{concurrency:n.concurrency,defaultTimeout:n.timeout,maxQueue:n.maxQueue,onFull:n.onFull})}function x(e,t={}){let n=h(t);return p(y(e,n),{concurrency:n.concurrency,defaultTimeout:n.timeout,maxQueue:n.maxQueue,onFull:n.onFull})}exports.FamiliarError=r,exports.FamiliarInvalidOptionsError=i,exports.FamiliarQueueFullError=a,exports.FamiliarRuntimeError=l,exports.FamiliarTaskError=o,exports.FamiliarTerminatedError=s,exports.FamiliarTimeoutError=c,exports.batch=d,exports.createStreamWorker=x,exports.createTaskGroup=f,exports.createWorker=b;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@vielzeug/arsenal");function t(e){typeof e==`object`&&e&&`unref`in e&&e.unref()}var n=class extends Error{static errorName=`FamiliarError`;constructor(e,t){super(e,t),this.name=new.target.errorName,Object.setPrototypeOf(this,new.target.prototype)}},r=class extends n{static errorName=`FamiliarInvalidOptionsError`},i=class extends n{static errorName=`FamiliarQueueFullError`;maxQueue;constructor(e){super(`Queue is full (maxQueue=${e})`),this.maxQueue=e}},a=class extends n{static errorName=`FamiliarTaskError`},o=class extends n{static errorName=`FamiliarTerminatedError`;constructor(e=`Worker was terminated`){super(e)}},s=class extends n{static errorName=`FamiliarTimeoutError`;timeoutMs;constructor(e,t=`Task`){super(`${t} timed out after ${e}ms`),this.timeoutMs=e}},c=class extends n{static errorName=`FamiliarRuntimeError`},l=2147483647;function u(e){if(!Number.isFinite(e))throw new r("`priority` must be a finite number");return e}function d(e,t=`timeout`){if(e!==void 0&&(!Number.isInteger(e)||e<1||e>2147483647))throw new r(`\`${t}\` must be an integer from 1 through ${l}`);return e}function f(n){let r=new AbortController,i=[],a=[],c=0,l=0,u=0,f=0,p,m=!1;function h(){if(n.isIdle())for(let e of i.splice(0))e.timer&&clearTimeout(e.timer),e.resolve()}function g(e){return n.isIdle()?Promise.resolve():new Promise((n,r)=>{let a={reject:r,resolve:n};e.timeout!==void 0&&(a.timer=setTimeout(()=>{let t=i.indexOf(a);t!==-1&&i.splice(t,1),r(new s(e.timeout,`Drain`))},e.timeout),t(a.timer)),i.push(a)})}function _(){a.shift()?.resolve()}function v(e){for(let t of a.splice(0))t.reject(e)}function y(t,n){return t?.aborted?Promise.reject((0,e.abortError)(t)):new Promise((r,i)=>{let o=!1,s={cleanup(){t?.removeEventListener(`abort`,c)},priority:n,reject(e){if(o)return;o=!0,s.cleanup();let t=a.indexOf(s);t!==-1&&a.splice(t,1),i(e)},resolve(){o||(o=!0,s.cleanup(),r())},sequence:l++},c=()=>s.reject((0,e.abortError)(t));t?.addEventListener(`abort`,c,{once:!0}),a.push(s),a.sort((e,t)=>t.priority-e.priority||e.sequence-t.sequence)})}function b(){m||(m=!0,r.abort(),n.onDispose(),v(new o),h())}function x(e={}){if(m)return Promise.resolve();try{d(e.timeout,`drain.timeout`)}catch(e){return Promise.reject(e)}return p||(n.onDrainStart(),v(new o(`Worker is draining`)),p=g(e).then(()=>b(),e=>{throw b(),e}),p)}function S(e){c+=e}function C(){u+=1}function w(){f+=1}function T(e){return{active:c,completed:u,failed:f,queued:e+a.length}}function E(){return m?`terminated`:c===0?`idle`:`running`}return{disposalSignal:r.signal,dispose:b,get disposed(){return m},drain:x,get drainPromise(){return p},isIdle:n.isIdle,rejectCapacity:v,releaseCapacity:_,settleIdle:h,stats:T,status:E,trackActive:S,trackCompleted:C,trackFailed:w,waitForCapacity:y,waitForIdle:g}}var p=class{#e=[];#t=0;#n=0;get size(){return this.#t}enqueue(e,t){return t!==void 0&&this.#t>=t?!1:(this.#e.push({item:e,sequence:this.#n++}),this.#a(this.#e.length-1),this.#t+=1,!0)}remove(e){let t=this.#e.findIndex(t=>t.item===e);if(t===-1)return!1;let n=this.#e.pop();if(--this.#t,t<this.#e.length){this.#e[t]=n;let e=t-1>>1;t>0&&this.#i(this.#e[t],this.#e[e])?this.#a(t):this.#o(t)}return!0}shift(){if(this.#e.length!==0)return--this.#t,this.#r().item}#r(){let e=this.#e[0],t=this.#e.pop();return this.#e.length>0&&(this.#e[0]=t,this.#o(0)),e}#i(e,t){return e.item.priority===t.item.priority?e.sequence<t.sequence:e.item.priority>t.item.priority}#a(e){for(;e>0;){let t=e-1>>1;if(!this.#i(this.#e[e],this.#e[t]))return;[this.#e[e],this.#e[t]]=[this.#e[t],this.#e[e]],e=t}}#o(e){for(;;){let t=e*2+1,n=t+1,r=e;if(t<this.#e.length&&this.#i(this.#e[t],this.#e[r])&&(r=t),n<this.#e.length&&this.#i(this.#e[n],this.#e[r])&&(r=n),r===e)return;[this.#e[e],this.#e[r]]=[this.#e[r],this.#e[e]],e=r}}};function m(t,n){let r=[...t],a=new p,s=!1,c=f({isIdle:()=>r.length===t.length&&a.size===0,onDispose(){for(let e of t)e.terminate();for(;a.size>0;){let e=a.shift();if(!e)break;e.cleanupAbort?.(),e.reject(new o)}},onDrainStart(){}});function l(){for(;a.size>0;){let t=a.shift();if(!t)break;if(t.signal?.aborted){t.cleanupAbort?.(),t.reject((0,e.abortError)(t.signal)),c.releaseCapacity();continue}return t}c.settleIdle()}function m(){if(!(s||c.disposed)){for(s=!0;!c.disposed&&r.length>0&&a.size>0;){let a=l();if(!a)break;let s=a,u=r.pop(),d=s.timeout??n.defaultTimeout;c.trackActive(1),c.releaseCapacity();let f=()=>{s.aborted=!0,u.cancel((0,e.abortError)(s.signal))};s.cleanupAbort=()=>{s.signal?.removeEventListener(`abort`,f),s.cleanupAbort=void 0},s.signal?.addEventListener(`abort`,f,{once:!0}),u.run(s.input,s.transferables,d).then(e=>t(e),e=>i(e));function t(e){s.cleanupAbort?.(),r.push(u),c.trackActive(-1),c.trackCompleted(),s.resolve(e),m(),c.settleIdle()}function i(e){s.cleanupAbort?.(),r.push(u),c.trackActive(-1),!s.aborted&&!(e instanceof o)&&c.trackFailed(),s.reject(e),m(),c.settleIdle()}}s=!1}}async function h(t,r={}){let{signal:s}=r,l=u(r.priority??0),f=d(r.timeout),p=[...r.transferables??[]];if(c.disposed)throw new o;if(c.drainPromise)throw new o(`Worker is draining`);if(s?.aborted)throw(0,e.abortError)(s);for(;n.onFull===`wait`&&n.maxQueue!==void 0&&a.size>=n.maxQueue;){if(await c.waitForCapacity(s,l),c.disposed)throw new o;if(c.drainPromise)throw new o(`Worker is draining`);if(s?.aborted)throw c.releaseCapacity(),(0,e.abortError)(s)}let h,g,_=new Promise((e,t)=>{h=e,g=t}),v={input:t,priority:l,reject:g,resolve:h,signal:s,timeout:f,transferables:p};if(!a.enqueue(v,n.onFull===`wait`?void 0:n.maxQueue))throw new i(n.maxQueue);if(s){let t=()=>{a.remove(v)&&(v.cleanupAbort?.(),g((0,e.abortError)(s)),c.releaseCapacity(),c.settleIdle())};v.cleanupAbort=()=>{s.removeEventListener(`abort`,t),v.cleanupAbort=void 0},s.addEventListener(`abort`,t,{once:!0})}return m(),_}return{get disposalSignal(){return c.disposalSignal},dispose:c.dispose,get disposed(){return c.disposed},drain:c.drain,run:h,get stats(){return c.stats(a.size)},get status(){return c.status()},[Symbol.asyncDispose]:()=>c.drain({}),[Symbol.dispose]:c.dispose}}function h(t,n,r={}){let i,a=async function*(i){let a=[],o=()=>i.abort(r.signal?.reason);r.signal?.aborted?i.abort(r.signal.reason):r.signal?.addEventListener(`abort`,o,{once:!0});try{for(let[e,o]of n.entries()){let n=t.run(o,{priority:r.priority,signal:i.signal,timeout:r.timeout,transferables:r.getTransferables?.(o,e)}).catch(e=>{throw i.abort(e),e});n.catch(()=>void 0),a.push(n)}if(a.length===0&&i.signal.aborted)throw(0,e.abortError)(i.signal);for(let t of a){if(i.signal.aborted)throw(0,e.abortError)(i.signal);let n=await t;if(i.signal.aborted)throw(0,e.abortError)(i.signal);yield n}}catch(e){throw i.abort(e),e}finally{r.signal?.removeEventListener(`abort`,o),i.abort(new DOMException(`Batch consumer stopped`,`AbortError`)),await Promise.allSettled(a)}};return{[Symbol.asyncIterator](){let e={},t=new AbortController,n,r=()=>{if(i??=e,i===e)return n??=a(t),n};return{next:()=>r()?.next()??Promise.reject(new c(`Worker batches can only be consumed once`)),return:async r=>!i||i!==e?{done:!0,value:r}:(t.abort(new o(`Batch consumer stopped`)),n?.return(r)??{done:!0,value:r}),throw:async e=>{let n=r();if(!n)throw new c(`Worker batches can only be consumed once`);return t.abort(e),n.throw(e)}}}}}function g(t,n){let r=[...t],a=[],s=0,l=f({isIdle:()=>r.length===t.length&&a.length===0,onDispose(){for(let e of t)e.terminate();for(let e of a.splice(0))e.reject(new o)},onDrainStart(){for(let e of a.splice(0))e.reject(new o(`Worker is draining`))}});function p(e){let t=a.shift();t?(t.resolve(e),l.releaseCapacity()):r.push(e)}async function m(t){if(l.disposed)throw new o;if(l.drainPromise)throw new o(`Worker is draining`);if(t.signal?.aborted)throw(0,e.abortError)(t.signal);for(;n.maxQueue!==void 0&&a.length>=n.maxQueue;){if(n.onFull===`reject`)throw new i(n.maxQueue);if(await l.waitForCapacity(t.signal,t.priority??0),l.disposed)throw new o;if(l.drainPromise)throw new o(`Worker is draining`);if(t.signal?.aborted)throw l.releaseCapacity(),(0,e.abortError)(t.signal)}return r.pop()||new Promise((n,r)=>{let i={cleanup(){i.signal?.removeEventListener(`abort`,o)},priority:t.priority??0,reject(e){i.cleanup();let t=a.indexOf(i);t!==-1&&(a.splice(t,1),l.releaseCapacity()),r(e),l.settleIdle()},resolve(e){i.cleanup(),n(e)},sequence:s++,signal:t.signal},o=()=>i.reject((0,e.abortError)(i.signal));i.signal?.addEventListener(`abort`,o,{once:!0}),a.push(i),a.sort((e,t)=>t.priority-e.priority||e.sequence-t.sequence)})}return{get disposalSignal(){return l.disposalSignal},dispose:l.dispose,get disposed(){return l.disposed},drain:l.drain,runStream(t,r={}){let i=u(r.priority??0),a=d(r.timeout)??n.defaultTimeout,s=[...r.transferables??[]],f,h=async function*(n){let c=()=>n.abort(r.signal?.reason),u,d;r.signal?.aborted?n.abort(r.signal.reason):r.signal?.addEventListener(`abort`,c,{once:!0});try{u=await m({priority:i,signal:n.signal,timeout:a,transferables:s}),l.trackActive(1),d=()=>u?.cancel((0,e.abortError)(n.signal)),n.signal.addEventListener(`abort`,d,{once:!0});let r=u.stream(t,{priority:i,signal:n.signal,timeout:a,transferables:s});for await(let e of r.iterable)yield e;await r.done,l.trackCompleted()}catch(e){throw u&&!n.signal.aborted&&!(e instanceof o)&&l.trackFailed(),e}finally{r.signal?.removeEventListener(`abort`,c),u&&(d&&n.signal.removeEventListener(`abort`,d),l.trackActive(-1),p(u),l.settleIdle())}};return{[Symbol.asyncIterator](){let e={},t=new AbortController,n,r=()=>{if(f??=e,f===e)return n??=h(t),n};return{next:()=>r()?.next()??Promise.reject(new c(`Worker streams can only be consumed once`)),return:async r=>!f||f!==e?{done:!0,value:r}:(t.abort(new o(`Stream consumer stopped`)),n?.return(r)??{done:!0,value:r}),throw:async e=>{let n=r();if(!n)throw new c(`Worker streams can only be consumed once`);return t.abort(e),n.throw(e)}}}}},get stats(){return l.stats(a.length)},get status(){return l.status()},[Symbol.asyncDispose]:()=>l.drain({}),[Symbol.dispose]:l.dispose}}function _(e={}){let{concurrency:t=1,maxQueue:n,onFull:i=`reject`,onSlotError:a,timeout:o}=e,s=t===`auto`?Math.min(512,Math.max(1,globalThis.navigator?.hardwareConcurrency??1)):t;if(!Number.isInteger(s)||s<1||s>512)throw new r('`concurrency` must be a positive integer ≤ 512 or "auto"');if(n!==void 0&&(!Number.isInteger(n)||n<1))throw new r("`maxQueue` must be a positive integer");if(i!==`reject`&&i!==`wait`)throw new r('`onFull` must be "reject" or "wait"');return d(o),{concurrency:s,maxQueue:n,onFull:i,onSlotError:a,timeout:o}}function v(e){if(typeof e!=`object`||!e)return!1;let t=e;return t.version!==1||typeof t.id!=`number`||!Number.isSafeInteger(t.id)||t.id<0?!1:t.kind===`chunk`||t.kind===`result`?`value`in t:t.kind!==`error`||typeof t.error!=`object`||t.error===null?!1:(t.error.category===void 0||t.error.category===`protocol`)&&typeof t.error.message==`string`&&typeof t.error.name==`string`&&(t.error.stack===void 0||typeof t.error.stack==`string`)}function y(e){let t=Error(e.message);return t.name=e.name,t.stack=e.stack,e.category===`protocol`?new c(e.message,{cause:t}):new a(e.message,{cause:t})}var b=class{#e;#t;#n=!1;#r;#i=0;#a;constructor(e,t){this.#t=e,this.#e=t}cancel(e){this.#r&&(this.#c(),this.#d(`reject`,e))}run(e,t,n){return this.#o(e,t,n,`run`)}stream(e,t){let n=()=>this.cancel(new o(`Stream consumer stopped`)),r=[],i=[],a=!1,s,c=e=>{let t=i.shift();t?t({done:!1,value:e}):r.push(e)},l=e=>{for(a=!0,s=e;i.length>0;)i.shift()(e===void 0?{done:!0,value:void 0}:Promise.reject(e))};return{done:this.#o(e,[...t.transferables??[]],t.timeout,`stream`,c).then(()=>l(),e=>l(e)),iterable:{[Symbol.asyncIterator]:()=>({async next(){if(r.length>0)return{done:!1,value:r.shift()};if(s!==void 0)throw s;return a?{done:!0,value:void 0}:new Promise((e,t)=>{i.push(n=>{n instanceof Promise?n.then(e,t):e(n)})})},async return(){return n(),{done:!0,value:void 0}}})}}}terminate(){this.#n=!0,this.#c(),this.#d(`reject`,new o)}#o(e,n,r,i,a){if(this.#n)return Promise.reject(new o);if(this.#r)return Promise.reject(new c(`Worker slot is already busy`));try{let o=this.#s(),l=this.#i;return this.#i=l===2**53-1?0:l+1,new Promise((u,d)=>{let f={emit:a,id:l,kind:i,reject:d,resolve:u};this.#r=f,r!==void 0&&(f.timer=setTimeout(()=>this.cancel(new s(r)),r),t(f.timer));try{o.postMessage({id:l,input:e,kind:i,version:1},n)}catch(e){this.cancel(new c(`Failed to post message to worker`,{cause:e}))}})}catch(e){return Promise.reject(e)}}#s(){if(this.#a)return this.#a;if(typeof Worker>`u`)throw new c(`Worker API is unavailable in this runtime`);try{let e=new Worker(this.#t,{type:`module`});return e.onmessage=t=>{this.#a===e&&this.#u(t.data)},e.onerror=t=>this.#l(e,new c(t.message||`Worker failed`)),e.onmessageerror=()=>this.#l(e,new c(`Worker response could not be deserialized`)),this.#a=e,e}catch(e){throw new c(`Failed to create Worker`,{cause:e})}}#c(){let e=this.#a;this.#a=void 0,e&&(e.onmessage=null,e.onerror=null,e.onmessageerror=null,e.terminate())}#l(e,t){if(this.#a===e){this.#c(),this.#d(`reject`,t);try{this.#e?.(t)}catch{}}}#u(e){if(this.#r){if(!v(e)||e.id!==this.#r.id||this.#r.kind===`run`&&e.kind===`chunk`){this.cancel(new c(`Worker returned an incompatible protocol response`));return}if(e.kind===`chunk`){this.#r.emit?.(e.value);return}if(e.kind===`error`){this.#d(`reject`,y(e.error));return}this.#d(`resolve`,e.value)}}#d(e,t){let n=this.#r;n&&(this.#r=void 0,n.timer&&clearTimeout(n.timer),e===`resolve`?n.resolve(t):n.reject(t))}};function x(e,t){let n=typeof e==`string`?e:e.href;return Array.from({length:t.concurrency},()=>new b(n,t.onSlotError))}function S(e,t={}){let n=_(t);return m(x(e,n),{concurrency:n.concurrency,defaultTimeout:n.timeout,maxQueue:n.maxQueue,onFull:n.onFull})}function C(e,t={}){let n=_(t);return g(x(e,n),{concurrency:n.concurrency,defaultTimeout:n.timeout,maxQueue:n.maxQueue,onFull:n.onFull})}exports.FamiliarError=n,exports.FamiliarInvalidOptionsError=r,exports.FamiliarQueueFullError=i,exports.FamiliarRuntimeError=c,exports.FamiliarTaskError=a,exports.FamiliarTerminatedError=o,exports.FamiliarTimeoutError=s,exports.createStreamWorker=C,exports.createWorker=S,exports.runBatch=h;
|
|
2
2
|
//# sourceMappingURL=familiar.cjs.map
|