@datalayer/core 0.0.12 → 0.0.13
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/README.md +2 -2
- package/lib/api/DatalayerApi.d.ts +38 -26
- package/lib/api/DatalayerApi.js +35 -8
- package/lib/api/iam/authentication.d.ts +8 -7
- package/lib/api/iam/authentication.js +14 -15
- package/lib/api/iam/healthz.d.ts +3 -2
- package/lib/api/iam/healthz.js +5 -3
- package/lib/api/iam/index.d.ts +9 -4
- package/lib/api/iam/index.js +9 -4
- package/lib/api/iam/oauth2.d.ts +115 -0
- package/lib/api/iam/oauth2.js +309 -0
- package/lib/api/iam/profile.d.ts +8 -1
- package/lib/api/iam/profile.js +17 -2
- package/lib/api/iam/usage.d.ts +56 -0
- package/lib/api/iam/usage.js +39 -0
- package/lib/api/index.d.ts +6 -5
- package/lib/api/index.js +6 -5
- package/lib/api/runtimes/environments.js +3 -2
- package/lib/api/runtimes/healthz.d.ts +3 -13
- package/lib/api/runtimes/healthz.js +4 -3
- package/lib/api/runtimes/index.d.ts +3 -2
- package/lib/api/runtimes/index.js +3 -2
- package/lib/api/runtimes/runtimes.js +17 -6
- package/lib/api/runtimes/snapshots.js +3 -2
- package/lib/api/spacer/documents.d.ts +12 -0
- package/lib/api/spacer/documents.js +43 -0
- package/lib/api/spacer/healthz.d.ts +3 -13
- package/lib/api/spacer/healthz.js +4 -3
- package/lib/api/spacer/index.d.ts +4 -2
- package/lib/api/spacer/index.js +4 -2
- package/lib/api/spacer/items.d.ts +9 -1
- package/lib/api/spacer/items.js +17 -2
- package/lib/api/spacer/lexicals.js +3 -2
- package/lib/api/spacer/notebooks.js +3 -2
- package/lib/api/spacer/spaces.js +3 -2
- package/lib/api/spacer/users.js +3 -2
- package/lib/api/types/common.d.ts +64 -0
- package/lib/api/types/iam.d.ts +88 -65
- package/lib/api/types/index.d.ts +4 -2
- package/lib/api/types/index.js +4 -2
- package/lib/api/types/runtimes.d.ts +9 -39
- package/lib/api/types/spacer.d.ts +37 -65
- package/lib/api/utils/validation.d.ts +24 -1
- package/lib/api/utils/validation.js +62 -1
- package/lib/client/base.d.ts +75 -0
- package/lib/client/base.js +199 -0
- package/lib/client/constants.d.ts +22 -0
- package/lib/client/constants.js +22 -0
- package/lib/client/index.d.ts +108 -0
- package/lib/client/index.js +79 -0
- package/lib/client/mixins/IAMMixin.d.ts +54 -0
- package/lib/client/mixins/IAMMixin.js +181 -0
- package/lib/client/mixins/RuntimesMixin.d.ts +93 -0
- package/lib/client/mixins/RuntimesMixin.js +229 -0
- package/lib/client/mixins/SpacerMixin.d.ts +111 -0
- package/lib/client/mixins/SpacerMixin.js +340 -0
- package/lib/client/models/Credits.d.ts +91 -0
- package/lib/client/models/Credits.js +130 -0
- package/lib/client/models/Environment.d.ts +73 -0
- package/lib/client/models/Environment.js +88 -0
- package/lib/client/models/HealthCheck.d.ts +72 -0
- package/lib/client/models/HealthCheck.js +107 -0
- package/lib/client/models/Item.d.ts +69 -0
- package/lib/client/models/Item.js +191 -0
- package/lib/client/models/Lexical.d.ts +83 -0
- package/lib/client/models/Lexical.js +152 -0
- package/lib/client/models/Notebook.d.ts +87 -0
- package/lib/client/models/Notebook.js +153 -0
- package/lib/client/models/Runtime.d.ts +122 -0
- package/lib/client/models/Runtime.js +204 -0
- package/lib/client/models/Snapshot.d.ts +92 -0
- package/lib/client/models/Snapshot.js +139 -0
- package/lib/client/models/Space.d.ts +135 -0
- package/lib/client/models/Space.js +234 -0
- package/lib/client/models/User.d.ts +64 -0
- package/lib/client/models/User.js +83 -0
- package/lib/client/models/index.d.ts +26 -0
- package/lib/client/models/index.js +25 -0
- package/lib/client/utils/mixins.d.ts +12 -0
- package/lib/{sdk/client → client}/utils/mixins.js +0 -28
- package/lib/client/utils/spacerUtils.d.ts +18 -0
- package/lib/client/utils/spacerUtils.js +32 -0
- package/lib/collaboration/DatalayerCollaboration.d.ts +6 -1
- package/lib/collaboration/DatalayerCollaboration.js +2 -2
- package/lib/collaboration/DatalayerCollaborationProvider.d.ts +5 -0
- package/lib/collaboration/DatalayerCollaborationProvider.js +10 -9
- package/lib/components/progress/CreditsIndicator.d.ts +1 -1
- package/lib/components/runtimes/RuntimeCellVariablesDialog.js +1 -1
- package/lib/components/runtimes/RuntimeLauncherDialog.d.ts +1 -1
- package/lib/components/runtimes/RuntimePickerBase.d.ts +1 -1
- package/lib/components/runtimes/RuntimePickerBase.js +1 -1
- package/lib/components/runtimes/RuntimePickerCell.js +2 -2
- package/lib/components/runtimes/RuntimePickerNotebook.d.ts +1 -1
- package/lib/components/runtimes/RuntimePickerNotebook.js +1 -1
- package/lib/components/runtimes/RuntimeTransfer.d.ts +1 -1
- package/lib/components/runtimes/RuntimeUtils.d.ts +1 -1
- package/lib/components/snapshots/RuntimeSnapshotMenu.d.ts +1 -1
- package/lib/components/snapshots/RuntimeSnapshotMenu.js +27 -20
- package/lib/config/Configuration.d.ts +8 -0
- package/lib/hooks/useDatalayer.js +1 -1
- package/lib/hooks/useRuntimes.js +1 -1
- package/lib/hooks/useToast.js +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.js +4 -2
- package/lib/sdk/index.d.ts +5 -4
- package/lib/sdk/index.js +6 -5
- package/lib/services/DatalayerServiceManager.js +1 -1
- package/lib/state/substates/CoreState.js +2 -0
- package/lib/state/substates/RuntimesState.d.ts +1 -1
- package/lib/state/substates/RuntimesState.js +1 -1
- package/lib/{sdk/stateful → stateful}/index.d.ts +1 -1
- package/lib/{sdk/stateful → stateful}/index.js +1 -1
- package/lib/{sdk/stateful → stateful}/jupyter/exec/Snippets.d.ts +1 -41
- package/lib/{sdk/stateful → stateful}/jupyter/exec/Snippets.js +1 -20
- package/lib/{sdk/stateful → stateful}/runtimes/actions.d.ts +3 -3
- package/lib/{sdk/stateful → stateful}/runtimes/actions.js +8 -8
- package/lib/{sdk/stateful → stateful}/runtimes/apis.d.ts +8 -8
- package/lib/stateful/runtimes/apis.js +5 -0
- package/package.json +12 -10
- package/lib/__tests__/hooks.test.d.ts +0 -1
- package/lib/__tests__/hooks.test.js +0 -19
- package/lib/__tests__/index.test.d.ts +0 -1
- package/lib/__tests__/index.test.js +0 -27
- package/lib/__tests__/integration.test.d.ts +0 -1
- package/lib/__tests__/integration.test.js +0 -57
- package/lib/__tests__/shared/cleanup-shared.d.ts +0 -4
- package/lib/__tests__/shared/cleanup-shared.js +0 -228
- package/lib/__tests__/shared/test-config.d.ts +0 -51
- package/lib/__tests__/shared/test-config.js +0 -110
- package/lib/__tests__/shared/test-constants.d.ts +0 -66
- package/lib/__tests__/shared/test-constants.js +0 -79
- package/lib/__tests__/utils.test.d.ts +0 -1
- package/lib/__tests__/utils.test.js +0 -59
- package/lib/api/__tests__/iam.authentication.integration.test.d.ts +0 -1
- package/lib/api/__tests__/iam.authentication.integration.test.js +0 -247
- package/lib/api/__tests__/iam.healthz.integration.test.d.ts +0 -1
- package/lib/api/__tests__/iam.healthz.integration.test.js +0 -63
- package/lib/api/__tests__/iam.profile.integration.test.d.ts +0 -1
- package/lib/api/__tests__/iam.profile.integration.test.js +0 -252
- package/lib/api/__tests__/runtimes.environments.integration.test.d.ts +0 -1
- package/lib/api/__tests__/runtimes.environments.integration.test.js +0 -122
- package/lib/api/__tests__/runtimes.healthz.integration.test.d.ts +0 -1
- package/lib/api/__tests__/runtimes.healthz.integration.test.js +0 -50
- package/lib/api/__tests__/runtimes.integration.test.d.ts +0 -1
- package/lib/api/__tests__/runtimes.integration.test.js +0 -369
- package/lib/api/__tests__/spacer.healthz.integration.test.d.ts +0 -1
- package/lib/api/__tests__/spacer.healthz.integration.test.js +0 -50
- package/lib/api/__tests__/spacer.integration.test.d.ts +0 -1
- package/lib/api/__tests__/spacer.integration.test.js +0 -519
- package/lib/api/iam/__tests__/authentication.unit.test.d.ts +0 -1
- package/lib/api/iam/__tests__/authentication.unit.test.js +0 -63
- package/lib/api/iam/__tests__/healthz.unit.test.d.ts +0 -1
- package/lib/api/iam/__tests__/healthz.unit.test.js +0 -60
- package/lib/api/iam/__tests__/profile.unit.test.d.ts +0 -1
- package/lib/api/iam/__tests__/profile.unit.test.js +0 -57
- package/lib/api/runtimes/__tests__/environments.unit.test.d.ts +0 -1
- package/lib/api/runtimes/__tests__/environments.unit.test.js +0 -77
- package/lib/api/runtimes/__tests__/healthz.unit.test.d.ts +0 -1
- package/lib/api/runtimes/__tests__/healthz.unit.test.js +0 -57
- package/lib/api/runtimes/__tests__/runtimes.unit.test.d.ts +0 -1
- package/lib/api/runtimes/__tests__/runtimes.unit.test.js +0 -139
- package/lib/api/runtimes/__tests__/snapshots.unit.test.d.ts +0 -1
- package/lib/api/runtimes/__tests__/snapshots.unit.test.js +0 -96
- package/lib/api/spacer/__tests__/healthz.unit.test.d.ts +0 -1
- package/lib/api/spacer/__tests__/healthz.unit.test.js +0 -57
- package/lib/api/spacer/__tests__/items.unit.test.d.ts +0 -1
- package/lib/api/spacer/__tests__/items.unit.test.js +0 -165
- package/lib/api/spacer/__tests__/lexicals.unit.test.d.ts +0 -1
- package/lib/api/spacer/__tests__/lexicals.unit.test.js +0 -323
- package/lib/api/spacer/__tests__/notebooks.unit.test.d.ts +0 -1
- package/lib/api/spacer/__tests__/notebooks.unit.test.js +0 -224
- package/lib/api/spacer/__tests__/users.unit.test.d.ts +0 -1
- package/lib/api/spacer/__tests__/users.unit.test.js +0 -132
- package/lib/api/utils/__tests__/validation.test.d.ts +0 -1
- package/lib/api/utils/__tests__/validation.test.js +0 -109
- package/lib/sdk/client/__tests__/sdk.health.integration.test.d.ts +0 -1
- package/lib/sdk/client/__tests__/sdk.health.integration.test.js +0 -110
- package/lib/sdk/client/__tests__/sdk.iam.integration.test.d.ts +0 -1
- package/lib/sdk/client/__tests__/sdk.iam.integration.test.js +0 -179
- package/lib/sdk/client/__tests__/sdk.models.integration.test.d.ts +0 -1
- package/lib/sdk/client/__tests__/sdk.models.integration.test.js +0 -376
- package/lib/sdk/client/__tests__/sdk.runtimes.integration.test.d.ts +0 -1
- package/lib/sdk/client/__tests__/sdk.runtimes.integration.test.js +0 -276
- package/lib/sdk/client/__tests__/sdk.spacer.integration.test.d.ts +0 -1
- package/lib/sdk/client/__tests__/sdk.spacer.integration.test.js +0 -361
- package/lib/sdk/client/base.d.ts +0 -88
- package/lib/sdk/client/base.js +0 -112
- package/lib/sdk/client/index.d.ts +0 -192
- package/lib/sdk/client/index.js +0 -128
- package/lib/sdk/client/mixins/HealthMixin.d.ts +0 -100
- package/lib/sdk/client/mixins/HealthMixin.js +0 -133
- package/lib/sdk/client/mixins/IAMMixin.d.ts +0 -59
- package/lib/sdk/client/mixins/IAMMixin.js +0 -83
- package/lib/sdk/client/mixins/RuntimesMixin.d.ts +0 -134
- package/lib/sdk/client/mixins/RuntimesMixin.js +0 -221
- package/lib/sdk/client/mixins/SpacerMixin.d.ts +0 -184
- package/lib/sdk/client/mixins/SpacerMixin.js +0 -278
- package/lib/sdk/client/models/Lexical.d.ts +0 -156
- package/lib/sdk/client/models/Lexical.js +0 -275
- package/lib/sdk/client/models/Notebook.d.ts +0 -174
- package/lib/sdk/client/models/Notebook.js +0 -311
- package/lib/sdk/client/models/Runtime.d.ts +0 -221
- package/lib/sdk/client/models/Runtime.js +0 -341
- package/lib/sdk/client/models/Snapshot.d.ts +0 -156
- package/lib/sdk/client/models/Snapshot.js +0 -244
- package/lib/sdk/client/models/Space.d.ts +0 -182
- package/lib/sdk/client/models/Space.js +0 -276
- package/lib/sdk/client/models/__tests__/Lexical.test.d.ts +0 -1
- package/lib/sdk/client/models/__tests__/Lexical.test.js +0 -288
- package/lib/sdk/client/models/__tests__/Notebook.test.d.ts +0 -1
- package/lib/sdk/client/models/__tests__/Notebook.test.js +0 -206
- package/lib/sdk/client/models/__tests__/Runtime.test.d.ts +0 -1
- package/lib/sdk/client/models/__tests__/Runtime.test.js +0 -133
- package/lib/sdk/client/models/__tests__/Snapshot.test.d.ts +0 -1
- package/lib/sdk/client/models/__tests__/Snapshot.test.js +0 -244
- package/lib/sdk/client/models/__tests__/Space.test.d.ts +0 -1
- package/lib/sdk/client/models/__tests__/Space.test.js +0 -334
- package/lib/sdk/client/models/index.d.ts +0 -30
- package/lib/sdk/client/models/index.js +0 -30
- package/lib/sdk/client/utils/mixins.d.ts +0 -42
- /package/lib/{sdk/stateful/runtimes/apis.js → api/types/common.js} +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/exec/Python.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/exec/Python.js +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/exec/index.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/exec/index.js +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/index.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/index.js +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/kernelsHandler.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/kernelsHandler.js +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/index.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/index.js +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/settings.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/settings.js +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/snapshots.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/snapshots.js +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/utils.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/utils.js +0 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Runtimes mixin for managing computational environments and runtime instances.
|
|
7
|
+
* @module client/mixins/RuntimesMixin
|
|
8
|
+
*/
|
|
9
|
+
import * as environments from '../../api/runtimes/environments';
|
|
10
|
+
import * as runtimes from '../../api/runtimes/runtimes';
|
|
11
|
+
import * as snapshots from '../../api/runtimes/snapshots';
|
|
12
|
+
import { Environment } from '../models/Environment';
|
|
13
|
+
import { Runtime } from '../models/Runtime';
|
|
14
|
+
import { Snapshot } from '../models/Snapshot';
|
|
15
|
+
import { HealthCheck } from '../models/HealthCheck';
|
|
16
|
+
/** Runtimes mixin providing computational environment and runtime management. */
|
|
17
|
+
export function RuntimesMixin(Base) {
|
|
18
|
+
return class extends Base {
|
|
19
|
+
// ========================================================================
|
|
20
|
+
// Helper Functions
|
|
21
|
+
// ========================================================================
|
|
22
|
+
_extractRuntimePodName(runtimePodNameOrInstance) {
|
|
23
|
+
return typeof runtimePodNameOrInstance === 'string'
|
|
24
|
+
? runtimePodNameOrInstance
|
|
25
|
+
: runtimePodNameOrInstance.podName;
|
|
26
|
+
}
|
|
27
|
+
_extractSnapshotId(snapshotIdOrInstance) {
|
|
28
|
+
return typeof snapshotIdOrInstance === 'string'
|
|
29
|
+
? snapshotIdOrInstance
|
|
30
|
+
: snapshotIdOrInstance.uid;
|
|
31
|
+
}
|
|
32
|
+
// ========================================================================
|
|
33
|
+
// Environments
|
|
34
|
+
// ========================================================================
|
|
35
|
+
/**
|
|
36
|
+
* List all available computational environments.
|
|
37
|
+
* @returns Array of Environment model instances
|
|
38
|
+
*/
|
|
39
|
+
async listEnvironments() {
|
|
40
|
+
const token = this.getToken();
|
|
41
|
+
const runtimesRunUrl = this.getRuntimesRunUrl();
|
|
42
|
+
const response = await environments.listEnvironments(token, runtimesRunUrl);
|
|
43
|
+
// Save for later use after first call
|
|
44
|
+
this.environments = response.environments.map(env => new Environment(env, this));
|
|
45
|
+
return this.environments;
|
|
46
|
+
}
|
|
47
|
+
// ========================================================================
|
|
48
|
+
// Runtimes
|
|
49
|
+
// ========================================================================
|
|
50
|
+
/**
|
|
51
|
+
* Create a new computational runtime.
|
|
52
|
+
* @param environmentName - Name of the environment to use
|
|
53
|
+
* @param type - Type of runtime
|
|
54
|
+
* @param givenName - User-friendly name for the runtime
|
|
55
|
+
* @param creditsLimit - Credits limit
|
|
56
|
+
* @returns Created runtime
|
|
57
|
+
*/
|
|
58
|
+
async createRuntime(environmentName, type, givenName, minutesLimit, fromSnapshotId) {
|
|
59
|
+
if (!this.environments) {
|
|
60
|
+
await this.listEnvironments();
|
|
61
|
+
}
|
|
62
|
+
if (this.environments) {
|
|
63
|
+
const env = this.environments.find((e) => e.name === environmentName);
|
|
64
|
+
if (!env) {
|
|
65
|
+
throw new Error(`Environment "${environmentName}" not found. Available environments: ${this.environments.map((e) => e.name).join(', ')}`);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
const token = this.getToken();
|
|
69
|
+
const runtimesRunUrl = this.getRuntimesRunUrl();
|
|
70
|
+
const creditsLimit = this.calculateCreditsFromMinutes(minutesLimit, env.burningRate);
|
|
71
|
+
const data = {
|
|
72
|
+
environment_name: environmentName,
|
|
73
|
+
type,
|
|
74
|
+
given_name: givenName,
|
|
75
|
+
credits_limit: creditsLimit,
|
|
76
|
+
from: fromSnapshotId,
|
|
77
|
+
};
|
|
78
|
+
const response = await runtimes.createRuntime(token, data, runtimesRunUrl);
|
|
79
|
+
return new Runtime(response.runtime, this);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
throw new Error('Environments not loaded');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* List all runtimes.
|
|
88
|
+
* @returns Array of runtimes
|
|
89
|
+
*/
|
|
90
|
+
async listRuntimes() {
|
|
91
|
+
const token = this.getToken();
|
|
92
|
+
const runtimesRunUrl = this.getRuntimesRunUrl();
|
|
93
|
+
const response = await runtimes.listRuntimes(token, runtimesRunUrl);
|
|
94
|
+
return response.runtimes.map(r => new Runtime(r, this));
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get details for a specific runtime by pod name.
|
|
98
|
+
* @param podName - Runtime pod name
|
|
99
|
+
* @returns Runtime details
|
|
100
|
+
*/
|
|
101
|
+
async getRuntime(podName) {
|
|
102
|
+
const token = this.getToken();
|
|
103
|
+
const runtimesRunUrl = this.getRuntimesRunUrl();
|
|
104
|
+
const runtimeData = await runtimes.getRuntime(token, podName, runtimesRunUrl);
|
|
105
|
+
return new Runtime(runtimeData, this);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Delete a runtime permanently.
|
|
109
|
+
* @param podName - Runtime pod name
|
|
110
|
+
*/
|
|
111
|
+
async deleteRuntime(podName) {
|
|
112
|
+
const token = this.getToken();
|
|
113
|
+
const runtimesRunUrl = this.getRuntimesRunUrl();
|
|
114
|
+
await runtimes.deleteRuntime(token, podName, runtimesRunUrl);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Terminate all runtimes.
|
|
118
|
+
* Lists all runtimes and deletes them in parallel.
|
|
119
|
+
* @returns Array of results for each deletion (fulfilled or rejected)
|
|
120
|
+
*/
|
|
121
|
+
async terminateAllRuntimes() {
|
|
122
|
+
const token = this.getToken();
|
|
123
|
+
const runtimesRunUrl = this.getRuntimesRunUrl();
|
|
124
|
+
// List all runtimes
|
|
125
|
+
const response = await runtimes.listRuntimes(token, runtimesRunUrl);
|
|
126
|
+
// Delete all runtimes in parallel
|
|
127
|
+
const deletePromises = response.runtimes.map(runtime => runtimes.deleteRuntime(token, runtime.pod_name, runtimesRunUrl));
|
|
128
|
+
return Promise.allSettled(deletePromises);
|
|
129
|
+
}
|
|
130
|
+
// ========================================================================
|
|
131
|
+
// Snapshots
|
|
132
|
+
// ========================================================================
|
|
133
|
+
/**
|
|
134
|
+
* Create a snapshot of a runtime.
|
|
135
|
+
* @param podName - Pod name of the runtime to snapshot
|
|
136
|
+
* @param name - Name for the snapshot
|
|
137
|
+
* @param description - Description of the snapshot
|
|
138
|
+
* @param stop - Whether to stop the runtime after creating snapshot (defaults to false)
|
|
139
|
+
* @returns Created snapshot
|
|
140
|
+
*/
|
|
141
|
+
async createSnapshot(podName, name, description, stop = false) {
|
|
142
|
+
const token = this.getToken();
|
|
143
|
+
const runtimesRunUrl = this.getRuntimesRunUrl();
|
|
144
|
+
const data = {
|
|
145
|
+
pod_name: podName,
|
|
146
|
+
name,
|
|
147
|
+
description,
|
|
148
|
+
stop,
|
|
149
|
+
};
|
|
150
|
+
const response = await snapshots.createSnapshot(token, data, runtimesRunUrl);
|
|
151
|
+
return new Snapshot(response.snapshot, this);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* List all runtime snapshots.
|
|
155
|
+
* @returns Array of snapshots
|
|
156
|
+
*/
|
|
157
|
+
async listSnapshots() {
|
|
158
|
+
const token = this.getToken();
|
|
159
|
+
const runtimesRunUrl = this.getRuntimesRunUrl();
|
|
160
|
+
const response = await snapshots.listSnapshots(token, runtimesRunUrl);
|
|
161
|
+
return response.snapshots.map(s => new Snapshot(s, this));
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Get details for a specific snapshot by ID.
|
|
165
|
+
* @param id - Snapshot ID
|
|
166
|
+
* @returns Snapshot details
|
|
167
|
+
*/
|
|
168
|
+
async getSnapshot(id) {
|
|
169
|
+
const token = this.getToken();
|
|
170
|
+
const runtimesRunUrl = this.getRuntimesRunUrl();
|
|
171
|
+
const response = await snapshots.getSnapshot(token, id, runtimesRunUrl);
|
|
172
|
+
return new Snapshot(response.snapshot, this);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Delete a snapshot permanently.
|
|
176
|
+
* @param id - Snapshot ID
|
|
177
|
+
*/
|
|
178
|
+
async deleteSnapshot(id) {
|
|
179
|
+
const token = this.getToken();
|
|
180
|
+
const runtimesRunUrl = this.getRuntimesRunUrl();
|
|
181
|
+
await snapshots.deleteSnapshot(token, id, runtimesRunUrl);
|
|
182
|
+
}
|
|
183
|
+
// ========================================================================
|
|
184
|
+
// Service Health Checks
|
|
185
|
+
// ========================================================================
|
|
186
|
+
/**
|
|
187
|
+
* Check the health status of the Runtimes service.
|
|
188
|
+
* @returns Health check result with status and response time
|
|
189
|
+
*/
|
|
190
|
+
async checkRuntimesHealth() {
|
|
191
|
+
const startTime = Date.now();
|
|
192
|
+
const errors = [];
|
|
193
|
+
let status = 'unknown';
|
|
194
|
+
let healthy = false;
|
|
195
|
+
try {
|
|
196
|
+
// Test basic connectivity by listing environments (lightweight operation)
|
|
197
|
+
const environments = await this.listEnvironments();
|
|
198
|
+
const responseTime = Date.now() - startTime;
|
|
199
|
+
if (Array.isArray(environments)) {
|
|
200
|
+
healthy = true;
|
|
201
|
+
status = 'operational';
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
status = 'degraded';
|
|
205
|
+
errors.push('Unexpected response format from environments endpoint');
|
|
206
|
+
}
|
|
207
|
+
return new HealthCheck({
|
|
208
|
+
healthy,
|
|
209
|
+
status,
|
|
210
|
+
responseTime,
|
|
211
|
+
errors,
|
|
212
|
+
timestamp: new Date(),
|
|
213
|
+
}, this);
|
|
214
|
+
}
|
|
215
|
+
catch (error) {
|
|
216
|
+
const responseTime = Date.now() - startTime;
|
|
217
|
+
status = 'down';
|
|
218
|
+
errors.push(`Service unreachable: ${error}`);
|
|
219
|
+
return new HealthCheck({
|
|
220
|
+
healthy: false,
|
|
221
|
+
status,
|
|
222
|
+
responseTime,
|
|
223
|
+
errors,
|
|
224
|
+
timestamp: new Date(),
|
|
225
|
+
}, this);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import type { Constructor } from '../utils/mixins';
|
|
2
|
+
import { Notebook } from '../models/Notebook';
|
|
3
|
+
import { Lexical } from '../models/Lexical';
|
|
4
|
+
import { Space } from '../models/Space';
|
|
5
|
+
import { HealthCheck } from '../models/HealthCheck';
|
|
6
|
+
/** Options for content loading with CDN support. */
|
|
7
|
+
export interface ContentLoadingOptions {
|
|
8
|
+
/** Whether to try CDN first before API (default: true) */
|
|
9
|
+
preferCDN?: boolean;
|
|
10
|
+
/** CDN base URL (default: https://cdn.datalayer.run) */
|
|
11
|
+
cdnBaseUrl?: string;
|
|
12
|
+
}
|
|
13
|
+
/** Spacer mixin providing workspace and content management. */
|
|
14
|
+
export declare function SpacerMixin<TBase extends Constructor>(Base: TBase): {
|
|
15
|
+
new (...args: any[]): {
|
|
16
|
+
/**
|
|
17
|
+
* Get all workspaces for the authenticated user.
|
|
18
|
+
* @returns Array of Space instances
|
|
19
|
+
*/
|
|
20
|
+
getMySpaces(): Promise<Space[]>;
|
|
21
|
+
/**
|
|
22
|
+
* Create a new workspace.
|
|
23
|
+
* @param name - Space name
|
|
24
|
+
* @param description - Space description
|
|
25
|
+
* @param variant - Space variant type
|
|
26
|
+
* @param spaceHandle - Unique handle for the space
|
|
27
|
+
* @param organizationId - Organization ID
|
|
28
|
+
* @param seedSpaceId - Seed space ID for initialization
|
|
29
|
+
* @param isPublic - Whether the space is public
|
|
30
|
+
* @returns Created Space instance
|
|
31
|
+
*/
|
|
32
|
+
createSpace(name: string, description: string, variant: string, spaceHandle: string, organizationId: string, seedSpaceId: string, isPublic: boolean): Promise<Space>;
|
|
33
|
+
/**
|
|
34
|
+
* Create a new notebook.
|
|
35
|
+
* @param spaceId - ID of the space to create the notebook in
|
|
36
|
+
* @param name - Name of the notebook
|
|
37
|
+
* @param description - Description of the notebook
|
|
38
|
+
* @param file - Optional file for notebook content
|
|
39
|
+
* @returns Created Notebook instance
|
|
40
|
+
*/
|
|
41
|
+
createNotebook(spaceId: string, name: string, description: string, file?: File | Blob): Promise<Notebook>;
|
|
42
|
+
/**
|
|
43
|
+
* Get a notebook by ID.
|
|
44
|
+
* @param id - Notebook ID
|
|
45
|
+
* @returns Notebook instance
|
|
46
|
+
*/
|
|
47
|
+
getNotebook(id: string): Promise<Notebook>;
|
|
48
|
+
/**
|
|
49
|
+
* Update a notebook.
|
|
50
|
+
* @param id - Notebook ID
|
|
51
|
+
* @param name - Optional new name for the notebook
|
|
52
|
+
* @param description - Optional new description for the notebook
|
|
53
|
+
* @returns Updated Notebook instance
|
|
54
|
+
*/
|
|
55
|
+
updateNotebook(id: string, name?: string, description?: string): Promise<Notebook>;
|
|
56
|
+
/**
|
|
57
|
+
* Create a new lexical document.
|
|
58
|
+
* @param spaceId - ID of the space to create the lexical document in
|
|
59
|
+
* @param name - Name of the lexical document
|
|
60
|
+
* @param description - Description of the lexical document
|
|
61
|
+
* @param file - Optional file for document content
|
|
62
|
+
* @returns Created Lexical instance
|
|
63
|
+
*/
|
|
64
|
+
createLexical(spaceId: string, name: string, description: string, file?: File | Blob): Promise<Lexical>;
|
|
65
|
+
/**
|
|
66
|
+
* Get a lexical document by ID.
|
|
67
|
+
* @param id - Document ID
|
|
68
|
+
* @returns Lexical instance
|
|
69
|
+
*/
|
|
70
|
+
getLexical(id: string): Promise<Lexical>;
|
|
71
|
+
/**
|
|
72
|
+
* Update a lexical document.
|
|
73
|
+
* @param id - Document ID
|
|
74
|
+
* @param name - Optional new name for the lexical document
|
|
75
|
+
* @param description - Optional new description for the lexical document
|
|
76
|
+
* @returns Updated Lexical instance
|
|
77
|
+
*/
|
|
78
|
+
updateLexical(id: string, name?: string, description?: string): Promise<Lexical>;
|
|
79
|
+
/**
|
|
80
|
+
* Get the items of a space as model instances.
|
|
81
|
+
* @param spaceId - Space ID
|
|
82
|
+
* @returns Array of Notebook and Lexical model instances
|
|
83
|
+
*/
|
|
84
|
+
getSpaceItems(spaceId: string): Promise<(Notebook | Lexical)[]>;
|
|
85
|
+
/**
|
|
86
|
+
* Get a single item from a space.
|
|
87
|
+
* @param itemId - Item ID to retrieve
|
|
88
|
+
* @returns Notebook or Lexical model instance
|
|
89
|
+
* @throws Error if item not found
|
|
90
|
+
*/
|
|
91
|
+
getSpaceItem(itemId: string): Promise<Notebook | Lexical>;
|
|
92
|
+
/**
|
|
93
|
+
* Delete an item from a space.
|
|
94
|
+
* @param itemId - Item ID to delete
|
|
95
|
+
* @throws Error if deletion fails
|
|
96
|
+
*/
|
|
97
|
+
deleteSpaceItem(itemId: string): Promise<void>;
|
|
98
|
+
getContent(itemId: string): Promise<any>;
|
|
99
|
+
/**
|
|
100
|
+
* Check the health status of the Spacer service.
|
|
101
|
+
* Performs a lightweight check to verify service accessibility.
|
|
102
|
+
*
|
|
103
|
+
* @returns Health check result with status and response time
|
|
104
|
+
*/
|
|
105
|
+
checkSpacerHealth(): Promise<HealthCheck>;
|
|
106
|
+
/**
|
|
107
|
+
* Get collaboration session ID for a document
|
|
108
|
+
*/
|
|
109
|
+
getCollaborationSessionId(documentId: string): Promise<string>;
|
|
110
|
+
};
|
|
111
|
+
} & TBase;
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Spacer mixin for managing workspaces, notebooks, and content.
|
|
7
|
+
* @module client/mixins/SpacerMixin
|
|
8
|
+
*/
|
|
9
|
+
import * as spaces from '../../api/spacer/spaces';
|
|
10
|
+
import * as notebooks from '../../api/spacer/notebooks';
|
|
11
|
+
import * as users from '../../api/spacer/users';
|
|
12
|
+
import * as lexicals from '../../api/spacer/lexicals';
|
|
13
|
+
import * as documents from '../../api/spacer/documents';
|
|
14
|
+
import * as items from '../../api/spacer/items';
|
|
15
|
+
import { Notebook } from '../models/Notebook';
|
|
16
|
+
import { Lexical } from '../models/Lexical';
|
|
17
|
+
import { Space } from '../models/Space';
|
|
18
|
+
import { HealthCheck } from '../models/HealthCheck';
|
|
19
|
+
import { convertSpaceItemsToModels } from '../utils/spacerUtils';
|
|
20
|
+
/** Spacer mixin providing workspace and content management. */
|
|
21
|
+
export function SpacerMixin(Base) {
|
|
22
|
+
return class extends Base {
|
|
23
|
+
// ========================================================================
|
|
24
|
+
// User
|
|
25
|
+
// ========================================================================
|
|
26
|
+
/**
|
|
27
|
+
* Get all workspaces for the authenticated user.
|
|
28
|
+
* @returns Array of Space instances
|
|
29
|
+
*/
|
|
30
|
+
async getMySpaces() {
|
|
31
|
+
const token = this.getToken();
|
|
32
|
+
const spacerRunUrl = this.getSpacerRunUrl();
|
|
33
|
+
const response = await users.getMySpaces(token, spacerRunUrl);
|
|
34
|
+
return response.spaces.map(s => new Space(s, this));
|
|
35
|
+
}
|
|
36
|
+
// ========================================================================
|
|
37
|
+
// Spaces
|
|
38
|
+
// ========================================================================
|
|
39
|
+
/**
|
|
40
|
+
* Create a new workspace.
|
|
41
|
+
* @param name - Space name
|
|
42
|
+
* @param description - Space description
|
|
43
|
+
* @param variant - Space variant type
|
|
44
|
+
* @param spaceHandle - Unique handle for the space
|
|
45
|
+
* @param organizationId - Organization ID
|
|
46
|
+
* @param seedSpaceId - Seed space ID for initialization
|
|
47
|
+
* @param isPublic - Whether the space is public
|
|
48
|
+
* @returns Created Space instance
|
|
49
|
+
*/
|
|
50
|
+
async createSpace(name, description, variant, spaceHandle, organizationId, seedSpaceId, isPublic) {
|
|
51
|
+
const token = this.getToken();
|
|
52
|
+
const spacerRunUrl = this.getSpacerRunUrl();
|
|
53
|
+
const data = {
|
|
54
|
+
name,
|
|
55
|
+
description,
|
|
56
|
+
variant,
|
|
57
|
+
spaceHandle,
|
|
58
|
+
organizationId,
|
|
59
|
+
seedSpaceId,
|
|
60
|
+
public: isPublic,
|
|
61
|
+
};
|
|
62
|
+
const response = await spaces.createSpace(token, data, spacerRunUrl);
|
|
63
|
+
if (!response.space) {
|
|
64
|
+
throw new Error('Failed to create space: no space returned');
|
|
65
|
+
}
|
|
66
|
+
return new Space(response.space, this);
|
|
67
|
+
}
|
|
68
|
+
// ========================================================================
|
|
69
|
+
// Notebooks
|
|
70
|
+
// ========================================================================
|
|
71
|
+
/**
|
|
72
|
+
* Create a new notebook.
|
|
73
|
+
* @param spaceId - ID of the space to create the notebook in
|
|
74
|
+
* @param name - Name of the notebook
|
|
75
|
+
* @param description - Description of the notebook
|
|
76
|
+
* @param file - Optional file for notebook content
|
|
77
|
+
* @returns Created Notebook instance
|
|
78
|
+
*/
|
|
79
|
+
async createNotebook(spaceId, name, description, file) {
|
|
80
|
+
// Get the Space model instance
|
|
81
|
+
const spaces = await this.getMySpaces();
|
|
82
|
+
const spaceModel = spaces.find((s) => s.uid === spaceId);
|
|
83
|
+
if (!spaceModel) {
|
|
84
|
+
throw new Error(`Space with ID '${spaceId}' not found`);
|
|
85
|
+
}
|
|
86
|
+
// Use the Space model's createNotebook method
|
|
87
|
+
return await spaceModel.createNotebook({
|
|
88
|
+
name,
|
|
89
|
+
description,
|
|
90
|
+
file,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get a notebook by ID.
|
|
95
|
+
* @param id - Notebook ID
|
|
96
|
+
* @returns Notebook instance
|
|
97
|
+
*/
|
|
98
|
+
async getNotebook(id) {
|
|
99
|
+
const spacerRunUrl = this.getSpacerRunUrl();
|
|
100
|
+
const token = this.getToken();
|
|
101
|
+
const response = await notebooks.getNotebook(token, id, spacerRunUrl);
|
|
102
|
+
if (!response.notebook) {
|
|
103
|
+
throw new Error(`Notebook with ID '${id}' not found`);
|
|
104
|
+
}
|
|
105
|
+
return new Notebook(response.notebook, this);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Update a notebook.
|
|
109
|
+
* @param id - Notebook ID
|
|
110
|
+
* @param name - Optional new name for the notebook
|
|
111
|
+
* @param description - Optional new description for the notebook
|
|
112
|
+
* @returns Updated Notebook instance
|
|
113
|
+
*/
|
|
114
|
+
async updateNotebook(id, name, description) {
|
|
115
|
+
const spacerRunUrl = this.getSpacerRunUrl();
|
|
116
|
+
const token = this.getToken();
|
|
117
|
+
const data = {};
|
|
118
|
+
if (name !== undefined)
|
|
119
|
+
data.name = name;
|
|
120
|
+
if (description !== undefined)
|
|
121
|
+
data.description = description;
|
|
122
|
+
const response = await notebooks.updateNotebook(token, id, data, spacerRunUrl);
|
|
123
|
+
if (!response.notebook) {
|
|
124
|
+
throw new Error('Failed to update notebook: no notebook returned');
|
|
125
|
+
}
|
|
126
|
+
return new Notebook(response.notebook, this);
|
|
127
|
+
}
|
|
128
|
+
// ========================================================================
|
|
129
|
+
// Lexicals
|
|
130
|
+
// ========================================================================
|
|
131
|
+
/**
|
|
132
|
+
* Create a new lexical document.
|
|
133
|
+
* @param spaceId - ID of the space to create the lexical document in
|
|
134
|
+
* @param name - Name of the lexical document
|
|
135
|
+
* @param description - Description of the lexical document
|
|
136
|
+
* @param file - Optional file for document content
|
|
137
|
+
* @returns Created Lexical instance
|
|
138
|
+
*/
|
|
139
|
+
async createLexical(spaceId, name, description, file) {
|
|
140
|
+
// Get the Space model instance
|
|
141
|
+
const spaces = await this.getMySpaces();
|
|
142
|
+
const spaceModel = spaces.find((s) => s.uid === spaceId);
|
|
143
|
+
if (!spaceModel) {
|
|
144
|
+
throw new Error(`Space with ID '${spaceId}' not found`);
|
|
145
|
+
}
|
|
146
|
+
// Use the Space model's createLexical method
|
|
147
|
+
return await spaceModel.createLexical({
|
|
148
|
+
name,
|
|
149
|
+
description,
|
|
150
|
+
file,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Get a lexical document by ID.
|
|
155
|
+
* @param id - Document ID
|
|
156
|
+
* @returns Lexical instance
|
|
157
|
+
*/
|
|
158
|
+
async getLexical(id) {
|
|
159
|
+
const spacerRunUrl = this.getSpacerRunUrl();
|
|
160
|
+
const token = this.getToken();
|
|
161
|
+
const response = await lexicals.getLexical(token, id, spacerRunUrl);
|
|
162
|
+
if (!response.document) {
|
|
163
|
+
throw new Error(`Lexical document with ID '${id}' not found`);
|
|
164
|
+
}
|
|
165
|
+
return new Lexical(response.document, this);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Update a lexical document.
|
|
169
|
+
* @param id - Document ID
|
|
170
|
+
* @param name - Optional new name for the lexical document
|
|
171
|
+
* @param description - Optional new description for the lexical document
|
|
172
|
+
* @returns Updated Lexical instance
|
|
173
|
+
*/
|
|
174
|
+
async updateLexical(id, name, description) {
|
|
175
|
+
const spacerRunUrl = this.getSpacerRunUrl();
|
|
176
|
+
const token = this.getToken();
|
|
177
|
+
const data = {};
|
|
178
|
+
if (name !== undefined)
|
|
179
|
+
data.name = name;
|
|
180
|
+
if (description !== undefined)
|
|
181
|
+
data.description = description;
|
|
182
|
+
const response = await lexicals.updateLexical(token, id, data, spacerRunUrl);
|
|
183
|
+
return new Lexical(response.document, this);
|
|
184
|
+
}
|
|
185
|
+
// ========================================================================
|
|
186
|
+
// Items
|
|
187
|
+
// ========================================================================
|
|
188
|
+
/**
|
|
189
|
+
* Get the items of a space as model instances.
|
|
190
|
+
* @param spaceId - Space ID
|
|
191
|
+
* @returns Array of Notebook and Lexical model instances
|
|
192
|
+
*/
|
|
193
|
+
async getSpaceItems(spaceId) {
|
|
194
|
+
const spacerRunUrl = this.getSpacerRunUrl();
|
|
195
|
+
const token = this.getToken();
|
|
196
|
+
const response = await items.getSpaceItems(token, spaceId, spacerRunUrl);
|
|
197
|
+
// Use shared utility function to convert items to model instances
|
|
198
|
+
return convertSpaceItemsToModels(response.items, this);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Get a single item from a space.
|
|
202
|
+
* @param itemId - Item ID to retrieve
|
|
203
|
+
* @returns Notebook or Lexical model instance
|
|
204
|
+
* @throws Error if item not found
|
|
205
|
+
*/
|
|
206
|
+
async getSpaceItem(itemId) {
|
|
207
|
+
const spacerRunUrl = this.getSpacerRunUrl();
|
|
208
|
+
const token = this.getToken();
|
|
209
|
+
const response = await items.getItem(token, itemId, spacerRunUrl);
|
|
210
|
+
if (!response.success || !response.item) {
|
|
211
|
+
throw new Error(`Space item '${itemId}' not found`);
|
|
212
|
+
}
|
|
213
|
+
// Determine item type and create appropriate model
|
|
214
|
+
const item = response.item;
|
|
215
|
+
if (item.type_s === 'notebook' || item.notebook_name_s !== undefined) {
|
|
216
|
+
return new Notebook(item, this);
|
|
217
|
+
}
|
|
218
|
+
else if (item.type_s === 'lexical' ||
|
|
219
|
+
item.document_name_s !== undefined) {
|
|
220
|
+
return new Lexical(item, this);
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
throw new Error(`Unknown item type for item '${itemId}'`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Delete an item from a space.
|
|
228
|
+
* @param itemId - Item ID to delete
|
|
229
|
+
* @throws Error if deletion fails
|
|
230
|
+
*/
|
|
231
|
+
async deleteSpaceItem(itemId) {
|
|
232
|
+
const spacerRunUrl = this.getSpacerRunUrl();
|
|
233
|
+
const token = this.getToken();
|
|
234
|
+
// First, check if the item exists
|
|
235
|
+
try {
|
|
236
|
+
const getResponse = await items.getItem(token, itemId, spacerRunUrl);
|
|
237
|
+
if (!getResponse.success || !getResponse.item) {
|
|
238
|
+
throw new Error(`Space item '${itemId}' not found`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
// If getItem throws (e.g., 404), wrap in descriptive error
|
|
243
|
+
if (error.message?.includes('404') ||
|
|
244
|
+
error.message?.includes('not found')) {
|
|
245
|
+
throw new Error(`Failed to delete space item '${itemId}': Item not found`);
|
|
246
|
+
}
|
|
247
|
+
throw new Error(`Failed to delete space item '${itemId}': ${error.message}`);
|
|
248
|
+
}
|
|
249
|
+
// Item exists, proceed with deletion
|
|
250
|
+
const response = await items.deleteItem(token, itemId, spacerRunUrl);
|
|
251
|
+
if (!response.success) {
|
|
252
|
+
throw new Error(`Failed to delete space item '${itemId}': ${response.message}`);
|
|
253
|
+
}
|
|
254
|
+
// Success - return void
|
|
255
|
+
}
|
|
256
|
+
// ========================================================================
|
|
257
|
+
// Content Loading with CDN Support
|
|
258
|
+
// ========================================================================
|
|
259
|
+
async getContent(itemId) {
|
|
260
|
+
const spacerRunUrl = this.getSpacerRunUrl();
|
|
261
|
+
const token = this.getToken();
|
|
262
|
+
// First, get the item to check for CDN URL
|
|
263
|
+
const response = await items.getItem(token, itemId, spacerRunUrl);
|
|
264
|
+
if (!response.success || !response.item) {
|
|
265
|
+
throw new Error(`Space item '${itemId}' not found`);
|
|
266
|
+
}
|
|
267
|
+
const item = response.item;
|
|
268
|
+
const cdnUrl = item.cdn_url_s;
|
|
269
|
+
if (cdnUrl) {
|
|
270
|
+
// Load content from CDN
|
|
271
|
+
const cdnResponse = await fetch(cdnUrl);
|
|
272
|
+
if (!cdnResponse.ok) {
|
|
273
|
+
throw new Error(`Failed to load content from CDN: ${cdnResponse.statusText}`);
|
|
274
|
+
}
|
|
275
|
+
return await cdnResponse.json();
|
|
276
|
+
}
|
|
277
|
+
// No CDN URL, return content from item
|
|
278
|
+
return item.content;
|
|
279
|
+
}
|
|
280
|
+
// ========================================================================
|
|
281
|
+
// Service Health Checks
|
|
282
|
+
// ========================================================================
|
|
283
|
+
/**
|
|
284
|
+
* Check the health status of the Spacer service.
|
|
285
|
+
* Performs a lightweight check to verify service accessibility.
|
|
286
|
+
*
|
|
287
|
+
* @returns Health check result with status and response time
|
|
288
|
+
*/
|
|
289
|
+
async checkSpacerHealth() {
|
|
290
|
+
const startTime = Date.now();
|
|
291
|
+
const errors = [];
|
|
292
|
+
let status = 'unknown';
|
|
293
|
+
let healthy = false;
|
|
294
|
+
try {
|
|
295
|
+
// Test basic connectivity by getting user spaces (lightweight operation)
|
|
296
|
+
const spaces = await this.getMySpaces();
|
|
297
|
+
const responseTime = Date.now() - startTime;
|
|
298
|
+
if (Array.isArray(spaces)) {
|
|
299
|
+
healthy = true;
|
|
300
|
+
status = 'operational';
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
status = 'degraded';
|
|
304
|
+
errors.push('Unexpected response format from spaces endpoint');
|
|
305
|
+
}
|
|
306
|
+
return new HealthCheck({
|
|
307
|
+
healthy,
|
|
308
|
+
status,
|
|
309
|
+
responseTime,
|
|
310
|
+
errors,
|
|
311
|
+
timestamp: new Date(),
|
|
312
|
+
}, this);
|
|
313
|
+
}
|
|
314
|
+
catch (error) {
|
|
315
|
+
const responseTime = Date.now() - startTime;
|
|
316
|
+
status = 'down';
|
|
317
|
+
errors.push(`Service unreachable: ${error}`);
|
|
318
|
+
return new HealthCheck({
|
|
319
|
+
healthy: false,
|
|
320
|
+
status,
|
|
321
|
+
responseTime,
|
|
322
|
+
errors,
|
|
323
|
+
timestamp: new Date(),
|
|
324
|
+
}, this);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Get collaboration session ID for a document
|
|
329
|
+
*/
|
|
330
|
+
async getCollaborationSessionId(documentId) {
|
|
331
|
+
const token = this.getToken();
|
|
332
|
+
const spacerRunUrl = this.getSpacerRunUrl();
|
|
333
|
+
const response = await documents.getCollaborationSessionId(token, documentId, spacerRunUrl);
|
|
334
|
+
if (!response.success || !response.sessionId) {
|
|
335
|
+
throw new Error(`Failed to get collaboration session ID for document '${documentId}': ${response.error || 'Unknown error'}`);
|
|
336
|
+
}
|
|
337
|
+
return response.sessionId;
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
}
|