@mnaoumov/typescript-lib 0.0.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/@types/debug/package.json +4 -0
- package/LICENSE +21 -0
- package/README.md +7 -1
- package/dist/lib/cjs/@types/debug.d.cts +21 -0
- package/dist/lib/cjs/abort-controller.cjs +202 -0
- package/dist/lib/cjs/abort-controller.d.cts +135 -0
- package/dist/lib/cjs/aggregate-error.cjs +98 -0
- package/dist/lib/cjs/aggregate-error.d.cts +24 -0
- package/dist/lib/cjs/array-buffer.cjs +96 -0
- package/dist/lib/cjs/array-buffer.d.cts +16 -0
- package/dist/lib/cjs/array.cjs +134 -0
- package/dist/lib/cjs/array.d.cts +46 -0
- package/dist/lib/cjs/async-events.cjs +466 -0
- package/dist/lib/cjs/async-events.d.cts +456 -0
- package/dist/lib/cjs/async-operation-hook.cjs +113 -0
- package/dist/lib/cjs/async-operation-hook.d.cts +59 -0
- package/dist/lib/cjs/async.cjs +521 -0
- package/dist/lib/cjs/async.d.cts +414 -0
- package/dist/lib/cjs/beeper.cjs +126 -0
- package/dist/lib/cjs/beeper.d.cts +21 -0
- package/dist/lib/cjs/blob.cjs +160 -0
- package/dist/lib/cjs/blob.d.cts +59 -0
- package/dist/lib/cjs/bytes.cjs +114 -0
- package/dist/lib/cjs/bytes.d.cts +17 -0
- package/dist/lib/cjs/debug-controller.cjs +80 -0
- package/dist/lib/cjs/debug-controller.d.cts +87 -0
- package/dist/lib/cjs/debug.cjs +235 -0
- package/dist/lib/cjs/debug.d.cts +66 -0
- package/dist/lib/cjs/desktop-zip-extractor.cjs +215 -0
- package/dist/lib/cjs/desktop-zip-extractor.d.cts +95 -0
- package/dist/lib/cjs/disposable.cjs +414 -0
- package/dist/lib/cjs/disposable.d.cts +387 -0
- package/dist/lib/cjs/enum.cjs +100 -0
- package/dist/lib/cjs/enum.d.cts +24 -0
- package/dist/lib/cjs/error.cjs +297 -0
- package/dist/lib/cjs/error.d.cts +181 -0
- package/dist/lib/cjs/function.cjs +141 -0
- package/dist/lib/cjs/function.d.cts +128 -0
- package/dist/lib/cjs/html-element.cjs +341 -0
- package/dist/lib/cjs/html-element.d.cts +199 -0
- package/dist/lib/cjs/index.cjs +195 -0
- package/dist/lib/cjs/index.d.cts +33 -0
- package/dist/lib/cjs/jpeg-metadata.cjs +228 -0
- package/dist/lib/cjs/jpeg-metadata.d.cts +42 -0
- package/dist/lib/cjs/library.cjs +158 -0
- package/dist/lib/cjs/library.d.cts +96 -0
- package/dist/lib/cjs/object-utils.cjs +617 -0
- package/dist/lib/cjs/object-utils.d.cts +298 -0
- package/dist/lib/cjs/path.cjs +202 -0
- package/dist/lib/cjs/path.d.cts +154 -0
- package/dist/lib/cjs/reg-exp.cjs +254 -0
- package/dist/lib/cjs/reg-exp.d.cts +87 -0
- package/dist/lib/cjs/string.cjs +326 -0
- package/dist/lib/cjs/string.d.cts +361 -0
- package/dist/lib/cjs/transformers/date-transformer.cjs +129 -0
- package/dist/lib/cjs/transformers/date-transformer.d.cts +39 -0
- package/dist/lib/cjs/transformers/group-transformer.cjs +173 -0
- package/dist/lib/cjs/transformers/group-transformer.d.cts +70 -0
- package/dist/lib/cjs/transformers/index.cjs +123 -0
- package/dist/lib/cjs/transformers/index.d.cts +9 -0
- package/dist/lib/cjs/transformers/map-transformer.cjs +129 -0
- package/dist/lib/cjs/transformers/map-transformer.d.cts +41 -0
- package/dist/lib/cjs/transformers/set-transformer.cjs +129 -0
- package/dist/lib/cjs/transformers/set-transformer.d.cts +39 -0
- package/dist/lib/cjs/transformers/skip-private-property-transformer.cjs +127 -0
- package/dist/lib/cjs/transformers/skip-private-property-transformer.d.cts +36 -0
- package/dist/lib/cjs/transformers/transformer.cjs +170 -0
- package/dist/lib/cjs/transformers/transformer.d.cts +70 -0
- package/dist/lib/cjs/transformers/two-way-map-transformer.cjs +130 -0
- package/dist/lib/cjs/transformers/two-way-map-transformer.d.cts +42 -0
- package/dist/lib/cjs/transformers/typed-transformer.cjs +94 -0
- package/dist/lib/cjs/transformers/typed-transformer.d.cts +39 -0
- package/dist/lib/cjs/two-way-map.cjs +208 -0
- package/dist/lib/cjs/two-way-map.d.cts +101 -0
- package/dist/lib/cjs/type-guards.cjs +128 -0
- package/dist/lib/cjs/type-guards.d.cts +84 -0
- package/dist/lib/cjs/type.cjs +121 -0
- package/dist/lib/cjs/type.d.cts +122 -0
- package/dist/lib/cjs/typescript-lib-state.cjs +126 -0
- package/dist/lib/cjs/typescript-lib-state.d.cts +56 -0
- package/dist/lib/cjs/url.cjs +136 -0
- package/dist/lib/cjs/url.d.cts +74 -0
- package/dist/lib/cjs/value-provider.cjs +100 -0
- package/dist/lib/cjs/value-provider.d.cts +28 -0
- package/dist/lib/cjs/value-wrapper.cjs +144 -0
- package/dist/lib/cjs/value-wrapper.d.cts +47 -0
- package/dist/lib/esm/@types/debug.d.mts +21 -0
- package/dist/lib/esm/abort-controller.d.mts +135 -0
- package/dist/lib/esm/abort-controller.mjs +159 -0
- package/dist/lib/esm/aggregate-error.d.mts +24 -0
- package/dist/lib/esm/aggregate-error.mjs +60 -0
- package/dist/lib/esm/array-buffer.d.mts +16 -0
- package/dist/lib/esm/array-buffer.mjs +58 -0
- package/dist/lib/esm/array.d.mts +46 -0
- package/dist/lib/esm/array.mjs +93 -0
- package/dist/lib/esm/async-events.d.mts +456 -0
- package/dist/lib/esm/async-events.mjs +427 -0
- package/dist/lib/esm/async-operation-hook.d.mts +59 -0
- package/dist/lib/esm/async-operation-hook.mjs +71 -0
- package/dist/lib/esm/async.d.mts +414 -0
- package/dist/lib/esm/async.mjs +479 -0
- package/dist/lib/esm/beeper.d.mts +21 -0
- package/dist/lib/esm/beeper.mjs +88 -0
- package/dist/lib/esm/blob.d.mts +59 -0
- package/dist/lib/esm/blob.mjs +121 -0
- package/dist/lib/esm/bytes.d.mts +17 -0
- package/dist/lib/esm/bytes.mjs +76 -0
- package/dist/lib/esm/debug-controller.d.mts +87 -0
- package/dist/lib/esm/debug-controller.mjs +50 -0
- package/dist/lib/esm/debug.d.mts +66 -0
- package/dist/lib/esm/debug.mjs +185 -0
- package/dist/lib/esm/desktop-zip-extractor.d.mts +95 -0
- package/dist/lib/esm/desktop-zip-extractor.mjs +180 -0
- package/dist/lib/esm/disposable.d.mts +387 -0
- package/dist/lib/esm/disposable.mjs +360 -0
- package/dist/lib/esm/enum.d.mts +24 -0
- package/dist/lib/esm/enum.mjs +61 -0
- package/dist/lib/esm/error.d.mts +181 -0
- package/dist/lib/esm/error.mjs +248 -0
- package/dist/lib/esm/function.d.mts +128 -0
- package/dist/lib/esm/function.mjs +96 -0
- package/dist/lib/esm/html-element.d.mts +199 -0
- package/dist/lib/esm/html-element.mjs +291 -0
- package/dist/lib/esm/index.d.mts +33 -0
- package/dist/lib/esm/index.mjs +116 -0
- package/dist/lib/esm/jpeg-metadata.d.mts +42 -0
- package/dist/lib/esm/jpeg-metadata.mjs +189 -0
- package/dist/lib/esm/library.d.mts +96 -0
- package/dist/lib/esm/library.mjs +118 -0
- package/dist/lib/esm/object-utils.d.mts +298 -0
- package/dist/lib/esm/object-utils.mjs +567 -0
- package/dist/lib/esm/path.d.mts +154 -0
- package/dist/lib/esm/path.mjs +139 -0
- package/dist/lib/esm/reg-exp.d.mts +87 -0
- package/dist/lib/esm/reg-exp.mjs +213 -0
- package/dist/lib/esm/string.d.mts +361 -0
- package/dist/lib/esm/string.mjs +274 -0
- package/dist/lib/esm/transformers/date-transformer.d.mts +39 -0
- package/dist/lib/esm/transformers/date-transformer.mjs +91 -0
- package/dist/lib/esm/transformers/group-transformer.d.mts +70 -0
- package/dist/lib/esm/transformers/group-transformer.mjs +138 -0
- package/dist/lib/esm/transformers/index.d.mts +9 -0
- package/dist/lib/esm/transformers/index.mjs +68 -0
- package/dist/lib/esm/transformers/map-transformer.d.mts +41 -0
- package/dist/lib/esm/transformers/map-transformer.mjs +91 -0
- package/dist/lib/esm/transformers/set-transformer.d.mts +39 -0
- package/dist/lib/esm/transformers/set-transformer.mjs +91 -0
- package/dist/lib/esm/transformers/skip-private-property-transformer.d.mts +36 -0
- package/dist/lib/esm/transformers/skip-private-property-transformer.mjs +89 -0
- package/dist/lib/esm/transformers/transformer.d.mts +70 -0
- package/dist/lib/esm/transformers/transformer.mjs +132 -0
- package/dist/lib/esm/transformers/two-way-map-transformer.d.mts +42 -0
- package/dist/lib/esm/transformers/two-way-map-transformer.mjs +92 -0
- package/dist/lib/esm/transformers/typed-transformer.d.mts +39 -0
- package/dist/lib/esm/transformers/typed-transformer.mjs +56 -0
- package/dist/lib/esm/two-way-map.d.mts +101 -0
- package/dist/lib/esm/two-way-map.mjs +170 -0
- package/dist/lib/esm/type-guards.d.mts +84 -0
- package/dist/lib/esm/type-guards.mjs +85 -0
- package/dist/lib/esm/type.d.mts +122 -0
- package/dist/lib/esm/type.mjs +83 -0
- package/dist/lib/esm/typescript-lib-state.d.mts +56 -0
- package/dist/lib/esm/typescript-lib-state.mjs +84 -0
- package/dist/lib/esm/url.d.mts +74 -0
- package/dist/lib/esm/url.mjs +94 -0
- package/dist/lib/esm/value-provider.d.mts +28 -0
- package/dist/lib/esm/value-provider.mjs +62 -0
- package/dist/lib/esm/value-wrapper.d.mts +47 -0
- package/dist/lib/esm/value-wrapper.mjs +106 -0
- package/package.json +111 -13
- package/transformers/date-transformer/package.json +6 -0
- package/transformers/group-transformer/package.json +6 -0
- package/transformers/index/package.json +6 -0
- package/transformers/map-transformer/package.json +6 -0
- package/transformers/package.json +6 -0
- package/transformers/set-transformer/package.json +6 -0
- package/transformers/skip-private-property-transformer/package.json +6 -0
- package/transformers/transformer/package.json +6 -0
- package/transformers/two-way-map-transformer/package.json +6 -0
- package/transformers/typed-transformer/package.json +6 -0
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
/// <reference path="./library.d.cts" />
|
|
2
|
+
/**
|
|
3
|
+
* @file
|
|
4
|
+
*
|
|
5
|
+
* Async event emitter.
|
|
6
|
+
*/
|
|
7
|
+
import type { AbstractConstructor, Promisable } from 'type-fest' with { 'resolution-mode': 'import' };
|
|
8
|
+
import type { AsyncDisposableEx } from './disposable.cjs';
|
|
9
|
+
import type { GenericPromisableVoidFunction } from './function.cjs';
|
|
10
|
+
import type { StringKeys } from './type.cjs';
|
|
11
|
+
import { AsyncDisposableBase } from './disposable.cjs';
|
|
12
|
+
declare const ASYNC_EVENT_MAP: unique symbol;
|
|
13
|
+
/**
|
|
14
|
+
* Async event reference.
|
|
15
|
+
*/
|
|
16
|
+
export interface AsyncEventRef {
|
|
17
|
+
/**
|
|
18
|
+
* An event source.
|
|
19
|
+
*/
|
|
20
|
+
asyncEventSource: GenericAsyncEventSource;
|
|
21
|
+
/**
|
|
22
|
+
* A callback to call when the event is triggered.
|
|
23
|
+
*/
|
|
24
|
+
callback: GenericCallback;
|
|
25
|
+
/**
|
|
26
|
+
* A name of the event.
|
|
27
|
+
*/
|
|
28
|
+
name: string;
|
|
29
|
+
/**
|
|
30
|
+
* A context passed as `this` to the `callback`.
|
|
31
|
+
*/
|
|
32
|
+
thisArgument: unknown;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Async event emitter implementation.
|
|
36
|
+
*
|
|
37
|
+
* @typeParam EventMap - Maps event names to their argument tuples.
|
|
38
|
+
* When omitted, the emitter accepts any string event name with any arguments.
|
|
39
|
+
* When provided, methods enforce correct event names and argument types
|
|
40
|
+
* with full autocomplete. Works with both `type` aliases and `interface` declarations.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* // Untyped (default) — any event name, any args:
|
|
45
|
+
* const events = new AsyncEvents();
|
|
46
|
+
* events.on('my-event', (arg1: string) => { ... });
|
|
47
|
+
*
|
|
48
|
+
* // Typed — only declared events with correct args:
|
|
49
|
+
* interface MyEventMap {
|
|
50
|
+
* save: [data: string];
|
|
51
|
+
* load: [id: number, force: boolean];
|
|
52
|
+
* }
|
|
53
|
+
* const events = new AsyncEvents<MyEventMap>();
|
|
54
|
+
* events.on('save', (data) => { ... }); // data: string — autocomplete on event name
|
|
55
|
+
* events.on('load', (id, force) => { ... }); // id: number, force: boolean
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export interface AsyncEventSource<EventMap extends EventMapConstraint<EventMap> = EventMapBase> extends GenericAsyncEventSource {
|
|
59
|
+
/**
|
|
60
|
+
* Phantom marker that makes {@link EventMap} inferable from an {@link AsyncEventSource} (e.g. via
|
|
61
|
+
* `Source extends AsyncEventSource<infer EventMap>`). Never present at runtime.
|
|
62
|
+
*/
|
|
63
|
+
readonly [ASYNC_EVENT_MAP]?: EventMap;
|
|
64
|
+
/**
|
|
65
|
+
* Remove an event listener.
|
|
66
|
+
*
|
|
67
|
+
* @typeParam EventName - The name of the event.
|
|
68
|
+
* @typeParam Arguments - The arguments of the event.
|
|
69
|
+
* @param name - The name of the event.
|
|
70
|
+
* @param callback - The callback to remove.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```ts
|
|
74
|
+
* events.off('my-event', myListener);
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
off: <EventName extends StringKeys<EventMap>, Arguments extends CallbackArguments<EventMap, EventName>>(name: EventName, callback: (...$arguments: Arguments) => Promisable<void>) => void;
|
|
78
|
+
/**
|
|
79
|
+
* Add an event listener.
|
|
80
|
+
*
|
|
81
|
+
* @typeParam EventName - The name of the event.
|
|
82
|
+
* @typeParam Arguments - The arguments of the event.
|
|
83
|
+
* @param name - The name of the event.
|
|
84
|
+
* @param callback - The callback to call when the event is triggered.
|
|
85
|
+
* @param thisArgument - The context passed as `this` to the `callback`.
|
|
86
|
+
* @returns A reference to the event listener.
|
|
87
|
+
*
|
|
88
|
+
* @remarks Not refactored to parameter-object pattern, to keep the parity with Obsidian's `Events.on` (or once, correspondingly).
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```ts
|
|
92
|
+
* events.on('my-event', async (arg1, arg2) => {
|
|
93
|
+
* await sleep(100);
|
|
94
|
+
* console.log(arg1, arg2);
|
|
95
|
+
* });
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
on: <EventName extends StringKeys<EventMap>, Arguments extends CallbackArguments<EventMap, EventName>>(name: EventName, callback: (...$arguments: Arguments) => Promisable<void>, thisArgument?: unknown) => AsyncEventRef;
|
|
99
|
+
/**
|
|
100
|
+
* Add an event listener that will be triggered only once.
|
|
101
|
+
*
|
|
102
|
+
* @typeParam EventName - The name of the event.
|
|
103
|
+
* @param name - The name of the event.
|
|
104
|
+
* @param callback - The callback to call when the event is triggered.
|
|
105
|
+
* @param thisArgument - The context passed as `this` to the `callback`.
|
|
106
|
+
* @returns A reference to the event listener.
|
|
107
|
+
*
|
|
108
|
+
* @remarks Not refactored to parameter-object pattern, to keep the parity with Obsidian's `Events.on` (or once, correspondingly).
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```ts
|
|
112
|
+
* events.once('my-event', async (arg1, arg2) => {
|
|
113
|
+
* await sleep(100);
|
|
114
|
+
* console.log(arg1, arg2);
|
|
115
|
+
* });
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
once: <EventName extends StringKeys<EventMap>, Arguments extends CallbackArguments<EventMap, EventName>>(name: EventName, callback: (...$arguments: Arguments) => Promisable<void>, thisArgument?: unknown) => AsyncEventRef;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Interface exposing event-triggering methods for subclasses of mixin-created classes.
|
|
122
|
+
*
|
|
123
|
+
* These methods are `protected` at runtime but surfaced in the declaration type
|
|
124
|
+
* because TypeScript cannot represent `protected` in anonymous-class return types.
|
|
125
|
+
*
|
|
126
|
+
* @typeParam EventMap - Maps event names to their argument tuples.
|
|
127
|
+
*/
|
|
128
|
+
export interface AsyncEventTrigger<EventMap extends EventMapConstraint<EventMap> = EventMapBase> {
|
|
129
|
+
/**
|
|
130
|
+
* Trigger an event, executing all the listeners in order even if some of them throw an error.
|
|
131
|
+
*
|
|
132
|
+
* @typeParam EventName - The name of the event.
|
|
133
|
+
* @param name - The name of the event.
|
|
134
|
+
* @param $arguments - The data to pass to the event listeners.
|
|
135
|
+
*/
|
|
136
|
+
trigger: <EventName extends StringKeys<EventMap>>(name: EventName, ...$arguments: CallbackArguments<EventMap, EventName>) => void;
|
|
137
|
+
/**
|
|
138
|
+
* Trigger an event asynchronously.
|
|
139
|
+
*
|
|
140
|
+
* @typeParam EventName - The name of the event.
|
|
141
|
+
* @param name - The name of the event.
|
|
142
|
+
* @param $arguments - The data to pass to the event listeners.
|
|
143
|
+
* @returns A {@link Promise} that resolves when all listeners have completed.
|
|
144
|
+
*/
|
|
145
|
+
triggerAsync: <EventName extends StringKeys<EventMap>>(name: EventName, ...$arguments: CallbackArguments<EventMap, EventName>) => Promise<void>;
|
|
146
|
+
/**
|
|
147
|
+
* Try to trigger an event, executing all the listeners in order even if some of them throw an error.
|
|
148
|
+
*
|
|
149
|
+
* @typeParam Arguments - The types of the arguments the function accepts.
|
|
150
|
+
* @param eventRef - The event reference.
|
|
151
|
+
* @param $arguments - The data to pass to the event listeners.
|
|
152
|
+
*/
|
|
153
|
+
tryTrigger: <Arguments extends unknown[]>(eventRef: AsyncEventRef, $arguments: Arguments) => void;
|
|
154
|
+
/**
|
|
155
|
+
* Try to trigger an event asynchronously.
|
|
156
|
+
*
|
|
157
|
+
* @typeParam Arguments - The types of the arguments the function accepts.
|
|
158
|
+
* @param eventRef - The event reference.
|
|
159
|
+
* @param $arguments - The data to pass to the event listeners.
|
|
160
|
+
* @returns A {@link Promise} that resolves when all listeners have completed.
|
|
161
|
+
*/
|
|
162
|
+
tryTriggerAsync: <Arguments extends unknown[]>(eventRef: AsyncEventRef, $arguments: Arguments) => Promise<void>;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Resolves callback argument types for an event.
|
|
166
|
+
*
|
|
167
|
+
* - When `EventMap` has an index signature (untyped default): returns `unknown[]`,
|
|
168
|
+
* allowing `Args` to be inferred freely from the callback.
|
|
169
|
+
* - When `EventMap` has explicit keys only (typed map): returns `EventMap[EventName]`,
|
|
170
|
+
* enforcing the declared argument types and enabling autocomplete.
|
|
171
|
+
*
|
|
172
|
+
* @typeParam EventMap - Maps event names to their argument tuples.
|
|
173
|
+
* @typeParam EventName - The name of the event.
|
|
174
|
+
*/
|
|
175
|
+
export type CallbackArguments<EventMap, EventName extends string> = string extends keyof EventMap ? unknown[] : (EventName extends keyof EventMap ? EventMap[EventName] : unknown[]);
|
|
176
|
+
/**
|
|
177
|
+
* Base event map type for untyped emitters.
|
|
178
|
+
*/
|
|
179
|
+
export type EventMapBase = Record<string, unknown[]>;
|
|
180
|
+
/**
|
|
181
|
+
* Interface for event source, used by {@link AsyncEventRef}
|
|
182
|
+
* so that refs can be stored regardless of the emitter's `EventMap`.
|
|
183
|
+
*/
|
|
184
|
+
export interface GenericAsyncEventSource {
|
|
185
|
+
/**
|
|
186
|
+
* Remove an event listener by reference.
|
|
187
|
+
*
|
|
188
|
+
* @param eventRef - The reference to remove.
|
|
189
|
+
*/
|
|
190
|
+
offref: (eventRef: AsyncEventRef) => void;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Parameters for {@link subscribeAsyncDisposableEvent}.
|
|
194
|
+
*
|
|
195
|
+
* @typeParam Source - The {@link AsyncEventSource} type.
|
|
196
|
+
* @typeParam EventName - The event name, constrained to the source's known events.
|
|
197
|
+
*/
|
|
198
|
+
export interface SubscribeAsyncDisposableEventParams<Source extends GenericAsyncEventSource, EventName extends AsyncEventNameOf<Source>> {
|
|
199
|
+
/**
|
|
200
|
+
* The async event source to subscribe on.
|
|
201
|
+
*/
|
|
202
|
+
readonly asyncEventSource: Source;
|
|
203
|
+
/**
|
|
204
|
+
* The event callback. Its argument types are inferred from {@link SubscribeAsyncDisposableEventParams.name}.
|
|
205
|
+
*/
|
|
206
|
+
readonly callback: AsyncEventCallbackOf<Source, EventName>;
|
|
207
|
+
/**
|
|
208
|
+
* The event name to subscribe to.
|
|
209
|
+
*/
|
|
210
|
+
readonly name: EventName;
|
|
211
|
+
/**
|
|
212
|
+
* The context passed as `this` to the callback.
|
|
213
|
+
*/
|
|
214
|
+
readonly thisArgument?: unknown;
|
|
215
|
+
}
|
|
216
|
+
type AsyncEventCallbackOf<Source extends GenericAsyncEventSource, EventName extends AsyncEventNameOf<Source>> = EventMapOf<Source>[EventName] extends infer Arguments extends unknown[] ? (...$arguments: Arguments) => Promisable<void> : never;
|
|
217
|
+
type AsyncEventNameOf<Source extends GenericAsyncEventSource> = keyof EventMapOf<Source> & string;
|
|
218
|
+
type EventMapConstraint<T> = Record<keyof T, unknown[]>;
|
|
219
|
+
type EventMapOf<Source> = Source extends AsyncEventSource<infer EventMap> ? EventMap : never;
|
|
220
|
+
type GenericCallback = GenericPromisableVoidFunction<unknown[]>;
|
|
221
|
+
/**
|
|
222
|
+
* An {@link AsyncDisposableEx} that unregisters an {@link AsyncEventRef} on dispose, via the event source stored
|
|
223
|
+
* on the ref itself. Async counterpart of the native `EventRefDisposable`.
|
|
224
|
+
*/
|
|
225
|
+
export declare class AsyncEventRefDisposable extends AsyncDisposableBase {
|
|
226
|
+
private readonly asyncEventRef;
|
|
227
|
+
/**
|
|
228
|
+
* Creates a disposable wrapping an existing {@link AsyncEventRef}.
|
|
229
|
+
*
|
|
230
|
+
* @param asyncEventRef - The async event reference to unregister on dispose.
|
|
231
|
+
*/
|
|
232
|
+
constructor(asyncEventRef: AsyncEventRef);
|
|
233
|
+
/**
|
|
234
|
+
* Unregisters the event via the source stored on the ref (`asyncEventSource.offref`).
|
|
235
|
+
*/
|
|
236
|
+
protected performDisposeAsync(): void;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Async event source implementation.
|
|
240
|
+
*
|
|
241
|
+
* @typeParam EventMap - Maps event names to their argument tuples.
|
|
242
|
+
* When omitted, the emitter accepts any string event name with any arguments.
|
|
243
|
+
* When provided, methods enforce correct event names and argument types
|
|
244
|
+
* with full autocomplete. Works with both `type` aliases and `interface` declarations.
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* ```ts
|
|
248
|
+
* // Untyped (default) — any event name, any args:
|
|
249
|
+
* const events = new AsyncEvents();
|
|
250
|
+
* events.on('my-event', (arg1: string) => { ... });
|
|
251
|
+
*
|
|
252
|
+
* // Typed — only declared events with correct args:
|
|
253
|
+
* interface MyEventMap {
|
|
254
|
+
* save: [data: string];
|
|
255
|
+
* load: [id: number, force: boolean];
|
|
256
|
+
* }
|
|
257
|
+
* const events = new AsyncEvents<MyEventMap>();
|
|
258
|
+
* events.on('save', (data) => { ... }); // data: string — autocomplete on event name
|
|
259
|
+
* events.on('load', (id, force) => { ... }); // id: number, force: boolean
|
|
260
|
+
* ```
|
|
261
|
+
*/
|
|
262
|
+
export declare abstract class AsyncEventsBase<EventMap extends EventMapConstraint<EventMap> = EventMapBase> implements AsyncEventSource<EventMap> {
|
|
263
|
+
/**
|
|
264
|
+
* The registry mapping each event name to its list of registered listener references.
|
|
265
|
+
*/
|
|
266
|
+
protected readonly eventReferencesMap: Map<string, AsyncEventRef[]>;
|
|
267
|
+
/**
|
|
268
|
+
* Remove an event listener.
|
|
269
|
+
*
|
|
270
|
+
* @typeParam EventName - The name of the event.
|
|
271
|
+
* @typeParam Arguments - The types of the arguments the event callback accepts.
|
|
272
|
+
* @param name - The name of the event.
|
|
273
|
+
* @param callback - The callback to remove.
|
|
274
|
+
*
|
|
275
|
+
* @example
|
|
276
|
+
* ```ts
|
|
277
|
+
* events.off('my-event', myListener);
|
|
278
|
+
* ```
|
|
279
|
+
*/
|
|
280
|
+
off<EventName extends StringKeys<EventMap>, Arguments extends CallbackArguments<EventMap, EventName>>(name: EventName, callback: (...$arguments: Arguments) => Promisable<void>): void;
|
|
281
|
+
/**
|
|
282
|
+
* Remove an event listener by reference.
|
|
283
|
+
*
|
|
284
|
+
* @param eventRef - The reference to the event listener.
|
|
285
|
+
*
|
|
286
|
+
* @example
|
|
287
|
+
* ```ts
|
|
288
|
+
* events.offref(myRef);
|
|
289
|
+
* ```
|
|
290
|
+
*/
|
|
291
|
+
offref(eventRef: AsyncEventRef): void;
|
|
292
|
+
/**
|
|
293
|
+
* Add an event listener.
|
|
294
|
+
*
|
|
295
|
+
* @typeParam EventName - The name of the event.
|
|
296
|
+
* @typeParam Arguments - The types of the arguments the event callback accepts.
|
|
297
|
+
* @param name - The name of the event.
|
|
298
|
+
* @param callback - The callback to call when the event is triggered.
|
|
299
|
+
* @param thisArgument - The context passed as `this` to the `callback`.
|
|
300
|
+
* @returns A reference to the event listener.
|
|
301
|
+
*
|
|
302
|
+
* @remarks Not refactored to parameter-object pattern, to keep the parity with Obsidian's `Events.on` (or once, correspondingly).
|
|
303
|
+
*
|
|
304
|
+
* @example
|
|
305
|
+
* ```ts
|
|
306
|
+
* events.on('my-event', async (arg1, arg2) => {
|
|
307
|
+
* await sleep(100);
|
|
308
|
+
* console.log(arg1, arg2);
|
|
309
|
+
* });
|
|
310
|
+
* ```
|
|
311
|
+
*/
|
|
312
|
+
on<EventName extends StringKeys<EventMap>, Arguments extends CallbackArguments<EventMap, EventName>>(name: EventName, callback: (...$arguments: Arguments) => Promisable<void>, thisArgument?: unknown): AsyncEventRef;
|
|
313
|
+
/**
|
|
314
|
+
* Add an event listener that will be triggered only once.
|
|
315
|
+
*
|
|
316
|
+
* @typeParam EventName - The name of the event.
|
|
317
|
+
* @typeParam Arguments - The types of the arguments the event callback accepts.
|
|
318
|
+
* @param name - The name of the event.
|
|
319
|
+
* @param callback - The callback to call when the event is triggered.
|
|
320
|
+
* @param thisArgument - The context passed as `this` to the `callback`.
|
|
321
|
+
* @returns A reference to the event listener.
|
|
322
|
+
*
|
|
323
|
+
* @remarks Not refactored to parameter-object pattern, to keep the parity with Obsidian's `Events.on` (or once, correspondingly).
|
|
324
|
+
*
|
|
325
|
+
* @example
|
|
326
|
+
* ```ts
|
|
327
|
+
* events.once('my-event', async (arg1, arg2) => {
|
|
328
|
+
* await sleep(100);
|
|
329
|
+
* console.log(arg1, arg2);
|
|
330
|
+
* });
|
|
331
|
+
* ```
|
|
332
|
+
*/
|
|
333
|
+
once<EventName extends StringKeys<EventMap>, Arguments extends CallbackArguments<EventMap, EventName>>(name: EventName, callback: (...$arguments: Arguments) => Promisable<void>, thisArgument?: unknown): AsyncEventRef;
|
|
334
|
+
/**
|
|
335
|
+
* Trigger an event, executing all the listeners in order even if some of them throw an error.
|
|
336
|
+
*
|
|
337
|
+
* @typeParam EventName - The name of the event.
|
|
338
|
+
* @param name - The name of the event.
|
|
339
|
+
* @param $arguments - The data to pass to the event listeners.
|
|
340
|
+
*
|
|
341
|
+
* @example
|
|
342
|
+
* ```ts
|
|
343
|
+
* events.trigger('my-event', 'arg1', 'arg2');
|
|
344
|
+
* ```
|
|
345
|
+
*/
|
|
346
|
+
protected trigger<EventName extends StringKeys<EventMap>>(name: EventName, ...$arguments: CallbackArguments<EventMap, EventName>): void;
|
|
347
|
+
/**
|
|
348
|
+
* Trigger an event asynchronously, executing all the listeners in order even if some of them throw an error.
|
|
349
|
+
*
|
|
350
|
+
* @typeParam EventName - The name of the event.
|
|
351
|
+
* @param name - The name of the event.
|
|
352
|
+
* @param $arguments - The data to pass to the event listeners.
|
|
353
|
+
* @returns A {@link Promise} that resolves when all listeners have completed.
|
|
354
|
+
*/
|
|
355
|
+
protected triggerAsync<EventName extends StringKeys<EventMap>>(name: EventName, ...$arguments: CallbackArguments<EventMap, EventName>): Promise<void>;
|
|
356
|
+
/**
|
|
357
|
+
* Try to trigger an event, executing all the listeners in order even if some of them throw an error.
|
|
358
|
+
*
|
|
359
|
+
* @typeParam Arguments - The types of the arguments the function accepts.
|
|
360
|
+
* @param eventRef - The event reference.
|
|
361
|
+
* @param $arguments - The data to pass to the event listeners.
|
|
362
|
+
*
|
|
363
|
+
* @example
|
|
364
|
+
* ```ts
|
|
365
|
+
* events.tryTrigger(myRef, ['arg1', 'arg2']);
|
|
366
|
+
* ```
|
|
367
|
+
*/
|
|
368
|
+
protected tryTrigger<Arguments extends unknown[]>(eventRef: AsyncEventRef, $arguments: Arguments): void;
|
|
369
|
+
/**
|
|
370
|
+
* Try to trigger an event asynchronously, executing all the listeners in order even if some of them throw an error.
|
|
371
|
+
*
|
|
372
|
+
* @typeParam Arguments - The types of the arguments the function accepts.
|
|
373
|
+
* @param eventRef - The event reference.
|
|
374
|
+
* @param $arguments - The data to pass to the event listeners.
|
|
375
|
+
* @returns A {@link Promise} that resolves when all listeners have completed.
|
|
376
|
+
*/
|
|
377
|
+
protected tryTriggerAsync<Arguments extends unknown[]>(eventRef: AsyncEventRef, $arguments: Arguments): Promise<void>;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* A class that extends {@link AsyncEventsBase} and provides public methods for triggering events.
|
|
381
|
+
*
|
|
382
|
+
* This class exists as parity with Obsidian's `Events`. But exposing publicly `trigger()` methods violates encapsulation.
|
|
383
|
+
*
|
|
384
|
+
* Avoid using it in favor of {@link AsyncEventsBase}.
|
|
385
|
+
*
|
|
386
|
+
* @typeParam EventMap - The type of the event map.
|
|
387
|
+
*/
|
|
388
|
+
export declare class AsyncEvents<EventMap extends EventMapConstraint<EventMap> = EventMapBase> extends AsyncEventsBase<EventMap> {
|
|
389
|
+
/**
|
|
390
|
+
* Trigger an event, executing all the listeners in order even if some of them throw an error.
|
|
391
|
+
*
|
|
392
|
+
* @typeParam EventName - The name of the event.
|
|
393
|
+
* @param name - The name of the event.
|
|
394
|
+
* @param $arguments - The data to pass to the event listeners.
|
|
395
|
+
*/
|
|
396
|
+
trigger<EventName extends StringKeys<EventMap>>(name: EventName, ...$arguments: CallbackArguments<EventMap, EventName>): void;
|
|
397
|
+
/**
|
|
398
|
+
* Trigger an event asynchronously, executing all the listeners in order even if some of them throw an error.
|
|
399
|
+
*
|
|
400
|
+
* @typeParam EventName - The name of the event.
|
|
401
|
+
* @param name - The name of the event.
|
|
402
|
+
* @param $arguments - The data to pass to the event listeners.
|
|
403
|
+
* @returns A {@link Promise} that resolves when all listeners have completed.
|
|
404
|
+
*/
|
|
405
|
+
triggerAsync<EventName extends StringKeys<EventMap>>(name: EventName, ...$arguments: CallbackArguments<EventMap, EventName>): Promise<void>;
|
|
406
|
+
/**
|
|
407
|
+
* Try to trigger an event, executing all the listeners in order even if some of them throw an error.
|
|
408
|
+
*
|
|
409
|
+
* @typeParam Arguments - The types of the arguments the function accepts.
|
|
410
|
+
* @param eventRef - The event reference.
|
|
411
|
+
* @param $arguments - The data to pass to the event listeners.
|
|
412
|
+
*/
|
|
413
|
+
tryTrigger<Arguments extends unknown[]>(eventRef: AsyncEventRef, $arguments: Arguments): void;
|
|
414
|
+
/**
|
|
415
|
+
* Try to trigger an event asynchronously, executing all the listeners in order even if some of them throw an error.
|
|
416
|
+
*
|
|
417
|
+
* @typeParam Arguments - The types of the arguments the function accepts.
|
|
418
|
+
* @param eventRef - The event reference.
|
|
419
|
+
* @param $arguments - The data to pass to the event listeners.
|
|
420
|
+
* @returns A {@link Promise} that resolves when all listeners have completed.
|
|
421
|
+
*/
|
|
422
|
+
tryTriggerAsync<Arguments extends unknown[]>(eventRef: AsyncEventRef, $arguments: Arguments): Promise<void>;
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Mixin that adds {@link AsyncEventSource} delegation to a base class.
|
|
426
|
+
*
|
|
427
|
+
* All event methods delegate to a private {@link AsyncEventsBase} instance.
|
|
428
|
+
* The `EventMap` generic is fixed at mixin-application time — if you need a class
|
|
429
|
+
* that is itself generic over its event map, use composition instead.
|
|
430
|
+
*
|
|
431
|
+
* @typeParam EventMap - Maps event names to their argument tuples.
|
|
432
|
+
* @returns A function that takes a base class and returns a new class extending it with {@link AsyncEventSource}.
|
|
433
|
+
*
|
|
434
|
+
* @example
|
|
435
|
+
* ```ts
|
|
436
|
+
* interface MyEvents {
|
|
437
|
+
* save: [data: string];
|
|
438
|
+
* }
|
|
439
|
+
* class MyComponent extends mixinAsyncEvents<MyEvents>()(Component) {
|
|
440
|
+
* // on(), off(), once(), offref() are available
|
|
441
|
+
* }
|
|
442
|
+
* ```
|
|
443
|
+
*/
|
|
444
|
+
export declare function mixinAsyncEvents<EventMap extends EventMapConstraint<EventMap> = EventMapBase>(): <TBase extends AbstractConstructor<object>>(baseClass: TBase) => AbstractConstructor<AsyncEventSource<EventMap> & AsyncEventTrigger<EventMap>> & TBase;
|
|
445
|
+
/**
|
|
446
|
+
* Subscribes to an event on an {@link AsyncEventSource} and returns an {@link AsyncDisposableEx} that unregisters
|
|
447
|
+
* it on dispose. Async counterpart of the native `subscribeDisposableEvent`; the event name and callback argument
|
|
448
|
+
* types are inferred from the source's event map.
|
|
449
|
+
*
|
|
450
|
+
* @typeParam Source - The {@link AsyncEventSource} type.
|
|
451
|
+
* @typeParam EventName - The event name.
|
|
452
|
+
* @param params - The subscription parameters.
|
|
453
|
+
* @returns An {@link AsyncDisposableEx} that unregisters the handler when disposed.
|
|
454
|
+
*/
|
|
455
|
+
export declare function subscribeAsyncDisposableEvent<Source extends GenericAsyncEventSource, EventName extends AsyncEventNameOf<Source>>(params: SubscribeAsyncDisposableEventParams<Source, EventName>): AsyncDisposableEx;
|
|
456
|
+
export {};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/*
|
|
2
|
+
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
|
3
|
+
if you want to view the source, please visit the github repository of this plugin
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
(function () {
|
|
7
|
+
function ensureDisposeSymbols(symbolConstructor = Symbol) {
|
|
8
|
+
symbolConstructor.asyncDispose ??= symbolConstructor.for('Symbol.asyncDispose');
|
|
9
|
+
symbolConstructor.dispose ??= symbolConstructor.for('Symbol.dispose');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function ensureBrowserProcess() {
|
|
13
|
+
const browserProcess = {
|
|
14
|
+
browser: true,
|
|
15
|
+
cwd() {
|
|
16
|
+
return '/';
|
|
17
|
+
},
|
|
18
|
+
env: {},
|
|
19
|
+
platform: 'android'
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// eslint-disable-next-line obsidianmd/no-global-this, unicorn/no-unnecessary-global-this -- Must stay `globalThis`-qualified: in the emitted banner a bare `process` is a free identifier, so reading it where the host has none throws a ReferenceError instead of yielding `undefined`. That is the very case this function exists to handle.
|
|
23
|
+
const existingProcess = globalThis.process;
|
|
24
|
+
|
|
25
|
+
if (!existingProcess) {
|
|
26
|
+
// eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
|
|
27
|
+
globalThis.process = browserProcess;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (existingProcess.versions?.node) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const existingProcessRecord = existingProcess;
|
|
36
|
+
|
|
37
|
+
for (const [key, value] of Object.entries(browserProcess)) {
|
|
38
|
+
existingProcessRecord[key] ??= value;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
existingProcessRecord['browser'] = true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function keepName($unknown) {
|
|
45
|
+
return $unknown;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
(function initCjs() {
|
|
49
|
+
// eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
|
|
50
|
+
const globalThisRecord = globalThis;
|
|
51
|
+
ensureDisposeSymbols();
|
|
52
|
+
globalThisRecord['__name'] ??= keepName;
|
|
53
|
+
globalThisRecord['__extractDefault'] ??= extractDefault;
|
|
54
|
+
|
|
55
|
+
ensureBrowserProcess();
|
|
56
|
+
|
|
57
|
+
// eslint-disable-next-line unicorn/consistent-function-scoping -- Serialized with initCjs into the banner; at module scope it would be left out of it.
|
|
58
|
+
function extractDefault(module) {
|
|
59
|
+
return module && module.__esModule && 'default' in module ? module.default : module;
|
|
60
|
+
}
|
|
61
|
+
})();
|
|
62
|
+
})();
|
|
63
|
+
|
|
64
|
+
"use strict";
|
|
65
|
+
var __defProp = Object.defineProperty;
|
|
66
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
67
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
68
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
69
|
+
var __export = (target, all) => {
|
|
70
|
+
for (var name in all)
|
|
71
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
72
|
+
};
|
|
73
|
+
var __copyProps = (to, from, except, desc) => {
|
|
74
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
75
|
+
for (let key of __getOwnPropNames(from))
|
|
76
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
77
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
78
|
+
}
|
|
79
|
+
return to;
|
|
80
|
+
};
|
|
81
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
82
|
+
var async_operation_hook_exports = {};
|
|
83
|
+
__export(async_operation_hook_exports, {
|
|
84
|
+
ASYNC_OPERATION_HOOK_KEY: () => ASYNC_OPERATION_HOOK_KEY,
|
|
85
|
+
ASYNC_OPERATION_HOOK_VERSION: () => ASYNC_OPERATION_HOOK_VERSION,
|
|
86
|
+
getAsyncOperationHook: () => getAsyncOperationHook,
|
|
87
|
+
notifyAsyncOperationStarted: () => notifyAsyncOperationStarted,
|
|
88
|
+
setAsyncOperationHook: () => setAsyncOperationHook
|
|
89
|
+
});
|
|
90
|
+
module.exports = __toCommonJS(async_operation_hook_exports);
|
|
91
|
+
const ASYNC_OPERATION_HOOK_VERSION = 1;
|
|
92
|
+
const ASYNC_OPERATION_HOOK_KEY = /* @__PURE__ */ Symbol.for("@mnaoumov/typescript-lib/async-operation-hook");
|
|
93
|
+
function getAsyncOperationHook() {
|
|
94
|
+
return getSlot()[ASYNC_OPERATION_HOOK_KEY] ?? null;
|
|
95
|
+
}
|
|
96
|
+
function notifyAsyncOperationStarted(operation) {
|
|
97
|
+
getAsyncOperationHook()?.onAsyncOperationStarted(operation);
|
|
98
|
+
}
|
|
99
|
+
function setAsyncOperationHook(hook) {
|
|
100
|
+
getSlot()[ASYNC_OPERATION_HOOK_KEY] = hook;
|
|
101
|
+
}
|
|
102
|
+
function getSlot() {
|
|
103
|
+
return globalThis;
|
|
104
|
+
}
|
|
105
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
106
|
+
0 && (module.exports = {
|
|
107
|
+
ASYNC_OPERATION_HOOK_KEY,
|
|
108
|
+
ASYNC_OPERATION_HOOK_VERSION,
|
|
109
|
+
getAsyncOperationHook,
|
|
110
|
+
notifyAsyncOperationStarted,
|
|
111
|
+
setAsyncOperationHook
|
|
112
|
+
});
|
|
113
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2FzeW5jLW9wZXJhdGlvbi1ob29rLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogQW4gb3B0aW9uYWwgb2JzZXJ2ZXIgdGhhdCBmaXJlLWFuZC1mb3JnZXQgb3BlcmF0aW9ucyByZXBvcnQgdG8gd2hlbiB0aGV5IHN0YXJ0LlxuICpcbiAqIFByb2R1Y3Rpb24gY29kZSBvbmx5IGV2ZXIgQ0FMTFMgdGhlIGhvb2s6IHtAbGluayBub3RpZnlBc3luY09wZXJhdGlvblN0YXJ0ZWR9IGlzIGEgbm8tb3AgdW50aWwgc29tZXRoaW5nXG4gKiBpbnN0YWxscyBvbmUsIHNvIG5vIGJvb2trZWVwaW5nIGlzIGtlcHQgd2hlbiBub3RoaW5nIGlzIGxpc3RlbmluZy4gVGhlIHRlc3Qgc3VwcG9ydFxuICogKGBhc3luYy1vcGVyYXRpb24tdHJhY2tpbmcudHNgKSBpcyB3aGF0IGluc3RhbGxzIGl0LCBhbmQgaXQgb3ducyB0aGUgcmVnaXN0cnkgb2YgcGVuZGluZyBvcGVyYXRpb25zLlxuICpcbiAqIFRoZSBzbG90IGxpdmVzIG9uIGBnbG9iYWxUaGlzYCB1bmRlciBhIGBTeW1ib2wuZm9yYCBrZXkgcmF0aGVyIHRoYW4gaW4gYSBtb2R1bGUtbGV2ZWwgdmFyaWFibGUuIFR3b1xuICogaW5zdGFsbGVkIGNvcGllcyBvZiB0aGlzIG1vZHVsZSBcdTIwMTQgdGhlIGNvZGUgdW5kZXIgdGVzdCBidW5kbGluZyBvbmUgdmVyc2lvbiwgdGhlIHRlc3Qgc3VwcG9ydCBkZXBlbmRpbmcgb25cbiAqIGFub3RoZXIgXHUyMDE0IHRoZW4gc3RpbGwgc2hhcmUgb25lIHNsb3QsIHNvIHRoZSBob29rIHRoZSB0ZXN0cyBpbnN0YWxsIGlzIHRoZSBob29rIHRoZSBjb2RlIHVuZGVyIHRlc3QgY2FsbHMuXG4gKiBBIG1vZHVsZS1sZXZlbCB2YXJpYWJsZSB3b3VsZCBsZXQgZWFjaCBjb3B5IGtlZXAgaXRzIG93biwgYW5kIHRyYWNraW5nIHdvdWxkIHNpbGVudGx5IHNlZSBub3RoaW5nLlxuICpcbiAqIFRoZSBzbG90IGlzIGEgY3Jvc3MtdmVyc2lvbiB3aXJlIGZvcm1hdDogaXRzIGtleSBhbmQgdGhlIG1lbWJlcnMgb2Yge0BsaW5rIEFzeW5jT3BlcmF0aW9uSG9va30gb25seSBldmVyXG4gKiBjaGFuZ2UgYWRkaXRpdmVseS5cbiAqL1xuXG4vKipcbiAqIFRoZSB2ZXJzaW9uIG9mIHRoZSB7QGxpbmsgQXN5bmNPcGVyYXRpb25Ib29rfSBzaGFwZSB0aGlzIGNvcHkgd3JpdGVzLlxuICovXG5leHBvcnQgY29uc3QgQVNZTkNfT1BFUkFUSU9OX0hPT0tfVkVSU0lPTiA9IDE7XG5cbi8qKlxuICogVGhlIGtleSBvZiB0aGUgZ2xvYmFsIHNsb3QgaG9sZGluZyB0aGUgaW5zdGFsbGVkIHtAbGluayBBc3luY09wZXJhdGlvbkhvb2t9LlxuICovXG5leHBvcnQgY29uc3QgQVNZTkNfT1BFUkFUSU9OX0hPT0tfS0VZOiB1bmlxdWUgc3ltYm9sID0gU3ltYm9sLmZvcignQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL2FzeW5jLW9wZXJhdGlvbi1ob29rJyk7XG5cbi8qKlxuICogQW4gb2JzZXJ2ZXIgbm90aWZpZWQgd2hlbmV2ZXIgYSBmaXJlLWFuZC1mb3JnZXQgb3BlcmF0aW9uIHN0YXJ0cy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBc3luY09wZXJhdGlvbkhvb2sge1xuICAvKipcbiAgICogQ2FsbGVkIHdpdGggZWFjaCBmaXJlLWFuZC1mb3JnZXQgb3BlcmF0aW9uIGFzIGl0IHN0YXJ0cy5cbiAgICpcbiAgICogQHBhcmFtIG9wZXJhdGlvbiAtIFRoZSBvcGVyYXRpb24uIEl0IG5ldmVyIHJlamVjdHM6IGVycm9ycyBhcmUgYWxyZWFkeSBoYW5kbGVkIGJlZm9yZSBpdCBpcyByZXBvcnRlZC5cbiAgICovXG4gIHJlYWRvbmx5IG9uQXN5bmNPcGVyYXRpb25TdGFydGVkOiAob3BlcmF0aW9uOiBQcm9taXNlPHZvaWQ+KSA9PiB2b2lkO1xuXG4gIC8qKlxuICAgKiBUaGUgdmVyc2lvbiBvZiB0aGUgaG9vayBzaGFwZSB0aGUgaW5zdGFsbGVyIHdyb3RlLiBJbmZvcm1hdGlvbmFsOiB0aGUgbWVtYmVycyBvbmx5IGNoYW5nZSBhZGRpdGl2ZWx5LlxuICAgKi9cbiAgcmVhZG9ubHkgdmVyc2lvbjogbnVtYmVyO1xufVxuXG50eXBlIEFzeW5jT3BlcmF0aW9uSG9va1Nsb3QgPSBQYXJ0aWFsPFJlY29yZDx0eXBlb2YgQVNZTkNfT1BFUkFUSU9OX0hPT0tfS0VZLCBBc3luY09wZXJhdGlvbkhvb2sgfCBudWxsPj47XG5cbi8qKlxuICogR2V0cyB0aGUgaW5zdGFsbGVkIHtAbGluayBBc3luY09wZXJhdGlvbkhvb2t9LlxuICpcbiAqIEByZXR1cm5zIFRoZSBpbnN0YWxsZWQgaG9vaywgb3IgYG51bGxgIHdoZW4gbm9uZSBpcyBpbnN0YWxsZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRBc3luY09wZXJhdGlvbkhvb2soKTogQXN5bmNPcGVyYXRpb25Ib29rIHwgbnVsbCB7XG4gIHJldHVybiBnZXRTbG90KClbQVNZTkNfT1BFUkFUSU9OX0hPT0tfS0VZXSA/PyBudWxsO1xufVxuXG4vKipcbiAqIFJlcG9ydHMgYSBmaXJlLWFuZC1mb3JnZXQgb3BlcmF0aW9uIHRvIHRoZSBpbnN0YWxsZWQge0BsaW5rIEFzeW5jT3BlcmF0aW9uSG9va30sIGlmIGFueS5cbiAqXG4gKiBAcGFyYW0gb3BlcmF0aW9uIC0gVGhlIG9wZXJhdGlvbiB0aGF0IGhhcyBqdXN0IHN0YXJ0ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3RpZnlBc3luY09wZXJhdGlvblN0YXJ0ZWQob3BlcmF0aW9uOiBQcm9taXNlPHZvaWQ+KTogdm9pZCB7XG4gIGdldEFzeW5jT3BlcmF0aW9uSG9vaygpPy5vbkFzeW5jT3BlcmF0aW9uU3RhcnRlZChvcGVyYXRpb24pO1xufVxuXG4vKipcbiAqIEluc3RhbGxzIGFuIHtAbGluayBBc3luY09wZXJhdGlvbkhvb2t9LCByZXBsYWNpbmcgYW55IGluc3RhbGxlZCBvbmUsIG9yIHJlbW92ZXMgaXQuXG4gKlxuICogQHBhcmFtIGhvb2sgLSBUaGUgaG9vayB0byBpbnN0YWxsLCBvciBgbnVsbGAgdG8gcmVtb3ZlIHRoZSBpbnN0YWxsZWQgb25lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0QXN5bmNPcGVyYXRpb25Ib29rKGhvb2s6IEFzeW5jT3BlcmF0aW9uSG9vayB8IG51bGwpOiB2b2lkIHtcbiAgZ2V0U2xvdCgpW0FTWU5DX09QRVJBVElPTl9IT09LX0tFWV0gPSBob29rO1xufVxuXG5mdW5jdGlvbiBnZXRTbG90KCk6IEFzeW5jT3BlcmF0aW9uSG9va1Nsb3Qge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgb2JzaWRpYW5tZC9uby1nbG9iYWwtdGhpcyAtLSBUaGUgaG9vayBzbG90IGludGVudGlvbmFsbHkgbGl2ZXMgb24gdGhlIHJlYWxtIGdsb2JhbCwgc2hhcmVkIGJ5IGV2ZXJ5IGNvcHkgb2YgdGhpcyBtb2R1bGUuXG4gIHJldHVybiBnbG9iYWxUaGlzIGFzIEFzeW5jT3BlcmF0aW9uSG9va1Nsb3Q7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFxQk8sTUFBTSwrQkFBK0I7QUFLckMsTUFBTSwyQkFBMEMsdUJBQU8sSUFBSSwrQ0FBK0M7QUEwQjFHLFNBQVMsd0JBQW1EO0FBQ2pFLFNBQU8sUUFBUSxFQUFFLHdCQUF3QixLQUFLO0FBQ2hEO0FBT08sU0FBUyw0QkFBNEIsV0FBZ0M7QUFDMUUsd0JBQXNCLEdBQUcsd0JBQXdCLFNBQVM7QUFDNUQ7QUFPTyxTQUFTLHNCQUFzQixNQUF1QztBQUMzRSxVQUFRLEVBQUUsd0JBQXdCLElBQUk7QUFDeEM7QUFFQSxTQUFTLFVBQWtDO0FBRXpDLFNBQU87QUFDVDsiLAogICJuYW1lcyI6IFtdCn0K
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/// <reference path="./library.d.cts" />
|
|
2
|
+
/**
|
|
3
|
+
* @file
|
|
4
|
+
*
|
|
5
|
+
* An optional observer that fire-and-forget operations report to when they start.
|
|
6
|
+
*
|
|
7
|
+
* Production code only ever CALLS the hook: {@link notifyAsyncOperationStarted} is a no-op until something
|
|
8
|
+
* installs one, so no bookkeeping is kept when nothing is listening. The test support
|
|
9
|
+
* (`async-operation-tracking.ts`) is what installs it, and it owns the registry of pending operations.
|
|
10
|
+
*
|
|
11
|
+
* The slot lives on `globalThis` under a `Symbol.for` key rather than in a module-level variable. Two
|
|
12
|
+
* installed copies of this module — the code under test bundling one version, the test support depending on
|
|
13
|
+
* another — then still share one slot, so the hook the tests install is the hook the code under test calls.
|
|
14
|
+
* A module-level variable would let each copy keep its own, and tracking would silently see nothing.
|
|
15
|
+
*
|
|
16
|
+
* The slot is a cross-version wire format: its key and the members of {@link AsyncOperationHook} only ever
|
|
17
|
+
* change additively.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* The version of the {@link AsyncOperationHook} shape this copy writes.
|
|
21
|
+
*/
|
|
22
|
+
export declare const ASYNC_OPERATION_HOOK_VERSION = 1;
|
|
23
|
+
/**
|
|
24
|
+
* The key of the global slot holding the installed {@link AsyncOperationHook}.
|
|
25
|
+
*/
|
|
26
|
+
export declare const ASYNC_OPERATION_HOOK_KEY: unique symbol;
|
|
27
|
+
/**
|
|
28
|
+
* An observer notified whenever a fire-and-forget operation starts.
|
|
29
|
+
*/
|
|
30
|
+
export interface AsyncOperationHook {
|
|
31
|
+
/**
|
|
32
|
+
* Called with each fire-and-forget operation as it starts.
|
|
33
|
+
*
|
|
34
|
+
* @param operation - The operation. It never rejects: errors are already handled before it is reported.
|
|
35
|
+
*/
|
|
36
|
+
readonly onAsyncOperationStarted: (operation: Promise<void>) => void;
|
|
37
|
+
/**
|
|
38
|
+
* The version of the hook shape the installer wrote. Informational: the members only change additively.
|
|
39
|
+
*/
|
|
40
|
+
readonly version: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Gets the installed {@link AsyncOperationHook}.
|
|
44
|
+
*
|
|
45
|
+
* @returns The installed hook, or `null` when none is installed.
|
|
46
|
+
*/
|
|
47
|
+
export declare function getAsyncOperationHook(): AsyncOperationHook | null;
|
|
48
|
+
/**
|
|
49
|
+
* Reports a fire-and-forget operation to the installed {@link AsyncOperationHook}, if any.
|
|
50
|
+
*
|
|
51
|
+
* @param operation - The operation that has just started.
|
|
52
|
+
*/
|
|
53
|
+
export declare function notifyAsyncOperationStarted(operation: Promise<void>): void;
|
|
54
|
+
/**
|
|
55
|
+
* Installs an {@link AsyncOperationHook}, replacing any installed one, or removes it.
|
|
56
|
+
*
|
|
57
|
+
* @param hook - The hook to install, or `null` to remove the installed one.
|
|
58
|
+
*/
|
|
59
|
+
export declare function setAsyncOperationHook(hook: AsyncOperationHook | null): void;
|