@augment-vir/common 30.2.0 → 30.4.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.
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { DeferredPromise, type MaybePromise } from '@augment-vir/core';
|
|
2
|
+
import type { RequireExactlyOne } from 'type-fest';
|
|
3
|
+
import { ListenTarget } from 'typed-event-target';
|
|
4
|
+
/**
|
|
5
|
+
* An individual item in a {@link PromiseQueue} instance.
|
|
6
|
+
*
|
|
7
|
+
* @category Promise : Util
|
|
8
|
+
* @category Package : @augment-vir/common
|
|
9
|
+
* @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
|
|
10
|
+
*/
|
|
11
|
+
export type PromiseQueueItem<T = void> = {
|
|
12
|
+
/** The original queue item that was added. */
|
|
13
|
+
original: () => MaybePromise<T>;
|
|
14
|
+
/**
|
|
15
|
+
* A {@link DeferredPromise} instance with a promise that is resolved once this queue item has
|
|
16
|
+
* met its turn and has finished executing.
|
|
17
|
+
*/
|
|
18
|
+
wrapper: DeferredPromise<T>;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Data contained within an instance of {@link PromiseQueueUpdateEvent}.
|
|
22
|
+
*
|
|
23
|
+
* @category Promise : Util
|
|
24
|
+
* @category Package : @augment-vir/common
|
|
25
|
+
* @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
|
|
26
|
+
*/
|
|
27
|
+
export type PromiseQueueUpdate<T = unknown> = {
|
|
28
|
+
queueSize: number;
|
|
29
|
+
} & RequireExactlyOne<{
|
|
30
|
+
finishedItem: PromiseQueueItem<T>;
|
|
31
|
+
addedItem: PromiseQueueItem<T>;
|
|
32
|
+
}>;
|
|
33
|
+
declare const PromiseQueueUpdateEvent_base: (new (eventInitDict: {
|
|
34
|
+
bubbles?: boolean;
|
|
35
|
+
cancelable?: boolean;
|
|
36
|
+
composed?: boolean;
|
|
37
|
+
detail: PromiseQueueUpdate<unknown>;
|
|
38
|
+
}) => import("typed-event-target").TypedCustomEvent<PromiseQueueUpdate<unknown>, "promise-queue-update">) & Pick<{
|
|
39
|
+
new (type: string, eventInitDict?: EventInit): Event;
|
|
40
|
+
prototype: Event;
|
|
41
|
+
readonly NONE: 0;
|
|
42
|
+
readonly CAPTURING_PHASE: 1;
|
|
43
|
+
readonly AT_TARGET: 2;
|
|
44
|
+
readonly BUBBLING_PHASE: 3;
|
|
45
|
+
}, "prototype" | "NONE" | "CAPTURING_PHASE" | "AT_TARGET" | "BUBBLING_PHASE"> & Pick<import("typed-event-target").TypedCustomEvent<PromiseQueueUpdate<unknown>, "promise-queue-update">, "type">;
|
|
46
|
+
/**
|
|
47
|
+
* The event emitted from a {@link PromiseQueue} instance whenever the queue is updated (an item is
|
|
48
|
+
* resolved or an item is added).
|
|
49
|
+
*
|
|
50
|
+
* @category Promise : Util
|
|
51
|
+
* @category Package : @augment-vir/common
|
|
52
|
+
* @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
|
|
53
|
+
*/
|
|
54
|
+
export declare class PromiseQueueUpdateEvent extends PromiseQueueUpdateEvent_base {
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* A queue that manages its items with promises.
|
|
58
|
+
*
|
|
59
|
+
* @category Promise
|
|
60
|
+
* @category Package : @augment-vir/common
|
|
61
|
+
* @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
|
|
62
|
+
*/
|
|
63
|
+
export declare class PromiseQueue extends ListenTarget<PromiseQueueUpdateEvent> {
|
|
64
|
+
protected queue: PromiseQueueItem<any>[];
|
|
65
|
+
protected currentlyAwaiting: undefined | PromiseQueueItem<any>;
|
|
66
|
+
/** The current size of the queue. */
|
|
67
|
+
get size(): number;
|
|
68
|
+
/**
|
|
69
|
+
* Add an item to the queue.
|
|
70
|
+
*
|
|
71
|
+
* @returns A promise that resolves at the same time as the added item.
|
|
72
|
+
*/
|
|
73
|
+
add<T = void>(item: PromiseQueueItem<T>['original']): Promise<T>;
|
|
74
|
+
/** Handles a queue item finishing, whether it be a rejection or a resolution. */
|
|
75
|
+
protected handleItemSettle({ rejection, resolution, }: RequireExactlyOne<{
|
|
76
|
+
rejection: unknown;
|
|
77
|
+
resolution: unknown;
|
|
78
|
+
}>): PromiseQueueItem<any>;
|
|
79
|
+
/**
|
|
80
|
+
* Tries to trigger the next queue item, if there is one.
|
|
81
|
+
*
|
|
82
|
+
* @returns Whether a new queue item was triggered or not. `true` if it was, otherwise `false`.
|
|
83
|
+
*/
|
|
84
|
+
protected triggerNextQueueItem(): boolean;
|
|
85
|
+
}
|
|
86
|
+
export {};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { check } from '@augment-vir/assert';
|
|
2
|
+
import { DeferredPromise } from '@augment-vir/core';
|
|
3
|
+
import { defineTypedCustomEvent, ListenTarget } from 'typed-event-target';
|
|
4
|
+
/**
|
|
5
|
+
* The event emitted from a {@link PromiseQueue} instance whenever the queue is updated (an item is
|
|
6
|
+
* resolved or an item is added).
|
|
7
|
+
*
|
|
8
|
+
* @category Promise : Util
|
|
9
|
+
* @category Package : @augment-vir/common
|
|
10
|
+
* @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
|
|
11
|
+
*/
|
|
12
|
+
export class PromiseQueueUpdateEvent extends defineTypedCustomEvent()('promise-queue-update') {
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A queue that manages its items with promises.
|
|
16
|
+
*
|
|
17
|
+
* @category Promise
|
|
18
|
+
* @category Package : @augment-vir/common
|
|
19
|
+
* @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
|
|
20
|
+
*/
|
|
21
|
+
export class PromiseQueue extends ListenTarget {
|
|
22
|
+
queue = [];
|
|
23
|
+
currentlyAwaiting = undefined;
|
|
24
|
+
/** The current size of the queue. */
|
|
25
|
+
get size() {
|
|
26
|
+
return this.queue.length;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Add an item to the queue.
|
|
30
|
+
*
|
|
31
|
+
* @returns A promise that resolves at the same time as the added item.
|
|
32
|
+
*/
|
|
33
|
+
add(item) {
|
|
34
|
+
const newItem = {
|
|
35
|
+
original: item,
|
|
36
|
+
wrapper: new DeferredPromise(),
|
|
37
|
+
};
|
|
38
|
+
this.queue.push(newItem);
|
|
39
|
+
this.dispatch(new PromiseQueueUpdateEvent({
|
|
40
|
+
detail: {
|
|
41
|
+
queueSize: this.size,
|
|
42
|
+
addedItem: newItem,
|
|
43
|
+
},
|
|
44
|
+
}));
|
|
45
|
+
this.triggerNextQueueItem();
|
|
46
|
+
return newItem.wrapper.promise;
|
|
47
|
+
}
|
|
48
|
+
/** Handles a queue item finishing, whether it be a rejection or a resolution. */
|
|
49
|
+
handleItemSettle({ rejection, resolution, }) {
|
|
50
|
+
const item = this.currentlyAwaiting;
|
|
51
|
+
if (!item) {
|
|
52
|
+
throw new Error(`Cannot handle queue item settle without a currently awaited queue item.`);
|
|
53
|
+
}
|
|
54
|
+
this.queue.splice(0, 1);
|
|
55
|
+
this.dispatch(new PromiseQueueUpdateEvent({
|
|
56
|
+
detail: {
|
|
57
|
+
queueSize: this.size,
|
|
58
|
+
finishedItem: item,
|
|
59
|
+
},
|
|
60
|
+
}));
|
|
61
|
+
if (rejection) {
|
|
62
|
+
item.wrapper.reject(rejection);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
item.wrapper.resolve(resolution);
|
|
66
|
+
}
|
|
67
|
+
this.currentlyAwaiting = undefined;
|
|
68
|
+
this.triggerNextQueueItem();
|
|
69
|
+
return item;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Tries to trigger the next queue item, if there is one.
|
|
73
|
+
*
|
|
74
|
+
* @returns Whether a new queue item was triggered or not. `true` if it was, otherwise `false`.
|
|
75
|
+
*/
|
|
76
|
+
triggerNextQueueItem() {
|
|
77
|
+
if (this.currentlyAwaiting || !check.isLengthAtLeast(this.queue, 1)) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
const item = this.queue[0];
|
|
81
|
+
this.currentlyAwaiting = item;
|
|
82
|
+
item.original()
|
|
83
|
+
.then((result) => {
|
|
84
|
+
this.handleItemSettle({ resolution: result });
|
|
85
|
+
})
|
|
86
|
+
.catch((error) => {
|
|
87
|
+
this.handleItemSettle({ rejection: error });
|
|
88
|
+
});
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -84,3 +84,8 @@ export * from './augments/type/type-recursion.js';
|
|
|
84
84
|
export * from './augments/type/union.js';
|
|
85
85
|
export * from './augments/type/void-type.js';
|
|
86
86
|
export * from './augments/type/writable.js';
|
|
87
|
+
/**
|
|
88
|
+
* This must be placed last to account for this depending on `typed-listen-target` which depends on
|
|
89
|
+
* part of `@augment-vir/common`.
|
|
90
|
+
*/
|
|
91
|
+
export * from './augments/promise/promise-queue.js';
|
package/dist/index.js
CHANGED
|
@@ -84,3 +84,8 @@ export * from './augments/type/type-recursion.js';
|
|
|
84
84
|
export * from './augments/type/union.js';
|
|
85
85
|
export * from './augments/type/void-type.js';
|
|
86
86
|
export * from './augments/type/writable.js';
|
|
87
|
+
/**
|
|
88
|
+
* This must be placed last to account for this depending on `typed-listen-target` which depends on
|
|
89
|
+
* part of `@augment-vir/common`.
|
|
90
|
+
*/
|
|
91
|
+
export * from './augments/promise/promise-queue.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@augment-vir/common",
|
|
3
|
-
"version": "30.
|
|
3
|
+
"version": "30.4.0",
|
|
4
4
|
"description": "A collection of augments, helpers types, functions, and classes for any JavaScript environment.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"augment",
|
|
@@ -39,22 +39,23 @@
|
|
|
39
39
|
"test:web": "virmator --no-deps test web"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@augment-vir/assert": "^30.
|
|
43
|
-
"@augment-vir/core": "^30.
|
|
42
|
+
"@augment-vir/assert": "^30.4.0",
|
|
43
|
+
"@augment-vir/core": "^30.4.0",
|
|
44
44
|
"@date-vir/duration": "^6.0.1",
|
|
45
45
|
"ansi-styles": "^6.2.1",
|
|
46
46
|
"json5": "^2.2.3",
|
|
47
|
-
"type-fest": "^4.26.1"
|
|
47
|
+
"type-fest": "^4.26.1",
|
|
48
|
+
"typed-event-target": "^4.0.2"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
|
-
"@web/dev-server-esbuild": "^1.0.
|
|
51
|
+
"@web/dev-server-esbuild": "^1.0.3",
|
|
51
52
|
"@web/test-runner": "^0.19.0",
|
|
52
53
|
"@web/test-runner-commands": "^0.9.0",
|
|
53
54
|
"@web/test-runner-playwright": "^0.11.0",
|
|
54
55
|
"@web/test-runner-visual-regression": "^0.10.0",
|
|
55
|
-
"concurrently": "^9.0
|
|
56
|
+
"concurrently": "^9.1.0",
|
|
56
57
|
"execute-in-browser": "^1.0.3",
|
|
57
|
-
"istanbul-smart-text-reporter": "^1.1.
|
|
58
|
+
"istanbul-smart-text-reporter": "^1.1.5"
|
|
58
59
|
},
|
|
59
60
|
"engines": {
|
|
60
61
|
"node": ">=22"
|