@nxtedition/scheduler 3.1.9 → 4.0.1
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/lib/limiter.d.ts +11 -15
- package/lib/limiter.d.ts.map +1 -1
- package/lib/limiter.js +111 -107
- package/lib/limiter.js.map +1 -1
- package/lib/queue.d.ts +1 -18
- package/lib/queue.d.ts.map +1 -1
- package/lib/queue.js +10 -42
- package/lib/queue.js.map +1 -1
- package/lib/scheduler.d.ts +17 -7
- package/lib/scheduler.d.ts.map +1 -1
- package/lib/scheduler.js +111 -52
- package/lib/scheduler.js.map +1 -1
- package/package.json +4 -4
package/lib/limiter.d.ts
CHANGED
|
@@ -2,21 +2,9 @@ import { Transform, type TransformOptions } from 'node:stream';
|
|
|
2
2
|
import { Queue, type Priority } from './queue.ts';
|
|
3
3
|
export declare class Limiter extends Queue {
|
|
4
4
|
#private;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
static makeSharedState(bytesPerSecond: number): SharedArrayBuffer;
|
|
9
|
-
[Symbol.dispose](): void;
|
|
10
|
-
stream(priority?: Priority, options?: TransformOptions): Transform;
|
|
11
|
-
/** @deprecated Use `consume` instead. */
|
|
12
|
-
acquire(fn: () => unknown, bytes: number, priority?: Priority): boolean;
|
|
13
|
-
/** @deprecated Use `consume` instead. */
|
|
14
|
-
acquire<U>(fn: (opaque: U) => unknown, bytes: number, priority: Priority | undefined, opaque: U): boolean;
|
|
15
|
-
consume(fn: () => unknown, bytes: number, priority?: Priority): boolean;
|
|
16
|
-
consume<U>(fn: (opaque: U) => unknown, bytes: number, priority: Priority | undefined, opaque: U): boolean;
|
|
17
|
-
/** @deprecated Use `tryConsume` instead. */
|
|
18
|
-
tryAcquire(bytes: number): boolean;
|
|
19
|
-
tryConsume(bytes: number): boolean;
|
|
5
|
+
private stateView;
|
|
6
|
+
private pending;
|
|
7
|
+
static makeSharedState(tokensPerSecond: number): SharedArrayBuffer;
|
|
20
8
|
get stats(): {
|
|
21
9
|
tokens: number;
|
|
22
10
|
pending: number;
|
|
@@ -24,5 +12,13 @@ export declare class Limiter extends Queue {
|
|
|
24
12
|
count: number;
|
|
25
13
|
}[];
|
|
26
14
|
};
|
|
15
|
+
get tokensPerSecond(): number;
|
|
16
|
+
constructor(opts: SharedArrayBuffer | {
|
|
17
|
+
tokensPerSecond: number;
|
|
18
|
+
});
|
|
19
|
+
stream(priority?: Priority, options?: TransformOptions): Transform;
|
|
20
|
+
consume(fn: () => unknown, bytes: number, priority?: Priority): boolean;
|
|
21
|
+
consume<U>(fn: (opaque: U) => unknown, bytes: number, priority: Priority | undefined, opaque: U): boolean;
|
|
22
|
+
tryConsume(bytes: number): boolean;
|
|
27
23
|
}
|
|
28
24
|
//# sourceMappingURL=limiter.d.ts.map
|
package/lib/limiter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"limiter.d.ts","sourceRoot":"","sources":["../src/limiter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9D,OAAO,EAA4B,KAAK,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"limiter.d.ts","sourceRoot":"","sources":["../src/limiter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9D,OAAO,EAA4B,KAAK,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAA;AAQ3E,qBAAa,OAAQ,SAAQ,KAAK;;IAChC,OAAO,CAAC,SAAS,CAAY;IAE7B,OAAO,CAAC,OAAO,CAAI;IAInB,MAAM,CAAC,eAAe,CAAC,eAAe,EAAE,MAAM;IAW9C,IAAI,KAAK;;;;;;MAMR;IAED,IAAI,eAAe,WAElB;gBAEW,IAAI,EAAE,iBAAiB,GAAG;QAAE,eAAe,EAAE,MAAM,CAAA;KAAE;IAyBjE,MAAM,CAAC,QAAQ,GAAE,QAAuB,EAAE,OAAO,CAAC,EAAE,gBAAgB;IASpE,OAAO,CAAC,EAAE,EAAE,MAAM,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO;IACvE,OAAO,CAAC,CAAC,EACP,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,EAC1B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAC9B,MAAM,EAAE,CAAC,GACR,OAAO;IA6BV,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;CAqGnC"}
|
package/lib/limiter.js
CHANGED
|
@@ -1,30 +1,54 @@
|
|
|
1
1
|
import { Transform } from 'node:stream';
|
|
2
2
|
import { FastQueue, parsePriority, Queue } from "./queue.js";
|
|
3
|
-
|
|
4
|
-
const TOKENS_INDEX =
|
|
3
|
+
const LIMIT_INDEX = 0;
|
|
4
|
+
const TOKENS_INDEX = 16; // separate cache line to avoid false sharing
|
|
5
|
+
const REFILL_INDEX = 32; // separate cache line to avoid false sharing
|
|
6
|
+
const MAGIC_INDEX = 8; // within first cache line, between LIMIT and TOKENS
|
|
7
|
+
const LIMITER_MAGIC = 0x4c494d54; // ASCII "LIMT" — sanity-check sentinel written by makeSharedState
|
|
5
8
|
export class Limiter extends Queue {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
stateView;
|
|
10
|
+
pending = 0;
|
|
11
|
+
#refillTimer;
|
|
12
|
+
static makeSharedState(tokensPerSecond) {
|
|
13
|
+
if (tokensPerSecond == null || !Number.isInteger(tokensPerSecond) || tokensPerSecond < 1) {
|
|
14
|
+
throw new Error('Invalid tokensPerSecond');
|
|
15
|
+
}
|
|
16
|
+
const stateBuffer = new SharedArrayBuffer(192); // 3 cache lines, one per field
|
|
17
|
+
const stateView = new Int32Array(stateBuffer);
|
|
18
|
+
Atomics.store(stateView, MAGIC_INDEX, LIMITER_MAGIC);
|
|
19
|
+
Atomics.store(stateView, LIMIT_INDEX, tokensPerSecond);
|
|
20
|
+
return stateBuffer;
|
|
17
21
|
}
|
|
18
|
-
|
|
19
|
-
return
|
|
22
|
+
get stats() {
|
|
23
|
+
return {
|
|
24
|
+
tokens: this.stateView[TOKENS_INDEX],
|
|
25
|
+
pending: this.pending,
|
|
26
|
+
queues: this.queues.map((q) => ({ count: q.cnt })),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
get tokensPerSecond() {
|
|
30
|
+
return this.stateView[LIMIT_INDEX];
|
|
20
31
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
32
|
+
constructor(opts) {
|
|
33
|
+
super();
|
|
34
|
+
if (opts instanceof SharedArrayBuffer) {
|
|
35
|
+
if (opts.byteLength !== 192) {
|
|
36
|
+
throw new Error('Invalid SharedArrayBuffer size');
|
|
37
|
+
}
|
|
38
|
+
if (new Int32Array(opts)[MAGIC_INDEX] !== LIMITER_MAGIC) {
|
|
39
|
+
throw new Error('Invalid SharedArrayBuffer: not created by Limiter.makeSharedState');
|
|
40
|
+
}
|
|
41
|
+
this.stateView = new Int32Array(opts);
|
|
24
42
|
}
|
|
25
|
-
|
|
26
|
-
|
|
43
|
+
else {
|
|
44
|
+
const tokensPerSecond = opts?.tokensPerSecond;
|
|
45
|
+
if (tokensPerSecond == null || !Number.isInteger(tokensPerSecond) || tokensPerSecond < 1) {
|
|
46
|
+
throw new Error('Invalid tokensPerSecond');
|
|
47
|
+
}
|
|
48
|
+
this.stateView = new Int32Array(64);
|
|
49
|
+
Atomics.store(this.stateView, LIMIT_INDEX, tokensPerSecond);
|
|
27
50
|
}
|
|
51
|
+
this.#refillTimer = setTimeout(() => this.#refill(), 100).unref();
|
|
28
52
|
}
|
|
29
53
|
stream(priority = Queue.NORMAL, options) {
|
|
30
54
|
return new Transform({
|
|
@@ -34,16 +58,10 @@ export class Limiter extends Queue {
|
|
|
34
58
|
},
|
|
35
59
|
});
|
|
36
60
|
}
|
|
37
|
-
acquire(fn, bytes, priority, opaque) {
|
|
38
|
-
return this.consume(fn, bytes, priority, opaque);
|
|
39
|
-
}
|
|
40
61
|
consume(fn, bytes, priority = Queue.NORMAL, opaque) {
|
|
41
62
|
if (priority == null) {
|
|
42
63
|
priority = Queue.NORMAL;
|
|
43
64
|
}
|
|
44
|
-
if ((!this.stateView || isMainThread) && this.#tokens < bytes) {
|
|
45
|
-
this.#refill();
|
|
46
|
-
}
|
|
47
65
|
if (this.pending === 0 && this.#tryConsumeTokens(bytes)) {
|
|
48
66
|
fn(opaque);
|
|
49
67
|
return true;
|
|
@@ -51,109 +69,95 @@ export class Limiter extends Queue {
|
|
|
51
69
|
const p = parsePriority(priority);
|
|
52
70
|
const queue = this.queues[p + 3];
|
|
53
71
|
this.pending += 1;
|
|
54
|
-
this.deferred += 1;
|
|
55
72
|
queue.arr.push(fn, bytes, opaque);
|
|
56
73
|
queue.cnt += 1;
|
|
74
|
+
this.#refill();
|
|
57
75
|
return false;
|
|
58
76
|
}
|
|
59
|
-
/** @deprecated Use `tryConsume` instead. */
|
|
60
|
-
tryAcquire(bytes) {
|
|
61
|
-
return this.tryConsume(bytes);
|
|
62
|
-
}
|
|
63
77
|
tryConsume(bytes) {
|
|
64
|
-
if (
|
|
78
|
+
if (this.stateView[TOKENS_INDEX] < bytes) {
|
|
65
79
|
this.#refill();
|
|
66
80
|
}
|
|
67
81
|
return this.pending === 0 && this.#tryConsumeTokens(bytes);
|
|
68
82
|
}
|
|
69
|
-
get stats() {
|
|
70
|
-
return {
|
|
71
|
-
tokens: this.#tokens,
|
|
72
|
-
pending: this.pending,
|
|
73
|
-
queues: this.queues.map((q) => ({ count: q.cnt })),
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
get #tokens() {
|
|
77
|
-
return this.stateView ? this.stateView[TOKENS_INDEX] : this.#singleThreadTokens;
|
|
78
|
-
}
|
|
79
83
|
#tryConsumeTokens(bytes) {
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
// Nothing in the queue, and enough tokens to run immediately.
|
|
87
|
-
if (this.stateView) {
|
|
88
|
-
Atomics.sub(this.stateView, TOKENS_INDEX, bytes);
|
|
84
|
+
// Zero-byte tasks consume no tokens and must always succeed, even when the bucket
|
|
85
|
+
// is in debt (tokens < 0) due to the soft-limit race described below.
|
|
86
|
+
if (bytes === 0) {
|
|
87
|
+
return true;
|
|
89
88
|
}
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
// There is a possibility that this check passes for two threads, but should only
|
|
90
|
+
// have passed for one of them. Given that the concurrency limit is a soft limit,
|
|
91
|
+
// this is not a problem and will just mean that we might briefly have tokens < 0
|
|
92
|
+
// until the next refill repays the debt.
|
|
93
|
+
if (this.stateView[TOKENS_INDEX] < bytes) {
|
|
94
|
+
return false;
|
|
92
95
|
}
|
|
96
|
+
Atomics.sub(this.stateView, TOKENS_INDEX, bytes);
|
|
93
97
|
return true;
|
|
94
98
|
}
|
|
95
99
|
#refill() {
|
|
96
|
-
const currentToken = this
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
else {
|
|
109
|
-
this.#singleThreadTokens += newTokens;
|
|
110
|
-
}
|
|
111
|
-
this.#lastRefillTime = now;
|
|
112
|
-
if (!this.stateView || isMainThread) {
|
|
113
|
-
this.#drain();
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
#drain() {
|
|
117
|
-
while (this.pending > 0) {
|
|
118
|
-
let queue = this.getNextQueue();
|
|
119
|
-
if (queue == null || queue.cnt === 0) {
|
|
120
|
-
break;
|
|
100
|
+
const currentToken = this.stateView[TOKENS_INDEX];
|
|
101
|
+
const refillTime = this.stateView[REFILL_INDEX];
|
|
102
|
+
// Use performance.now() | 0 (integer ms since process start) to avoid the
|
|
103
|
+
// Int32 overflow that Date.now() (~1.74 trillion) would cause.
|
|
104
|
+
const now = performance.now() | 0;
|
|
105
|
+
if (Atomics.compareExchange(this.stateView, REFILL_INDEX, refillTime, now) === refillTime) {
|
|
106
|
+
const elapsed = refillTime === 0 ? Infinity : (now - refillTime) / 1000;
|
|
107
|
+
// Guard against negative elapsed (Int32 wrap-around every ~24.8 days).
|
|
108
|
+
// Skip Infinity concurrency — tokens are not tracked for that case.
|
|
109
|
+
if (elapsed > 0) {
|
|
110
|
+
const newTokens = Math.min(this.tokensPerSecond - currentToken, elapsed * this.tokensPerSecond);
|
|
111
|
+
Atomics.add(this.stateView, TOKENS_INDEX, newTokens | 0);
|
|
121
112
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
queue
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
while (this.pending > 0 && this.stateView[TOKENS_INDEX] > 0) {
|
|
116
|
+
let queue = this.getNextQueue();
|
|
117
|
+
if (queue == null || queue.cnt === 0) {
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
if (!this.#tryConsumeTokens(queue.arr[queue.idx + 1])) {
|
|
121
|
+
// The preferred queue's front task doesn't fit; scan all queues from
|
|
122
|
+
// highest to lowest priority for any task whose byte requirement fits
|
|
123
|
+
// within available tokens (starvation prevention).
|
|
124
|
+
queue = null;
|
|
125
|
+
for (let p = this.queues.length - 1; p >= 0; p--) {
|
|
126
|
+
const q = this.queues[p];
|
|
127
|
+
if (q.cnt === 0) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (this.#tryConsumeTokens(q.arr[q.idx + 1])) {
|
|
131
|
+
queue = q;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
131
134
|
}
|
|
132
|
-
if (
|
|
133
|
-
|
|
134
|
-
break;
|
|
135
|
+
if (queue == null) {
|
|
136
|
+
return;
|
|
135
137
|
}
|
|
136
138
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
+
const fn = queue.arr[queue.idx];
|
|
140
|
+
const opaque = queue.arr[queue.idx + 2];
|
|
141
|
+
queue.arr[queue.idx++] = null;
|
|
142
|
+
queue.arr[queue.idx++] = null;
|
|
143
|
+
queue.arr[queue.idx++] = null;
|
|
144
|
+
queue.cnt -= 1;
|
|
145
|
+
this.pending -= 1;
|
|
146
|
+
if (queue.cnt === 0) {
|
|
147
|
+
queue.idx = 0;
|
|
148
|
+
queue.arr.length = 0;
|
|
139
149
|
}
|
|
150
|
+
else if (queue.idx > 1024) {
|
|
151
|
+
queue.arr.splice(0, queue.idx);
|
|
152
|
+
queue.idx = 0;
|
|
153
|
+
}
|
|
154
|
+
fn(opaque);
|
|
140
155
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
queue.arr[queue.idx++] = null;
|
|
146
|
-
queue.cnt -= 1;
|
|
147
|
-
this.pending -= 1;
|
|
148
|
-
if (queue.cnt === 0) {
|
|
149
|
-
queue.idx = 0;
|
|
150
|
-
queue.arr.length = 0;
|
|
151
|
-
}
|
|
152
|
-
else if (queue.idx > 1024) {
|
|
153
|
-
queue.arr.splice(0, queue.idx);
|
|
154
|
-
queue.idx = 0;
|
|
156
|
+
}
|
|
157
|
+
finally {
|
|
158
|
+
if (this.pending > 0) {
|
|
159
|
+
this.#refillTimer.refresh();
|
|
155
160
|
}
|
|
156
|
-
fn(opaque);
|
|
157
161
|
}
|
|
158
162
|
}
|
|
159
163
|
}
|
package/lib/limiter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"limiter.js","sourceRoot":"","sources":["../src/limiter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAyB,MAAM,aAAa,CAAA;AAC9D,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,EAAiB,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"limiter.js","sourceRoot":"","sources":["../src/limiter.ts"],"names":[],"mappings":"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"}
|
package/lib/queue.d.ts
CHANGED
|
@@ -7,7 +7,6 @@ export type NumberPriority = -3 | -2 | -1 | 0 | 1 | 2 | 3;
|
|
|
7
7
|
export type Priority = NumberPriority | 'lowest' | 'lower' | 'low' | 'normal' | 'high' | 'higher' | 'highest';
|
|
8
8
|
export declare function parsePriority(p: string | number): NumberPriority;
|
|
9
9
|
export declare class Queue {
|
|
10
|
-
#private;
|
|
11
10
|
static readonly LOWEST = -3;
|
|
12
11
|
static readonly LOWER = -2;
|
|
13
12
|
static readonly LOW = -1;
|
|
@@ -15,24 +14,8 @@ export declare class Queue {
|
|
|
15
14
|
static readonly HIGH = 1;
|
|
16
15
|
static readonly HIGHER = 2;
|
|
17
16
|
static readonly HIGHEST = 3;
|
|
18
|
-
|
|
19
|
-
protected running: number;
|
|
20
|
-
protected pending: number;
|
|
21
|
-
protected counter: number;
|
|
22
|
-
protected releasing: boolean;
|
|
23
|
-
protected deferred: number;
|
|
17
|
+
private counter;
|
|
24
18
|
protected queues: FastQueue[];
|
|
25
|
-
get concurrency(): number;
|
|
26
|
-
get stats(): {
|
|
27
|
-
pending: number;
|
|
28
|
-
queues: {
|
|
29
|
-
count: number;
|
|
30
|
-
}[];
|
|
31
|
-
};
|
|
32
19
|
protected getNextQueue(): FastQueue | null;
|
|
33
|
-
static makeSharedState(concurrency: number): SharedArrayBuffer;
|
|
34
|
-
constructor(opts: SharedArrayBuffer | {
|
|
35
|
-
concurrency?: number;
|
|
36
|
-
});
|
|
37
20
|
}
|
|
38
21
|
//# sourceMappingURL=queue.d.ts.map
|
package/lib/queue.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAAA,qBAAa,SAAS;IACpB,GAAG,SAAI;IACP,GAAG,SAAI;IACP,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,CAAK;CACzB;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;AAEzD,MAAM,MAAM,QAAQ,GAChB,cAAc,GACd,QAAQ,GACR,OAAO,GACP,KAAK,GACL,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,SAAS,CAAA;AAEb,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,cAAc,CA8BhE;AAID,qBAAa,KAAK;IAChB,MAAM,CAAC,QAAQ,CAAC,MAAM,MAAK;IAC3B,MAAM,CAAC,QAAQ,CAAC,KAAK,MAAK;IAC1B,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAK;IACxB,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAI;IAC1B,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAI;IACxB,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAI;IAC1B,MAAM,CAAC,QAAQ,CAAC,OAAO,KAAI;IAE3B,OAAO,CAAC,OAAO,CAAI;IAGnB,SAAS,CAAC,MAAM,cAQf;IAED,SAAS,CAAC,YAAY;CAqCvB"}
|
package/lib/queue.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const CONCURRENCY_INDEX = 1;
|
|
2
1
|
export class FastQueue {
|
|
3
2
|
idx = 0;
|
|
4
3
|
cnt = 0;
|
|
@@ -54,13 +53,7 @@ export class Queue {
|
|
|
54
53
|
static HIGH = 1;
|
|
55
54
|
static HIGHER = 2;
|
|
56
55
|
static HIGHEST = 3;
|
|
57
|
-
#concurrency;
|
|
58
|
-
stateView;
|
|
59
|
-
running = 0;
|
|
60
|
-
pending = 0;
|
|
61
56
|
counter = 0;
|
|
62
|
-
releasing = false;
|
|
63
|
-
deferred = 0;
|
|
64
57
|
// Queues are stored in order of priority, so index == priority + 3
|
|
65
58
|
queues = [
|
|
66
59
|
new FastQueue(), // 0 lowest
|
|
@@ -71,17 +64,7 @@ export class Queue {
|
|
|
71
64
|
new FastQueue(), // 5 higher
|
|
72
65
|
new FastQueue(), // 6 highest
|
|
73
66
|
];
|
|
74
|
-
get concurrency() {
|
|
75
|
-
return this.#concurrency;
|
|
76
|
-
}
|
|
77
|
-
get stats() {
|
|
78
|
-
return {
|
|
79
|
-
pending: this.pending,
|
|
80
|
-
queues: this.queues.map((q) => ({ count: q.cnt })),
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
67
|
getNextQueue() {
|
|
84
|
-
let queue = null;
|
|
85
68
|
this.counter = (this.counter + 1) & maxInt;
|
|
86
69
|
let idx = this.queues.length - 1;
|
|
87
70
|
if (this.counter & 0b0000001) {
|
|
@@ -105,34 +88,19 @@ export class Queue {
|
|
|
105
88
|
else if (this.counter & 0b1000000) {
|
|
106
89
|
idx = 0; // lowest: 0.78%
|
|
107
90
|
}
|
|
108
|
-
for (let n = idx; n >= 0
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
queue = this.queues[n];
|
|
113
|
-
}
|
|
114
|
-
return queue;
|
|
115
|
-
}
|
|
116
|
-
static makeSharedState(concurrency) {
|
|
117
|
-
if (concurrency != null && (concurrency < 0 || !Number.isInteger(concurrency))) {
|
|
118
|
-
throw new Error('Invalid concurrency');
|
|
119
|
-
}
|
|
120
|
-
const stateBuffer = new SharedArrayBuffer(64);
|
|
121
|
-
const stateView = new Int32Array(stateBuffer);
|
|
122
|
-
Atomics.store(stateView, CONCURRENCY_INDEX, concurrency ?? -1);
|
|
123
|
-
return stateBuffer;
|
|
124
|
-
}
|
|
125
|
-
constructor(opts) {
|
|
126
|
-
if (opts instanceof SharedArrayBuffer) {
|
|
127
|
-
this.stateView = new Int32Array(opts);
|
|
128
|
-
this.#concurrency = Atomics.load(this.stateView, CONCURRENCY_INDEX);
|
|
129
|
-
if (this.#concurrency === -1) {
|
|
130
|
-
this.#concurrency = Infinity;
|
|
91
|
+
for (let n = idx; n >= 0; n--) {
|
|
92
|
+
const q = this.queues[n];
|
|
93
|
+
if (q.cnt > 0) {
|
|
94
|
+
return q;
|
|
131
95
|
}
|
|
132
96
|
}
|
|
133
|
-
|
|
134
|
-
|
|
97
|
+
for (let n = this.queues.length - 1; n > idx; n--) {
|
|
98
|
+
const q = this.queues[n];
|
|
99
|
+
if (q.cnt > 0) {
|
|
100
|
+
return q;
|
|
101
|
+
}
|
|
135
102
|
}
|
|
103
|
+
return null;
|
|
136
104
|
}
|
|
137
105
|
}
|
|
138
106
|
//# sourceMappingURL=queue.js.map
|
package/lib/queue.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAAA,MAAM,
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"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"}
|
package/lib/scheduler.d.ts
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
import { Queue, type Priority } from './queue.ts';
|
|
2
2
|
export declare class Scheduler extends Queue {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
#private;
|
|
4
|
+
private stateView;
|
|
5
|
+
private readonly shared;
|
|
6
|
+
private running;
|
|
7
|
+
private pending;
|
|
8
|
+
private releasing;
|
|
9
|
+
static makeSharedState(concurrency: number): SharedArrayBuffer;
|
|
10
|
+
get concurrency(): number;
|
|
9
11
|
get stats(): {
|
|
10
|
-
deferred: number;
|
|
11
12
|
running: number;
|
|
12
13
|
pending: number;
|
|
13
14
|
queues: {
|
|
14
15
|
count: number;
|
|
15
16
|
}[];
|
|
16
17
|
};
|
|
18
|
+
constructor(opts: SharedArrayBuffer | {
|
|
19
|
+
concurrency?: number;
|
|
20
|
+
});
|
|
21
|
+
run<T>(fn: () => PromiseLike<T> | T, priority?: Priority): Promise<T>;
|
|
22
|
+
run<T, U>(fn: (opaque: U) => PromiseLike<T> | T, priority: Priority, opaque: U): Promise<T>;
|
|
23
|
+
acquire(fn: () => unknown, priority?: Priority): boolean;
|
|
24
|
+
acquire<U>(fn: (opaque: U) => unknown, priority: Priority | undefined, opaque: U): boolean;
|
|
25
|
+
tryAcquire(): boolean;
|
|
26
|
+
release: () => void;
|
|
17
27
|
}
|
|
18
28
|
//# sourceMappingURL=scheduler.d.ts.map
|
package/lib/scheduler.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAA;AAc3E,qBAAa,SAAU,SAAQ,KAAK;;IAClC,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IAGjC,OAAO,CAAC,OAAO,CAAI;IACnB,OAAO,CAAC,OAAO,CAAI;IACnB,OAAO,CAAC,SAAS,CAAQ;IAmBzB,MAAM,CAAC,eAAe,CAAC,WAAW,EAAE,MAAM;IAc1C,IAAI,WAAW,WAGd;IAED,IAAI,KAAK;;;;;;MAMR;gBAEW,IAAI,EAAE,iBAAiB,GAAG;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE;IA8B9D,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC;IACrE,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAkB3F,OAAO,CAAC,EAAE,EAAE,MAAM,OAAO,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO;IACxD,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAAE,MAAM,EAAE,CAAC,GAAG,OAAO;IAsB1F,UAAU,IAAI,OAAO;IA2BrB,OAAO,aAsDN;CACF"}
|
package/lib/scheduler.js
CHANGED
|
@@ -1,88 +1,155 @@
|
|
|
1
1
|
import { FastQueue, parsePriority, Queue } from "./queue.js";
|
|
2
2
|
const RUNNING_INDEX = 0;
|
|
3
|
+
const CONCURRENCY_INDEX = 16; // separate cache line to avoid false sharing
|
|
4
|
+
const MAGIC_INDEX = 8; // within first cache line, between RUNNING and CONCURRENCY
|
|
5
|
+
const SCHEDULER_MAGIC = 0x5ca4edde; // sanity-check sentinel written by makeSharedState
|
|
3
6
|
export class Scheduler extends Queue {
|
|
7
|
+
stateView;
|
|
8
|
+
shared;
|
|
9
|
+
#concurrency; // MAX_SAFE_INTEGER = unlimited; cached to avoid repeated getter + array read
|
|
10
|
+
running = 0;
|
|
11
|
+
pending = 0;
|
|
12
|
+
releasing = false;
|
|
13
|
+
// Pre-bound method used as the acquire callback in run()'s slow path.
|
|
14
|
+
// Defined as an arrow function so it captures `this` without a per-call closure.
|
|
15
|
+
#runTask = ({ resolve, reject, fn, opaque }) => {
|
|
16
|
+
try {
|
|
17
|
+
const result = fn(opaque);
|
|
18
|
+
if (result != null && typeof result.then === 'function') {
|
|
19
|
+
void result.then(resolve, reject).then(this.release);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
resolve(result);
|
|
23
|
+
this.release();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
reject(err); // eslint-disable-line @typescript-eslint/prefer-promise-reject-errors
|
|
28
|
+
this.release();
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
static makeSharedState(concurrency) {
|
|
32
|
+
if (concurrency === Infinity) {
|
|
33
|
+
concurrency = -1;
|
|
34
|
+
}
|
|
35
|
+
else if (concurrency == null || !Number.isInteger(concurrency) || concurrency < 0) {
|
|
36
|
+
throw new Error('Invalid concurrency');
|
|
37
|
+
}
|
|
38
|
+
const stateBuffer = new SharedArrayBuffer(128); // 2 cache lines, one per field
|
|
39
|
+
const stateView = new Int32Array(stateBuffer);
|
|
40
|
+
Atomics.store(stateView, MAGIC_INDEX, SCHEDULER_MAGIC);
|
|
41
|
+
Atomics.store(stateView, CONCURRENCY_INDEX, concurrency);
|
|
42
|
+
return stateBuffer;
|
|
43
|
+
}
|
|
44
|
+
get concurrency() {
|
|
45
|
+
const c = this.stateView[CONCURRENCY_INDEX];
|
|
46
|
+
return c === -1 ? Infinity : c;
|
|
47
|
+
}
|
|
48
|
+
get stats() {
|
|
49
|
+
return {
|
|
50
|
+
running: this.running,
|
|
51
|
+
pending: this.pending,
|
|
52
|
+
queues: this.queues.map((q) => ({ count: q.cnt })),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
constructor(opts) {
|
|
56
|
+
super();
|
|
57
|
+
if (opts instanceof SharedArrayBuffer) {
|
|
58
|
+
if (opts.byteLength !== 128) {
|
|
59
|
+
throw new Error('Invalid SharedArrayBuffer size');
|
|
60
|
+
}
|
|
61
|
+
if (new Int32Array(opts)[MAGIC_INDEX] !== SCHEDULER_MAGIC) {
|
|
62
|
+
throw new Error('Invalid SharedArrayBuffer: not created by Scheduler.makeSharedState');
|
|
63
|
+
}
|
|
64
|
+
this.stateView = new Int32Array(opts);
|
|
65
|
+
this.shared = true;
|
|
66
|
+
const sc = Atomics.load(this.stateView, CONCURRENCY_INDEX);
|
|
67
|
+
this.#concurrency = sc < 0 ? Number.MAX_SAFE_INTEGER : sc;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
let concurrency = opts?.concurrency ?? Infinity;
|
|
71
|
+
if (concurrency === Infinity) {
|
|
72
|
+
concurrency = -1;
|
|
73
|
+
}
|
|
74
|
+
else if (!Number.isInteger(concurrency) || concurrency < 0) {
|
|
75
|
+
throw new Error('Invalid concurrency');
|
|
76
|
+
}
|
|
77
|
+
this.stateView = new Int32Array(64);
|
|
78
|
+
Atomics.store(this.stateView, CONCURRENCY_INDEX, concurrency);
|
|
79
|
+
this.shared = false;
|
|
80
|
+
this.#concurrency = concurrency < 0 ? Number.MAX_SAFE_INTEGER : concurrency;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
4
83
|
run(fn, priority = Queue.NORMAL, opaque) {
|
|
5
84
|
return new Promise((resolve, reject) => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
catch (err) {
|
|
18
|
-
reject(err); // eslint-disable-line @typescript-eslint/prefer-promise-reject-errors
|
|
19
|
-
this.release();
|
|
20
|
-
}
|
|
21
|
-
}, priority, opaque);
|
|
85
|
+
const ctx = { resolve, reject, fn, opaque };
|
|
86
|
+
if (this.tryAcquire()) {
|
|
87
|
+
// Fast path: slot available immediately — call #runTask directly.
|
|
88
|
+
this.#runTask(ctx);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
// Slow path: no slot — queue the work via acquire.
|
|
92
|
+
this.acquire(this.#runTask, priority, ctx);
|
|
93
|
+
}
|
|
22
94
|
});
|
|
23
95
|
}
|
|
24
96
|
acquire(fn, priority = Queue.NORMAL, opaque) {
|
|
25
97
|
const p = priority == null ? Queue.NORMAL : parsePriority(priority);
|
|
26
98
|
const queue = this.queues[p + 3];
|
|
27
|
-
if (this.
|
|
28
|
-
// Make sure we are always running at least one local job even if we might globally over subscribe.
|
|
29
|
-
if (this.running < 1) {
|
|
30
|
-
Atomics.add(this.stateView, RUNNING_INDEX, 1);
|
|
31
|
-
this.running += 1;
|
|
32
|
-
fn(opaque);
|
|
33
|
-
return true;
|
|
34
|
-
}
|
|
35
|
-
// We use non atomic access here as an optimization and treat the concurrency limit as a soft limit.
|
|
36
|
-
if (this.stateView[RUNNING_INDEX] < this.concurrency) {
|
|
37
|
-
Atomics.add(this.stateView, RUNNING_INDEX, 1);
|
|
38
|
-
this.running += 1;
|
|
39
|
-
fn(opaque);
|
|
40
|
-
return true;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
else if (this.running < this.concurrency) {
|
|
44
|
-
this.running += 1;
|
|
99
|
+
if (this.tryAcquire()) {
|
|
45
100
|
fn(opaque);
|
|
46
101
|
return true;
|
|
47
102
|
}
|
|
48
103
|
queue.arr.push(fn, opaque);
|
|
49
104
|
queue.cnt += 1;
|
|
50
|
-
this.deferred += 1;
|
|
51
105
|
this.pending += 1;
|
|
52
106
|
return false;
|
|
53
107
|
}
|
|
54
108
|
tryAcquire() {
|
|
55
|
-
if (this.
|
|
56
|
-
|
|
109
|
+
if (this.shared) {
|
|
110
|
+
// In shared-buffer mode, other workers may hold global slots so we guarantee at least one
|
|
111
|
+
// local job runs regardless (starvation prevention). Not applicable to non-shared mode where
|
|
112
|
+
// concurrency=0 should queue everything.
|
|
113
|
+
if (this.running < 1) {
|
|
57
114
|
Atomics.add(this.stateView, RUNNING_INDEX, 1);
|
|
58
115
|
this.running += 1;
|
|
59
116
|
return true;
|
|
60
117
|
}
|
|
118
|
+
// We use non-atomic access here as an optimization and treat the concurrency limit as a soft limit.
|
|
119
|
+
if (this.stateView[RUNNING_INDEX] < this.#concurrency) {
|
|
120
|
+
Atomics.add(this.stateView, RUNNING_INDEX, 1);
|
|
121
|
+
this.running += 1;
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
return false;
|
|
61
125
|
}
|
|
62
|
-
|
|
126
|
+
// Non-shared: JS is single-threaded, no atomics needed.
|
|
127
|
+
if (this.running < this.#concurrency) {
|
|
63
128
|
this.running += 1;
|
|
64
129
|
return true;
|
|
65
130
|
}
|
|
66
131
|
return false;
|
|
67
132
|
}
|
|
68
133
|
release = () => {
|
|
134
|
+
const shared = this.shared;
|
|
69
135
|
let running;
|
|
70
136
|
if (this.running > 0) {
|
|
71
137
|
this.running -= 1;
|
|
72
|
-
running =
|
|
138
|
+
running = shared ? Atomics.sub(this.stateView, RUNNING_INDEX, 1) - 1 : this.running;
|
|
73
139
|
}
|
|
74
140
|
else {
|
|
75
141
|
// Gracefully handle user error...
|
|
76
|
-
running =
|
|
142
|
+
running = shared ? Atomics.load(this.stateView, RUNNING_INDEX) : this.running;
|
|
77
143
|
}
|
|
78
144
|
if (this.pending === 0 || this.releasing) {
|
|
79
145
|
return;
|
|
80
146
|
}
|
|
147
|
+
const c = this.#concurrency; // cache for loop
|
|
81
148
|
try {
|
|
82
149
|
this.releasing = true;
|
|
83
|
-
while (this.pending > 0 && (this.running === 0 || running <
|
|
150
|
+
while (this.pending > 0 && (this.running === 0 || running < c)) {
|
|
84
151
|
const queue = this.getNextQueue();
|
|
85
|
-
if (queue == null
|
|
152
|
+
if (queue == null) {
|
|
86
153
|
throw new Error('Invariant violation: pending > 0 but no tasks in queues');
|
|
87
154
|
}
|
|
88
155
|
const fn = queue.arr[queue.idx];
|
|
@@ -100,25 +167,17 @@ export class Scheduler extends Queue {
|
|
|
100
167
|
}
|
|
101
168
|
this.pending -= 1;
|
|
102
169
|
this.running += 1;
|
|
103
|
-
if (
|
|
170
|
+
if (shared) {
|
|
104
171
|
Atomics.add(this.stateView, RUNNING_INDEX, 1);
|
|
105
172
|
}
|
|
106
173
|
fn(opaque);
|
|
107
174
|
// Re-read running after fn() in case it synchronously called release()
|
|
108
|
-
running =
|
|
175
|
+
running = shared ? Atomics.load(this.stateView, RUNNING_INDEX) : this.running;
|
|
109
176
|
}
|
|
110
177
|
}
|
|
111
178
|
finally {
|
|
112
179
|
this.releasing = false;
|
|
113
180
|
}
|
|
114
181
|
};
|
|
115
|
-
get stats() {
|
|
116
|
-
return {
|
|
117
|
-
deferred: this.deferred,
|
|
118
|
-
running: this.running,
|
|
119
|
-
pending: this.pending,
|
|
120
|
-
queues: this.queues.map((q) => ({ count: q.cnt })),
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
182
|
}
|
|
124
183
|
//# sourceMappingURL=scheduler.js.map
|
package/lib/scheduler.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,EAAiB,MAAM,YAAY,CAAA;AAE3E,MAAM,aAAa,GAAG,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,EAAiB,MAAM,YAAY,CAAA;AAE3E,MAAM,aAAa,GAAG,CAAC,CAAA;AACvB,MAAM,iBAAiB,GAAG,EAAE,CAAA,CAAC,6CAA6C;AAC1E,MAAM,WAAW,GAAG,CAAC,CAAA,CAAC,2DAA2D;AACjF,MAAM,eAAe,GAAG,UAAU,CAAA,CAAC,mDAAmD;AAStF,MAAM,OAAO,SAAU,SAAQ,KAAK;IAC1B,SAAS,CAAY;IACZ,MAAM,CAAU;IACjC,YAAY,CAAS,CAAC,6EAA6E;IAE3F,OAAO,GAAG,CAAC,CAAA;IACX,OAAO,GAAG,CAAC,CAAA;IACX,SAAS,GAAG,KAAK,CAAA;IAEzB,sEAAsE;IACtE,iFAAiF;IACjF,QAAQ,GAAG,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAU,EAAE,EAAE;QACrD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,CAAA;YACzB,IAAI,MAAM,IAAI,IAAI,IAAI,OAAQ,MAA+B,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAClF,KAAM,MAA+B,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAChF,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,CAAA;gBACf,IAAI,CAAC,OAAO,EAAE,CAAA;YAChB,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,GAAG,CAAC,CAAA,CAAC,sEAAsE;YAClF,IAAI,CAAC,OAAO,EAAE,CAAA;QAChB,CAAC;IACH,CAAC,CAAA;IAED,MAAM,CAAC,eAAe,CAAC,WAAmB;QACxC,IAAI,WAAW,KAAK,QAAQ,EAAE,CAAC;YAC7B,WAAW,GAAG,CAAC,CAAC,CAAA;QAClB,CAAC;aAAM,IAAI,WAAW,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;YACpF,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAA;QACxC,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,iBAAiB,CAAC,GAAG,CAAC,CAAA,CAAC,+BAA+B;QAC9E,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAA;QAC7C,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,WAAW,EAAE,eAAe,CAAC,CAAA;QACtD,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,iBAAiB,EAAE,WAAW,CAAC,CAAA;QACxD,OAAO,WAAW,CAAA;IACpB,CAAC;IAED,IAAI,WAAW;QACb,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAA;QAC3C,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;IAChC,CAAC;IAED,IAAI,KAAK;QACP,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;SACnD,CAAA;IACH,CAAC;IAED,YAAY,IAAkD;QAC5D,KAAK,EAAE,CAAA;QAEP,IAAI,IAAI,YAAY,iBAAiB,EAAE,CAAC;YACtC,IAAI,IAAI,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;YACnD,CAAC;YACD,IAAI,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,KAAK,eAAe,EAAE,CAAC;gBAC1D,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAA;YACxF,CAAC;YACD,IAAI,CAAC,SAAS,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAA;YACrC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;YAClB,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAA;YAC1D,IAAI,CAAC,YAAY,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAA;QAC3D,CAAC;aAAM,CAAC;YACN,IAAI,WAAW,GAAG,IAAI,EAAE,WAAW,IAAI,QAAQ,CAAA;YAE/C,IAAI,WAAW,KAAK,QAAQ,EAAE,CAAC;gBAC7B,WAAW,GAAG,CAAC,CAAC,CAAA;YAClB,CAAC;iBAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;gBAC7D,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAA;YACxC,CAAC;YAED,IAAI,CAAC,SAAS,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAA;YACnC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,EAAE,WAAW,CAAC,CAAA;YAC7D,IAAI,CAAC,MAAM,GAAG,KAAK,CAAA;YACnB,IAAI,CAAC,YAAY,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAA;QAC7E,CAAC;IACH,CAAC;IAID,GAAG,CACD,EAAsC,EACtC,WAAqB,KAAK,CAAC,MAAM,EACjC,MAAU;QAEV,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACxC,MAAM,GAAG,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAY,CAAA;YACrD,IAAI,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;gBACtB,kEAAkE;gBAClE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;YACpB,CAAC;iBAAM,CAAC;gBACN,mDAAmD;gBACnD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAA;YAC5C,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAID,OAAO,CACL,EAA2B,EAC3B,WAAiC,KAAK,CAAC,MAAM,EAC7C,MAAU;QAEV,MAAM,CAAC,GAAG,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;QACnE,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QAEhC,IAAI,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;YACtB,EAAE,CAAC,MAAM,CAAC,CAAA;YACV,OAAO,IAAI,CAAA;QACb,CAAC;QAED,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;QAC1B,KAAK,CAAC,GAAG,IAAI,CAAC,CAAA;QAEd,IAAI,CAAC,OAAO,IAAI,CAAC,CAAA;QAEjB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,UAAU;QACR,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,0FAA0F;YAC1F,6FAA6F;YAC7F,yCAAyC;YACzC,IAAI,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;gBACrB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC,CAAA;gBAC7C,IAAI,CAAC,OAAO,IAAI,CAAC,CAAA;gBACjB,OAAO,IAAI,CAAA;YACb,CAAC;YACD,oGAAoG;YACpG,IAAI,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC,CAAA;gBAC7C,IAAI,CAAC,OAAO,IAAI,CAAC,CAAA;gBACjB,OAAO,IAAI,CAAA;YACb,CAAC;YACD,OAAO,KAAK,CAAA;QACd,CAAC;QAED,wDAAwD;QACxD,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YACrC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAA;YACjB,OAAO,IAAI,CAAA;QACb,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,GAAG,GAAG,EAAE;QACb,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QAC1B,IAAI,OAAe,CAAA;QACnB,IAAI,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;YACrB,IAAI,CAAC,OAAO,IAAI,CAAC,CAAA;YACjB,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAA;QACrF,CAAC;aAAM,CAAC;YACN,kCAAkC;YAClC,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAA;QAC/E,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACzC,OAAM;QACR,CAAC;QAED,MAAM,CAAC,GAAG,IAAI,CAAC,YAAY,CAAA,CAAC,iBAAiB;QAC7C,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,GAAG,IAAI,CAAA;YACrB,OAAO,IAAI,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC,EAAE,CAAC;gBAC/D,MAAM,KAAK,GAAqB,IAAI,CAAC,YAAY,EAAE,CAAA;gBAEnD,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;oBAClB,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAA;gBAC5E,CAAC;gBAED,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAkC,CAAA;gBAChE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAA;gBAC7B,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;gBACnC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAA;gBAC7B,KAAK,CAAC,GAAG,IAAI,CAAC,CAAA;gBAEd,IAAI,KAAK,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;oBACpB,KAAK,CAAC,GAAG,GAAG,CAAC,CAAA;oBACb,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAA;gBACtB,CAAC;qBAAM,IAAI,KAAK,CAAC,GAAG,GAAG,IAAI,EAAE,CAAC;oBAC5B,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;oBAC9B,KAAK,CAAC,GAAG,GAAG,CAAC,CAAA;gBACf,CAAC;gBAED,IAAI,CAAC,OAAO,IAAI,CAAC,CAAA;gBACjB,IAAI,CAAC,OAAO,IAAI,CAAC,CAAA;gBAEjB,IAAI,MAAM,EAAE,CAAC;oBACX,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC,CAAA;gBAC/C,CAAC;gBAED,EAAE,CAAC,MAAM,CAAC,CAAA;gBAEV,uEAAuE;gBACvE,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAA;YAC/E,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,SAAS,GAAG,KAAK,CAAA;QACxB,CAAC;IACH,CAAC,CAAA;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxtedition/scheduler",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -26,12 +26,12 @@
|
|
|
26
26
|
"test:types": "tsd"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@types/node": "^25.
|
|
29
|
+
"@types/node": "^25.5.0",
|
|
30
30
|
"amaroc": "^1.0.1",
|
|
31
|
-
"oxlint-tsgolint": "^0.
|
|
31
|
+
"oxlint-tsgolint": "^0.17.0",
|
|
32
32
|
"rimraf": "^6.1.3",
|
|
33
33
|
"tsd": "^0.33.0",
|
|
34
34
|
"typescript": "^5.9.3"
|
|
35
35
|
},
|
|
36
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "7c9c7457c885c644c7a1e70ef894d4727ce240d6"
|
|
37
37
|
}
|