@ms-cloudpack/api-server 0.63.11 → 0.64.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/lib/apis/addPackageOverride.d.ts +1 -1
- package/lib/apis/addPackageOverride.js +7 -7
- package/lib/apis/addPackageOverride.js.map +1 -1
- package/lib/apis/ensurePackageBundled.js.map +1 -1
- package/lib/apis/getData.d.ts +7 -13
- package/lib/apis/getData.d.ts.map +1 -1
- package/lib/apis/getData.js +3 -4
- package/lib/apis/getData.js.map +1 -1
- package/lib/apis/getLinkConfig.d.ts +2 -2
- package/lib/apis/getLinkConfig.d.ts.map +1 -1
- package/lib/apis/getLinkConfig.js +3 -2
- package/lib/apis/getLinkConfig.js.map +1 -1
- package/lib/apis/getSessionId.d.ts +2 -6
- package/lib/apis/getSessionId.d.ts.map +1 -1
- package/lib/apis/getSessionId.js +3 -4
- package/lib/apis/getSessionId.js.map +1 -1
- package/lib/apis/linkPath.d.ts +29 -3
- package/lib/apis/linkPath.js +2 -2
- package/lib/apis/linkPath.js.map +1 -1
- package/lib/apis/notifyLinkChange.d.ts +2 -2
- package/lib/apis/notifyLinkChange.d.ts.map +1 -1
- package/lib/apis/notifyLinkChange.js +3 -2
- package/lib/apis/notifyLinkChange.js.map +1 -1
- package/lib/apis/onDataChanged.d.ts +7 -13
- package/lib/apis/onDataChanged.d.ts.map +1 -1
- package/lib/apis/onDataChanged.js +3 -7
- package/lib/apis/onDataChanged.js.map +1 -1
- package/lib/apis/openCodeEditor.d.ts +9 -19
- package/lib/apis/openCodeEditor.d.ts.map +1 -1
- package/lib/apis/openCodeEditor.js +6 -6
- package/lib/apis/openCodeEditor.js.map +1 -1
- package/lib/apis/openConfigEditor.d.ts +1 -1
- package/lib/apis/openConfigEditor.d.ts.map +1 -1
- package/lib/apis/openConfigEditor.js +3 -2
- package/lib/apis/openConfigEditor.js.map +1 -1
- package/lib/apis/openFilePath.d.ts +6 -12
- package/lib/apis/openFilePath.d.ts.map +1 -1
- package/lib/apis/openFilePath.js +4 -4
- package/lib/apis/openFilePath.js.map +1 -1
- package/lib/apis/publishData.d.ts +7 -13
- package/lib/apis/publishData.d.ts.map +1 -1
- package/lib/apis/publishData.js +3 -3
- package/lib/apis/publishData.js.map +1 -1
- package/lib/apis/reportSpan.d.ts +10 -20
- package/lib/apis/reportSpan.d.ts.map +1 -1
- package/lib/apis/reportSpan.js +5 -5
- package/lib/apis/reportSpan.js.map +1 -1
- package/lib/apis/restartAllTasks.d.ts +1 -1
- package/lib/apis/restartAllTasks.d.ts.map +1 -1
- package/lib/apis/restartAllTasks.js +14 -7
- package/lib/apis/restartAllTasks.js.map +1 -1
- package/lib/apis/restartTask.d.ts +4 -18
- package/lib/apis/restartTask.d.ts.map +1 -1
- package/lib/apis/restartTask.js +6 -5
- package/lib/apis/restartTask.js.map +1 -1
- package/lib/apis/unlinkPath.d.ts +29 -3
- package/lib/apis/unlinkPath.js +2 -2
- package/lib/apis/unlinkPath.js.map +1 -1
- package/lib/apis/validatePackageOverride.d.ts +1 -1
- package/lib/apis/validatePackageOverride.js +5 -8
- package/lib/apis/validatePackageOverride.js.map +1 -1
- package/lib/common/createApiContext.d.ts.map +1 -1
- package/lib/common/createApiContext.js +4 -1
- package/lib/common/createApiContext.js.map +1 -1
- package/lib/common/createMockContext.d.ts +16 -9
- package/lib/common/createMockContext.d.ts.map +1 -1
- package/lib/common/createMockContext.js +21 -16
- package/lib/common/createMockContext.js.map +1 -1
- package/lib/common/createMockSession.d.ts +1 -1
- package/lib/common/createMockSession.d.ts.map +1 -1
- package/lib/common/createMockSession.js.map +1 -1
- package/lib/common/createSession.d.ts +5 -1
- package/lib/common/createSession.d.ts.map +1 -1
- package/lib/common/createSession.js +1 -1
- package/lib/common/createSession.js.map +1 -1
- package/lib/data/busSources.d.ts +27 -240
- package/lib/data/busSources.d.ts.map +1 -1
- package/lib/data/busSources.js +2 -2
- package/lib/data/busSources.js.map +1 -1
- package/lib/index.d.ts +0 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/trpc/common.d.ts +41 -2
- package/lib/trpc/common.d.ts.map +1 -1
- package/lib/trpc/common.js +44 -3
- package/lib/trpc/common.js.map +1 -1
- package/lib/types/LinkPath.d.ts +16 -92
- package/lib/types/LinkPath.d.ts.map +1 -1
- package/lib/types/LinkPath.js +21 -17
- package/lib/types/LinkPath.js.map +1 -1
- package/lib/types/Task.d.ts +20 -12
- package/lib/types/Task.d.ts.map +1 -1
- package/lib/types/Task.js.map +1 -1
- package/lib/types/TaskDescription.d.ts +19 -73
- package/lib/types/TaskDescription.d.ts.map +1 -1
- package/lib/types/TaskDescription.js +15 -12
- package/lib/types/TaskDescription.js.map +1 -1
- package/lib/types/TaskList.d.ts +6 -115
- package/lib/types/TaskList.d.ts.map +1 -1
- package/lib/types/TaskList.js +3 -2
- package/lib/types/TaskList.js.map +1 -1
- package/lib/types/TaskMessage.d.ts +3 -11
- package/lib/types/TaskMessage.d.ts.map +1 -1
- package/lib/types/TaskMessage.js +4 -4
- package/lib/types/TaskMessage.js.map +1 -1
- package/lib/types/TaskMessageLocation.d.ts +2 -6
- package/lib/types/TaskMessageLocation.d.ts.map +1 -1
- package/lib/types/TaskMessageLocation.js +3 -3
- package/lib/types/TaskMessageLocation.js.map +1 -1
- package/lib/types/TaskStats.d.ts +26 -17
- package/lib/types/TaskStats.d.ts.map +1 -1
- package/lib/types/TaskStats.js +4 -3
- package/lib/types/TaskStats.js.map +1 -1
- package/lib/types/Timing.d.ts +8 -18
- package/lib/types/Timing.d.ts.map +1 -1
- package/lib/types/Timing.js +5 -8
- package/lib/types/Timing.js.map +1 -1
- package/lib/types/ZodGetLinkConfigOutput.d.ts +2 -2
- package/lib/types/ZodGetLinkConfigOutput.d.ts.map +1 -1
- package/lib/types/ZodGetLinkConfigOutput.js +12 -10
- package/lib/types/ZodGetLinkConfigOutput.js.map +1 -1
- package/lib/types/ZodNotifyLinkChangeInput.d.ts +12 -44
- package/lib/types/ZodNotifyLinkChangeInput.d.ts.map +1 -1
- package/lib/types/ZodNotifyLinkChangeInput.js +7 -3
- package/lib/types/ZodNotifyLinkChangeInput.js.map +1 -1
- package/lib/types/ZodResolveMap.d.ts +2 -2
- package/lib/types/ZodResolveMap.d.ts.map +1 -1
- package/lib/types/ZodResolveMap.js +6 -6
- package/lib/types/ZodResolveMap.js.map +1 -1
- package/lib/utilities/TaskRunner.d.ts +56 -18
- package/lib/utilities/TaskRunner.d.ts.map +1 -1
- package/lib/utilities/TaskRunner.js +176 -98
- package/lib/utilities/TaskRunner.js.map +1 -1
- package/lib/utilities/createBundleTask.d.ts.map +1 -1
- package/lib/utilities/createBundleTask.js +9 -15
- package/lib/utilities/createBundleTask.js.map +1 -1
- package/lib/utilities/matchingZodObject.d.ts +15 -9
- package/lib/utilities/matchingZodObject.d.ts.map +1 -1
- package/lib/utilities/matchingZodObject.js +16 -6
- package/lib/utilities/matchingZodObject.js.map +1 -1
- package/lib/utilities/notifyReload.d.ts.map +1 -1
- package/lib/utilities/notifyReload.js +2 -1
- package/lib/utilities/notifyReload.js.map +1 -1
- package/lib/utilities/waitForBusData.d.ts +2 -2
- package/lib/utilities/waitForBusData.d.ts.map +1 -1
- package/lib/utilities/waitForBusData.js.map +1 -1
- package/package.json +16 -16
- package/lib/types/TaskEndDescription.d.ts +0 -26
- package/lib/types/TaskEndDescription.d.ts.map +0 -1
- package/lib/types/TaskEndDescription.js +0 -8
- package/lib/types/TaskEndDescription.js.map +0 -1
- package/lib/types/TaskStartDescription.d.ts +0 -19
- package/lib/types/TaskStartDescription.d.ts.map +0 -1
- package/lib/types/TaskStartDescription.js +0 -8
- package/lib/types/TaskStartDescription.js.map +0 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
1
|
+
import { z } from 'zod/v4-mini';
|
|
2
2
|
import { matchingZodObject } from '../utilities/matchingZodObject.js';
|
|
3
3
|
const ZodResolveMapEntry = z.lazy(() => matchingZodObject({
|
|
4
4
|
name: z.string(),
|
|
5
5
|
version: z.string(),
|
|
6
6
|
path: z.string(),
|
|
7
|
-
dependencies: z.record(z.string()),
|
|
8
|
-
requiredBy: z.record(z.string()),
|
|
9
|
-
isExternal: z.
|
|
10
|
-
isLinked: z.
|
|
11
|
-
scopedVersions: z.record(z.lazy(() => ZodResolveMapEntry))
|
|
7
|
+
dependencies: z.record(z.string(), z.string()),
|
|
8
|
+
requiredBy: z.record(z.string(), z.string()),
|
|
9
|
+
isExternal: z.optional(z.boolean()),
|
|
10
|
+
isLinked: z.optional(z.boolean()),
|
|
11
|
+
scopedVersions: z.optional(z.record(z.string(), z.lazy(() => ZodResolveMapEntry))),
|
|
12
12
|
}));
|
|
13
13
|
export const ZodResolveMap = z.record(z.string(), ZodResolveMapEntry);
|
|
14
14
|
//# sourceMappingURL=ZodResolveMap.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ZodResolveMap.js","sourceRoot":"","sources":["../../src/types/ZodResolveMap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"ZodResolveMap.js","sourceRoot":"","sources":["../../src/types/ZodResolveMap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,aAAa,CAAC;AAEhC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAEtE,MAAM,kBAAkB,GAAoD,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CACtF,iBAAiB,CAAkB;IACjC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IAC9C,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IAC5C,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IACnC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IACjC,cAAc,EAAE,CAAC,CAAC,QAAQ,CACxB,CAAC,CAAC,MAAM,CACN,CAAC,CAAC,MAAM,EAAE,EACV,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,CACjC,CACF;CACF,CAAC,CACH,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAA0C,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,CAAC","sourcesContent":["import { z } from 'zod/v4-mini';\nimport type { ResolveMap, ResolveMapEntry } from '@ms-cloudpack/common-types';\nimport { matchingZodObject } from '../utilities/matchingZodObject.js';\n\nconst ZodResolveMapEntry: z.ZodMiniType<ResolveMapEntry, ResolveMapEntry> = z.lazy(() =>\n matchingZodObject<ResolveMapEntry>({\n name: z.string(),\n version: z.string(),\n path: z.string(),\n dependencies: z.record(z.string(), z.string()),\n requiredBy: z.record(z.string(), z.string()),\n isExternal: z.optional(z.boolean()),\n isLinked: z.optional(z.boolean()),\n scopedVersions: z.optional(\n z.record(\n z.string(),\n z.lazy(() => ZodResolveMapEntry),\n ),\n ),\n }),\n);\n\nexport const ZodResolveMap: z.ZodMiniType<ResolveMap, ResolveMap> = z.record(z.string(), ZodResolveMapEntry);\n"]}
|
|
@@ -1,21 +1,39 @@
|
|
|
1
|
-
import type { Task } from '../types/Task.js';
|
|
2
1
|
import type { DataBus } from '@ms-cloudpack/data-bus';
|
|
2
|
+
import type { Task } from '../types/Task.js';
|
|
3
|
+
import type { TaskStats } from '../types/TaskStats.js';
|
|
3
4
|
/**
|
|
4
5
|
* TaskRunner tracks the status of tasks, manages concurrency, allows reusing task results,
|
|
5
6
|
* and sends notifications about task status to the data bus (currently just used for `start`).
|
|
6
7
|
*
|
|
7
8
|
* NOTE: To enable data bus notifications, you must call `connectToBus()`.
|
|
8
9
|
* `createApiContext` does this with the `taskRunner` passed in.
|
|
10
|
+
* (`createPartialApiContext` does not create or connect a data bus.)
|
|
9
11
|
*/
|
|
10
12
|
export declare class TaskRunner {
|
|
11
13
|
private _bus;
|
|
12
|
-
private _queue;
|
|
13
|
-
|
|
14
|
-
private
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
private readonly _queue;
|
|
15
|
+
/** Stats about task errors/warnings, only updated if a bus is connected */
|
|
16
|
+
private _taskIssues;
|
|
17
|
+
/**
|
|
18
|
+
* Tasks that are currently either running or waiting. (Note that `PQeueue`'s definition of
|
|
19
|
+
* "pending" is slightly different: it only counts tasks that are currently running.)
|
|
20
|
+
*/
|
|
21
|
+
private readonly _pendingTasks;
|
|
22
|
+
/** Tasks that have completed */
|
|
23
|
+
private readonly _completedTasks;
|
|
24
|
+
/**
|
|
25
|
+
* Task IDs where a re-run was requested while the task was running.
|
|
26
|
+
* We let the current task finish, and then re-run it.
|
|
27
|
+
*/
|
|
28
|
+
private readonly _requiresRerun;
|
|
29
|
+
/** All previously-seen tasks (regardless of state) */
|
|
30
|
+
private readonly _allTasks;
|
|
18
31
|
constructor();
|
|
32
|
+
/**
|
|
33
|
+
* Get current task stats. Public for testing.
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
36
|
+
get _taskStats(): Readonly<TaskStats>;
|
|
19
37
|
/**
|
|
20
38
|
* Connects the TaskRunner to the data bus. Tasks will still run without this, but they won't
|
|
21
39
|
* send any notifications to a client (which only matters if a client is listening, e.g.
|
|
@@ -27,29 +45,43 @@ export declare class TaskRunner {
|
|
|
27
45
|
*
|
|
28
46
|
* If a task with the same `id` was already added, it returns either the previous result
|
|
29
47
|
* (if completed) or the promise (if pending). Pass `options.rerun` to force re-running.
|
|
48
|
+
*
|
|
49
|
+
* (Note that any re-runs will use the *original* task function, not the new one.
|
|
50
|
+
* If something has changed that requires a new task function, you should incorporate this
|
|
51
|
+
* into the `id`.)
|
|
30
52
|
*/
|
|
31
53
|
add<TReturn>(task: Task<TReturn>, options?: {
|
|
32
54
|
rerun?: boolean;
|
|
33
55
|
priority?: number;
|
|
34
56
|
}): Promise<TReturn>;
|
|
35
57
|
/**
|
|
36
|
-
*
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
58
|
+
* Dispose in-memory resources of all tasks and clear the TaskRunner's state.
|
|
59
|
+
*/
|
|
60
|
+
dispose(): void;
|
|
61
|
+
/**
|
|
62
|
+
* Clear the result of a specific task (could involve deleting files from disk) and remove
|
|
63
|
+
* it from the TaskRunner's task records.
|
|
64
|
+
*/
|
|
65
|
+
clearResult(id: string): Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* Clear the results of all tasks (might include deleting files on disk) and clear the
|
|
68
|
+
* TaskRunner's task records.
|
|
40
69
|
*
|
|
41
|
-
*
|
|
42
|
-
* to clear the TaskRunner's state before reloading the page.
|
|
70
|
+
* (To only dispose in-memory resources, use `dispose()`.)
|
|
43
71
|
*/
|
|
44
|
-
|
|
72
|
+
clearAllResults(): Promise<void>;
|
|
45
73
|
/**
|
|
46
|
-
*
|
|
74
|
+
* Pauses the TaskRunner (for testing).
|
|
75
|
+
* @internal
|
|
47
76
|
*/
|
|
48
|
-
clear(): void;
|
|
49
|
-
/** Pauses the TaskRunner (for testing). */
|
|
50
77
|
_pause(): void;
|
|
51
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
* Starts or resumes the TaskRunner (for testing).
|
|
80
|
+
* @internal
|
|
81
|
+
*/
|
|
52
82
|
_start(): void;
|
|
83
|
+
/** Remove any records of previous issues with this task from the totals */
|
|
84
|
+
private _removeTaskIssues;
|
|
53
85
|
/**
|
|
54
86
|
* Internal method to report the start of a task to the bus.
|
|
55
87
|
*/
|
|
@@ -58,5 +90,11 @@ export declare class TaskRunner {
|
|
|
58
90
|
* Internal method to report the end of a task to the bus.
|
|
59
91
|
*/
|
|
60
92
|
private _reportEnd;
|
|
93
|
+
/** Get the task list from the data bus, and find the task's index. */
|
|
94
|
+
private _findFromTaskList;
|
|
95
|
+
/**
|
|
96
|
+
* Publish tasks and/or stats to the data bus.
|
|
97
|
+
*/
|
|
98
|
+
private _publishUpdates;
|
|
61
99
|
}
|
|
62
100
|
//# sourceMappingURL=TaskRunner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskRunner.d.ts","sourceRoot":"","sources":["../../src/utilities/TaskRunner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TaskRunner.d.ts","sourceRoot":"","sources":["../../src/utilities/TaskRunner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGtD,OAAO,KAAK,EAAE,IAAI,EAAsB,MAAM,kBAAkB,CAAC;AAGjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AASvD;;;;;;;GAOG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,IAAI,CAAsB;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,2EAA2E;IAC3E,OAAO,CAAC,WAAW,CAAiB;IACpC;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgC;IAC9D,gCAAgC;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAuB;IACvD;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAc;IAC7C,sDAAsD;IACtD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;;IAWvD;;;OAGG;IACH,IAAI,UAAU,IAAI,QAAQ,CAAC,SAAS,CAAC,CAQpC;IAED;;;;OAIG;IACI,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IAIvC;;;;;;;;;OASG;IACH,GAAG,CAAC,OAAO,EACT,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,EACnB,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GACA,OAAO,CAAC,OAAO,CAAC;IAyEnB;;OAEG;IAGH,OAAO,IAAI,IAAI;IAYf;;;OAGG;IACG,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB5C;;;;;OAKG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IActC;;;OAGG;IACH,MAAM,IAAI,IAAI;IAId;;;OAGG;IACH,MAAM,IAAI,IAAI;IAId,2EAA2E;IAC3E,OAAO,CAAC,iBAAiB;IAOzB;;OAEG;IACH,OAAO,CAAC,YAAY;IAqBpB;;OAEG;IACH,OAAO,CAAC,UAAU;IA0ClB,sEAAsE;IACtE,OAAO,CAAC,iBAAiB;IAMzB;;OAEG;IACH,OAAO,CAAC,eAAe;CAMxB"}
|
|
@@ -1,27 +1,52 @@
|
|
|
1
1
|
import PQueue from 'p-queue';
|
|
2
|
-
import { taskListSource, taskStatsSource } from '../
|
|
2
|
+
import { taskListSource, taskStatsSource } from '../data/busSources.js';
|
|
3
3
|
/**
|
|
4
4
|
* TaskRunner tracks the status of tasks, manages concurrency, allows reusing task results,
|
|
5
5
|
* and sends notifications about task status to the data bus (currently just used for `start`).
|
|
6
6
|
*
|
|
7
7
|
* NOTE: To enable data bus notifications, you must call `connectToBus()`.
|
|
8
8
|
* `createApiContext` does this with the `taskRunner` passed in.
|
|
9
|
+
* (`createPartialApiContext` does not create or connect a data bus.)
|
|
9
10
|
*/
|
|
10
11
|
export class TaskRunner {
|
|
11
12
|
_bus;
|
|
12
13
|
_queue;
|
|
13
|
-
|
|
14
|
+
/** Stats about task errors/warnings, only updated if a bus is connected */
|
|
15
|
+
_taskIssues;
|
|
16
|
+
/**
|
|
17
|
+
* Tasks that are currently either running or waiting. (Note that `PQeueue`'s definition of
|
|
18
|
+
* "pending" is slightly different: it only counts tasks that are currently running.)
|
|
19
|
+
*/
|
|
14
20
|
_pendingTasks;
|
|
21
|
+
/** Tasks that have completed */
|
|
15
22
|
_completedTasks;
|
|
23
|
+
/**
|
|
24
|
+
* Task IDs where a re-run was requested while the task was running.
|
|
25
|
+
* We let the current task finish, and then re-run it.
|
|
26
|
+
*/
|
|
16
27
|
_requiresRerun;
|
|
17
|
-
|
|
28
|
+
/** All previously-seen tasks (regardless of state) */
|
|
29
|
+
_allTasks;
|
|
18
30
|
constructor() {
|
|
19
31
|
this._queue = new PQueue({ concurrency: 10 });
|
|
20
|
-
this.
|
|
32
|
+
this._taskIssues = { totalErrors: 0, totalWarnings: 0, taskWarnings: {}, taskErrors: {} };
|
|
21
33
|
this._pendingTasks = new Map();
|
|
22
34
|
this._completedTasks = new Map();
|
|
23
35
|
this._requiresRerun = new Set();
|
|
24
|
-
this.
|
|
36
|
+
this._allTasks = new Map();
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get current task stats. Public for testing.
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
42
|
+
get _taskStats() {
|
|
43
|
+
return {
|
|
44
|
+
status: this._pendingTasks.size ? 'pending' : 'idle',
|
|
45
|
+
remainingTasks: this._pendingTasks.size,
|
|
46
|
+
totalTasks: this._allTasks.size,
|
|
47
|
+
totalErrors: this._taskIssues.totalErrors,
|
|
48
|
+
totalWarnings: this._taskIssues.totalWarnings,
|
|
49
|
+
};
|
|
25
50
|
}
|
|
26
51
|
/**
|
|
27
52
|
* Connects the TaskRunner to the data bus. Tasks will still run without this, but they won't
|
|
@@ -36,12 +61,16 @@ export class TaskRunner {
|
|
|
36
61
|
*
|
|
37
62
|
* If a task with the same `id` was already added, it returns either the previous result
|
|
38
63
|
* (if completed) or the promise (if pending). Pass `options.rerun` to force re-running.
|
|
64
|
+
*
|
|
65
|
+
* (Note that any re-runs will use the *original* task function, not the new one.
|
|
66
|
+
* If something has changed that requires a new task function, you should incorporate this
|
|
67
|
+
* into the `id`.)
|
|
39
68
|
*/
|
|
40
69
|
add(task, options) {
|
|
41
70
|
const { name, id, execute } = task;
|
|
42
71
|
const { rerun, priority } = options || {};
|
|
43
|
-
if (!this.
|
|
44
|
-
this.
|
|
72
|
+
if (!this._allTasks.has(id)) {
|
|
73
|
+
this._allTasks.set(id, task);
|
|
45
74
|
}
|
|
46
75
|
// Check if we are already completed the task with that id.
|
|
47
76
|
const action = this._completedTasks.get(id);
|
|
@@ -58,18 +87,26 @@ export class TaskRunner {
|
|
|
58
87
|
}
|
|
59
88
|
const resultPromise = (async () => {
|
|
60
89
|
let taskResult;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
90
|
+
let taskError;
|
|
91
|
+
try {
|
|
92
|
+
do {
|
|
93
|
+
// Delete from rerun list (if present).
|
|
94
|
+
this._requiresRerun.delete(id);
|
|
95
|
+
taskResult = await this._queue.add(execute,
|
|
96
|
+
// Removes void from return type.
|
|
97
|
+
// Read more on: https://github.com/sindresorhus/p-queue/issues/175
|
|
98
|
+
{ throwOnTimeout: true, priority });
|
|
99
|
+
} while (this._requiresRerun.has(id));
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
taskError = error;
|
|
103
|
+
// Re-throw the error, but `finally` will handle completion
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
// Delete from pending list.
|
|
108
|
+
this._pendingTasks.delete(id);
|
|
109
|
+
this._reportEnd(task, taskResult, taskError);
|
|
73
110
|
}
|
|
74
111
|
// Extra check to ensure that the task returned a value.
|
|
75
112
|
// It should never throw, if it does we have a bug.
|
|
@@ -81,124 +118,165 @@ export class TaskRunner {
|
|
|
81
118
|
return taskResult;
|
|
82
119
|
})();
|
|
83
120
|
this._pendingTasks.set(id, resultPromise);
|
|
84
|
-
this._completedTasks.delete(id);
|
|
85
|
-
if (
|
|
86
|
-
this.
|
|
121
|
+
const wasCompleted = this._completedTasks.delete(id);
|
|
122
|
+
if (wasCompleted) {
|
|
123
|
+
this._removeTaskIssues(task.id);
|
|
87
124
|
}
|
|
125
|
+
this._reportStart(task);
|
|
88
126
|
return resultPromise;
|
|
89
127
|
}
|
|
90
128
|
/**
|
|
91
|
-
*
|
|
92
|
-
* and then removes it from the TaskRunner.
|
|
93
|
-
*
|
|
94
|
-
* This is useful when the state of a task needs to be cleared.
|
|
95
|
-
*
|
|
96
|
-
* It is intended to be used by the api server
|
|
97
|
-
* to clear the TaskRunner's state before reloading the page.
|
|
129
|
+
* Dispose in-memory resources of all tasks and clear the TaskRunner's state.
|
|
98
130
|
*/
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
});
|
|
106
|
-
this._prevTasks.get(id)?.onDispose?.();
|
|
107
|
-
this._prevTasks.delete(id);
|
|
108
|
-
this._requiresRerun.delete(id);
|
|
109
|
-
if (this._pendingTasks.has(id)) {
|
|
110
|
-
this._pendingTasks.delete(id);
|
|
111
|
-
this._taskStats.remainingTasks = this._pendingTasks.size;
|
|
131
|
+
// NOTE: This is also used by clearAllResults(), so if it's updated to do anything that
|
|
132
|
+
// renders the TaskRunner unusable/finished, the common parts should be refactored out.
|
|
133
|
+
dispose() {
|
|
134
|
+
this._queue.clear();
|
|
135
|
+
for (const task of this._allTasks.values()) {
|
|
136
|
+
task.dispose?.();
|
|
112
137
|
}
|
|
138
|
+
this._allTasks.clear();
|
|
139
|
+
this._pendingTasks.clear();
|
|
140
|
+
this._completedTasks.clear();
|
|
141
|
+
this._requiresRerun.clear();
|
|
142
|
+
this._taskIssues = { totalErrors: 0, totalWarnings: 0, taskWarnings: {}, taskErrors: {} };
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Clear the result of a specific task (could involve deleting files from disk) and remove
|
|
146
|
+
* it from the TaskRunner's task records.
|
|
147
|
+
*/
|
|
148
|
+
async clearResult(id) {
|
|
149
|
+
const task = this._allTasks.get(id);
|
|
150
|
+
task?.dispose?.();
|
|
151
|
+
await task?.clear?.();
|
|
152
|
+
this._allTasks.delete(id);
|
|
153
|
+
this._requiresRerun.delete(id);
|
|
154
|
+
this._pendingTasks.delete(id);
|
|
113
155
|
this._completedTasks.delete(id);
|
|
156
|
+
this._removeTaskIssues(id);
|
|
157
|
+
if (this._bus) {
|
|
158
|
+
const { tasks, index } = this._findFromTaskList(id);
|
|
159
|
+
if (index !== -1) {
|
|
160
|
+
tasks.splice(index, 1);
|
|
161
|
+
this._publishUpdates({ tasks, stats: true });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
114
164
|
}
|
|
115
165
|
/**
|
|
116
|
-
*
|
|
166
|
+
* Clear the results of all tasks (might include deleting files on disk) and clear the
|
|
167
|
+
* TaskRunner's task records.
|
|
168
|
+
*
|
|
169
|
+
* (To only dispose in-memory resources, use `dispose()`.)
|
|
117
170
|
*/
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
this.
|
|
121
|
-
for (const
|
|
122
|
-
|
|
171
|
+
async clearAllResults() {
|
|
172
|
+
// Publish the empty task list first since deleting things might take awhile.
|
|
173
|
+
this._publishUpdates({ tasks: [] });
|
|
174
|
+
for (const task of this._allTasks.values()) {
|
|
175
|
+
task.dispose?.();
|
|
176
|
+
await task.clear?.();
|
|
123
177
|
}
|
|
178
|
+
this.dispose();
|
|
179
|
+
// Publish new stats after clearing everything (otherwise the calculated values will be wrong)
|
|
180
|
+
this._publishUpdates({ stats: true });
|
|
124
181
|
}
|
|
125
|
-
/**
|
|
182
|
+
/**
|
|
183
|
+
* Pauses the TaskRunner (for testing).
|
|
184
|
+
* @internal
|
|
185
|
+
*/
|
|
126
186
|
_pause() {
|
|
127
187
|
this._queue.pause();
|
|
128
188
|
}
|
|
129
|
-
/**
|
|
189
|
+
/**
|
|
190
|
+
* Starts or resumes the TaskRunner (for testing).
|
|
191
|
+
* @internal
|
|
192
|
+
*/
|
|
130
193
|
_start() {
|
|
131
194
|
this._queue.start();
|
|
132
195
|
}
|
|
196
|
+
/** Remove any records of previous issues with this task from the totals */
|
|
197
|
+
_removeTaskIssues(id) {
|
|
198
|
+
this._taskIssues.totalErrors -= this._taskIssues.taskErrors[id] || 0;
|
|
199
|
+
this._taskIssues.totalWarnings -= this._taskIssues.taskWarnings[id] || 0;
|
|
200
|
+
delete this._taskIssues.taskErrors[id];
|
|
201
|
+
delete this._taskIssues.taskWarnings[id];
|
|
202
|
+
}
|
|
133
203
|
/**
|
|
134
204
|
* Internal method to report the start of a task to the bus.
|
|
135
205
|
*/
|
|
136
|
-
_reportStart(
|
|
137
|
-
if (!this._bus)
|
|
206
|
+
_reportStart(task) {
|
|
207
|
+
if (!this._bus || !task.getStartDescription)
|
|
138
208
|
return;
|
|
139
|
-
const
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
if (!previousDescription) {
|
|
145
|
-
this._taskStats.totalTasks++;
|
|
146
|
-
}
|
|
147
|
-
if (previousDescription?.status === 'complete') {
|
|
148
|
-
this._taskStats.totalErrors -= previousDescription.errors?.length || 0;
|
|
149
|
-
this._taskStats.totalWarnings -= previousDescription.warnings?.length || 0;
|
|
150
|
-
}
|
|
151
|
-
this._taskStats.remainingTasks = this._pendingTasks.size;
|
|
152
|
-
this._taskStats.status = 'pending';
|
|
153
|
-
const task = {
|
|
154
|
-
...description,
|
|
209
|
+
const { tasks, index } = this._findFromTaskList(task.id);
|
|
210
|
+
const taskDesc = {
|
|
211
|
+
id: task.id,
|
|
212
|
+
name: task.name,
|
|
213
|
+
...task.getStartDescription(),
|
|
155
214
|
status: 'pending',
|
|
156
|
-
startTime: now,
|
|
215
|
+
startTime: Date.now(),
|
|
157
216
|
};
|
|
158
217
|
if (index === -1) {
|
|
159
|
-
tasks.push(
|
|
218
|
+
tasks.push(taskDesc);
|
|
160
219
|
}
|
|
161
220
|
else {
|
|
162
|
-
tasks[index] =
|
|
221
|
+
tasks[index] = taskDesc;
|
|
163
222
|
}
|
|
164
|
-
|
|
165
|
-
bus.publish(taskListSource, { tasks });
|
|
223
|
+
this._publishUpdates({ tasks, stats: true });
|
|
166
224
|
}
|
|
167
225
|
/**
|
|
168
226
|
* Internal method to report the end of a task to the bus.
|
|
169
227
|
*/
|
|
170
|
-
_reportEnd(
|
|
171
|
-
if (!this._bus)
|
|
228
|
+
_reportEnd(task, taskResult, taskError) {
|
|
229
|
+
if (!this._bus || !task.getEndDescription)
|
|
172
230
|
return;
|
|
173
|
-
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
231
|
+
// Replace the usual description with an error if relevant
|
|
232
|
+
const description = taskError
|
|
233
|
+
? {
|
|
234
|
+
errors: [
|
|
235
|
+
{
|
|
236
|
+
source: 'running task',
|
|
237
|
+
text: taskError instanceof Error ? taskError.stack || taskError.message : String(taskError),
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
}
|
|
241
|
+
: task.getEndDescription(taskResult);
|
|
242
|
+
const errorCount = description.errors?.length || 0;
|
|
243
|
+
const warningCount = description.warnings?.length || 0;
|
|
244
|
+
if (errorCount) {
|
|
245
|
+
this._taskIssues.taskErrors[task.id] = errorCount;
|
|
246
|
+
this._taskIssues.totalErrors += errorCount;
|
|
247
|
+
}
|
|
248
|
+
if (warningCount) {
|
|
249
|
+
this._taskIssues.taskWarnings[task.id] = warningCount;
|
|
250
|
+
this._taskIssues.totalWarnings += warningCount;
|
|
251
|
+
}
|
|
252
|
+
const { tasks, index } = this._findFromTaskList(task.id);
|
|
253
|
+
const startDescription = tasks[index];
|
|
254
|
+
if (startDescription) {
|
|
255
|
+
const now = Date.now();
|
|
182
256
|
tasks[index] = {
|
|
183
|
-
...
|
|
257
|
+
...startDescription,
|
|
184
258
|
...description,
|
|
185
259
|
status: 'complete',
|
|
186
|
-
|
|
260
|
+
duration: now - startDescription.startTime,
|
|
187
261
|
lastUpdated: now,
|
|
188
262
|
};
|
|
189
|
-
|
|
190
|
-
this._taskStats.status = 'idle';
|
|
191
|
-
}
|
|
192
|
-
bus.publish(taskStatsSource, this._taskStats);
|
|
193
|
-
bus.publish(taskListSource, { tasks });
|
|
263
|
+
this._publishUpdates({ tasks, stats: true });
|
|
194
264
|
}
|
|
195
265
|
}
|
|
266
|
+
/** Get the task list from the data bus, and find the task's index. */
|
|
267
|
+
_findFromTaskList(id) {
|
|
268
|
+
const tasks = this._bus?.getData(taskListSource.path)?.tasks || [];
|
|
269
|
+
const index = tasks.findIndex((t) => t.id === id);
|
|
270
|
+
return { tasks, index };
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Publish tasks and/or stats to the data bus.
|
|
274
|
+
*/
|
|
275
|
+
_publishUpdates(params) {
|
|
276
|
+
const { tasks, stats } = params;
|
|
277
|
+
// Publish using .path for easier testing
|
|
278
|
+
stats && this._bus?.publish(taskStatsSource.path, this._taskStats);
|
|
279
|
+
tasks && this._bus?.publish(taskListSource.path, { tasks });
|
|
280
|
+
}
|
|
196
281
|
}
|
|
197
|
-
const getDefaultTaskStats = () => ({
|
|
198
|
-
status: 'idle',
|
|
199
|
-
remainingTasks: 0,
|
|
200
|
-
totalTasks: 0,
|
|
201
|
-
totalErrors: 0,
|
|
202
|
-
totalWarnings: 0,
|
|
203
|
-
});
|
|
204
282
|
//# sourceMappingURL=TaskRunner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskRunner.js","sourceRoot":"","sources":["../../src/utilities/TaskRunner.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TaskStartDescription } from '../types/TaskStartDescription.js';\nimport type { TaskEndDescription } from '../types/TaskEndDescription.js';\nimport type { Task } from '../types/Task.js';\nimport type { TaskStats } from '../types/TaskStats.js';\nimport type { TaskList } from '../types/TaskList.js';\nimport PQueue from 'p-queue';\nimport { taskListSource, taskStatsSource, type TaskDescription } from '../index.browser.js';\nimport type { DataBus } from '@ms-cloudpack/data-bus';\n\n/**\n * TaskRunner tracks the status of tasks, manages concurrency, allows reusing task results,\n * and sends notifications about task status to the data bus (currently just used for `start`).\n *\n * NOTE: To enable data bus notifications, you must call `connectToBus()`.\n * `createApiContext` does this with the `taskRunner` passed in.\n */\nexport class TaskRunner {\n private _bus: DataBus | undefined;\n private _queue: PQueue;\n private _taskStats: TaskStats;\n private _pendingTasks: Map<string, Promise<unknown>>;\n private _completedTasks: Map<string, unknown>;\n private _requiresRerun: Set<string>;\n private _prevTasks: Map<string, Task<unknown>>;\n\n constructor() {\n this._queue = new PQueue({ concurrency: 10 });\n this._taskStats = getDefaultTaskStats();\n this._pendingTasks = new Map();\n this._completedTasks = new Map();\n this._requiresRerun = new Set();\n this._prevTasks = new Map();\n }\n\n /**\n * Connects the TaskRunner to the data bus. Tasks will still run without this, but they won't\n * send any notifications to a client (which only matters if a client is listening, e.g.\n * the browser while running `start`).\n */\n public connectToBus(bus: DataBus): void {\n this._bus = bus;\n }\n\n /**\n * Enqueue a task and return its result promise.\n *\n * If a task with the same `id` was already added, it returns either the previous result\n * (if completed) or the promise (if pending). Pass `options.rerun` to force re-running.\n */\n add<TReturn>(\n task: Task<TReturn>,\n options?: {\n rerun?: boolean;\n priority?: number;\n },\n ): Promise<TReturn> {\n const { name, id, execute } = task;\n const { rerun, priority } = options || {};\n\n if (!this._prevTasks.has(id)) {\n this._prevTasks.set(id, task as Task<unknown>);\n }\n\n // Check if we are already completed the task with that id.\n const action = this._completedTasks.get(id) as TReturn | undefined;\n if (action !== undefined && !rerun) {\n return Promise.resolve(action);\n }\n\n // Check if we are already running the task with that id.\n const pending = this._pendingTasks.get(id) as Promise<TReturn> | undefined;\n if (pending !== undefined) {\n if (rerun) {\n this._requiresRerun.add(id);\n }\n return pending;\n }\n\n const resultPromise: Promise<TReturn> = (async () => {\n let taskResult: TReturn | undefined;\n\n do {\n // Delete from rerun list (if present).\n this._requiresRerun.delete(id);\n\n taskResult = await this._queue.add(\n execute,\n // Removes void from return type.\n // Read more on: https://github.com/sindresorhus/p-queue/issues/175\n { throwOnTimeout: true, priority },\n );\n } while (this._requiresRerun.has(id));\n\n // Delete from pending list.\n this._pendingTasks.delete(id);\n if (task.getEndDescription) {\n this._reportEnd(id, task.getEndDescription(taskResult));\n }\n\n // Extra check to ensure that the task returned a value.\n // It should never throw, if it does we have a bug.\n if (taskResult === undefined) {\n throw new Error(`Task \"${name}:${id}\" returned undefined, without throwing an error, which was unexpected.`);\n }\n\n // Update finished Tasks.\n this._completedTasks.set(id, taskResult);\n\n return taskResult;\n })();\n\n this._pendingTasks.set(id, resultPromise);\n this._completedTasks.delete(id);\n if (task.getStartDescription) {\n this._reportStart(id, task.getStartDescription());\n }\n\n return resultPromise;\n }\n\n /**\n * The remove method disposes a task if available\n * and then removes it from the TaskRunner.\n *\n * This is useful when the state of a task needs to be cleared.\n *\n * It is intended to be used by the api server\n * to clear the TaskRunner's state before reloading the page.\n */\n remove(id: string): void {\n this._prevTasks\n .get(id)\n ?.dispose?.()\n .catch(() => {\n console.debug(`Error disposing task: ${id}`);\n });\n this._prevTasks.get(id)?.onDispose?.();\n this._prevTasks.delete(id);\n this._requiresRerun.delete(id);\n if (this._pendingTasks.has(id)) {\n this._pendingTasks.delete(id);\n this._taskStats.remainingTasks = this._pendingTasks.size;\n }\n this._completedTasks.delete(id);\n }\n /**\n * The clear method disposes all tasks and clears the TaskRunner.\n */\n clear(): void {\n this._taskStats = getDefaultTaskStats();\n this._bus?.publish(taskListSource, { tasks: [] });\n\n for (const id of this._prevTasks.keys()) {\n this.remove(id);\n }\n }\n\n /** Pauses the TaskRunner (for testing). */\n _pause(): void {\n this._queue.pause();\n }\n\n /** Starts or resumes the TaskRunner (for testing). */\n _start(): void {\n this._queue.start();\n }\n\n /**\n * Internal method to report the start of a task to the bus.\n */\n private _reportStart(id: string, description: TaskStartDescription): void {\n if (!this._bus) return;\n\n const bus = this._bus;\n const { tasks } = bus.getData<TaskList>(taskListSource.path) || { tasks: [] };\n const index = tasks.findIndex((t) => t.id === id);\n const previousDescription = tasks[index];\n const now = new Date().getTime();\n\n if (!previousDescription) {\n this._taskStats.totalTasks++;\n }\n\n if (previousDescription?.status === 'complete') {\n this._taskStats.totalErrors -= previousDescription.errors?.length || 0;\n this._taskStats.totalWarnings -= previousDescription.warnings?.length || 0;\n }\n\n this._taskStats.remainingTasks = this._pendingTasks.size;\n this._taskStats.status = 'pending';\n\n const task: TaskDescription = {\n ...description,\n status: 'pending',\n startTime: now,\n };\n if (index === -1) {\n tasks.push(task);\n } else {\n tasks[index] = task;\n }\n\n bus.publish(taskStatsSource, this._taskStats);\n bus.publish(taskListSource, { tasks });\n }\n\n /**\n * Internal method to report the end of a task to the bus.\n */\n private _reportEnd(id: string, description: TaskEndDescription): void {\n if (!this._bus) return;\n\n const bus = this._bus;\n const { tasks } = bus.getData<TaskList>(taskListSource.path) || { tasks: [] };\n const index = tasks.findIndex((t) => t.id === id);\n const previousDescription = tasks[index];\n const now = new Date().getTime();\n\n if (previousDescription) {\n this._taskStats.remainingTasks = this._pendingTasks.size;\n this._taskStats.totalErrors += description?.errors?.length || 0;\n this._taskStats.totalWarnings += description?.warnings?.length || 0;\n\n tasks[index] = {\n ...previousDescription,\n ...description,\n status: 'complete',\n durationMilliseconds: now - previousDescription.startTime,\n lastUpdated: now,\n };\n\n if (this._taskStats.remainingTasks === 0) {\n this._taskStats.status = 'idle';\n }\n\n bus.publish(taskStatsSource, this._taskStats);\n bus.publish(taskListSource, { tasks });\n }\n }\n}\n\nconst getDefaultTaskStats: () => TaskStats = () => ({\n status: 'idle',\n remainingTasks: 0,\n totalTasks: 0,\n totalErrors: 0,\n totalWarnings: 0,\n});\n"]}
|
|
1
|
+
{"version":3,"file":"TaskRunner.js","sourceRoot":"","sources":["../../src/utilities/TaskRunner.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DataBus } from '@ms-cloudpack/data-bus';\nimport PQueue from 'p-queue';\nimport { taskListSource, taskStatsSource } from '../data/busSources.js';\nimport type { Task, TaskEndDescription } from '../types/Task.js';\nimport type { TaskDescription } from '../types/TaskDescription.js';\nimport type { TaskList } from '../types/TaskList.js';\nimport type { TaskStats } from '../types/TaskStats.js';\n\ninterface TaskIssueStats extends Pick<TaskStats, 'totalErrors' | 'totalWarnings'> {\n /** Mapping from ID to count */\n taskWarnings: Record<string, number>;\n /** Mapping from ID to count */\n taskErrors: Record<string, number>;\n}\n\n/**\n * TaskRunner tracks the status of tasks, manages concurrency, allows reusing task results,\n * and sends notifications about task status to the data bus (currently just used for `start`).\n *\n * NOTE: To enable data bus notifications, you must call `connectToBus()`.\n * `createApiContext` does this with the `taskRunner` passed in.\n * (`createPartialApiContext` does not create or connect a data bus.)\n */\nexport class TaskRunner {\n private _bus: DataBus | undefined;\n private readonly _queue: PQueue;\n /** Stats about task errors/warnings, only updated if a bus is connected */\n private _taskIssues: TaskIssueStats;\n /**\n * Tasks that are currently either running or waiting. (Note that `PQeueue`'s definition of\n * \"pending\" is slightly different: it only counts tasks that are currently running.)\n */\n private readonly _pendingTasks: Map<string, Promise<unknown>>;\n /** Tasks that have completed */\n private readonly _completedTasks: Map<string, unknown>;\n /**\n * Task IDs where a re-run was requested while the task was running.\n * We let the current task finish, and then re-run it.\n */\n private readonly _requiresRerun: Set<string>;\n /** All previously-seen tasks (regardless of state) */\n private readonly _allTasks: Map<string, Task<unknown>>;\n\n constructor() {\n this._queue = new PQueue({ concurrency: 10 });\n this._taskIssues = { totalErrors: 0, totalWarnings: 0, taskWarnings: {}, taskErrors: {} };\n this._pendingTasks = new Map();\n this._completedTasks = new Map();\n this._requiresRerun = new Set();\n this._allTasks = new Map();\n }\n\n /**\n * Get current task stats. Public for testing.\n * @internal\n */\n get _taskStats(): Readonly<TaskStats> {\n return {\n status: this._pendingTasks.size ? 'pending' : 'idle',\n remainingTasks: this._pendingTasks.size,\n totalTasks: this._allTasks.size,\n totalErrors: this._taskIssues.totalErrors,\n totalWarnings: this._taskIssues.totalWarnings,\n };\n }\n\n /**\n * Connects the TaskRunner to the data bus. Tasks will still run without this, but they won't\n * send any notifications to a client (which only matters if a client is listening, e.g.\n * the browser while running `start`).\n */\n public connectToBus(bus: DataBus): void {\n this._bus = bus;\n }\n\n /**\n * Enqueue a task and return its result promise.\n *\n * If a task with the same `id` was already added, it returns either the previous result\n * (if completed) or the promise (if pending). Pass `options.rerun` to force re-running.\n *\n * (Note that any re-runs will use the *original* task function, not the new one.\n * If something has changed that requires a new task function, you should incorporate this\n * into the `id`.)\n */\n add<TReturn>(\n task: Task<TReturn>,\n options?: {\n rerun?: boolean;\n priority?: number;\n },\n ): Promise<TReturn> {\n const { name, id, execute } = task;\n const { rerun, priority } = options || {};\n\n if (!this._allTasks.has(id)) {\n this._allTasks.set(id, task as Task<unknown>);\n }\n\n // Check if we are already completed the task with that id.\n const action = this._completedTasks.get(id) as TReturn | undefined;\n if (action !== undefined && !rerun) {\n return Promise.resolve(action);\n }\n\n // Check if we are already running the task with that id.\n const pending = this._pendingTasks.get(id) as Promise<TReturn> | undefined;\n if (pending !== undefined) {\n if (rerun) {\n this._requiresRerun.add(id);\n }\n return pending;\n }\n\n const resultPromise: Promise<TReturn> = (async () => {\n let taskResult: TReturn | undefined;\n let taskError: unknown;\n\n try {\n do {\n // Delete from rerun list (if present).\n this._requiresRerun.delete(id);\n\n taskResult = await this._queue.add(\n execute,\n // Removes void from return type.\n // Read more on: https://github.com/sindresorhus/p-queue/issues/175\n { throwOnTimeout: true, priority },\n );\n } while (this._requiresRerun.has(id));\n } catch (error) {\n taskError = error;\n // Re-throw the error, but `finally` will handle completion\n throw error;\n } finally {\n // Delete from pending list.\n this._pendingTasks.delete(id);\n\n this._reportEnd(task, taskResult, taskError);\n }\n\n // Extra check to ensure that the task returned a value.\n // It should never throw, if it does we have a bug.\n if (taskResult === undefined) {\n throw new Error(`Task \"${name}:${id}\" returned undefined, without throwing an error, which was unexpected.`);\n }\n\n // Update finished Tasks.\n this._completedTasks.set(id, taskResult);\n\n return taskResult;\n })();\n\n this._pendingTasks.set(id, resultPromise);\n const wasCompleted = this._completedTasks.delete(id);\n if (wasCompleted) {\n this._removeTaskIssues(task.id);\n }\n\n this._reportStart<TReturn>(task);\n\n return resultPromise;\n }\n\n /**\n * Dispose in-memory resources of all tasks and clear the TaskRunner's state.\n */\n // NOTE: This is also used by clearAllResults(), so if it's updated to do anything that\n // renders the TaskRunner unusable/finished, the common parts should be refactored out.\n dispose(): void {\n this._queue.clear();\n for (const task of this._allTasks.values()) {\n task.dispose?.();\n }\n this._allTasks.clear();\n this._pendingTasks.clear();\n this._completedTasks.clear();\n this._requiresRerun.clear();\n this._taskIssues = { totalErrors: 0, totalWarnings: 0, taskWarnings: {}, taskErrors: {} };\n }\n\n /**\n * Clear the result of a specific task (could involve deleting files from disk) and remove\n * it from the TaskRunner's task records.\n */\n async clearResult(id: string): Promise<void> {\n const task = this._allTasks.get(id);\n task?.dispose?.();\n await task?.clear?.();\n\n this._allTasks.delete(id);\n this._requiresRerun.delete(id);\n this._pendingTasks.delete(id);\n this._completedTasks.delete(id);\n this._removeTaskIssues(id);\n\n if (this._bus) {\n const { tasks, index } = this._findFromTaskList(id);\n if (index !== -1) {\n tasks.splice(index, 1);\n this._publishUpdates({ tasks, stats: true });\n }\n }\n }\n\n /**\n * Clear the results of all tasks (might include deleting files on disk) and clear the\n * TaskRunner's task records.\n *\n * (To only dispose in-memory resources, use `dispose()`.)\n */\n async clearAllResults(): Promise<void> {\n // Publish the empty task list first since deleting things might take awhile.\n this._publishUpdates({ tasks: [] });\n\n for (const task of this._allTasks.values()) {\n task.dispose?.();\n await task.clear?.();\n }\n this.dispose();\n\n // Publish new stats after clearing everything (otherwise the calculated values will be wrong)\n this._publishUpdates({ stats: true });\n }\n\n /**\n * Pauses the TaskRunner (for testing).\n * @internal\n */\n _pause(): void {\n this._queue.pause();\n }\n\n /**\n * Starts or resumes the TaskRunner (for testing).\n * @internal\n */\n _start(): void {\n this._queue.start();\n }\n\n /** Remove any records of previous issues with this task from the totals */\n private _removeTaskIssues(id: string): void {\n this._taskIssues.totalErrors -= this._taskIssues.taskErrors[id] || 0;\n this._taskIssues.totalWarnings -= this._taskIssues.taskWarnings[id] || 0;\n delete this._taskIssues.taskErrors[id];\n delete this._taskIssues.taskWarnings[id];\n }\n\n /**\n * Internal method to report the start of a task to the bus.\n */\n private _reportStart<TReturn>(task: Task<TReturn>): void {\n if (!this._bus || !task.getStartDescription) return;\n\n const { tasks, index } = this._findFromTaskList(task.id);\n\n const taskDesc: TaskDescription = {\n id: task.id,\n name: task.name,\n ...task.getStartDescription(),\n status: 'pending',\n startTime: Date.now(),\n };\n if (index === -1) {\n tasks.push(taskDesc);\n } else {\n tasks[index] = taskDesc;\n }\n\n this._publishUpdates({ tasks, stats: true });\n }\n\n /**\n * Internal method to report the end of a task to the bus.\n */\n private _reportEnd<TReturn>(task: Task<TReturn>, taskResult: TReturn | undefined, taskError: unknown): void {\n if (!this._bus || !task.getEndDescription) return;\n\n // Replace the usual description with an error if relevant\n const description: TaskEndDescription = taskError\n ? {\n errors: [\n {\n source: 'running task',\n text: taskError instanceof Error ? taskError.stack || taskError.message : String(taskError),\n },\n ],\n }\n : task.getEndDescription(taskResult);\n const errorCount = description.errors?.length || 0;\n const warningCount = description.warnings?.length || 0;\n if (errorCount) {\n this._taskIssues.taskErrors[task.id] = errorCount;\n this._taskIssues.totalErrors += errorCount;\n }\n if (warningCount) {\n this._taskIssues.taskWarnings[task.id] = warningCount;\n this._taskIssues.totalWarnings += warningCount;\n }\n\n const { tasks, index } = this._findFromTaskList(task.id);\n const startDescription = tasks[index];\n\n if (startDescription) {\n const now = Date.now();\n tasks[index] = {\n ...startDescription,\n ...description,\n status: 'complete',\n duration: now - startDescription.startTime,\n lastUpdated: now,\n };\n\n this._publishUpdates({ tasks, stats: true });\n }\n }\n\n /** Get the task list from the data bus, and find the task's index. */\n private _findFromTaskList(id: string): { tasks: TaskDescription[]; index: number } {\n const tasks = this._bus?.getData<TaskList>(taskListSource.path)?.tasks || [];\n const index = tasks.findIndex((t) => t.id === id);\n return { tasks, index };\n }\n\n /**\n * Publish tasks and/or stats to the data bus.\n */\n private _publishUpdates(params: { tasks?: TaskDescription[]; stats?: boolean }): void {\n const { tasks, stats } = params;\n // Publish using .path for easier testing\n stats && this._bus?.publish<TaskStats>(taskStatsSource.path, this._taskStats);\n tasks && this._bus?.publish<TaskList>(taskListSource.path, { tasks });\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createBundleTask.d.ts","sourceRoot":"","sources":["../../src/utilities/createBundleTask.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"createBundleTask.d.ts","sourceRoot":"","sources":["../../src/utilities/createBundleTask.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAc,KAAK,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC7F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,iBAAiB,GACxB,cAAc,CAAC,eAAe,EAAE,MAAM,iBAAiB,CAAC,SAAS,CAAC,GAAG,WAAW,GAAG,oBAAoB,GAAG,MAAM,CAAC,GAClH,IAAI,CAAC,aAAa,CAAC,CA6DrB"}
|