@datalayer/core 0.0.11 → 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.
Files changed (237) hide show
  1. package/README.md +2 -2
  2. package/lib/api/DatalayerApi.d.ts +38 -26
  3. package/lib/api/DatalayerApi.js +35 -8
  4. package/lib/api/iam/authentication.d.ts +8 -7
  5. package/lib/api/iam/authentication.js +14 -15
  6. package/lib/api/iam/healthz.d.ts +3 -2
  7. package/lib/api/iam/healthz.js +5 -3
  8. package/lib/api/iam/index.d.ts +9 -4
  9. package/lib/api/iam/index.js +9 -4
  10. package/lib/api/iam/oauth2.d.ts +115 -0
  11. package/lib/api/iam/oauth2.js +309 -0
  12. package/lib/api/iam/profile.d.ts +8 -1
  13. package/lib/api/iam/profile.js +17 -2
  14. package/lib/api/iam/usage.d.ts +56 -0
  15. package/lib/api/iam/usage.js +39 -0
  16. package/lib/api/index.d.ts +6 -5
  17. package/lib/api/index.js +6 -5
  18. package/lib/api/runtimes/environments.js +3 -2
  19. package/lib/api/runtimes/healthz.d.ts +3 -13
  20. package/lib/api/runtimes/healthz.js +4 -3
  21. package/lib/api/runtimes/index.d.ts +3 -2
  22. package/lib/api/runtimes/index.js +3 -2
  23. package/lib/api/runtimes/runtimes.js +17 -6
  24. package/lib/api/runtimes/snapshots.js +3 -2
  25. package/lib/api/spacer/documents.d.ts +12 -0
  26. package/lib/api/spacer/documents.js +43 -0
  27. package/lib/api/spacer/healthz.d.ts +3 -13
  28. package/lib/api/spacer/healthz.js +4 -3
  29. package/lib/api/spacer/index.d.ts +4 -2
  30. package/lib/api/spacer/index.js +4 -2
  31. package/lib/api/spacer/items.d.ts +9 -1
  32. package/lib/api/spacer/items.js +17 -2
  33. package/lib/api/spacer/lexicals.js +3 -2
  34. package/lib/api/spacer/notebooks.js +3 -2
  35. package/lib/api/spacer/spaces.js +3 -2
  36. package/lib/api/spacer/users.js +3 -2
  37. package/lib/api/types/common.d.ts +64 -0
  38. package/lib/api/types/iam.d.ts +88 -65
  39. package/lib/api/types/index.d.ts +4 -2
  40. package/lib/api/types/index.js +4 -2
  41. package/lib/api/types/runtimes.d.ts +9 -39
  42. package/lib/api/types/spacer.d.ts +37 -65
  43. package/lib/api/utils/validation.d.ts +24 -1
  44. package/lib/api/utils/validation.js +62 -1
  45. package/lib/client/base.d.ts +75 -0
  46. package/lib/client/base.js +199 -0
  47. package/lib/client/constants.d.ts +22 -0
  48. package/lib/client/constants.js +22 -0
  49. package/lib/client/index.d.ts +108 -0
  50. package/lib/client/index.js +79 -0
  51. package/lib/client/mixins/IAMMixin.d.ts +54 -0
  52. package/lib/client/mixins/IAMMixin.js +181 -0
  53. package/lib/client/mixins/RuntimesMixin.d.ts +93 -0
  54. package/lib/client/mixins/RuntimesMixin.js +229 -0
  55. package/lib/client/mixins/SpacerMixin.d.ts +111 -0
  56. package/lib/client/mixins/SpacerMixin.js +340 -0
  57. package/lib/client/models/Credits.d.ts +91 -0
  58. package/lib/client/models/Credits.js +130 -0
  59. package/lib/client/models/Environment.d.ts +73 -0
  60. package/lib/client/models/Environment.js +88 -0
  61. package/lib/client/models/HealthCheck.d.ts +72 -0
  62. package/lib/client/models/HealthCheck.js +107 -0
  63. package/lib/client/models/Item.d.ts +69 -0
  64. package/lib/client/models/Item.js +191 -0
  65. package/lib/client/models/Lexical.d.ts +83 -0
  66. package/lib/client/models/Lexical.js +152 -0
  67. package/lib/client/models/Notebook.d.ts +87 -0
  68. package/lib/client/models/Notebook.js +153 -0
  69. package/lib/client/models/Runtime.d.ts +122 -0
  70. package/lib/client/models/Runtime.js +204 -0
  71. package/lib/client/models/Snapshot.d.ts +92 -0
  72. package/lib/client/models/Snapshot.js +139 -0
  73. package/lib/client/models/Space.d.ts +135 -0
  74. package/lib/client/models/Space.js +234 -0
  75. package/lib/client/models/User.d.ts +64 -0
  76. package/lib/client/models/User.js +83 -0
  77. package/lib/client/models/index.d.ts +26 -0
  78. package/lib/client/models/index.js +25 -0
  79. package/lib/client/utils/mixins.d.ts +12 -0
  80. package/lib/{sdk/client → client}/utils/mixins.js +0 -28
  81. package/lib/client/utils/spacerUtils.d.ts +18 -0
  82. package/lib/client/utils/spacerUtils.js +32 -0
  83. package/lib/collaboration/DatalayerCollaboration.d.ts +6 -1
  84. package/lib/collaboration/DatalayerCollaboration.js +2 -2
  85. package/lib/collaboration/DatalayerCollaborationProvider.d.ts +5 -0
  86. package/lib/collaboration/DatalayerCollaborationProvider.js +10 -9
  87. package/lib/components/progress/CreditsIndicator.d.ts +1 -1
  88. package/lib/components/runtimes/RuntimeCellVariablesDialog.js +1 -1
  89. package/lib/components/runtimes/RuntimeLauncherDialog.d.ts +1 -1
  90. package/lib/components/runtimes/RuntimePickerBase.d.ts +1 -1
  91. package/lib/components/runtimes/RuntimePickerBase.js +1 -1
  92. package/lib/components/runtimes/RuntimePickerCell.js +2 -2
  93. package/lib/components/runtimes/RuntimePickerNotebook.d.ts +1 -1
  94. package/lib/components/runtimes/RuntimePickerNotebook.js +1 -1
  95. package/lib/components/runtimes/RuntimeTransfer.d.ts +1 -1
  96. package/lib/components/runtimes/RuntimeUtils.d.ts +1 -1
  97. package/lib/components/snapshots/RuntimeSnapshotMenu.d.ts +1 -1
  98. package/lib/components/snapshots/RuntimeSnapshotMenu.js +27 -20
  99. package/lib/config/Configuration.d.ts +8 -0
  100. package/lib/hooks/useDatalayer.js +1 -1
  101. package/lib/hooks/useRuntimes.js +1 -1
  102. package/lib/hooks/useToast.js +1 -1
  103. package/lib/index.d.ts +2 -2
  104. package/lib/index.js +4 -2
  105. package/lib/sdk/index.d.ts +5 -4
  106. package/lib/sdk/index.js +6 -5
  107. package/lib/services/DatalayerServiceManager.js +1 -1
  108. package/lib/state/substates/CoreState.js +2 -0
  109. package/lib/state/substates/RuntimesState.d.ts +1 -1
  110. package/lib/state/substates/RuntimesState.js +1 -1
  111. package/lib/{sdk/stateful → stateful}/index.d.ts +1 -1
  112. package/lib/{sdk/stateful → stateful}/index.js +1 -1
  113. package/lib/{sdk/stateful → stateful}/jupyter/exec/Snippets.d.ts +1 -41
  114. package/lib/{sdk/stateful → stateful}/jupyter/exec/Snippets.js +1 -20
  115. package/lib/{sdk/stateful → stateful}/runtimes/actions.d.ts +3 -3
  116. package/lib/{sdk/stateful → stateful}/runtimes/actions.js +8 -8
  117. package/lib/{sdk/stateful → stateful}/runtimes/apis.d.ts +8 -8
  118. package/lib/stateful/runtimes/apis.js +5 -0
  119. package/package.json +12 -10
  120. package/lib/__tests__/hooks.test.d.ts +0 -1
  121. package/lib/__tests__/hooks.test.js +0 -19
  122. package/lib/__tests__/index.test.d.ts +0 -1
  123. package/lib/__tests__/index.test.js +0 -27
  124. package/lib/__tests__/integration.test.d.ts +0 -1
  125. package/lib/__tests__/integration.test.js +0 -57
  126. package/lib/__tests__/shared/cleanup-shared.d.ts +0 -4
  127. package/lib/__tests__/shared/cleanup-shared.js +0 -228
  128. package/lib/__tests__/shared/test-config.d.ts +0 -51
  129. package/lib/__tests__/shared/test-config.js +0 -110
  130. package/lib/__tests__/shared/test-constants.d.ts +0 -66
  131. package/lib/__tests__/shared/test-constants.js +0 -79
  132. package/lib/__tests__/utils.test.d.ts +0 -1
  133. package/lib/__tests__/utils.test.js +0 -59
  134. package/lib/api/__tests__/iam.authentication.integration.test.d.ts +0 -1
  135. package/lib/api/__tests__/iam.authentication.integration.test.js +0 -247
  136. package/lib/api/__tests__/iam.healthz.integration.test.d.ts +0 -1
  137. package/lib/api/__tests__/iam.healthz.integration.test.js +0 -63
  138. package/lib/api/__tests__/iam.profile.integration.test.d.ts +0 -1
  139. package/lib/api/__tests__/iam.profile.integration.test.js +0 -252
  140. package/lib/api/__tests__/runtimes.environments.integration.test.d.ts +0 -1
  141. package/lib/api/__tests__/runtimes.environments.integration.test.js +0 -122
  142. package/lib/api/__tests__/runtimes.healthz.integration.test.d.ts +0 -1
  143. package/lib/api/__tests__/runtimes.healthz.integration.test.js +0 -50
  144. package/lib/api/__tests__/runtimes.integration.test.d.ts +0 -1
  145. package/lib/api/__tests__/runtimes.integration.test.js +0 -369
  146. package/lib/api/__tests__/spacer.healthz.integration.test.d.ts +0 -1
  147. package/lib/api/__tests__/spacer.healthz.integration.test.js +0 -50
  148. package/lib/api/__tests__/spacer.integration.test.d.ts +0 -1
  149. package/lib/api/__tests__/spacer.integration.test.js +0 -519
  150. package/lib/api/iam/__tests__/authentication.unit.test.d.ts +0 -1
  151. package/lib/api/iam/__tests__/authentication.unit.test.js +0 -63
  152. package/lib/api/iam/__tests__/healthz.unit.test.d.ts +0 -1
  153. package/lib/api/iam/__tests__/healthz.unit.test.js +0 -60
  154. package/lib/api/iam/__tests__/profile.unit.test.d.ts +0 -1
  155. package/lib/api/iam/__tests__/profile.unit.test.js +0 -57
  156. package/lib/api/runtimes/__tests__/environments.unit.test.d.ts +0 -1
  157. package/lib/api/runtimes/__tests__/environments.unit.test.js +0 -77
  158. package/lib/api/runtimes/__tests__/healthz.unit.test.d.ts +0 -1
  159. package/lib/api/runtimes/__tests__/healthz.unit.test.js +0 -57
  160. package/lib/api/runtimes/__tests__/runtimes.unit.test.d.ts +0 -1
  161. package/lib/api/runtimes/__tests__/runtimes.unit.test.js +0 -139
  162. package/lib/api/runtimes/__tests__/snapshots.unit.test.d.ts +0 -1
  163. package/lib/api/runtimes/__tests__/snapshots.unit.test.js +0 -96
  164. package/lib/api/spacer/__tests__/healthz.unit.test.d.ts +0 -1
  165. package/lib/api/spacer/__tests__/healthz.unit.test.js +0 -57
  166. package/lib/api/spacer/__tests__/items.unit.test.d.ts +0 -1
  167. package/lib/api/spacer/__tests__/items.unit.test.js +0 -165
  168. package/lib/api/spacer/__tests__/lexicals.unit.test.d.ts +0 -1
  169. package/lib/api/spacer/__tests__/lexicals.unit.test.js +0 -323
  170. package/lib/api/spacer/__tests__/notebooks.unit.test.d.ts +0 -1
  171. package/lib/api/spacer/__tests__/notebooks.unit.test.js +0 -224
  172. package/lib/api/spacer/__tests__/users.unit.test.d.ts +0 -1
  173. package/lib/api/spacer/__tests__/users.unit.test.js +0 -132
  174. package/lib/api/utils/__tests__/validation.test.d.ts +0 -1
  175. package/lib/api/utils/__tests__/validation.test.js +0 -109
  176. package/lib/sdk/client/__tests__/sdk.health.integration.test.d.ts +0 -1
  177. package/lib/sdk/client/__tests__/sdk.health.integration.test.js +0 -110
  178. package/lib/sdk/client/__tests__/sdk.iam.integration.test.d.ts +0 -1
  179. package/lib/sdk/client/__tests__/sdk.iam.integration.test.js +0 -179
  180. package/lib/sdk/client/__tests__/sdk.models.integration.test.d.ts +0 -1
  181. package/lib/sdk/client/__tests__/sdk.models.integration.test.js +0 -376
  182. package/lib/sdk/client/__tests__/sdk.runtimes.integration.test.d.ts +0 -1
  183. package/lib/sdk/client/__tests__/sdk.runtimes.integration.test.js +0 -276
  184. package/lib/sdk/client/__tests__/sdk.spacer.integration.test.d.ts +0 -1
  185. package/lib/sdk/client/__tests__/sdk.spacer.integration.test.js +0 -361
  186. package/lib/sdk/client/base.d.ts +0 -88
  187. package/lib/sdk/client/base.js +0 -112
  188. package/lib/sdk/client/index.d.ts +0 -192
  189. package/lib/sdk/client/index.js +0 -128
  190. package/lib/sdk/client/mixins/HealthMixin.d.ts +0 -100
  191. package/lib/sdk/client/mixins/HealthMixin.js +0 -133
  192. package/lib/sdk/client/mixins/IAMMixin.d.ts +0 -59
  193. package/lib/sdk/client/mixins/IAMMixin.js +0 -83
  194. package/lib/sdk/client/mixins/RuntimesMixin.d.ts +0 -134
  195. package/lib/sdk/client/mixins/RuntimesMixin.js +0 -221
  196. package/lib/sdk/client/mixins/SpacerMixin.d.ts +0 -184
  197. package/lib/sdk/client/mixins/SpacerMixin.js +0 -278
  198. package/lib/sdk/client/models/Lexical.d.ts +0 -156
  199. package/lib/sdk/client/models/Lexical.js +0 -275
  200. package/lib/sdk/client/models/Notebook.d.ts +0 -174
  201. package/lib/sdk/client/models/Notebook.js +0 -311
  202. package/lib/sdk/client/models/Runtime.d.ts +0 -221
  203. package/lib/sdk/client/models/Runtime.js +0 -341
  204. package/lib/sdk/client/models/Snapshot.d.ts +0 -156
  205. package/lib/sdk/client/models/Snapshot.js +0 -244
  206. package/lib/sdk/client/models/Space.d.ts +0 -182
  207. package/lib/sdk/client/models/Space.js +0 -276
  208. package/lib/sdk/client/models/__tests__/Lexical.test.d.ts +0 -1
  209. package/lib/sdk/client/models/__tests__/Lexical.test.js +0 -288
  210. package/lib/sdk/client/models/__tests__/Notebook.test.d.ts +0 -1
  211. package/lib/sdk/client/models/__tests__/Notebook.test.js +0 -206
  212. package/lib/sdk/client/models/__tests__/Runtime.test.d.ts +0 -1
  213. package/lib/sdk/client/models/__tests__/Runtime.test.js +0 -133
  214. package/lib/sdk/client/models/__tests__/Snapshot.test.d.ts +0 -1
  215. package/lib/sdk/client/models/__tests__/Snapshot.test.js +0 -244
  216. package/lib/sdk/client/models/__tests__/Space.test.d.ts +0 -1
  217. package/lib/sdk/client/models/__tests__/Space.test.js +0 -334
  218. package/lib/sdk/client/models/index.d.ts +0 -30
  219. package/lib/sdk/client/models/index.js +0 -30
  220. package/lib/sdk/client/utils/mixins.d.ts +0 -42
  221. /package/lib/{sdk/stateful/runtimes/apis.js → api/types/common.js} +0 -0
  222. /package/lib/{sdk/stateful → stateful}/jupyter/exec/Python.d.ts +0 -0
  223. /package/lib/{sdk/stateful → stateful}/jupyter/exec/Python.js +0 -0
  224. /package/lib/{sdk/stateful → stateful}/jupyter/exec/index.d.ts +0 -0
  225. /package/lib/{sdk/stateful → stateful}/jupyter/exec/index.js +0 -0
  226. /package/lib/{sdk/stateful → stateful}/jupyter/index.d.ts +0 -0
  227. /package/lib/{sdk/stateful → stateful}/jupyter/index.js +0 -0
  228. /package/lib/{sdk/stateful → stateful}/jupyter/kernelsHandler.d.ts +0 -0
  229. /package/lib/{sdk/stateful → stateful}/jupyter/kernelsHandler.js +0 -0
  230. /package/lib/{sdk/stateful → stateful}/runtimes/index.d.ts +0 -0
  231. /package/lib/{sdk/stateful → stateful}/runtimes/index.js +0 -0
  232. /package/lib/{sdk/stateful → stateful}/runtimes/settings.d.ts +0 -0
  233. /package/lib/{sdk/stateful → stateful}/runtimes/settings.js +0 -0
  234. /package/lib/{sdk/stateful → stateful}/runtimes/snapshots.d.ts +0 -0
  235. /package/lib/{sdk/stateful → stateful}/runtimes/snapshots.js +0 -0
  236. /package/lib/{sdk/stateful → stateful}/runtimes/utils.d.ts +0 -0
  237. /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
+ }