@nmtjs/common 0.16.1 → 0.17.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -1
- package/README.md +41 -1
- package/dist/abort-signal.d.ts +5 -0
- package/dist/{abortSignal.js → abort-signal.js} +2 -3
- package/dist/abort-signal.js.map +1 -0
- package/dist/error.d.ts +13 -0
- package/dist/error.js +20 -0
- package/dist/error.js.map +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/operation-queue.d.ts +26 -0
- package/dist/operation-queue.js +102 -0
- package/dist/operation-queue.js.map +1 -0
- package/dist/pool.d.ts +18 -0
- package/dist/pool.js +106 -0
- package/dist/pool.js.map +1 -0
- package/dist/semaphore.d.ts +13 -0
- package/dist/semaphore.js +56 -0
- package/dist/semaphore.js.map +1 -0
- package/dist/streams.d.ts +6 -6
- package/dist/streams.js +2 -2
- package/dist/streams.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/utils.d.ts +5 -12
- package/dist/utils.js +5 -23
- package/dist/utils.js.map +1 -1
- package/package.json +1 -4
- package/src/{abortSignal.ts → abort-signal.ts} +4 -6
- package/src/error.ts +44 -0
- package/src/index.ts +5 -1
- package/src/operation-queue.ts +134 -0
- package/src/pool.ts +111 -0
- package/src/semaphore.ts +63 -0
- package/src/streams.ts +10 -8
- package/src/types.ts +8 -11
- package/src/utils.ts +12 -34
- package/dist/abortSignal.d.ts +0 -5
- package/dist/abortSignal.js.map +0 -1
package/LICENSE.md
CHANGED
|
@@ -4,4 +4,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
|
4
4
|
|
|
5
5
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
6
|
|
|
7
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,9 +1,49 @@
|
|
|
1
1
|
# NeemataJS - RPC application server for real-time applications (proof of concept)
|
|
2
2
|
|
|
3
3
|
### Built with following in mind:
|
|
4
|
+
|
|
4
5
|
- transport-agnostic (like WebSockets, WebTransport, .etc)
|
|
5
6
|
- format-agnostic (like JSON, MessagePack, BSON, .etc)
|
|
6
7
|
- binary data streaming and event subscriptions
|
|
7
8
|
- contract-based API
|
|
8
9
|
- end-to-end type safety
|
|
9
|
-
- CPU-intensive task execution on separate workers
|
|
10
|
+
- CPU-intensive task execution on separate workers
|
|
11
|
+
|
|
12
|
+
## Neem CLI draft
|
|
13
|
+
|
|
14
|
+
`neem build` compiles config, app entries, plugin entries, and plugin-declared
|
|
15
|
+
artifacts into `dist` by default. It writes an internal `neem.manifest.json`
|
|
16
|
+
with relative artifact paths.
|
|
17
|
+
|
|
18
|
+
`neem start` consumes an existing built output directory. It reads the manifest
|
|
19
|
+
for executable artifacts and serialized runtime config, registers built plugin
|
|
20
|
+
hooks, and starts app workers in production mode.
|
|
21
|
+
|
|
22
|
+
`neem dev` uses `.neem` by default as a build-like watched output directory. It
|
|
23
|
+
uses the same manifest shape as `start`, restarts app workers after successful
|
|
24
|
+
config/app rebuilds, reloads plugin hooks after plugin entry rebuilds, and keeps
|
|
25
|
+
existing workers alive on rebuild errors.
|
|
26
|
+
|
|
27
|
+
## Service integration tests
|
|
28
|
+
|
|
29
|
+
Service-backed package integration tests live beside package owners under
|
|
30
|
+
`packages/*/tests/integration`.
|
|
31
|
+
|
|
32
|
+
Local services:
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
docker compose up -d --wait redis valkey kafka
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Run required service tests:
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
NMTJS_REQUIRE_SERVICE_TESTS=1 \
|
|
42
|
+
REDIS_URL=redis://localhost:6379 \
|
|
43
|
+
VALKEY_URL=redis://localhost:6380 \
|
|
44
|
+
KAFKA_BROKERS=localhost:9092 \
|
|
45
|
+
pnpm run test:integration:services
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Without service env, these tests skip in normal package/root test runs. In CI,
|
|
49
|
+
`NMTJS_REQUIRE_SERVICE_TESTS=1` makes missing service env fail instead of skip.
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference lib="dom" />
|
|
2
1
|
/**
|
|
3
2
|
* Little helper to combine multiple AbortSignals into one,
|
|
4
3
|
* with handling of null or undefined values.
|
|
@@ -12,7 +11,7 @@ export function anyAbortSignal(...signals) {
|
|
|
12
11
|
return filtered[0];
|
|
13
12
|
}
|
|
14
13
|
else {
|
|
15
|
-
return AbortSignal.any(filtered);
|
|
14
|
+
return globalThis.AbortSignal.any(filtered);
|
|
16
15
|
}
|
|
17
16
|
}
|
|
18
|
-
//# sourceMappingURL=
|
|
17
|
+
//# sourceMappingURL=abort-signal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abort-signal.js","sourceRoot":"","sources":["../src/abort-signal.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,GAAG,OAAsD;IAEzD,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAA6B,CAAA;IACpE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;IAC7C,CAAC;SAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAA;IACpB,CAAC;SAAM,CAAC;QACN,OAAO,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC7C,CAAC;AACH,CAAC"}
|
package/dist/error.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type SerializedError = {
|
|
2
|
+
readonly name?: string;
|
|
3
|
+
readonly message: string;
|
|
4
|
+
readonly stack?: string;
|
|
5
|
+
readonly cause?: SerializedError;
|
|
6
|
+
};
|
|
7
|
+
export declare const MAX_SERIALIZED_ERROR_DEPTH = 5;
|
|
8
|
+
export type SerializeErrorOptions = {
|
|
9
|
+
depth?: number;
|
|
10
|
+
omitUndefinedStack?: boolean;
|
|
11
|
+
fallback?: (value: unknown) => SerializedError;
|
|
12
|
+
};
|
|
13
|
+
export declare function serializeError(value: unknown, options?: SerializeErrorOptions): SerializedError;
|
package/dist/error.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Depth-limited so a cyclic cause chain cannot recurse forever.
|
|
2
|
+
export const MAX_SERIALIZED_ERROR_DEPTH = 5;
|
|
3
|
+
export function serializeError(value, options = {}) {
|
|
4
|
+
const { depth = MAX_SERIALIZED_ERROR_DEPTH, omitUndefinedStack = false, fallback, } = options;
|
|
5
|
+
if (value instanceof Error) {
|
|
6
|
+
const cause = value.cause;
|
|
7
|
+
return {
|
|
8
|
+
name: value.name,
|
|
9
|
+
message: value.message,
|
|
10
|
+
...(omitUndefinedStack && value.stack === undefined
|
|
11
|
+
? {}
|
|
12
|
+
: { stack: value.stack }),
|
|
13
|
+
...(cause === undefined || depth <= 0
|
|
14
|
+
? {}
|
|
15
|
+
: { cause: serializeError(cause, { ...options, depth: depth - 1 }) }),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
return fallback ? fallback(value) : { message: String(value) };
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAOA,gEAAgE;AAChE,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAA;AAU3C,MAAM,UAAU,cAAc,CAC5B,KAAc,EACd,OAAO,GAA0B,EAAE;IAEnC,MAAM,EACJ,KAAK,GAAG,0BAA0B,EAClC,kBAAkB,GAAG,KAAK,EAC1B,QAAQ,GACT,GAAG,OAAO,CAAA;IAEX,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAI,KAA8C,CAAC,KAAK,CAAA;QACnE,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,GAAG,CAAC,kBAAkB,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;gBACjD,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;YAC3B,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,IAAI,CAAC;gBACnC,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,EAAE,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;SACxE,CAAA;IACH,CAAC;IAED,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;AAChE,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './abort-signal.ts';
|
|
2
2
|
export * from './constants.ts';
|
|
3
|
+
export * from './error.ts';
|
|
4
|
+
export * from './operation-queue.ts';
|
|
5
|
+
export * from './pool.ts';
|
|
6
|
+
export * from './semaphore.ts';
|
|
3
7
|
export * from './streams.ts';
|
|
4
8
|
export * from './types.ts';
|
|
5
9
|
export * from './utils.ts';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './abort-signal.js';
|
|
2
2
|
export * from './constants.js';
|
|
3
|
+
export * from './error.js';
|
|
4
|
+
export * from './operation-queue.js';
|
|
5
|
+
export * from './pool.js';
|
|
6
|
+
export * from './semaphore.js';
|
|
3
7
|
export * from './streams.js';
|
|
4
8
|
export * from './types.js';
|
|
5
9
|
export * from './utils.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,YAAY,CAAA;AAC1B,cAAc,sBAAsB,CAAA;AACpC,cAAc,WAAW,CAAA;AACzB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { MaybePromise } from './types.ts';
|
|
2
|
+
export type OperationQueueStrategy = 'serial' | 'latest';
|
|
3
|
+
export type OperationQueueOptions = {
|
|
4
|
+
strategy?: OperationQueueStrategy;
|
|
5
|
+
};
|
|
6
|
+
export declare class OperationSupersededError extends Error {
|
|
7
|
+
constructor(message?: string);
|
|
8
|
+
}
|
|
9
|
+
export declare class OperationQueue {
|
|
10
|
+
private readonly strategy;
|
|
11
|
+
private tail;
|
|
12
|
+
private count;
|
|
13
|
+
private runningLatest;
|
|
14
|
+
private latestOperation;
|
|
15
|
+
private readonly idleWaiters;
|
|
16
|
+
constructor({ strategy }?: OperationQueueOptions);
|
|
17
|
+
get pending(): number;
|
|
18
|
+
get busy(): boolean;
|
|
19
|
+
run<T>(task: () => MaybePromise<T>): Promise<T>;
|
|
20
|
+
waitIdle(): Promise<void>;
|
|
21
|
+
private runSerial;
|
|
22
|
+
private runLatest;
|
|
23
|
+
private runLatestOperations;
|
|
24
|
+
private runLatestOperation;
|
|
25
|
+
private finishOperation;
|
|
26
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { createFuture } from './utils.js';
|
|
2
|
+
export class OperationSupersededError extends Error {
|
|
3
|
+
constructor(message = 'Operation superseded') {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = 'OperationSupersededError';
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export class OperationQueue {
|
|
9
|
+
strategy;
|
|
10
|
+
tail = Promise.resolve();
|
|
11
|
+
count = 0;
|
|
12
|
+
runningLatest = false;
|
|
13
|
+
latestOperation;
|
|
14
|
+
idleWaiters = new Set();
|
|
15
|
+
constructor({ strategy = 'serial' } = {}) {
|
|
16
|
+
this.strategy = strategy;
|
|
17
|
+
}
|
|
18
|
+
get pending() {
|
|
19
|
+
return this.count;
|
|
20
|
+
}
|
|
21
|
+
get busy() {
|
|
22
|
+
return this.count > 0;
|
|
23
|
+
}
|
|
24
|
+
run(task) {
|
|
25
|
+
return this.strategy === 'latest'
|
|
26
|
+
? this.runLatest(task)
|
|
27
|
+
: this.runSerial(task);
|
|
28
|
+
}
|
|
29
|
+
async waitIdle() {
|
|
30
|
+
if (!this.busy)
|
|
31
|
+
return;
|
|
32
|
+
await new Promise((resolve) => {
|
|
33
|
+
this.idleWaiters.add(resolve);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
runSerial(task) {
|
|
37
|
+
this.count++;
|
|
38
|
+
const result = this.tail.then(task, task);
|
|
39
|
+
this.tail = result
|
|
40
|
+
.catch(() => undefined)
|
|
41
|
+
.finally(() => {
|
|
42
|
+
this.finishOperation();
|
|
43
|
+
});
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
runLatest(task) {
|
|
47
|
+
this.count++;
|
|
48
|
+
const { operation, promise } = createQueuedOperation(task);
|
|
49
|
+
if (this.runningLatest) {
|
|
50
|
+
const previous = this.latestOperation;
|
|
51
|
+
if (previous) {
|
|
52
|
+
previous.reject(new OperationSupersededError());
|
|
53
|
+
this.finishOperation();
|
|
54
|
+
}
|
|
55
|
+
this.latestOperation = operation;
|
|
56
|
+
return promise;
|
|
57
|
+
}
|
|
58
|
+
this.runningLatest = true;
|
|
59
|
+
void this.runLatestOperations(operation);
|
|
60
|
+
return promise;
|
|
61
|
+
}
|
|
62
|
+
async runLatestOperations(operation) {
|
|
63
|
+
let current = operation;
|
|
64
|
+
while (current) {
|
|
65
|
+
await this.runLatestOperation(current);
|
|
66
|
+
current = this.latestOperation;
|
|
67
|
+
this.latestOperation = undefined;
|
|
68
|
+
}
|
|
69
|
+
this.runningLatest = false;
|
|
70
|
+
}
|
|
71
|
+
async runLatestOperation(operation) {
|
|
72
|
+
try {
|
|
73
|
+
operation.resolve(await operation.task());
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
operation.reject(error);
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
this.finishOperation();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
finishOperation() {
|
|
83
|
+
this.count--;
|
|
84
|
+
if (this.count > 0)
|
|
85
|
+
return;
|
|
86
|
+
for (const resolve of this.idleWaiters)
|
|
87
|
+
resolve();
|
|
88
|
+
this.idleWaiters.clear();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function createQueuedOperation(task) {
|
|
92
|
+
const future = createFuture();
|
|
93
|
+
return {
|
|
94
|
+
operation: {
|
|
95
|
+
task: task,
|
|
96
|
+
resolve: future.resolve,
|
|
97
|
+
reject: future.reject,
|
|
98
|
+
},
|
|
99
|
+
promise: future.promise,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=operation-queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operation-queue.js","sourceRoot":"","sources":["../src/operation-queue.ts"],"names":[],"mappings":"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"}
|
package/dist/pool.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface PoolOptions {
|
|
2
|
+
timeout?: number;
|
|
3
|
+
}
|
|
4
|
+
export declare class PoolError extends Error {
|
|
5
|
+
}
|
|
6
|
+
export declare class Pool<T = unknown> {
|
|
7
|
+
#private;
|
|
8
|
+
private readonly options;
|
|
9
|
+
constructor(options?: PoolOptions);
|
|
10
|
+
add(item: T): void;
|
|
11
|
+
remove(item: T): void;
|
|
12
|
+
capture(timeout?: number | undefined): Promise<T>;
|
|
13
|
+
next(exclusive?: boolean, timeout?: number | undefined): Promise<T>;
|
|
14
|
+
release(item: T): undefined;
|
|
15
|
+
isFree(item: T): boolean;
|
|
16
|
+
get items(): T[];
|
|
17
|
+
}
|
|
18
|
+
export {};
|
package/dist/pool.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
export class PoolError extends Error {
|
|
2
|
+
}
|
|
3
|
+
// Ported from https://github.com/metarhia/metautil
|
|
4
|
+
export class Pool {
|
|
5
|
+
options;
|
|
6
|
+
#items = [];
|
|
7
|
+
#free = [];
|
|
8
|
+
#queue = [];
|
|
9
|
+
#current = 0;
|
|
10
|
+
#size = 0;
|
|
11
|
+
#available = 0;
|
|
12
|
+
constructor(options = {}) {
|
|
13
|
+
this.options = options;
|
|
14
|
+
}
|
|
15
|
+
add(item) {
|
|
16
|
+
if (this.#items.includes(item))
|
|
17
|
+
throw new PoolError('Item already exists');
|
|
18
|
+
this.#size++;
|
|
19
|
+
this.#available++;
|
|
20
|
+
this.#items.push(item);
|
|
21
|
+
this.#free.push(true);
|
|
22
|
+
}
|
|
23
|
+
remove(item) {
|
|
24
|
+
if (this.#size === 0)
|
|
25
|
+
throw new PoolError('Pool is empty');
|
|
26
|
+
const index = this.#items.indexOf(item);
|
|
27
|
+
if (index < 0)
|
|
28
|
+
throw new PoolError('Item is not in the pool');
|
|
29
|
+
const isCaptured = this.isFree(item);
|
|
30
|
+
if (isCaptured)
|
|
31
|
+
this.#available--;
|
|
32
|
+
this.#size--;
|
|
33
|
+
this.#current--;
|
|
34
|
+
this.#items.splice(index, 1);
|
|
35
|
+
this.#free.splice(index, 1);
|
|
36
|
+
}
|
|
37
|
+
capture(timeout = this.options.timeout) {
|
|
38
|
+
return this.next(true, timeout);
|
|
39
|
+
}
|
|
40
|
+
async next(exclusive = false, timeout = this.options.timeout) {
|
|
41
|
+
if (this.#size === 0)
|
|
42
|
+
throw new PoolError('Pool is empty');
|
|
43
|
+
if (this.#available === 0) {
|
|
44
|
+
return new Promise((resolve, reject) => {
|
|
45
|
+
const waiting = {
|
|
46
|
+
resolve: (item) => {
|
|
47
|
+
if (exclusive)
|
|
48
|
+
this.#capture(item);
|
|
49
|
+
resolve(item);
|
|
50
|
+
},
|
|
51
|
+
timer: undefined,
|
|
52
|
+
};
|
|
53
|
+
if (timeout) {
|
|
54
|
+
waiting.timer = setTimeout(() => {
|
|
55
|
+
waiting.resolve = undefined;
|
|
56
|
+
this.#queue.shift();
|
|
57
|
+
reject(new PoolError('Next item timeout'));
|
|
58
|
+
}, timeout);
|
|
59
|
+
}
|
|
60
|
+
this.#queue.push(waiting);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
let item;
|
|
64
|
+
let free = false;
|
|
65
|
+
do {
|
|
66
|
+
item = this.#items[this.#current];
|
|
67
|
+
free = this.#free[this.#current];
|
|
68
|
+
this.#current++;
|
|
69
|
+
if (this.#current >= this.#size)
|
|
70
|
+
this.#current = 0;
|
|
71
|
+
} while (typeof item === 'undefined' || !free);
|
|
72
|
+
if (exclusive)
|
|
73
|
+
this.#capture(item);
|
|
74
|
+
return item;
|
|
75
|
+
}
|
|
76
|
+
release(item) {
|
|
77
|
+
const index = this.#items.indexOf(item);
|
|
78
|
+
if (index < 0)
|
|
79
|
+
throw new PoolError('Unexpected item');
|
|
80
|
+
if (this.#free[index])
|
|
81
|
+
throw new PoolError('Unable to release not captured item');
|
|
82
|
+
if (this.#queue.length > 0) {
|
|
83
|
+
const { resolve, timer } = this.#queue.shift();
|
|
84
|
+
clearTimeout(timer);
|
|
85
|
+
if (resolve)
|
|
86
|
+
return void setTimeout(resolve, 0, item);
|
|
87
|
+
}
|
|
88
|
+
this.#free[index] = true;
|
|
89
|
+
this.#available++;
|
|
90
|
+
}
|
|
91
|
+
isFree(item) {
|
|
92
|
+
const index = this.#items.indexOf(item);
|
|
93
|
+
if (index < 0)
|
|
94
|
+
return false;
|
|
95
|
+
return this.#free[index];
|
|
96
|
+
}
|
|
97
|
+
get items() {
|
|
98
|
+
return [...this.#items];
|
|
99
|
+
}
|
|
100
|
+
#capture(item) {
|
|
101
|
+
const index = this.#items.indexOf(item);
|
|
102
|
+
this.#free[index] = false;
|
|
103
|
+
this.#available--;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=pool.js.map
|
package/dist/pool.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pool.js","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare class SemaphoreError extends Error {
|
|
2
|
+
}
|
|
3
|
+
export declare class Semaphore {
|
|
4
|
+
private readonly size;
|
|
5
|
+
private readonly timeout;
|
|
6
|
+
private counter;
|
|
7
|
+
private readonly queue;
|
|
8
|
+
constructor(concurrency: number, size?: number, timeout?: number);
|
|
9
|
+
enter(): Promise<void>;
|
|
10
|
+
leave(): void;
|
|
11
|
+
get isEmpty(): boolean;
|
|
12
|
+
get queueLength(): number;
|
|
13
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export class SemaphoreError extends Error {
|
|
2
|
+
}
|
|
3
|
+
// Ported from https://github.com/metarhia/metautil
|
|
4
|
+
export class Semaphore {
|
|
5
|
+
size;
|
|
6
|
+
timeout;
|
|
7
|
+
counter;
|
|
8
|
+
queue = [];
|
|
9
|
+
constructor(concurrency, size = 0, timeout = 0) {
|
|
10
|
+
this.size = size;
|
|
11
|
+
this.timeout = timeout;
|
|
12
|
+
this.counter = concurrency;
|
|
13
|
+
}
|
|
14
|
+
enter() {
|
|
15
|
+
if (this.counter > 0) {
|
|
16
|
+
this.counter--;
|
|
17
|
+
return Promise.resolve();
|
|
18
|
+
}
|
|
19
|
+
else if (this.queue.length >= this.size) {
|
|
20
|
+
return Promise.reject(new SemaphoreError('Queue is full'));
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
const waiting = { resolve };
|
|
25
|
+
waiting.timer = setTimeout(() => {
|
|
26
|
+
waiting.resolve = undefined;
|
|
27
|
+
this.queue.shift();
|
|
28
|
+
reject(new SemaphoreError('Timeout'));
|
|
29
|
+
}, this.timeout);
|
|
30
|
+
this.queue.push(waiting);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
leave() {
|
|
35
|
+
if (this.queue.length === 0) {
|
|
36
|
+
this.counter++;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
const item = this.queue.shift();
|
|
40
|
+
if (item) {
|
|
41
|
+
const { resolve, timer } = item;
|
|
42
|
+
if (timer)
|
|
43
|
+
clearTimeout(timer);
|
|
44
|
+
if (resolve)
|
|
45
|
+
setTimeout(resolve, 0);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
get isEmpty() {
|
|
50
|
+
return this.queue.length === 0;
|
|
51
|
+
}
|
|
52
|
+
get queueLength() {
|
|
53
|
+
return this.queue.length;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=semaphore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semaphore.js","sourceRoot":"","sources":["../src/semaphore.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,cAAe,SAAQ,KAAK;CAAG;AAE5C,mDAAmD;AACnD,MAAM,OAAO,SAAS;IAOD,IAAI;IACJ,OAAO;IAPlB,OAAO,CAAQ;IAEN,KAAK,GAAyB,EAAE,CAAA;IAEjD,YACE,WAAmB,EACF,IAAI,GAAW,CAAC,EAChB,OAAO,GAAW,CAAC;oBADnB,IAAI;uBACJ,OAAO;QAExB,IAAI,CAAC,OAAO,GAAG,WAAW,CAAA;IAC5B,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;YACrB,IAAI,CAAC,OAAO,EAAE,CAAA;YACd,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;QAC1B,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC1C,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,cAAc,CAAC,eAAe,CAAC,CAAC,CAAA;QAC5D,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACrC,MAAM,OAAO,GAAuB,EAAE,OAAO,EAAE,CAAA;gBAC/C,OAAO,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;oBAC9B,OAAO,CAAC,OAAO,GAAG,SAAS,CAAA;oBAC3B,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;oBAClB,MAAM,CAAC,IAAI,cAAc,CAAC,SAAS,CAAC,CAAC,CAAA;gBACvC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;gBAChB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAC1B,CAAC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC,OAAO,EAAE,CAAA;QAChB,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;YAC/B,IAAI,IAAI,EAAE,CAAC;gBACT,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAA;gBAC/B,IAAI,KAAK;oBAAE,YAAY,CAAC,KAAK,CAAC,CAAA;gBAC9B,IAAI,OAAO;oBAAE,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;YACrC,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAA;IAChC,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAA;IAC1B,CAAC;CACF"}
|
package/dist/streams.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { MaybePromise } from './types.ts';
|
|
2
2
|
export interface DuplexStreamOptions<O = unknown, I = O> {
|
|
3
|
-
start?: (controller: ReadableStreamDefaultController<O>) => void;
|
|
4
|
-
pull?: (controller: ReadableStreamDefaultController<O>) => MaybePromise<void>;
|
|
3
|
+
start?: (controller: globalThis.ReadableStreamDefaultController<O>) => void;
|
|
4
|
+
pull?: (controller: globalThis.ReadableStreamDefaultController<O>) => MaybePromise<void>;
|
|
5
5
|
cancel?: (reason: unknown) => void;
|
|
6
6
|
transform?: (chunk: I) => O;
|
|
7
7
|
close?: () => void;
|
|
8
|
-
readableStrategy?: QueuingStrategy<O>;
|
|
9
|
-
writableStrategy?: QueuingStrategy<I>;
|
|
8
|
+
readableStrategy?: globalThis.QueuingStrategy<O>;
|
|
9
|
+
writableStrategy?: globalThis.QueuingStrategy<I>;
|
|
10
10
|
}
|
|
11
11
|
export declare class DuplexStream<O = unknown, I = O> {
|
|
12
|
-
readonly readable: ReadableStream<O>;
|
|
13
|
-
readonly writable: WritableStream<I>;
|
|
12
|
+
readonly readable: globalThis.ReadableStream<O>;
|
|
13
|
+
readonly writable: globalThis.WritableStream<I>;
|
|
14
14
|
constructor(options?: DuplexStreamOptions<O, I>);
|
|
15
15
|
}
|
package/dist/streams.js
CHANGED
|
@@ -3,11 +3,11 @@ export class DuplexStream {
|
|
|
3
3
|
readable;
|
|
4
4
|
writable;
|
|
5
5
|
constructor(options = {}) {
|
|
6
|
-
this.readable = new ReadableStream({
|
|
6
|
+
this.readable = new globalThis.ReadableStream({
|
|
7
7
|
cancel: options.cancel,
|
|
8
8
|
start: (controller) => {
|
|
9
9
|
// @ts-expect-error
|
|
10
|
-
this.writable = new WritableStream({
|
|
10
|
+
this.writable = new globalThis.WritableStream({
|
|
11
11
|
write: (_chunk) => {
|
|
12
12
|
const chunk = options?.transform
|
|
13
13
|
? options?.transform(_chunk)
|
package/dist/streams.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"streams.js","sourceRoot":"","sources":["../src/streams.ts"],"names":[],"mappings":"AAAA,0DAA0D;
|
|
1
|
+
{"version":3,"file":"streams.js","sourceRoot":"","sources":["../src/streams.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAgB1D,MAAM,OAAO,YAAY;IACd,QAAQ,CAA8B;IACtC,QAAQ,CAA+B;IAEhD,YAAY,OAAO,GAA8B,EAAE;QACjD,IAAI,CAAC,QAAQ,GAAG,IAAI,UAAU,CAAC,cAAc,CAC3C;YACE,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,KAAK,EAAE,CAAC,UAAU,EAAE,EAAE;gBACpB,mBAAmB;gBACnB,IAAI,CAAC,QAAQ,GAAG,IAAI,UAAU,CAAC,cAAc,CAC3C;oBACE,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE;wBAChB,MAAM,KAAK,GAAG,OAAO,EAAE,SAAS;4BAC9B,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC;4BAC5B,CAAC,CAAC,MAAM,CAAA;wBACV,UAAU,CAAC,OAAO,CAAC,KAAU,CAAC,CAAA;oBAChC,CAAC;oBACD,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC;oBAC3C,KAAK,EAAE,GAAG,EAAE;wBACV,OAAO,EAAE,KAAK,EAAE,EAAE,CAAA;wBAClB,IAAI,CAAC;4BACH,UAAU,CAAC,KAAK,EAAE,CAAA;wBACpB,CAAC;wBAAC,MAAM,CAAC;4BACP,sDAAsD;wBACxD,CAAC;oBACH,CAAC;iBACF,EACD,OAAO,CAAC,gBAAgB,CACzB,CAAA;gBACD,OAAO,CAAC,KAAK,EAAE,CAAC,UAAU,CAAC,CAAA;YAC7B,CAAC;YACD,IAAI,EAAE,OAAO,EAAE,IAAI;SACpB,EACD,OAAO,CAAC,gBAAgB,CACzB,CAAA;IACH,CAAC;CACF"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
declare const TSErrorSymbol: unique symbol;
|
|
2
2
|
export type TSError<ErrorMessage extends string = string, TagType = never> = `TS Error: ${ErrorMessage}` & {
|
|
3
3
|
[TSErrorSymbol]: true;
|
|
4
|
+
readonly __tag?: TagType;
|
|
4
5
|
};
|
|
5
6
|
export interface TypeProvider {
|
|
6
7
|
readonly input: unknown;
|
package/dist/utils.d.ts
CHANGED
|
@@ -11,25 +11,18 @@ export declare function range(count: number, start?: number): {
|
|
|
11
11
|
};
|
|
12
12
|
};
|
|
13
13
|
};
|
|
14
|
-
export
|
|
15
|
-
clear: () => any;
|
|
16
|
-
};
|
|
17
|
-
export interface Future<T = any> {
|
|
18
|
-
promise: Promise<T>;
|
|
19
|
-
resolve: (value: T) => void;
|
|
20
|
-
reject: (error: any) => void;
|
|
21
|
-
}
|
|
14
|
+
export type Future<T = any> = PromiseWithResolvers<T>;
|
|
22
15
|
export declare function createFuture<T>(): Future<T>;
|
|
23
|
-
export declare function onAbort<T extends Callback>(signal: AbortSignal, cb: T, reason?: any): () => void;
|
|
16
|
+
export declare function onAbort<T extends Callback>(signal: globalThis.AbortSignal, cb: T, reason?: any): () => void;
|
|
24
17
|
export declare function withTimeout(value: Promise<any>, timeout: number, timeoutError: Error): Promise<any>;
|
|
25
18
|
export declare function tryCaptureStackTrace(depth?: number): string | undefined;
|
|
26
19
|
export declare function isGeneratorFunction(value: any): value is GeneratorFunction;
|
|
27
20
|
export declare function isAsyncGeneratorFunction(value: any): value is AsyncGeneratorFunction;
|
|
28
21
|
export declare function isAsyncIterable(value: any): value is AsyncIterable<unknown>;
|
|
29
22
|
export declare function throwError(message: string, ErrorClass?: ErrorConstructor): never;
|
|
30
|
-
export declare function once(target: EventTarget, event: string): Promise<void>;
|
|
31
|
-
export declare function onceAborted(signal: AbortSignal): Promise<void>;
|
|
32
|
-
export declare function isAbortError(error: any):
|
|
23
|
+
export declare function once(target: globalThis.EventTarget, event: string): Promise<void>;
|
|
24
|
+
export declare function onceAborted(signal: globalThis.AbortSignal): Promise<void>;
|
|
25
|
+
export declare function isAbortError(error: any): error is Error;
|
|
33
26
|
/**
|
|
34
27
|
* Very simple pattern matching function.
|
|
35
28
|
*/
|
package/dist/utils.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference lib="dom" />
|
|
2
1
|
export const noopFn = () => { };
|
|
3
2
|
export function merge(...objects) {
|
|
4
3
|
return Object.assign({}, ...objects);
|
|
@@ -7,7 +6,7 @@ export function unique(array) {
|
|
|
7
6
|
return new Set(array).values();
|
|
8
7
|
}
|
|
9
8
|
export function defer(cb, ms = 1, ...args) {
|
|
10
|
-
return new Promise((resolve, reject) => setTimeout(async () => {
|
|
9
|
+
return new Promise((resolve, reject) => globalThis.setTimeout(async () => {
|
|
11
10
|
try {
|
|
12
11
|
resolve(await cb(...args));
|
|
13
12
|
}
|
|
@@ -33,25 +32,8 @@ export function range(count, start = 0) {
|
|
|
33
32
|
},
|
|
34
33
|
};
|
|
35
34
|
}
|
|
36
|
-
export function debounce(cb, delay) {
|
|
37
|
-
let timer;
|
|
38
|
-
const clear = () => timer && clearTimeout(timer);
|
|
39
|
-
const fn = (...args) => {
|
|
40
|
-
clear();
|
|
41
|
-
timer = setTimeout(cb, delay, ...args);
|
|
42
|
-
};
|
|
43
|
-
return Object.assign(fn, { clear });
|
|
44
|
-
}
|
|
45
|
-
// TODO: Promise.withResolvers?
|
|
46
35
|
export function createFuture() {
|
|
47
|
-
|
|
48
|
-
let reject;
|
|
49
|
-
const promise = new Promise((res, rej) => {
|
|
50
|
-
resolve = res;
|
|
51
|
-
reject = rej;
|
|
52
|
-
});
|
|
53
|
-
// @ts-expect-error
|
|
54
|
-
return { resolve, reject, promise };
|
|
36
|
+
return Promise.withResolvers();
|
|
55
37
|
}
|
|
56
38
|
export function onAbort(signal, cb, reason) {
|
|
57
39
|
const listener = () => cb(reason ?? signal.reason);
|
|
@@ -61,11 +43,11 @@ export function onAbort(signal, cb, reason) {
|
|
|
61
43
|
export function withTimeout(value, timeout, timeoutError) {
|
|
62
44
|
return Promise.race([
|
|
63
45
|
value,
|
|
64
|
-
new Promise((_, reject) => setTimeout(reject, timeout, timeoutError)),
|
|
46
|
+
new Promise((_, reject) => globalThis.setTimeout(reject, timeout, timeoutError)),
|
|
65
47
|
]);
|
|
66
48
|
}
|
|
67
49
|
export function tryCaptureStackTrace(depth = 0) {
|
|
68
|
-
const traceLines = new Error().stack?.split('\n');
|
|
50
|
+
const traceLines = new Error().stack?.split('\n').slice(depth);
|
|
69
51
|
if (traceLines) {
|
|
70
52
|
for (const traceLine of traceLines) {
|
|
71
53
|
const trimmed = traceLine.trim();
|
|
@@ -104,7 +86,7 @@ export function isAbortError(error) {
|
|
|
104
86
|
error.name === 'AbortError' &&
|
|
105
87
|
'code' in error &&
|
|
106
88
|
(error.code === 20 || error.code === 'ABORT_ERR')) ||
|
|
107
|
-
(error instanceof Event && error.type === 'abort'));
|
|
89
|
+
(error instanceof globalThis.Event && error.type === 'abort'));
|
|
108
90
|
}
|
|
109
91
|
/**
|
|
110
92
|
* Very simple pattern matching function.
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
/// <reference lib="dom" />
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* Little helper to combine multiple AbortSignals into one,
|
|
5
3
|
* with handling of null or undefined values.
|
|
6
4
|
*/
|
|
7
5
|
export function anyAbortSignal(
|
|
8
|
-
...signals: (AbortSignal | undefined | null)[]
|
|
9
|
-
): AbortSignal {
|
|
10
|
-
const filtered = signals.filter(Boolean) as AbortSignal[]
|
|
6
|
+
...signals: (globalThis.AbortSignal | undefined | null)[]
|
|
7
|
+
): globalThis.AbortSignal {
|
|
8
|
+
const filtered = signals.filter(Boolean) as globalThis.AbortSignal[]
|
|
11
9
|
if (filtered.length === 0) {
|
|
12
10
|
throw new Error('No AbortSignals provided')
|
|
13
11
|
} else if (filtered.length === 1) {
|
|
14
12
|
return filtered[0]
|
|
15
13
|
} else {
|
|
16
|
-
return AbortSignal.any(filtered)
|
|
14
|
+
return globalThis.AbortSignal.any(filtered)
|
|
17
15
|
}
|
|
18
16
|
}
|
package/src/error.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export type SerializedError = {
|
|
2
|
+
readonly name?: string
|
|
3
|
+
readonly message: string
|
|
4
|
+
readonly stack?: string
|
|
5
|
+
readonly cause?: SerializedError
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// Depth-limited so a cyclic cause chain cannot recurse forever.
|
|
9
|
+
export const MAX_SERIALIZED_ERROR_DEPTH = 5
|
|
10
|
+
|
|
11
|
+
export type SerializeErrorOptions = {
|
|
12
|
+
depth?: number
|
|
13
|
+
// Whether to drop the `stack` key when it is undefined instead of emitting it.
|
|
14
|
+
omitUndefinedStack?: boolean
|
|
15
|
+
// Handles values that are not Error instances (callers differ: normalize vs. passthrough).
|
|
16
|
+
fallback?: (value: unknown) => SerializedError
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function serializeError(
|
|
20
|
+
value: unknown,
|
|
21
|
+
options: SerializeErrorOptions = {},
|
|
22
|
+
): SerializedError {
|
|
23
|
+
const {
|
|
24
|
+
depth = MAX_SERIALIZED_ERROR_DEPTH,
|
|
25
|
+
omitUndefinedStack = false,
|
|
26
|
+
fallback,
|
|
27
|
+
} = options
|
|
28
|
+
|
|
29
|
+
if (value instanceof Error) {
|
|
30
|
+
const cause = (value as Error & { readonly cause?: unknown }).cause
|
|
31
|
+
return {
|
|
32
|
+
name: value.name,
|
|
33
|
+
message: value.message,
|
|
34
|
+
...(omitUndefinedStack && value.stack === undefined
|
|
35
|
+
? {}
|
|
36
|
+
: { stack: value.stack }),
|
|
37
|
+
...(cause === undefined || depth <= 0
|
|
38
|
+
? {}
|
|
39
|
+
: { cause: serializeError(cause, { ...options, depth: depth - 1 }) }),
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return fallback ? fallback(value) : { message: String(value) }
|
|
44
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './abort-signal.ts'
|
|
2
2
|
export * from './constants.ts'
|
|
3
|
+
export * from './error.ts'
|
|
4
|
+
export * from './operation-queue.ts'
|
|
5
|
+
export * from './pool.ts'
|
|
6
|
+
export * from './semaphore.ts'
|
|
3
7
|
export * from './streams.ts'
|
|
4
8
|
export * from './types.ts'
|
|
5
9
|
export * from './utils.ts'
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { MaybePromise } from './types.ts'
|
|
2
|
+
import { createFuture } from './utils.ts'
|
|
3
|
+
|
|
4
|
+
export type OperationQueueStrategy = 'serial' | 'latest'
|
|
5
|
+
|
|
6
|
+
export type OperationQueueOptions = { strategy?: OperationQueueStrategy }
|
|
7
|
+
|
|
8
|
+
type QueuedOperation = {
|
|
9
|
+
task: () => MaybePromise<unknown>
|
|
10
|
+
resolve: (value: unknown) => void
|
|
11
|
+
reject: (error: unknown) => void
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class OperationSupersededError extends Error {
|
|
15
|
+
constructor(message = 'Operation superseded') {
|
|
16
|
+
super(message)
|
|
17
|
+
this.name = 'OperationSupersededError'
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export class OperationQueue {
|
|
22
|
+
private readonly strategy: OperationQueueStrategy
|
|
23
|
+
private tail: Promise<unknown> = Promise.resolve()
|
|
24
|
+
private count = 0
|
|
25
|
+
private runningLatest = false
|
|
26
|
+
private latestOperation: QueuedOperation | undefined
|
|
27
|
+
private readonly idleWaiters = new Set<() => void>()
|
|
28
|
+
|
|
29
|
+
constructor({ strategy = 'serial' }: OperationQueueOptions = {}) {
|
|
30
|
+
this.strategy = strategy
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
get pending(): number {
|
|
34
|
+
return this.count
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
get busy(): boolean {
|
|
38
|
+
return this.count > 0
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
run<T>(task: () => MaybePromise<T>): Promise<T> {
|
|
42
|
+
return this.strategy === 'latest'
|
|
43
|
+
? this.runLatest(task)
|
|
44
|
+
: this.runSerial(task)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async waitIdle(): Promise<void> {
|
|
48
|
+
if (!this.busy) return
|
|
49
|
+
|
|
50
|
+
await new Promise<void>((resolve) => {
|
|
51
|
+
this.idleWaiters.add(resolve)
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private runSerial<T>(task: () => MaybePromise<T>): Promise<T> {
|
|
56
|
+
this.count++
|
|
57
|
+
|
|
58
|
+
const result = this.tail.then(task, task)
|
|
59
|
+
this.tail = result
|
|
60
|
+
.catch(() => undefined)
|
|
61
|
+
.finally(() => {
|
|
62
|
+
this.finishOperation()
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
return result
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private runLatest<T>(task: () => MaybePromise<T>): Promise<T> {
|
|
69
|
+
this.count++
|
|
70
|
+
|
|
71
|
+
const { operation, promise } = createQueuedOperation(task)
|
|
72
|
+
|
|
73
|
+
if (this.runningLatest) {
|
|
74
|
+
const previous = this.latestOperation
|
|
75
|
+
if (previous) {
|
|
76
|
+
previous.reject(new OperationSupersededError())
|
|
77
|
+
this.finishOperation()
|
|
78
|
+
}
|
|
79
|
+
this.latestOperation = operation
|
|
80
|
+
return promise
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
this.runningLatest = true
|
|
84
|
+
void this.runLatestOperations(operation)
|
|
85
|
+
|
|
86
|
+
return promise
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private async runLatestOperations(operation: QueuedOperation): Promise<void> {
|
|
90
|
+
let current: QueuedOperation | undefined = operation
|
|
91
|
+
|
|
92
|
+
while (current) {
|
|
93
|
+
await this.runLatestOperation(current)
|
|
94
|
+
current = this.latestOperation
|
|
95
|
+
this.latestOperation = undefined
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
this.runningLatest = false
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private async runLatestOperation(operation: QueuedOperation): Promise<void> {
|
|
102
|
+
try {
|
|
103
|
+
operation.resolve(await operation.task())
|
|
104
|
+
} catch (error) {
|
|
105
|
+
operation.reject(error)
|
|
106
|
+
} finally {
|
|
107
|
+
this.finishOperation()
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private finishOperation(): void {
|
|
112
|
+
this.count--
|
|
113
|
+
if (this.count > 0) return
|
|
114
|
+
|
|
115
|
+
for (const resolve of this.idleWaiters) resolve()
|
|
116
|
+
this.idleWaiters.clear()
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function createQueuedOperation<T>(task: () => MaybePromise<T>): {
|
|
121
|
+
operation: QueuedOperation
|
|
122
|
+
promise: Promise<T>
|
|
123
|
+
} {
|
|
124
|
+
const future = createFuture<T>()
|
|
125
|
+
|
|
126
|
+
return {
|
|
127
|
+
operation: {
|
|
128
|
+
task: task as () => MaybePromise<unknown>,
|
|
129
|
+
resolve: future.resolve as (value: unknown) => void,
|
|
130
|
+
reject: future.reject,
|
|
131
|
+
},
|
|
132
|
+
promise: future.promise,
|
|
133
|
+
}
|
|
134
|
+
}
|
package/src/pool.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import type { Callback } from './types.ts'
|
|
2
|
+
|
|
3
|
+
interface PoolOptions {
|
|
4
|
+
timeout?: number
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface PoolQueueItem {
|
|
8
|
+
resolve?: Callback
|
|
9
|
+
timer?: ReturnType<typeof globalThis.setTimeout>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class PoolError extends Error {}
|
|
13
|
+
|
|
14
|
+
// Ported from https://github.com/metarhia/metautil
|
|
15
|
+
export class Pool<T = unknown> {
|
|
16
|
+
#items: Array<T> = []
|
|
17
|
+
#free: Array<boolean> = []
|
|
18
|
+
#queue: PoolQueueItem[] = []
|
|
19
|
+
#current: number = 0
|
|
20
|
+
#size: number = 0
|
|
21
|
+
#available: number = 0
|
|
22
|
+
|
|
23
|
+
constructor(private readonly options: PoolOptions = {}) {}
|
|
24
|
+
|
|
25
|
+
add(item: T) {
|
|
26
|
+
if (this.#items.includes(item)) throw new PoolError('Item already exists')
|
|
27
|
+
this.#size++
|
|
28
|
+
this.#available++
|
|
29
|
+
this.#items.push(item)
|
|
30
|
+
this.#free.push(true)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
remove(item: T) {
|
|
34
|
+
if (this.#size === 0) throw new PoolError('Pool is empty')
|
|
35
|
+
const index = this.#items.indexOf(item)
|
|
36
|
+
if (index < 0) throw new PoolError('Item is not in the pool')
|
|
37
|
+
const isCaptured = this.isFree(item)
|
|
38
|
+
if (isCaptured) this.#available--
|
|
39
|
+
this.#size--
|
|
40
|
+
this.#current--
|
|
41
|
+
this.#items.splice(index, 1)
|
|
42
|
+
this.#free.splice(index, 1)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
capture(timeout = this.options.timeout) {
|
|
46
|
+
return this.next(true, timeout)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async next(exclusive = false, timeout = this.options.timeout): Promise<T> {
|
|
50
|
+
if (this.#size === 0) throw new PoolError('Pool is empty')
|
|
51
|
+
if (this.#available === 0) {
|
|
52
|
+
return new Promise((resolve, reject) => {
|
|
53
|
+
const waiting: PoolQueueItem = {
|
|
54
|
+
resolve: (item: T) => {
|
|
55
|
+
if (exclusive) this.#capture(item)
|
|
56
|
+
resolve(item)
|
|
57
|
+
},
|
|
58
|
+
timer: undefined,
|
|
59
|
+
}
|
|
60
|
+
if (timeout) {
|
|
61
|
+
waiting.timer = setTimeout(() => {
|
|
62
|
+
waiting.resolve = undefined
|
|
63
|
+
this.#queue.shift()
|
|
64
|
+
reject(new PoolError('Next item timeout'))
|
|
65
|
+
}, timeout)
|
|
66
|
+
}
|
|
67
|
+
this.#queue.push(waiting)
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
let item: T | undefined
|
|
71
|
+
let free = false
|
|
72
|
+
do {
|
|
73
|
+
item = this.#items[this.#current]
|
|
74
|
+
free = this.#free[this.#current]
|
|
75
|
+
this.#current++
|
|
76
|
+
if (this.#current >= this.#size) this.#current = 0
|
|
77
|
+
} while (typeof item === 'undefined' || !free)
|
|
78
|
+
if (exclusive) this.#capture(item)
|
|
79
|
+
return item
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
release(item: T) {
|
|
83
|
+
const index = this.#items.indexOf(item)
|
|
84
|
+
if (index < 0) throw new PoolError('Unexpected item')
|
|
85
|
+
if (this.#free[index])
|
|
86
|
+
throw new PoolError('Unable to release not captured item')
|
|
87
|
+
if (this.#queue.length > 0) {
|
|
88
|
+
const { resolve, timer } = this.#queue.shift()!
|
|
89
|
+
clearTimeout(timer)
|
|
90
|
+
if (resolve) return void setTimeout(resolve, 0, item)
|
|
91
|
+
}
|
|
92
|
+
this.#free[index] = true
|
|
93
|
+
this.#available++
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
isFree(item: T) {
|
|
97
|
+
const index = this.#items.indexOf(item)
|
|
98
|
+
if (index < 0) return false
|
|
99
|
+
return this.#free[index]
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
get items() {
|
|
103
|
+
return [...this.#items]
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
#capture(item: T) {
|
|
107
|
+
const index = this.#items.indexOf(item)
|
|
108
|
+
this.#free[index] = false
|
|
109
|
+
this.#available--
|
|
110
|
+
}
|
|
111
|
+
}
|
package/src/semaphore.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Callback } from './types.ts'
|
|
2
|
+
|
|
3
|
+
interface SemaphoreQueueItem {
|
|
4
|
+
resolve?: Callback
|
|
5
|
+
timer?: ReturnType<typeof setTimeout>
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class SemaphoreError extends Error {}
|
|
9
|
+
|
|
10
|
+
// Ported from https://github.com/metarhia/metautil
|
|
11
|
+
export class Semaphore {
|
|
12
|
+
private counter: number
|
|
13
|
+
|
|
14
|
+
private readonly queue: SemaphoreQueueItem[] = []
|
|
15
|
+
|
|
16
|
+
constructor(
|
|
17
|
+
concurrency: number,
|
|
18
|
+
private readonly size: number = 0,
|
|
19
|
+
private readonly timeout: number = 0,
|
|
20
|
+
) {
|
|
21
|
+
this.counter = concurrency
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
enter(): Promise<void> {
|
|
25
|
+
if (this.counter > 0) {
|
|
26
|
+
this.counter--
|
|
27
|
+
return Promise.resolve()
|
|
28
|
+
} else if (this.queue.length >= this.size) {
|
|
29
|
+
return Promise.reject(new SemaphoreError('Queue is full'))
|
|
30
|
+
} else {
|
|
31
|
+
return new Promise((resolve, reject) => {
|
|
32
|
+
const waiting: SemaphoreQueueItem = { resolve }
|
|
33
|
+
waiting.timer = setTimeout(() => {
|
|
34
|
+
waiting.resolve = undefined
|
|
35
|
+
this.queue.shift()
|
|
36
|
+
reject(new SemaphoreError('Timeout'))
|
|
37
|
+
}, this.timeout)
|
|
38
|
+
this.queue.push(waiting)
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
leave() {
|
|
44
|
+
if (this.queue.length === 0) {
|
|
45
|
+
this.counter++
|
|
46
|
+
} else {
|
|
47
|
+
const item = this.queue.shift()
|
|
48
|
+
if (item) {
|
|
49
|
+
const { resolve, timer } = item
|
|
50
|
+
if (timer) clearTimeout(timer)
|
|
51
|
+
if (resolve) setTimeout(resolve, 0)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get isEmpty() {
|
|
57
|
+
return this.queue.length === 0
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
get queueLength() {
|
|
61
|
+
return this.queue.length
|
|
62
|
+
}
|
|
63
|
+
}
|
package/src/streams.ts
CHANGED
|
@@ -3,26 +3,28 @@
|
|
|
3
3
|
import type { MaybePromise } from './types.ts'
|
|
4
4
|
|
|
5
5
|
export interface DuplexStreamOptions<O = unknown, I = O> {
|
|
6
|
-
start?: (controller: ReadableStreamDefaultController<O>) => void
|
|
7
|
-
pull?: (
|
|
6
|
+
start?: (controller: globalThis.ReadableStreamDefaultController<O>) => void
|
|
7
|
+
pull?: (
|
|
8
|
+
controller: globalThis.ReadableStreamDefaultController<O>,
|
|
9
|
+
) => MaybePromise<void>
|
|
8
10
|
cancel?: (reason: unknown) => void
|
|
9
11
|
transform?: (chunk: I) => O
|
|
10
12
|
close?: () => void
|
|
11
|
-
readableStrategy?: QueuingStrategy<O>
|
|
12
|
-
writableStrategy?: QueuingStrategy<I>
|
|
13
|
+
readableStrategy?: globalThis.QueuingStrategy<O>
|
|
14
|
+
writableStrategy?: globalThis.QueuingStrategy<I>
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
export class DuplexStream<O = unknown, I = O> {
|
|
16
|
-
readonly readable: ReadableStream<O>
|
|
17
|
-
readonly writable!: WritableStream<I>
|
|
18
|
+
readonly readable: globalThis.ReadableStream<O>
|
|
19
|
+
readonly writable!: globalThis.WritableStream<I>
|
|
18
20
|
|
|
19
21
|
constructor(options: DuplexStreamOptions<O, I> = {}) {
|
|
20
|
-
this.readable = new ReadableStream<O>(
|
|
22
|
+
this.readable = new globalThis.ReadableStream<O>(
|
|
21
23
|
{
|
|
22
24
|
cancel: options.cancel,
|
|
23
25
|
start: (controller) => {
|
|
24
26
|
// @ts-expect-error
|
|
25
|
-
this.writable = new WritableStream<I>(
|
|
27
|
+
this.writable = new globalThis.WritableStream<I>(
|
|
26
28
|
{
|
|
27
29
|
write: (_chunk) => {
|
|
28
30
|
const chunk = options?.transform
|
package/src/types.ts
CHANGED
|
@@ -2,9 +2,12 @@ const TSErrorSymbol: unique symbol = Symbol('TSError')
|
|
|
2
2
|
|
|
3
3
|
export type TSError<
|
|
4
4
|
ErrorMessage extends string = string,
|
|
5
|
-
//
|
|
5
|
+
// Used to tag the type.
|
|
6
6
|
TagType = never,
|
|
7
|
-
> = `TS Error: ${ErrorMessage}` & {
|
|
7
|
+
> = `TS Error: ${ErrorMessage}` & {
|
|
8
|
+
[TSErrorSymbol]: true
|
|
9
|
+
readonly __tag?: TagType
|
|
10
|
+
}
|
|
8
11
|
|
|
9
12
|
export interface TypeProvider {
|
|
10
13
|
readonly input: unknown
|
|
@@ -16,12 +19,8 @@ export type CallTypeProvider<T extends TypeProvider, V> = (T & {
|
|
|
16
19
|
})['output']
|
|
17
20
|
|
|
18
21
|
export type ClassConstructor<T = any, A extends any[] = any[]> =
|
|
19
|
-
| (abstract new (
|
|
20
|
-
|
|
21
|
-
) => T)
|
|
22
|
-
| (new (
|
|
23
|
-
...args: A
|
|
24
|
-
) => T)
|
|
22
|
+
| (abstract new (...args: A) => T)
|
|
23
|
+
| (new (...args: A) => T)
|
|
25
24
|
|
|
26
25
|
export type ClassInstance<T> = T extends ClassConstructor<infer U> ? U : never
|
|
27
26
|
export type ClassConstructorArgs<T, A = never> =
|
|
@@ -40,9 +39,7 @@ export type ArrayMap<T extends readonly any[], K extends keyof T[number]> = {
|
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
export type UnionToIntersection<U> = (
|
|
43
|
-
U extends any
|
|
44
|
-
? (k: U) => void
|
|
45
|
-
: never
|
|
42
|
+
U extends any ? (k: U) => void : never
|
|
46
43
|
) extends (k: infer I) => void
|
|
47
44
|
? I
|
|
48
45
|
: never
|
package/src/utils.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/// <reference lib="dom" />
|
|
2
|
-
|
|
3
1
|
import type { Callback, Pattern } from './types.ts'
|
|
4
2
|
|
|
5
3
|
export const noopFn = () => {}
|
|
@@ -18,7 +16,7 @@ export function defer<T extends Callback>(
|
|
|
18
16
|
...args: Parameters<T>
|
|
19
17
|
): Promise<Awaited<ReturnType<T>>> {
|
|
20
18
|
return new Promise((resolve, reject) =>
|
|
21
|
-
setTimeout(async () => {
|
|
19
|
+
globalThis.setTimeout(async () => {
|
|
22
20
|
try {
|
|
23
21
|
resolve(await cb(...args))
|
|
24
22
|
} catch (error) {
|
|
@@ -45,36 +43,14 @@ export function range(count: number, start = 0) {
|
|
|
45
43
|
}
|
|
46
44
|
}
|
|
47
45
|
|
|
48
|
-
export
|
|
49
|
-
let timer: any
|
|
50
|
-
const clear = () => timer && clearTimeout(timer)
|
|
51
|
-
const fn = (...args: any[]) => {
|
|
52
|
-
clear()
|
|
53
|
-
timer = setTimeout(cb, delay, ...args)
|
|
54
|
-
}
|
|
55
|
-
return Object.assign(fn, { clear })
|
|
56
|
-
}
|
|
46
|
+
export type Future<T = any> = PromiseWithResolvers<T>
|
|
57
47
|
|
|
58
|
-
// TODO: Promise.withResolvers?
|
|
59
|
-
export interface Future<T = any> {
|
|
60
|
-
promise: Promise<T>
|
|
61
|
-
resolve: (value: T) => void
|
|
62
|
-
reject: (error: any) => void
|
|
63
|
-
}
|
|
64
|
-
// TODO: Promise.withResolvers?
|
|
65
48
|
export function createFuture<T>(): Future<T> {
|
|
66
|
-
|
|
67
|
-
let reject: Future<T>['reject']
|
|
68
|
-
const promise = new Promise<T>((res, rej) => {
|
|
69
|
-
resolve = res
|
|
70
|
-
reject = rej
|
|
71
|
-
})
|
|
72
|
-
// @ts-expect-error
|
|
73
|
-
return { resolve, reject, promise }
|
|
49
|
+
return Promise.withResolvers<T>()
|
|
74
50
|
}
|
|
75
51
|
|
|
76
52
|
export function onAbort<T extends Callback>(
|
|
77
|
-
signal: AbortSignal,
|
|
53
|
+
signal: globalThis.AbortSignal,
|
|
78
54
|
cb: T,
|
|
79
55
|
reason?: any,
|
|
80
56
|
) {
|
|
@@ -90,12 +66,14 @@ export function withTimeout(
|
|
|
90
66
|
) {
|
|
91
67
|
return Promise.race([
|
|
92
68
|
value,
|
|
93
|
-
new Promise((_, reject) =>
|
|
69
|
+
new Promise((_, reject) =>
|
|
70
|
+
globalThis.setTimeout(reject, timeout, timeoutError),
|
|
71
|
+
),
|
|
94
72
|
])
|
|
95
73
|
}
|
|
96
74
|
|
|
97
75
|
export function tryCaptureStackTrace(depth = 0) {
|
|
98
|
-
const traceLines = new Error().stack?.split('\n')
|
|
76
|
+
const traceLines = new Error().stack?.split('\n').slice(depth)
|
|
99
77
|
if (traceLines) {
|
|
100
78
|
for (const traceLine of traceLines) {
|
|
101
79
|
const trimmed = traceLine.trim()
|
|
@@ -132,23 +110,23 @@ export function throwError(message: string, ErrorClass = Error): never {
|
|
|
132
110
|
throw new ErrorClass(message)
|
|
133
111
|
}
|
|
134
112
|
|
|
135
|
-
export function once(target: EventTarget, event: string) {
|
|
113
|
+
export function once(target: globalThis.EventTarget, event: string) {
|
|
136
114
|
return new Promise<void>((resolve) => {
|
|
137
115
|
target.addEventListener(event, () => resolve(), { once: true })
|
|
138
116
|
})
|
|
139
117
|
}
|
|
140
118
|
|
|
141
|
-
export function onceAborted(signal: AbortSignal) {
|
|
119
|
+
export function onceAborted(signal: globalThis.AbortSignal) {
|
|
142
120
|
return once(signal, 'abort')
|
|
143
121
|
}
|
|
144
122
|
|
|
145
|
-
export function isAbortError(error) {
|
|
123
|
+
export function isAbortError(error: any): error is Error {
|
|
146
124
|
return (
|
|
147
125
|
(error instanceof Error &&
|
|
148
126
|
error.name === 'AbortError' &&
|
|
149
127
|
'code' in error &&
|
|
150
128
|
(error.code === 20 || error.code === 'ABORT_ERR')) ||
|
|
151
|
-
(error instanceof Event && error.type === 'abort')
|
|
129
|
+
(error instanceof globalThis.Event && error.type === 'abort')
|
|
152
130
|
)
|
|
153
131
|
}
|
|
154
132
|
|
package/dist/abortSignal.d.ts
DELETED
package/dist/abortSignal.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"abortSignal.js","sourceRoot":"","sources":["../src/abortSignal.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAE3B;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,GAAG,OAA2C;IAE9C,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAkB,CAAA;IACzD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;IAC7C,CAAC;SAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAA;IACpB,CAAC;SAAM,CAAC;QACN,OAAO,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAClC,CAAC;AACH,CAAC"}
|