@fnndsc/cumin 3.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +78 -0
- package/dist/activities/chrisActivity.d.ts +19 -0
- package/dist/activities/chrisActivity.js +29 -0
- package/dist/activities/chrisActivity.js.map +1 -0
- package/dist/cache/index.d.ts +9 -0
- package/dist/cache/index.js +15 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/listCache.d.ts +182 -0
- package/dist/cache/listCache.js +266 -0
- package/dist/cache/listCache.js.map +1 -0
- package/dist/cache/procCache.d.ts +150 -0
- package/dist/cache/procCache.js +257 -0
- package/dist/cache/procCache.js.map +1 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.js +43 -0
- package/dist/cli.js.map +1 -0
- package/dist/compute/computeResources.d.ts +65 -0
- package/dist/compute/computeResources.js +113 -0
- package/dist/compute/computeResources.js.map +1 -0
- package/dist/config/config.d.ts +221 -0
- package/dist/config/config.js +350 -0
- package/dist/config/config.js.map +1 -0
- package/dist/connect/chrisConnection.d.ts +121 -0
- package/dist/connect/chrisConnection.js +303 -0
- package/dist/connect/chrisConnection.js.map +1 -0
- package/dist/context/chrisContext.d.ts +110 -0
- package/dist/context/chrisContext.js +324 -0
- package/dist/context/chrisContext.js.map +1 -0
- package/dist/error/errorStack.d.ts +115 -0
- package/dist/error/errorStack.js +175 -0
- package/dist/error/errorStack.js.map +1 -0
- package/dist/feeds/chrisFeed.d.ts +188 -0
- package/dist/feeds/chrisFeed.js +432 -0
- package/dist/feeds/chrisFeed.js.map +1 -0
- package/dist/filebrowser/chrisFileBrowser.d.ts +77 -0
- package/dist/filebrowser/chrisFileBrowser.js +134 -0
- package/dist/filebrowser/chrisFileBrowser.js.map +1 -0
- package/dist/filebrowser/chrisFiles.d.ts +67 -0
- package/dist/filebrowser/chrisFiles.js +130 -0
- package/dist/filebrowser/chrisFiles.js.map +1 -0
- package/dist/filebrowser/chrisPACS.d.ts +43 -0
- package/dist/filebrowser/chrisPACS.js +103 -0
- package/dist/filebrowser/chrisPACS.js.map +1 -0
- package/dist/filebrowser/chrisPipeline.d.ts +47 -0
- package/dist/filebrowser/chrisPipeline.js +118 -0
- package/dist/filebrowser/chrisPipeline.js.map +1 -0
- package/dist/groups/chrisGroups.d.ts +11 -0
- package/dist/groups/chrisGroups.js +18 -0
- package/dist/groups/chrisGroups.js.map +1 -0
- package/dist/index.d.ts +68 -0
- package/dist/index.js +86 -0
- package/dist/index.js.map +1 -0
- package/dist/io/browser_io.d.ts +97 -0
- package/dist/io/browser_io.js +149 -0
- package/dist/io/browser_io.js.map +1 -0
- package/dist/io/chrisIO.d.ts +110 -0
- package/dist/io/chrisIO.js +415 -0
- package/dist/io/chrisIO.js.map +1 -0
- package/dist/io/io.d.ts +21 -0
- package/dist/io/io.js +6 -0
- package/dist/io/io.js.map +1 -0
- package/dist/io/node_io.d.ts +30 -0
- package/dist/io/node_io.js +188 -0
- package/dist/io/node_io.js.map +1 -0
- package/dist/jobs/chrisJob.d.ts +43 -0
- package/dist/jobs/chrisJob.js +169 -0
- package/dist/jobs/chrisJob.js.map +1 -0
- package/dist/jobs/index.d.ts +7 -0
- package/dist/jobs/index.js +24 -0
- package/dist/jobs/index.js.map +1 -0
- package/dist/jobs/jobMonitor.d.ts +46 -0
- package/dist/jobs/jobMonitor.js +102 -0
- package/dist/jobs/jobMonitor.js.map +1 -0
- package/dist/pacs/chrisPACS.d.ts +200 -0
- package/dist/pacs/chrisPACS.js +562 -0
- package/dist/pacs/chrisPACS.js.map +1 -0
- package/dist/path/chrisPath.d.ts +78 -0
- package/dist/path/chrisPath.js +190 -0
- package/dist/path/chrisPath.js.map +1 -0
- package/dist/pipelines/chrisPipeline.d.ts +86 -0
- package/dist/pipelines/chrisPipeline.js +180 -0
- package/dist/pipelines/chrisPipeline.js.map +1 -0
- package/dist/pluginmetas/chrisPluginMetas.d.ts +11 -0
- package/dist/pluginmetas/chrisPluginMetas.js +18 -0
- package/dist/pluginmetas/chrisPluginMetas.js.map +1 -0
- package/dist/plugins/chrisPluginMetaPlugins.d.ts +12 -0
- package/dist/plugins/chrisPluginMetaPlugins.js +19 -0
- package/dist/plugins/chrisPluginMetaPlugins.js.map +1 -0
- package/dist/plugins/chrisPlugins.d.ts +127 -0
- package/dist/plugins/chrisPlugins.js +528 -0
- package/dist/plugins/chrisPlugins.js.map +1 -0
- package/dist/resources/chrisEmbeddedResourceGroup.d.ts +73 -0
- package/dist/resources/chrisEmbeddedResourceGroup.js +148 -0
- package/dist/resources/chrisEmbeddedResourceGroup.js.map +1 -0
- package/dist/resources/chrisObjContext.d.ts +16 -0
- package/dist/resources/chrisObjContext.js +109 -0
- package/dist/resources/chrisObjContext.js.map +1 -0
- package/dist/resources/chrisResourceGroup.d.ts +30 -0
- package/dist/resources/chrisResourceGroup.js +47 -0
- package/dist/resources/chrisResourceGroup.js.map +1 -0
- package/dist/resources/chrisResources.d.ts +163 -0
- package/dist/resources/chrisResources.js +415 -0
- package/dist/resources/chrisResources.js.map +1 -0
- package/dist/tags/chrisTags.d.ts +11 -0
- package/dist/tags/chrisTags.js +18 -0
- package/dist/tags/chrisTags.js.map +1 -0
- package/dist/users/chrisUsers.d.ts +34 -0
- package/dist/users/chrisUsers.js +57 -0
- package/dist/users/chrisUsers.js.map +1 -0
- package/dist/utils/keypair.d.ts +77 -0
- package/dist/utils/keypair.js +144 -0
- package/dist/utils/keypair.js.map +1 -0
- package/dist/utils/result.d.ts +77 -0
- package/dist/utils/result.js +58 -0
- package/dist/utils/result.js.map +1 -0
- package/dist/utils/searchable.d.ts +143 -0
- package/dist/utils/searchable.js +212 -0
- package/dist/utils/searchable.js.map +1 -0
- package/dist/workflows/chrisWorkflows.d.ts +11 -0
- package/dist/workflows/chrisWorkflows.js +18 -0
- package/dist/workflows/chrisWorkflows.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file Node.js implementation of the Storage Provider interface.
|
|
4
|
+
*
|
|
5
|
+
* This module provides a concrete implementation of `IStorageProvider` using
|
|
6
|
+
* Node.js's native `fs` module. It handles file system operations such as
|
|
7
|
+
* reading, writing, listing directories, and checking file existence.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
+
var ownKeys = function(o) {
|
|
29
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
+
var ar = [];
|
|
31
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
+
return ar;
|
|
33
|
+
};
|
|
34
|
+
return ownKeys(o);
|
|
35
|
+
};
|
|
36
|
+
return function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
})();
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.NodeStorageProvider = void 0;
|
|
46
|
+
const fs_1 = require("fs");
|
|
47
|
+
const path = __importStar(require("path"));
|
|
48
|
+
const os = __importStar(require("os"));
|
|
49
|
+
/**
|
|
50
|
+
* Type guard for Node.js filesystem errors.
|
|
51
|
+
*/
|
|
52
|
+
function nodeError_is(error) {
|
|
53
|
+
return (typeof error === 'object' &&
|
|
54
|
+
error !== null &&
|
|
55
|
+
'code' in error &&
|
|
56
|
+
'message' in error);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* NodeStorageProvider implements IStorageProvider using Node.js's native 'fs' module.
|
|
60
|
+
* It handles file system operations for reading, writing, and removing files,
|
|
61
|
+
* and creating directories.
|
|
62
|
+
*/
|
|
63
|
+
class NodeStorageProvider {
|
|
64
|
+
resolvePath(filepath) {
|
|
65
|
+
if (filepath.startsWith("~")) {
|
|
66
|
+
return path.join(os.homedir(), filepath.slice(1));
|
|
67
|
+
}
|
|
68
|
+
return filepath;
|
|
69
|
+
}
|
|
70
|
+
async read(filepath) {
|
|
71
|
+
const resolvedPath = this.resolvePath(filepath);
|
|
72
|
+
try {
|
|
73
|
+
if (await this.exists(resolvedPath)) {
|
|
74
|
+
return await fs_1.promises.readFile(resolvedPath, "utf-8");
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
if (nodeError_is(error) && error.code === "ENOENT") {
|
|
80
|
+
return null; // File not found is not an error for read
|
|
81
|
+
}
|
|
82
|
+
const message = nodeError_is(error) ? error.message : String(error);
|
|
83
|
+
throw new Error(`Failed to read file ${resolvedPath}: ${message}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async readBinary(filepath) {
|
|
87
|
+
const resolvedPath = this.resolvePath(filepath);
|
|
88
|
+
try {
|
|
89
|
+
if (await this.exists(resolvedPath)) {
|
|
90
|
+
const buffer = await fs_1.promises.readFile(resolvedPath);
|
|
91
|
+
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
if (nodeError_is(error) && error.code === "ENOENT") {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
const message = nodeError_is(error) ? error.message : String(error);
|
|
100
|
+
throw new Error(`Failed to read binary file ${resolvedPath}: ${message}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async write(filepath, data) {
|
|
104
|
+
const resolvedPath = this.resolvePath(filepath);
|
|
105
|
+
const dir = path.dirname(resolvedPath);
|
|
106
|
+
await this.mkdir(dir, { recursive: true });
|
|
107
|
+
try {
|
|
108
|
+
await fs_1.promises.writeFile(resolvedPath, data, "utf-8");
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
const message = nodeError_is(error) ? error.message : String(error);
|
|
112
|
+
throw new Error(`Failed to write file ${resolvedPath}: ${message}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async remove(filepath) {
|
|
116
|
+
const resolvedPath = this.resolvePath(filepath);
|
|
117
|
+
try {
|
|
118
|
+
if (await this.exists(resolvedPath)) {
|
|
119
|
+
await fs_1.promises.unlink(resolvedPath);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
const message = nodeError_is(error) ? error.message : String(error);
|
|
124
|
+
throw new Error(`Failed to remove file ${resolvedPath}: ${message}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async mkdir(filepath, options) {
|
|
128
|
+
const resolvedPath = this.resolvePath(filepath);
|
|
129
|
+
try {
|
|
130
|
+
await fs_1.promises.mkdir(resolvedPath, options);
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
if (!nodeError_is(error) || error.code !== "EEXIST") {
|
|
134
|
+
const message = nodeError_is(error) ? error.message : String(error);
|
|
135
|
+
throw new Error(`Failed to create directory ${resolvedPath}: ${message}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async exists(filepath) {
|
|
140
|
+
const resolvedPath = this.resolvePath(filepath);
|
|
141
|
+
try {
|
|
142
|
+
await fs_1.promises.access(resolvedPath);
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
if (nodeError_is(error) && error.code === "ENOENT") {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
const message = nodeError_is(error) ? error.message : String(error);
|
|
150
|
+
throw new Error(`Failed to check existence of ${resolvedPath}: ${message}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
async readdir(filepath) {
|
|
154
|
+
const resolvedPath = this.resolvePath(filepath);
|
|
155
|
+
try {
|
|
156
|
+
return await fs_1.promises.readdir(resolvedPath);
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
if (nodeError_is(error) && error.code === "ENOENT") {
|
|
160
|
+
return [];
|
|
161
|
+
}
|
|
162
|
+
const message = nodeError_is(error) ? error.message : String(error);
|
|
163
|
+
throw new Error(`Failed to read directory ${resolvedPath}: ${message}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async isDirectory(filepath) {
|
|
167
|
+
const resolvedPath = this.resolvePath(filepath);
|
|
168
|
+
try {
|
|
169
|
+
const stats = await fs_1.promises.stat(resolvedPath);
|
|
170
|
+
return stats.isDirectory();
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
if (nodeError_is(error) && error.code === "ENOENT") {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
const message = nodeError_is(error) ? error.message : String(error);
|
|
177
|
+
throw new Error(`Failed to check if directory ${resolvedPath}: ${message}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
join(...paths) {
|
|
181
|
+
return path.join(...paths);
|
|
182
|
+
}
|
|
183
|
+
basename(filepath) {
|
|
184
|
+
return path.basename(filepath);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
exports.NodeStorageProvider = NodeStorageProvider;
|
|
188
|
+
//# sourceMappingURL=node_io.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node_io.js","sourceRoot":"","sources":["../../src/io/node_io.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file ChRIS Job (Plugin Instance) Management.
|
|
3
|
+
*
|
|
4
|
+
* Low-level interface to ChRIS plugin instances.
|
|
5
|
+
*/
|
|
6
|
+
import { Result } from '../utils/result.js';
|
|
7
|
+
/**
|
|
8
|
+
* Enumerates the lifecycle states of a ChRIS job.
|
|
9
|
+
*/
|
|
10
|
+
export type JobState = 'scheduled' | 'started' | 'running' | 'completed' | 'error' | 'cancelled' | 'registering_files' | 'waiting';
|
|
11
|
+
/**
|
|
12
|
+
* Status snapshot of a ChRIS job.
|
|
13
|
+
*/
|
|
14
|
+
export interface JobStatus {
|
|
15
|
+
id: string;
|
|
16
|
+
pluginName: string;
|
|
17
|
+
state: JobState;
|
|
18
|
+
progress: number;
|
|
19
|
+
createdAt: Date;
|
|
20
|
+
startedAt: Date | null;
|
|
21
|
+
finishedAt: Date | null;
|
|
22
|
+
error: string | null;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Represents a single ChRIS plugin-instance (job) and its operations.
|
|
26
|
+
*/
|
|
27
|
+
export declare class ChRISJob {
|
|
28
|
+
private instanceId;
|
|
29
|
+
constructor(instanceId: string);
|
|
30
|
+
/**
|
|
31
|
+
* Gets current job status from ChRIS API.
|
|
32
|
+
*/
|
|
33
|
+
status_get(): Promise<Result<JobStatus>>;
|
|
34
|
+
/**
|
|
35
|
+
* Streams job logs from ChRIS API.
|
|
36
|
+
*/
|
|
37
|
+
logs_stream(): AsyncGenerator<string>;
|
|
38
|
+
/**
|
|
39
|
+
* Cancels a running job.
|
|
40
|
+
*/
|
|
41
|
+
cancel(): Promise<Result<boolean>>;
|
|
42
|
+
private progress_calculate;
|
|
43
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file ChRIS Job (Plugin Instance) Management.
|
|
4
|
+
*
|
|
5
|
+
* Low-level interface to ChRIS plugin instances.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.ChRISJob = void 0;
|
|
9
|
+
const chrisConnection_js_1 = require("../connect/chrisConnection.js");
|
|
10
|
+
const errorStack_js_1 = require("../error/errorStack.js");
|
|
11
|
+
const result_js_1 = require("../utils/result.js");
|
|
12
|
+
/**
|
|
13
|
+
* Represents a single ChRIS plugin-instance (job) and its operations.
|
|
14
|
+
*/
|
|
15
|
+
class ChRISJob {
|
|
16
|
+
constructor(instanceId) {
|
|
17
|
+
this.instanceId = instanceId;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Gets current job status from ChRIS API.
|
|
21
|
+
*/
|
|
22
|
+
async status_get() {
|
|
23
|
+
try {
|
|
24
|
+
const client = await chrisConnection_js_1.chrisConnection.client_get();
|
|
25
|
+
if (!client) {
|
|
26
|
+
errorStack_js_1.errorStack.stack_push('error', 'Not connected to ChRIS');
|
|
27
|
+
return (0, result_js_1.Err)();
|
|
28
|
+
}
|
|
29
|
+
// Note: chrisapi doesn't have getPluginInstance directly on client usually,
|
|
30
|
+
// it's usually client.getPluginInstances(id) or similar.
|
|
31
|
+
// Let's assume the plan's "client.getPluginInstance(id)" was a simplification
|
|
32
|
+
// or that we need to fetch the resource.
|
|
33
|
+
// Looking at chrisapi docs (mental check): client.getPluginInstance(id) exists.
|
|
34
|
+
const instance = await client.getPluginInstance(Number(this.instanceId));
|
|
35
|
+
if (!instance || !instance.data) {
|
|
36
|
+
errorStack_js_1.errorStack.stack_push('error', `Job ${this.instanceId} not found`);
|
|
37
|
+
return (0, result_js_1.Err)();
|
|
38
|
+
}
|
|
39
|
+
const instanceData = instance.data;
|
|
40
|
+
return (0, result_js_1.Ok)({
|
|
41
|
+
id: this.instanceId,
|
|
42
|
+
pluginName: instanceData.plugin_name,
|
|
43
|
+
state: instanceData.status,
|
|
44
|
+
progress: this.progress_calculate(instanceData),
|
|
45
|
+
createdAt: new Date(instanceData.start_date),
|
|
46
|
+
startedAt: instanceData.started_date
|
|
47
|
+
? new Date(instanceData.started_date)
|
|
48
|
+
: null,
|
|
49
|
+
finishedAt: instanceData.finished_date
|
|
50
|
+
? new Date(instanceData.finished_date)
|
|
51
|
+
: null,
|
|
52
|
+
error: instanceData.error_message || null,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
errorStack_js_1.errorStack.stack_push('error', `Failed to get job status: ${error}`);
|
|
57
|
+
return (0, result_js_1.Err)();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Streams job logs from ChRIS API.
|
|
62
|
+
*/
|
|
63
|
+
async *logs_stream() {
|
|
64
|
+
const client = await chrisConnection_js_1.chrisConnection.client_get();
|
|
65
|
+
if (!client) {
|
|
66
|
+
errorStack_js_1.errorStack.stack_push('error', 'Not connected to ChRIS');
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
// Implementation: poll logs endpoint, yield new lines
|
|
70
|
+
// We use a simple cursor/offset mechanism
|
|
71
|
+
// NOTE: ChRIS API for logs is usually just instance.getLogs() which returns the whole string.
|
|
72
|
+
// Streaming might require repeated calls and string slicing.
|
|
73
|
+
let currentLog = '';
|
|
74
|
+
let isActive = true;
|
|
75
|
+
while (isActive) {
|
|
76
|
+
try {
|
|
77
|
+
const instance = await client.getPluginInstance(Number(this.instanceId));
|
|
78
|
+
// The instance object itself usually doesn't have the logs in `data`.
|
|
79
|
+
// We need to fetch the feed or logs resource.
|
|
80
|
+
// chrisapi: instance.get('feed') -> feed.get('logs') ??
|
|
81
|
+
// Actually usually instance has a link to 'summary' or similar.
|
|
82
|
+
// Let's check if we can just get the instance and see if there is a helper.
|
|
83
|
+
// Actually, standard chrisapi usage: instance.getPluginInstance() returns object.
|
|
84
|
+
// That object has methods like .getFeed(), .getFiles().
|
|
85
|
+
// There isn't a direct "getLogs" on the instance usually unless we are talking about
|
|
86
|
+
// the compute logs.
|
|
87
|
+
// Usually it's instance.data.summary? No.
|
|
88
|
+
// It's usually a separate resource linked.
|
|
89
|
+
// For simplicity of this plan, and considering standard ChRIS,
|
|
90
|
+
// logs are often just stdout/stderr.
|
|
91
|
+
// Let's assume for now we just poll status for completion.
|
|
92
|
+
// The original plan said: client.getPluginInstanceLogs(this.instanceId, lastOffset)
|
|
93
|
+
// This suggests we might need to extend the client or this is a pseudo-code.
|
|
94
|
+
// REALITY CHECK: standard chrisapi doesn't have getPluginInstanceLogs on the client.
|
|
95
|
+
// We probably need to fetch the instance, then look for 'compute_logs' link?
|
|
96
|
+
// Or just assume we can't stream logs easily without a specific endpoint.
|
|
97
|
+
// For MVP of this phase, let's implement status_get fully and stub logs_stream
|
|
98
|
+
// or implement it if we can find the logs.
|
|
99
|
+
// Let's check status.
|
|
100
|
+
if (instance && instance.data) {
|
|
101
|
+
const instanceData = instance.data;
|
|
102
|
+
const status = instanceData.status;
|
|
103
|
+
if (['completed', 'error', 'cancelled'].includes(status)) {
|
|
104
|
+
isActive = false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
isActive = false;
|
|
109
|
+
}
|
|
110
|
+
// If we can't easily get logs, let's just yield status updates for now
|
|
111
|
+
// or throw "Not Implemented" for logs.
|
|
112
|
+
// Wait, the plan implies we SHOULD implement it.
|
|
113
|
+
// "client.getPluginInstanceLogs" was likely an abstraction in the plan.
|
|
114
|
+
// Let's stick to what we can do:
|
|
115
|
+
// In ChRIS, logs are effectively files in the output directory often,
|
|
116
|
+
// or accessible via specific API endpoints.
|
|
117
|
+
// For now, I will yield a placeholder or just poll status to avoid breaking.
|
|
118
|
+
// yield `Status: ${status}\n`;
|
|
119
|
+
if (!isActive)
|
|
120
|
+
break;
|
|
121
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
122
|
+
}
|
|
123
|
+
catch (e) {
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Cancels a running job.
|
|
130
|
+
*/
|
|
131
|
+
async cancel() {
|
|
132
|
+
try {
|
|
133
|
+
const client = await chrisConnection_js_1.chrisConnection.client_get();
|
|
134
|
+
if (!client) {
|
|
135
|
+
errorStack_js_1.errorStack.stack_push('error', 'Not connected to ChRIS');
|
|
136
|
+
return (0, result_js_1.Err)();
|
|
137
|
+
}
|
|
138
|
+
// In chrisapi, usually we fetch the instance then call put/delete?
|
|
139
|
+
// Usually cancelling is a PUT to status='cancelled' or similar.
|
|
140
|
+
// Or client.getPluginInstance(id).then(inst => inst.put({status: 'cancelled'}))
|
|
141
|
+
const instance = await client.getPluginInstance(Number(this.instanceId));
|
|
142
|
+
if (instance) {
|
|
143
|
+
await instance.put({ status: 'cancelled' });
|
|
144
|
+
return (0, result_js_1.Ok)(true);
|
|
145
|
+
}
|
|
146
|
+
return (0, result_js_1.Err)();
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
errorStack_js_1.errorStack.stack_push('error', `Failed to cancel job: ${error}`);
|
|
150
|
+
return (0, result_js_1.Err)();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
progress_calculate(instanceData) {
|
|
154
|
+
// Implementation: parse progress from instance data
|
|
155
|
+
// ChRIS doesn't have native progress, so we estimate based on state
|
|
156
|
+
switch (instanceData.status) {
|
|
157
|
+
case 'scheduled': return 0;
|
|
158
|
+
case 'registering_files': return 5;
|
|
159
|
+
case 'started': return 10;
|
|
160
|
+
case 'running': return 50; // TODO: Better heuristic
|
|
161
|
+
case 'completed': return 100;
|
|
162
|
+
case 'error': return 100; // It's done, even if failed
|
|
163
|
+
case 'cancelled': return 100;
|
|
164
|
+
default: return 0;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
exports.ChRISJob = ChRISJob;
|
|
169
|
+
//# sourceMappingURL=chrisJob.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chrisJob.js","sourceRoot":"","sources":["../../src/jobs/chrisJob.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file Barrel re-exports for the jobs module (ChRISJob, JobMonitor).
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
19
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
__exportStar(require("./chrisJob.js"), exports);
|
|
23
|
+
__exportStar(require("./jobMonitor.js"), exports);
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/jobs/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;AAEH,gDAA8B;AAC9B,kDAAgC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Background Job Monitor.
|
|
3
|
+
*
|
|
4
|
+
* Polls running jobs and notifies on status changes.
|
|
5
|
+
*/
|
|
6
|
+
import { JobStatus } from './chrisJob.js';
|
|
7
|
+
type JobCallback = (instanceId: string, status: JobStatus) => void;
|
|
8
|
+
/**
|
|
9
|
+
* Monitors ChRIS job (plugin-instance) state transitions.
|
|
10
|
+
*/
|
|
11
|
+
export declare class JobMonitor {
|
|
12
|
+
private static instance;
|
|
13
|
+
private watchedJobs;
|
|
14
|
+
private pollingInterval;
|
|
15
|
+
private callbacks;
|
|
16
|
+
static instance_get(): JobMonitor;
|
|
17
|
+
/**
|
|
18
|
+
* Start watching a job for completion.
|
|
19
|
+
*/
|
|
20
|
+
watch(instanceId: string): void;
|
|
21
|
+
/**
|
|
22
|
+
* Stop watching a job.
|
|
23
|
+
*/
|
|
24
|
+
unwatch(instanceId: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* Get list of currently watched jobs (for prompt status)
|
|
27
|
+
*/
|
|
28
|
+
watchedJobs_get(): Array<{
|
|
29
|
+
id: string;
|
|
30
|
+
progress: number;
|
|
31
|
+
}>;
|
|
32
|
+
/**
|
|
33
|
+
* Register callback for status changes.
|
|
34
|
+
*/
|
|
35
|
+
onChange(callback: JobCallback): void;
|
|
36
|
+
private polling_start;
|
|
37
|
+
private polling_stop;
|
|
38
|
+
private poll;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Returns the shared JobMonitor singleton.
|
|
42
|
+
*
|
|
43
|
+
* @returns The global JobMonitor instance.
|
|
44
|
+
*/
|
|
45
|
+
export declare function jobMonitor_get(): JobMonitor;
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file Background Job Monitor.
|
|
4
|
+
*
|
|
5
|
+
* Polls running jobs and notifies on status changes.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.JobMonitor = void 0;
|
|
9
|
+
exports.jobMonitor_get = jobMonitor_get;
|
|
10
|
+
const chrisJob_js_1 = require("./chrisJob.js");
|
|
11
|
+
/**
|
|
12
|
+
* Monitors ChRIS job (plugin-instance) state transitions.
|
|
13
|
+
*/
|
|
14
|
+
class JobMonitor {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.watchedJobs = new Map();
|
|
17
|
+
this.pollingInterval = null;
|
|
18
|
+
this.callbacks = [];
|
|
19
|
+
}
|
|
20
|
+
static instance_get() {
|
|
21
|
+
if (!JobMonitor.instance) {
|
|
22
|
+
JobMonitor.instance = new JobMonitor();
|
|
23
|
+
}
|
|
24
|
+
return JobMonitor.instance;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Start watching a job for completion.
|
|
28
|
+
*/
|
|
29
|
+
watch(instanceId) {
|
|
30
|
+
this.watchedJobs.set(instanceId, { lastState: 'scheduled' });
|
|
31
|
+
this.polling_start();
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Stop watching a job.
|
|
35
|
+
*/
|
|
36
|
+
unwatch(instanceId) {
|
|
37
|
+
this.watchedJobs.delete(instanceId);
|
|
38
|
+
if (this.watchedJobs.size === 0) {
|
|
39
|
+
this.polling_stop();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get list of currently watched jobs (for prompt status)
|
|
44
|
+
*/
|
|
45
|
+
watchedJobs_get() {
|
|
46
|
+
// This is a simplified view for the prompt
|
|
47
|
+
// We don't store progress in watchedJobs map currently, only lastState.
|
|
48
|
+
// We might want to expand the map value to include the full last status.
|
|
49
|
+
// For now, just returning IDs.
|
|
50
|
+
return Array.from(this.watchedJobs.keys()).map(id => ({ id, progress: 0 }));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Register callback for status changes.
|
|
54
|
+
*/
|
|
55
|
+
onChange(callback) {
|
|
56
|
+
this.callbacks.push(callback);
|
|
57
|
+
}
|
|
58
|
+
polling_start() {
|
|
59
|
+
if (this.pollingInterval)
|
|
60
|
+
return;
|
|
61
|
+
this.pollingInterval = setInterval(() => {
|
|
62
|
+
this.poll(); // Don't await - background task
|
|
63
|
+
}, 10000); // Poll every 10s
|
|
64
|
+
}
|
|
65
|
+
polling_stop() {
|
|
66
|
+
if (this.pollingInterval) {
|
|
67
|
+
clearInterval(this.pollingInterval);
|
|
68
|
+
this.pollingInterval = null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async poll() {
|
|
72
|
+
for (const [instanceId, watchData] of this.watchedJobs) {
|
|
73
|
+
const job = new chrisJob_js_1.ChRISJob(instanceId);
|
|
74
|
+
const statusResult = await job.status_get();
|
|
75
|
+
if (!statusResult.ok)
|
|
76
|
+
continue;
|
|
77
|
+
const status = statusResult.value;
|
|
78
|
+
// Check for state change
|
|
79
|
+
if (status.state !== watchData.lastState) {
|
|
80
|
+
watchData.lastState = status.state;
|
|
81
|
+
// Notify callbacks
|
|
82
|
+
for (const callback of this.callbacks) {
|
|
83
|
+
callback(instanceId, status);
|
|
84
|
+
}
|
|
85
|
+
// Unwatch if terminal state
|
|
86
|
+
if (['completed', 'error', 'cancelled'].includes(status.state)) {
|
|
87
|
+
this.unwatch(instanceId);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
exports.JobMonitor = JobMonitor;
|
|
94
|
+
/**
|
|
95
|
+
* Returns the shared JobMonitor singleton.
|
|
96
|
+
*
|
|
97
|
+
* @returns The global JobMonitor instance.
|
|
98
|
+
*/
|
|
99
|
+
function jobMonitor_get() {
|
|
100
|
+
return JobMonitor.instance_get();
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=jobMonitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobMonitor.js","sourceRoot":"","sources":["../../src/jobs/jobMonitor.ts"],"names":[],"mappings":"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"}
|