@dxos/async 0.8.4-main.7ace549 → 0.8.4-main.937b3ca
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/dist/lib/browser/index.mjs +73 -0
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +73 -0
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/cleanup.d.ts +1 -0
- package/dist/types/src/cleanup.d.ts.map +1 -1
- package/dist/types/src/persistent-lifecycle.d.ts +2 -2
- package/dist/types/src/persistent-lifecycle.d.ts.map +1 -1
- package/dist/types/src/task-scheduling.d.ts +28 -0
- package/dist/types/src/task-scheduling.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +11 -7
- package/src/cleanup.ts +1 -0
- package/src/persistent-lifecycle.ts +2 -2
- package/src/task-scheduling.ts +93 -0
package/package.json
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/async",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.937b3ca",
|
|
4
4
|
"description": "Async utilities.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/dxos/dxos"
|
|
10
|
+
},
|
|
7
11
|
"license": "MIT",
|
|
8
12
|
"author": "DXOS.org",
|
|
9
13
|
"sideEffects": true,
|
|
@@ -29,12 +33,12 @@
|
|
|
29
33
|
"dependencies": {
|
|
30
34
|
"zen-observable": "^0.10.0",
|
|
31
35
|
"zen-push": "^0.3.1",
|
|
32
|
-
"@dxos/context": "0.8.4-main.
|
|
33
|
-
"@dxos/debug": "0.8.4-main.
|
|
34
|
-
"@dxos/
|
|
35
|
-
"@dxos/
|
|
36
|
-
"@dxos/util": "0.8.4-main.
|
|
37
|
-
"@dxos/
|
|
36
|
+
"@dxos/context": "0.8.4-main.937b3ca",
|
|
37
|
+
"@dxos/debug": "0.8.4-main.937b3ca",
|
|
38
|
+
"@dxos/log": "0.8.4-main.937b3ca",
|
|
39
|
+
"@dxos/node-std": "0.8.4-main.937b3ca",
|
|
40
|
+
"@dxos/util": "0.8.4-main.937b3ca",
|
|
41
|
+
"@dxos/invariant": "0.8.4-main.937b3ca"
|
|
38
42
|
},
|
|
39
43
|
"devDependencies": {
|
|
40
44
|
"@types/zen-observable": "^0.8.3"
|
package/src/cleanup.ts
CHANGED
|
@@ -37,6 +37,7 @@ type EventMap<T> = T extends Window
|
|
|
37
37
|
/**
|
|
38
38
|
* Add the event listener and return a cleanup function.
|
|
39
39
|
* Can be used in effect hooks in conjunction with `combine`.
|
|
40
|
+
* @deprecated use bind-event-listener
|
|
40
41
|
*/
|
|
41
42
|
export const addEventListener = <T extends EventTarget, K extends keyof EventMap<T>>(
|
|
42
43
|
target: T,
|
|
@@ -13,7 +13,7 @@ import { sleep } from './timeout';
|
|
|
13
13
|
const INIT_RESTART_DELAY = 100;
|
|
14
14
|
const DEFAULT_MAX_RESTART_DELAY = 5000;
|
|
15
15
|
|
|
16
|
-
export type
|
|
16
|
+
export type PersistentLifecycleProps<T> = {
|
|
17
17
|
/**
|
|
18
18
|
* Create connection.
|
|
19
19
|
* If promise resolves successfully, connection is considered established.
|
|
@@ -51,7 +51,7 @@ export class PersistentLifecycle<T> extends Resource {
|
|
|
51
51
|
private _restartTask?: DeferredTask = undefined;
|
|
52
52
|
private _restartAfter = 0;
|
|
53
53
|
|
|
54
|
-
constructor({ start, stop, onRestart, maxRestartDelay = DEFAULT_MAX_RESTART_DELAY }:
|
|
54
|
+
constructor({ start, stop, onRestart, maxRestartDelay = DEFAULT_MAX_RESTART_DELAY }: PersistentLifecycleProps<T>) {
|
|
55
55
|
super();
|
|
56
56
|
this._start = start;
|
|
57
57
|
this._stop = stop;
|
package/src/task-scheduling.ts
CHANGED
|
@@ -77,6 +77,99 @@ export class DeferredTask {
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
// TODO(dmaretskyi): Protyping this an alternative API to DeferredTask.
|
|
81
|
+
export class AsyncTask {
|
|
82
|
+
#callback: () => Promise<void>;
|
|
83
|
+
#ctx?: Context = undefined;
|
|
84
|
+
|
|
85
|
+
#scheduled = false;
|
|
86
|
+
#currentTask: Promise<void> | null = null; // Can't be rejected.
|
|
87
|
+
#nextTask = new Trigger();
|
|
88
|
+
|
|
89
|
+
constructor(callback: () => Promise<void>) {
|
|
90
|
+
this.#callback = callback;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
get scheduled() {
|
|
94
|
+
return this.#scheduled;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Context of the resource that owns the task.
|
|
99
|
+
* When the context is disposed, the task is cancelled and cannot be scheduled again.
|
|
100
|
+
*/
|
|
101
|
+
// TODO(dmaretskyi): We don't really need to pass ctx in here, since close will also signal dispose.
|
|
102
|
+
open(ctx: Context): void {
|
|
103
|
+
this.#ctx = ctx;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Closes the task and waits for it to finish if it is running.
|
|
108
|
+
*/
|
|
109
|
+
async close(): Promise<void> {
|
|
110
|
+
this.#ctx = undefined;
|
|
111
|
+
await this.join();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
[Symbol.asyncDispose](): Promise<void> {
|
|
115
|
+
return this.close();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Schedule the task to run asynchronously.
|
|
120
|
+
*/
|
|
121
|
+
schedule(): void {
|
|
122
|
+
if (!this.#ctx || this.#ctx.disposed) {
|
|
123
|
+
throw new Error('AsyncTask not open');
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (this.#scheduled) {
|
|
127
|
+
return; // Already scheduled.
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
scheduleTask(this.#ctx, async () => {
|
|
131
|
+
// The previous task might still be running, so we need to wait for it to finish.
|
|
132
|
+
await this.#currentTask; // Can't be rejected.
|
|
133
|
+
|
|
134
|
+
if (!this.#ctx || this.#ctx.disposed) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Reset the flag. New tasks can now be scheduled. They would wait for the callback to finish.
|
|
139
|
+
this.#scheduled = false;
|
|
140
|
+
const completionTrigger = this.#nextTask;
|
|
141
|
+
this.#nextTask = new Trigger(); // Re-create the trigger as opposed to resetting it since there might be listeners waiting for it.
|
|
142
|
+
|
|
143
|
+
// Store the promise so that new tasks could wait for this one to finish.
|
|
144
|
+
this.#currentTask = runInContextAsync(this.#ctx, () => this.#callback()).then(() => {
|
|
145
|
+
completionTrigger.wake();
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
this.#scheduled = true;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Schedule the task to run and wait for it to finish.
|
|
154
|
+
*/
|
|
155
|
+
async runBlocking(): Promise<void> {
|
|
156
|
+
if (this.#ctx?.disposed) {
|
|
157
|
+
throw new ContextDisposedError();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
this.schedule();
|
|
161
|
+
await this.#nextTask.wait();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Waits for the current task to finish if it is running.
|
|
166
|
+
* Does not schedule a new task.
|
|
167
|
+
*/
|
|
168
|
+
async join(): Promise<void> {
|
|
169
|
+
await this.#currentTask;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
80
173
|
export const runInContext = (ctx: Context, fn: () => void) => {
|
|
81
174
|
try {
|
|
82
175
|
fn();
|