@milaboratories/pl-middle-layer 1.10.12

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 (179) hide show
  1. package/dist/block_registry/index.d.ts +4 -0
  2. package/dist/block_registry/index.d.ts.map +1 -0
  3. package/dist/block_registry/registry.d.ts +37 -0
  4. package/dist/block_registry/registry.d.ts.map +1 -0
  5. package/dist/block_registry/registry_spec.d.ts +12 -0
  6. package/dist/block_registry/registry_spec.d.ts.map +1 -0
  7. package/dist/block_registry/watcher.d.ts +15 -0
  8. package/dist/block_registry/watcher.d.ts.map +1 -0
  9. package/dist/block_registry/well_known_registries.d.ts +4 -0
  10. package/dist/block_registry/well_known_registries.d.ts.map +1 -0
  11. package/dist/cfg_render/executor.d.ts +8 -0
  12. package/dist/cfg_render/executor.d.ts.map +1 -0
  13. package/dist/cfg_render/operation.d.ts +29 -0
  14. package/dist/cfg_render/operation.d.ts.map +1 -0
  15. package/dist/cfg_render/renderer.d.ts +6 -0
  16. package/dist/cfg_render/renderer.d.ts.map +1 -0
  17. package/dist/cfg_render/traverse.d.ts +3 -0
  18. package/dist/cfg_render/traverse.d.ts.map +1 -0
  19. package/dist/cfg_render/util.d.ts +5 -0
  20. package/dist/cfg_render/util.d.ts.map +1 -0
  21. package/dist/dev/index.d.ts +21 -0
  22. package/dist/dev/index.d.ts.map +1 -0
  23. package/dist/dev/util.d.ts +3 -0
  24. package/dist/dev/util.d.ts.map +1 -0
  25. package/dist/index.d.ts +13 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +2 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/index.mjs +3587 -0
  30. package/dist/index.mjs.map +1 -0
  31. package/dist/js_render/context.d.ts +68 -0
  32. package/dist/js_render/context.d.ts.map +1 -0
  33. package/dist/js_render/index.d.ts +6 -0
  34. package/dist/js_render/index.d.ts.map +1 -0
  35. package/dist/middle_layer/active_cfg.d.ts +6 -0
  36. package/dist/middle_layer/active_cfg.d.ts.map +1 -0
  37. package/dist/middle_layer/block.d.ts +9 -0
  38. package/dist/middle_layer/block.d.ts.map +1 -0
  39. package/dist/middle_layer/block_ctx.d.ts +20 -0
  40. package/dist/middle_layer/block_ctx.d.ts.map +1 -0
  41. package/dist/middle_layer/block_ctx_unsafe.d.ts +16 -0
  42. package/dist/middle_layer/block_ctx_unsafe.d.ts.map +1 -0
  43. package/dist/middle_layer/driver_kit.d.ts +31 -0
  44. package/dist/middle_layer/driver_kit.d.ts.map +1 -0
  45. package/dist/middle_layer/frontend_path.d.ts +6 -0
  46. package/dist/middle_layer/frontend_path.d.ts.map +1 -0
  47. package/dist/middle_layer/index.d.ts +5 -0
  48. package/dist/middle_layer/index.d.ts.map +1 -0
  49. package/dist/middle_layer/middle_layer.d.ts +78 -0
  50. package/dist/middle_layer/middle_layer.d.ts.map +1 -0
  51. package/dist/middle_layer/navigation_states.d.ts +10 -0
  52. package/dist/middle_layer/navigation_states.d.ts.map +1 -0
  53. package/dist/middle_layer/ops.d.ts +64 -0
  54. package/dist/middle_layer/ops.d.ts.map +1 -0
  55. package/dist/middle_layer/project.d.ts +110 -0
  56. package/dist/middle_layer/project.d.ts.map +1 -0
  57. package/dist/middle_layer/project_list.d.ts +11 -0
  58. package/dist/middle_layer/project_list.d.ts.map +1 -0
  59. package/dist/middle_layer/project_overview.d.ts +8 -0
  60. package/dist/middle_layer/project_overview.d.ts.map +1 -0
  61. package/dist/middle_layer/render.d.ts +6 -0
  62. package/dist/middle_layer/render.d.ts.map +1 -0
  63. package/dist/middle_layer/types.d.ts +11 -0
  64. package/dist/middle_layer/types.d.ts.map +1 -0
  65. package/dist/middle_layer/util.d.ts +3 -0
  66. package/dist/middle_layer/util.d.ts.map +1 -0
  67. package/dist/model/args.d.ts +12 -0
  68. package/dist/model/args.d.ts.map +1 -0
  69. package/dist/model/block_pack.d.ts +8 -0
  70. package/dist/model/block_pack.d.ts.map +1 -0
  71. package/dist/model/block_pack_spec.d.ts +40 -0
  72. package/dist/model/block_pack_spec.d.ts.map +1 -0
  73. package/dist/model/frontend.d.ts +10 -0
  74. package/dist/model/frontend.d.ts.map +1 -0
  75. package/dist/model/index.d.ts +3 -0
  76. package/dist/model/index.d.ts.map +1 -0
  77. package/dist/model/project_model.d.ts +67 -0
  78. package/dist/model/project_model.d.ts.map +1 -0
  79. package/dist/model/project_model_util.d.ts +29 -0
  80. package/dist/model/project_model_util.d.ts.map +1 -0
  81. package/dist/model/template_spec.d.ts +16 -0
  82. package/dist/model/template_spec.d.ts.map +1 -0
  83. package/dist/mutator/block-pack/block_pack.d.ts +17 -0
  84. package/dist/mutator/block-pack/block_pack.d.ts.map +1 -0
  85. package/dist/mutator/block-pack/frontend.d.ts +4 -0
  86. package/dist/mutator/block-pack/frontend.d.ts.map +1 -0
  87. package/dist/mutator/context_export.d.ts +9 -0
  88. package/dist/mutator/context_export.d.ts.map +1 -0
  89. package/dist/mutator/project.d.ts +121 -0
  90. package/dist/mutator/project.d.ts.map +1 -0
  91. package/dist/mutator/template/render_block.d.ts +32 -0
  92. package/dist/mutator/template/render_block.d.ts.map +1 -0
  93. package/dist/mutator/template/render_template.d.ts +12 -0
  94. package/dist/mutator/template/render_template.d.ts.map +1 -0
  95. package/dist/mutator/template/template_loading.d.ts +13 -0
  96. package/dist/mutator/template/template_loading.d.ts.map +1 -0
  97. package/dist/pool/data.d.ts +24 -0
  98. package/dist/pool/data.d.ts.map +1 -0
  99. package/dist/pool/driver.d.ts +22 -0
  100. package/dist/pool/driver.d.ts.map +1 -0
  101. package/dist/pool/index.d.ts +3 -0
  102. package/dist/pool/index.d.ts.map +1 -0
  103. package/dist/pool/p_object_collection.d.ts +29 -0
  104. package/dist/pool/p_object_collection.d.ts.map +1 -0
  105. package/dist/pool/ref_count_pool.d.ts +25 -0
  106. package/dist/pool/ref_count_pool.d.ts.map +1 -0
  107. package/dist/pool/result_pool.d.ts +25 -0
  108. package/dist/pool/result_pool.d.ts.map +1 -0
  109. package/dist/test/block_packs.d.ts +6 -0
  110. package/dist/test/block_packs.d.ts.map +1 -0
  111. package/dist/test/explicit_templates.d.ts +3 -0
  112. package/dist/test/explicit_templates.d.ts.map +1 -0
  113. package/dist/test/known_templates.d.ts +6 -0
  114. package/dist/test/known_templates.d.ts.map +1 -0
  115. package/package.json +55 -0
  116. package/src/block_registry/index.ts +3 -0
  117. package/src/block_registry/registry.test.ts +35 -0
  118. package/src/block_registry/registry.ts +180 -0
  119. package/src/block_registry/registry_spec.ts +13 -0
  120. package/src/block_registry/watcher.ts +72 -0
  121. package/src/block_registry/well_known_registries.ts +13 -0
  122. package/src/cfg_render/executor.test.ts +120 -0
  123. package/src/cfg_render/executor.ts +253 -0
  124. package/src/cfg_render/operation.ts +38 -0
  125. package/src/cfg_render/renderer.ts +540 -0
  126. package/src/cfg_render/traverse.ts +58 -0
  127. package/src/cfg_render/util.ts +29 -0
  128. package/src/dev/index.ts +89 -0
  129. package/src/dev/util.ts +13 -0
  130. package/src/index.ts +21 -0
  131. package/src/js_render/context.ts +768 -0
  132. package/src/js_render/index.ts +41 -0
  133. package/src/middle_layer/active_cfg.ts +56 -0
  134. package/src/middle_layer/block.ts +70 -0
  135. package/src/middle_layer/block_ctx.ts +90 -0
  136. package/src/middle_layer/block_ctx_unsafe.ts +29 -0
  137. package/src/middle_layer/driver_kit.ts +107 -0
  138. package/src/middle_layer/frontend_path.ts +83 -0
  139. package/src/middle_layer/index.ts +4 -0
  140. package/src/middle_layer/middle_layer.test.ts +720 -0
  141. package/src/middle_layer/middle_layer.ts +235 -0
  142. package/src/middle_layer/navigation_states.ts +48 -0
  143. package/src/middle_layer/ops.ts +147 -0
  144. package/src/middle_layer/project.ts +380 -0
  145. package/src/middle_layer/project_list.ts +59 -0
  146. package/src/middle_layer/project_overview.ts +220 -0
  147. package/src/middle_layer/render.test.ts +129 -0
  148. package/src/middle_layer/render.ts +19 -0
  149. package/src/middle_layer/types.ts +16 -0
  150. package/src/middle_layer/util.ts +22 -0
  151. package/src/model/args.ts +62 -0
  152. package/src/model/block_pack.ts +8 -0
  153. package/src/model/block_pack_spec.ts +52 -0
  154. package/src/model/frontend.ts +10 -0
  155. package/src/model/index.ts +2 -0
  156. package/src/model/project_model.test.ts +26 -0
  157. package/src/model/project_model.ts +142 -0
  158. package/src/model/project_model_util.test.ts +88 -0
  159. package/src/model/project_model_util.ts +169 -0
  160. package/src/model/template_spec.ts +18 -0
  161. package/src/mutator/block-pack/block_pack.test.ts +53 -0
  162. package/src/mutator/block-pack/block_pack.ts +187 -0
  163. package/src/mutator/block-pack/frontend.ts +29 -0
  164. package/src/mutator/context_export.ts +25 -0
  165. package/src/mutator/project.test.ts +272 -0
  166. package/src/mutator/project.ts +1112 -0
  167. package/src/mutator/template/render_block.ts +91 -0
  168. package/src/mutator/template/render_template.ts +40 -0
  169. package/src/mutator/template/template_loading.ts +77 -0
  170. package/src/mutator/template/template_render.test.ts +272 -0
  171. package/src/pool/data.ts +239 -0
  172. package/src/pool/driver.ts +325 -0
  173. package/src/pool/index.ts +2 -0
  174. package/src/pool/p_object_collection.ts +122 -0
  175. package/src/pool/ref_count_pool.ts +76 -0
  176. package/src/pool/result_pool.ts +284 -0
  177. package/src/test/block_packs.ts +23 -0
  178. package/src/test/explicit_templates.ts +8 -0
  179. package/src/test/known_templates.ts +24 -0
@@ -0,0 +1,768 @@
1
+ import { Computable, ComputableCtx } from '@milaboratories/computable';
2
+ import { PlTreeNodeAccessor } from '@milaboratories/pl-tree';
3
+ import {
4
+ CommonFieldTraverseOps as CommonFieldTraverseOpsFromSDK,
5
+ FieldTraversalStep as FieldTraversalStepFromSDK,
6
+ JsRenderInternal,
7
+ Option,
8
+ PColumn,
9
+ PFrameDef,
10
+ PFrameHandle,
11
+ PObject,
12
+ PObjectSpec,
13
+ PSpecPredicate,
14
+ PTableDef,
15
+ PTableHandle,
16
+ ResourceType as ResourceTypeFromSDK,
17
+ ResultCollection,
18
+ ValueOrError,
19
+ mapPObjectData,
20
+ mapPTableDef,
21
+ mapValueInVOE
22
+ } from '@platforma-sdk/model';
23
+ import { notEmpty } from '@milaboratories/ts-helpers';
24
+ import { randomUUID } from 'node:crypto';
25
+ import { QuickJSContext, QuickJSHandle, Scope, VmFunctionImplementation } from 'quickjs-emscripten';
26
+ import { Optional } from 'utility-types';
27
+ import { BlockContextAny } from '../middle_layer/block_ctx';
28
+ import { MiddleLayerEnvironment } from '../middle_layer/middle_layer';
29
+ import { Block } from '../model/project_model';
30
+ import { parseFinalPObjectCollection } from '../pool/p_object_collection';
31
+ import { ResultPool } from '../pool/result_pool';
32
+
33
+ function isArrayBufferOrView(obj: unknown): obj is ArrayBufferLike {
34
+ return obj instanceof ArrayBuffer || ArrayBuffer.isView(obj);
35
+ }
36
+
37
+ function bytesToBase64(data: Uint8Array | undefined): string | undefined {
38
+ return data !== undefined ? Buffer.from(data).toString('base64') : undefined;
39
+ }
40
+
41
+ export class JsExecutionContext
42
+ implements JsRenderInternal.GlobalCfgRenderCtxMethods<string, string>
43
+ {
44
+ private readonly callbackRegistry: QuickJSHandle;
45
+ private readonly fnJSONStringify: QuickJSHandle;
46
+ private readonly fnJSONParse: QuickJSHandle;
47
+
48
+ public readonly computablesToResolve: Record<string, Computable<any>> = {};
49
+
50
+ private computableCtx: ComputableCtx | undefined;
51
+ private readonly accessors = new Map<string, PlTreeNodeAccessor | undefined>();
52
+
53
+ private readonly meta: Map<string, Block>;
54
+
55
+ constructor(
56
+ private readonly scope: Scope,
57
+ private readonly vm: QuickJSContext,
58
+ private readonly blockCtx: BlockContextAny,
59
+ private readonly env: MiddleLayerEnvironment,
60
+ computableCtx: ComputableCtx
61
+ ) {
62
+ this.computableCtx = computableCtx;
63
+ this.callbackRegistry = this.scope.manage(this.vm.newObject());
64
+
65
+ this.fnJSONStringify = scope.manage(
66
+ vm.getProp(vm.global, 'JSON').consume((json) => vm.getProp(json, 'stringify'))
67
+ );
68
+ if (vm.typeof(this.fnJSONStringify) !== 'function')
69
+ throw new Error(`JSON.stringify() not found.`);
70
+
71
+ this.fnJSONParse = scope.manage(
72
+ vm.getProp(vm.global, 'JSON').consume((json) => vm.getProp(json, 'parse'))
73
+ );
74
+ if (vm.typeof(this.fnJSONParse) !== 'function') throw new Error(`JSON.parse() not found.`);
75
+
76
+ this.meta = blockCtx.blockMeta(computableCtx);
77
+
78
+ this.injectCtx();
79
+ }
80
+
81
+ public resetComputableCtx() {
82
+ this.computableCtx = undefined;
83
+ this.accessors.clear();
84
+ }
85
+
86
+ private static cleanErrorContext(error: unknown): void {
87
+ if (typeof error === 'object' && error !== null && 'context' in error) delete error['context'];
88
+ }
89
+
90
+ public evaluateBundle(code: string) {
91
+ try {
92
+ this.vm.unwrapResult(this.vm.evalCode(code, 'bundle.js', { type: 'global' })).dispose();
93
+ } catch (err: unknown) {
94
+ JsExecutionContext.cleanErrorContext(err);
95
+ throw err;
96
+ }
97
+ }
98
+
99
+ public runCallback(cbName: string, ...args: unknown[]): QuickJSHandle {
100
+ try {
101
+ return Scope.withScope((localScope) => {
102
+ const targetCallback = localScope.manage(this.vm.getProp(this.callbackRegistry, cbName));
103
+
104
+ if (this.vm.typeof(targetCallback) !== 'function')
105
+ throw new Error(`No such callback: ${cbName}`);
106
+
107
+ return this.scope.manage(
108
+ this.vm.unwrapResult(
109
+ this.vm.callFunction(
110
+ targetCallback,
111
+ this.vm.undefined,
112
+ ...args.map((arg) => this.exportObjectUniversal(arg, localScope))
113
+ )
114
+ )
115
+ );
116
+ });
117
+ } catch (err: unknown) {
118
+ JsExecutionContext.cleanErrorContext(err);
119
+ throw err;
120
+ }
121
+ }
122
+
123
+ //
124
+ // Methods for injected ctx object
125
+ //
126
+
127
+ getAccessorHandleByName(name: string): string | undefined {
128
+ if (this.computableCtx === undefined)
129
+ throw new Error("Accessors can't be used in this context");
130
+ const wellKnownAccessor = (name: string, ctxKey: 'staging' | 'prod'): string | undefined => {
131
+ if (!this.accessors.has(name)) {
132
+ const lambda = this.blockCtx[ctxKey];
133
+ if (lambda === undefined) throw new Error('Staging context not available');
134
+ const entry = lambda(this.computableCtx!);
135
+ if (!entry) this.accessors.set(name, undefined);
136
+ else
137
+ this.accessors.set(name, this.computableCtx!.accessor(entry).node({ ignoreError: true }));
138
+ }
139
+ return this.accessors.get(name) ? name : undefined;
140
+ };
141
+ if (name === 'staging') return wellKnownAccessor('staging', 'staging');
142
+ else if (name === 'main') return wellKnownAccessor('main', 'prod');
143
+ return undefined;
144
+ }
145
+
146
+ //
147
+ // Accessors
148
+ //
149
+
150
+ resolveWithCommon(
151
+ handle: string,
152
+ commonOptions: CommonFieldTraverseOpsFromSDK,
153
+ ...steps: (FieldTraversalStepFromSDK | string)[]
154
+ ): string | undefined {
155
+ return this.wrapAccessor(this.getAccessor(handle).traverseWithCommon(commonOptions, ...steps));
156
+ }
157
+
158
+ getResourceType(handle: string): ResourceTypeFromSDK {
159
+ return this.getAccessor(handle).resourceType;
160
+ }
161
+
162
+ getInputsLocked(handle: string): boolean {
163
+ return this.getAccessor(handle).getInputsLocked();
164
+ }
165
+
166
+ getOutputsLocked(handle: string): boolean {
167
+ return this.getAccessor(handle).getOutputsLocked();
168
+ }
169
+
170
+ getIsReadyOrError(handle: string): boolean {
171
+ return this.getAccessor(handle).getIsReadyOrError();
172
+ }
173
+
174
+ getIsFinal(handle: string): boolean {
175
+ return this.getAccessor(handle).getIsFinal();
176
+ }
177
+
178
+ getError(handle: string): string | undefined {
179
+ return this.wrapAccessor(this.getAccessor(handle).getError());
180
+ }
181
+
182
+ listInputFields(handle: string): string[] {
183
+ return this.getAccessor(handle).listInputFields();
184
+ }
185
+
186
+ listOutputFields(handle: string): string[] {
187
+ return this.getAccessor(handle).listOutputFields();
188
+ }
189
+
190
+ listDynamicFields(handle: string): string[] {
191
+ return this.getAccessor(handle).listDynamicFields();
192
+ }
193
+
194
+ getKeyValueBase64(handle: string, key: string): string | undefined {
195
+ return bytesToBase64(this.getAccessor(handle).getKeyValue(key));
196
+ }
197
+
198
+ getKeyValueAsString(handle: string, key: string): string | undefined {
199
+ return this.getAccessor(handle).getKeyValueAsString(key);
200
+ }
201
+
202
+ getDataBase64(handle: string): string | undefined {
203
+ return bytesToBase64(this.getAccessor(handle).getData());
204
+ }
205
+
206
+ getDataAsString(handle: string): string | undefined {
207
+ return this.getAccessor(handle).getDataAsString();
208
+ }
209
+
210
+ //
211
+ // Accessor helpers
212
+ //
213
+
214
+ parsePObjectCollection(
215
+ handle: string,
216
+ errorOnUnknownField: boolean,
217
+ prefix: string
218
+ ): Record<string, PObject<string>> | undefined {
219
+ const acc = this.getAccessor(handle);
220
+ if (!acc.getIsReadyOrError()) return undefined;
221
+ const accResult = parseFinalPObjectCollection(acc, errorOnUnknownField, prefix);
222
+ const result: Record<string, PObject<string>> = {};
223
+ for (const [key, obj] of Object.entries(accResult)) {
224
+ result[key] = mapPObjectData(obj, (d) => this.wrapAccessor(d));
225
+ }
226
+ return result;
227
+ }
228
+
229
+ //
230
+ // Blobs
231
+ //
232
+
233
+ private registerComputable(hPrefix: string, computable: Computable<unknown>): string {
234
+ const fHandle = `${hPrefix}_${randomUUID()}`;
235
+ this.computablesToResolve[fHandle] = computable;
236
+ return fHandle;
237
+ }
238
+
239
+ public getBlobContentAsString(handle: string): string {
240
+ const resourceInfo = this.getAccessor(handle).resourceInfo;
241
+ return this.registerComputable(
242
+ 'getBlobContentAsString',
243
+ Computable.make((ctx) => this.env.driverKit.blobDriver.getDownloadedBlob(resourceInfo, ctx), {
244
+ postprocessValue: async (value) => {
245
+ if (value === undefined) return undefined;
246
+ return Buffer.from(await this.env.driverKit.blobDriver.getContent(value.handle)).toString(
247
+ 'utf-8'
248
+ );
249
+ }
250
+ })
251
+ );
252
+ }
253
+
254
+ public getBlobContentAsBase64(handle: string): string {
255
+ const resourceInfo = this.getAccessor(handle).resourceInfo;
256
+ return this.registerComputable(
257
+ 'getBlobContentAsBase64',
258
+ Computable.make((ctx) => this.env.driverKit.blobDriver.getDownloadedBlob(resourceInfo, ctx), {
259
+ postprocessValue: async (value) => {
260
+ if (value === undefined) return undefined;
261
+ return Buffer.from(await this.env.driverKit.blobDriver.getContent(value.handle)).toString(
262
+ 'base64'
263
+ );
264
+ }
265
+ })
266
+ );
267
+ }
268
+
269
+ public getDownloadedBlobContentHandle(handle: string): string {
270
+ const resourceInfo = this.getAccessor(handle).resourceInfo;
271
+ return this.registerComputable(
272
+ 'getDownloadedBlobContentHandle',
273
+ this.env.driverKit.blobDriver.getDownloadedBlob(resourceInfo)
274
+ );
275
+ }
276
+
277
+ public getOnDemandBlobContentHandle(handle: string): string {
278
+ const resource = this.getAccessor(handle).persist();
279
+ return this.registerComputable(
280
+ 'getOnDemandBlobContentHandle',
281
+ this.env.driverKit.blobDriver.getOnDemandBlob(resource)
282
+ );
283
+ }
284
+
285
+ //
286
+ // Import progress
287
+ //
288
+
289
+ getImportProgress(handle: string): string {
290
+ const resource = this.getAccessor(handle).persist();
291
+ return this.registerComputable(
292
+ 'getImportProgress',
293
+ this.env.driverKit.uploadDriver.getProgressId(resource)
294
+ );
295
+ }
296
+
297
+ //
298
+ // Logs
299
+ //
300
+
301
+ getLastLogs(handle: string, nLines: number): string {
302
+ const resource = this.getAccessor(handle).persist();
303
+ return this.registerComputable(
304
+ 'getLastLogs',
305
+ this.env.driverKit.logDriver.getLastLogs(resource, nLines)
306
+ );
307
+ }
308
+
309
+ getProgressLog(handle: string, patternToSearch: string): string {
310
+ const resource = this.getAccessor(handle).persist();
311
+ return this.registerComputable(
312
+ 'getProgressLog',
313
+ this.env.driverKit.logDriver.getProgressLog(resource, patternToSearch)
314
+ );
315
+ }
316
+
317
+ getLogHandle(handle: string): string {
318
+ const resource = this.getAccessor(handle).persist();
319
+ return this.registerComputable(
320
+ 'getLogHandle',
321
+ this.env.driverKit.logDriver.getLogHandle(resource)
322
+ );
323
+ }
324
+
325
+ //
326
+ // Blocks
327
+ //
328
+
329
+ public getBlockLabel(blockId: string): string {
330
+ const b = this.meta.get(blockId);
331
+ if (b === undefined) throw new Error(`Block ${blockId} not found.`);
332
+ return b.label;
333
+ }
334
+
335
+ //
336
+ // Result Pool
337
+ //
338
+
339
+ private _resultPool: ResultPool | undefined = undefined;
340
+ private get resultPool(): ResultPool {
341
+ if (this._resultPool === undefined) {
342
+ if (this.computableCtx === undefined)
343
+ throw new Error(
344
+ "can't use result pool in this context (most porbably called from the future mapper)"
345
+ );
346
+ this._resultPool = notEmpty(
347
+ this.blockCtx.getResultsPool,
348
+ 'getResultsPool'
349
+ )(this.computableCtx);
350
+ }
351
+ return this._resultPool;
352
+ }
353
+
354
+ public calculateOptions(predicate: PSpecPredicate): Option[] {
355
+ return this.resultPool.calculateOptions(predicate);
356
+ }
357
+
358
+ public getDataFromResultPool(): ResultCollection<PObject<string>> {
359
+ const collection = this.resultPool.getData();
360
+ if (collection.instabilityMarker !== undefined)
361
+ this.computableCtx!.markUnstable(`incomplete_result_pool:${collection.instabilityMarker}`);
362
+ return {
363
+ isComplete: collection.isComplete,
364
+ entries: collection.entries.map((e) => ({
365
+ ref: e.ref,
366
+ obj: mapPObjectData(e.obj, (d) => this.wrapAccessor(d))
367
+ }))
368
+ };
369
+ }
370
+
371
+ public getDataWithErrorsFromResultPool(): ResultCollection<
372
+ Optional<PObject<ValueOrError<string, string>>, 'id'>
373
+ > {
374
+ const collection = this.resultPool.getDataWithErrors();
375
+ if (collection.instabilityMarker !== undefined)
376
+ this.computableCtx!.markUnstable(`incomplete_result_pool:${collection.instabilityMarker}`);
377
+ return {
378
+ isComplete: collection.isComplete,
379
+ entries: collection.entries.map((e) => ({
380
+ ref: e.ref,
381
+ obj: {
382
+ id: e.obj.id,
383
+ spec: e.obj.spec,
384
+ data: mapValueInVOE(e.obj.data, (d) => this.wrapAccessor(d))
385
+ }
386
+ }))
387
+ };
388
+ }
389
+
390
+ public getSpecsFromResultPool(): ResultCollection<PObjectSpec> {
391
+ const specs = this.resultPool.getSpecs();
392
+ if (specs.instabilityMarker !== undefined)
393
+ this.computableCtx!.markUnstable(`specs_from_pool_incomplete:${specs.instabilityMarker}`);
394
+ return specs;
395
+ }
396
+
397
+ //
398
+ // PFrames / PTables
399
+ //
400
+
401
+ public createPFrame(def: PFrameDef<string>): PFrameHandle {
402
+ if (this.computableCtx === undefined)
403
+ throw new Error(
404
+ "can't instantiate PFrames from this context (most porbably called from the future mapper)"
405
+ );
406
+ return this.env.driverKit.pFrameDriver.createPFrame(
407
+ def.map((c) => mapPObjectData(c, (d) => this.getAccessor(d))),
408
+ this.computableCtx
409
+ );
410
+ }
411
+
412
+ public createPTable(def: PTableDef<PColumn<string>>): PTableHandle {
413
+ if (this.computableCtx === undefined)
414
+ throw new Error(
415
+ "can't instantiate PTable from this context (most porbably called from the future mapper)"
416
+ );
417
+ return this.env.driverKit.pFrameDriver.createPTable(
418
+ mapPTableDef(def, (c) => mapPObjectData(c, (d) => this.getAccessor(d))),
419
+ this.computableCtx
420
+ );
421
+ }
422
+
423
+ //
424
+ // Helpers
425
+ //
426
+
427
+ private getAccessor(handle: string): PlTreeNodeAccessor {
428
+ const accessor = this.accessors.get(handle);
429
+ if (accessor === undefined) throw new Error('No such accessor');
430
+ return accessor;
431
+ }
432
+
433
+ private wrapAccessor(accessor: PlTreeNodeAccessor): string;
434
+ private wrapAccessor(accessor: PlTreeNodeAccessor | undefined): string | undefined;
435
+ private wrapAccessor(accessor: PlTreeNodeAccessor | undefined): string | undefined {
436
+ if (accessor === undefined) return undefined;
437
+ else {
438
+ const nextHandle = randomUUID();
439
+ this.accessors.set(nextHandle, accessor);
440
+ return nextHandle;
441
+ }
442
+ }
443
+
444
+ //
445
+ // QuickJS Helpers
446
+ //
447
+
448
+ private exportSingleValue(
449
+ obj: boolean | number | string | null | ArrayBuffer | undefined,
450
+ scope: Scope | undefined
451
+ ): QuickJSHandle {
452
+ const result = this.tryExportSingleValue(obj, scope);
453
+ if (result === undefined) throw new Error(`Can't export value: ${obj}`);
454
+ return result;
455
+ }
456
+
457
+ private tryExportSingleValue(obj: unknown, scope: Scope | undefined): QuickJSHandle | undefined {
458
+ let handle: QuickJSHandle;
459
+ let manage = false;
460
+ switch (typeof obj) {
461
+ case 'string':
462
+ handle = this.vm.newString(obj);
463
+ manage = true;
464
+ break;
465
+ case 'number':
466
+ handle = this.vm.newNumber(obj);
467
+ manage = true;
468
+ break;
469
+ case 'undefined':
470
+ handle = this.vm.undefined;
471
+ break;
472
+ case 'boolean':
473
+ handle = obj ? this.vm.true : this.vm.false;
474
+ break;
475
+ default:
476
+ if (obj === null) {
477
+ handle = this.vm.null;
478
+ break;
479
+ }
480
+ if (isArrayBufferOrView(obj)) {
481
+ handle = this.vm.newArrayBuffer(obj);
482
+ manage = true;
483
+ break;
484
+ }
485
+ return undefined;
486
+ }
487
+ return manage && scope != undefined ? scope.manage(handle) : handle;
488
+ }
489
+
490
+ public exportObjectUniversal(obj: unknown, scope: Scope | undefined): QuickJSHandle {
491
+ const simpleHandle = this.tryExportSingleValue(obj, scope);
492
+ if (simpleHandle !== undefined) return simpleHandle;
493
+ return this.exportObjectViaJson(obj, scope);
494
+ }
495
+
496
+ public exportObjectViaJson(obj: unknown, scope: Scope | undefined): QuickJSHandle {
497
+ const result = this.vm
498
+ .newString(JSON.stringify(obj))
499
+ .consume((json) =>
500
+ this.vm.unwrapResult(this.vm.callFunction(this.fnJSONParse, this.vm.undefined, json))
501
+ );
502
+ return scope !== undefined ? scope.manage(result) : result;
503
+ }
504
+
505
+ public importObjectUniversal(handle: QuickJSHandle): unknown {
506
+ switch (this.vm.typeof(handle)) {
507
+ case 'undefined':
508
+ return undefined;
509
+ case 'boolean':
510
+ case 'number':
511
+ case 'string':
512
+ return this.vm.dump(handle);
513
+ default:
514
+ return this.importObjectViaJson(handle);
515
+ }
516
+ }
517
+
518
+ public importObjectViaJson(handle: QuickJSHandle): unknown {
519
+ const text = this.vm
520
+ .unwrapResult(this.vm.callFunction(this.fnJSONStringify, this.vm.undefined, handle))
521
+ .consume((strHandle) => this.vm.getString(strHandle));
522
+ if (text === 'undefined')
523
+ // special case with futures
524
+ return undefined;
525
+ return JSON.parse(text);
526
+ }
527
+
528
+ private injectCtx() {
529
+ Scope.withScope((localScope) => {
530
+ const configCtx = localScope.manage(this.vm.newObject());
531
+
532
+ // Exporting props
533
+
534
+ this.vm.setProp(configCtx, 'args', localScope.manage(this.vm.newString(this.blockCtx.args)));
535
+ if (this.blockCtx.uiState !== undefined)
536
+ this.vm.setProp(
537
+ configCtx,
538
+ 'uiState',
539
+ localScope.manage(this.vm.newString(this.blockCtx.uiState))
540
+ );
541
+
542
+ this.vm.setProp(configCtx, 'callbackRegistry', this.callbackRegistry);
543
+
544
+ // Exporting methods
545
+
546
+ const exportCtxFunction = (
547
+ name: string,
548
+ fn: VmFunctionImplementation<QuickJSHandle>
549
+ ): void => {
550
+ this.vm.newFunction(name, fn).consume((fnh) => this.vm.setProp(configCtx, name, fnh));
551
+ };
552
+
553
+ //
554
+ // Methods for injected ctx object
555
+ //
556
+
557
+ exportCtxFunction('getAccessorHandleByName', (name) => {
558
+ return this.exportSingleValue(
559
+ this.getAccessorHandleByName(this.vm.getString(name)),
560
+ undefined
561
+ );
562
+ });
563
+
564
+ //
565
+ // Accessors
566
+ //
567
+
568
+ exportCtxFunction('resolveWithCommon', (handle, commonOptions, ...steps) => {
569
+ return this.exportSingleValue(
570
+ this.resolveWithCommon(
571
+ this.vm.getString(handle),
572
+ this.importObjectViaJson(commonOptions) as CommonFieldTraverseOpsFromSDK,
573
+ ...steps.map(
574
+ (step) => this.importObjectViaJson(step) as FieldTraversalStepFromSDK | string
575
+ )
576
+ ),
577
+ undefined
578
+ );
579
+ });
580
+
581
+ exportCtxFunction('getResourceType', (handle) => {
582
+ return this.exportObjectViaJson(this.getResourceType(this.vm.getString(handle)), undefined);
583
+ });
584
+
585
+ exportCtxFunction('getInputsLocked', (handle) => {
586
+ return this.exportSingleValue(this.getInputsLocked(this.vm.getString(handle)), undefined);
587
+ });
588
+
589
+ exportCtxFunction('getOutputsLocked', (handle) => {
590
+ return this.exportSingleValue(this.getOutputsLocked(this.vm.getString(handle)), undefined);
591
+ });
592
+
593
+ exportCtxFunction('getIsReadyOrError', (handle) => {
594
+ return this.exportSingleValue(this.getIsReadyOrError(this.vm.getString(handle)), undefined);
595
+ });
596
+
597
+ exportCtxFunction('getIsFinal', (handle) => {
598
+ return this.exportSingleValue(this.getIsFinal(this.vm.getString(handle)), undefined);
599
+ });
600
+
601
+ exportCtxFunction('getError', (handle) => {
602
+ return this.exportSingleValue(this.getError(this.vm.getString(handle)), undefined);
603
+ });
604
+
605
+ exportCtxFunction('listInputFields', (handle) => {
606
+ return this.exportObjectViaJson(this.listInputFields(this.vm.getString(handle)), undefined);
607
+ });
608
+
609
+ exportCtxFunction('listOutputFields', (handle) => {
610
+ return this.exportObjectViaJson(this.listInputFields(this.vm.getString(handle)), undefined);
611
+ });
612
+
613
+ exportCtxFunction('listDynamicFields', (handle) => {
614
+ return this.exportObjectViaJson(this.listInputFields(this.vm.getString(handle)), undefined);
615
+ });
616
+
617
+ exportCtxFunction('getKeyValueBase64', (handle, key) => {
618
+ return this.exportSingleValue(
619
+ this.getKeyValueBase64(this.vm.getString(handle), this.vm.getString(key)),
620
+ undefined
621
+ );
622
+ });
623
+
624
+ exportCtxFunction('getKeyValueAsString', (handle, key) => {
625
+ return this.exportSingleValue(
626
+ this.getKeyValueAsString(this.vm.getString(handle), this.vm.getString(key)),
627
+ undefined
628
+ );
629
+ });
630
+
631
+ exportCtxFunction('getDataBase64', (handle) => {
632
+ return this.exportSingleValue(this.getDataBase64(this.vm.getString(handle)), undefined);
633
+ });
634
+
635
+ exportCtxFunction('getDataAsString', (handle) => {
636
+ return this.exportSingleValue(this.getDataAsString(this.vm.getString(handle)), undefined);
637
+ });
638
+
639
+ //
640
+ // Accessor helpers
641
+ //
642
+
643
+ exportCtxFunction('parsePObjectCollection', (handle, errorOnUnknownField, prefix) => {
644
+ return this.exportObjectUniversal(
645
+ this.parsePObjectCollection(
646
+ this.vm.getString(handle),
647
+ this.vm.dump(errorOnUnknownField) as boolean,
648
+ this.vm.getString(prefix)
649
+ ),
650
+ undefined
651
+ );
652
+ });
653
+
654
+ //
655
+ // Blobs
656
+ //
657
+
658
+ exportCtxFunction('getBlobContentAsBase64', (handle) => {
659
+ return this.exportSingleValue(
660
+ this.getBlobContentAsBase64(this.vm.getString(handle)),
661
+ undefined
662
+ );
663
+ });
664
+
665
+ exportCtxFunction('getBlobContentAsString', (handle) => {
666
+ return this.exportSingleValue(
667
+ this.getBlobContentAsString(this.vm.getString(handle)),
668
+ undefined
669
+ );
670
+ });
671
+
672
+ exportCtxFunction('getDownloadedBlobContentHandle', (handle) => {
673
+ return this.exportSingleValue(
674
+ this.getDownloadedBlobContentHandle(this.vm.getString(handle)),
675
+ undefined
676
+ );
677
+ });
678
+
679
+ exportCtxFunction('getOnDemandBlobContentHandle', (handle) => {
680
+ return this.exportSingleValue(
681
+ this.getOnDemandBlobContentHandle(this.vm.getString(handle)),
682
+ undefined
683
+ );
684
+ });
685
+
686
+ //
687
+ // ImportProgress
688
+ //
689
+
690
+ exportCtxFunction('getImportProgress', (handle) => {
691
+ return this.exportSingleValue(this.getImportProgress(this.vm.getString(handle)), undefined);
692
+ });
693
+
694
+ //
695
+ // Logs
696
+ //
697
+
698
+ exportCtxFunction('getLastLogs', (handle, nLines) => {
699
+ return this.exportSingleValue(
700
+ this.getLastLogs(this.vm.getString(handle), this.vm.getNumber(nLines)),
701
+ undefined
702
+ );
703
+ });
704
+
705
+ exportCtxFunction('getProgressLog', (handle, patternToSearch) => {
706
+ return this.exportSingleValue(
707
+ this.getProgressLog(this.vm.getString(handle), this.vm.getString(patternToSearch)),
708
+ undefined
709
+ );
710
+ });
711
+
712
+ exportCtxFunction('getLogHandle', (handle) => {
713
+ return this.exportSingleValue(this.getLogHandle(this.vm.getString(handle)), undefined);
714
+ });
715
+
716
+ //
717
+ // Blocks
718
+ //
719
+
720
+ exportCtxFunction('getBlockLabel', (blockId) => {
721
+ return this.exportSingleValue(this.getBlockLabel(this.vm.getString(blockId)), undefined);
722
+ });
723
+
724
+ //
725
+ // Result pool
726
+ //
727
+
728
+ exportCtxFunction('getDataFromResultPool', (predicate) => {
729
+ return this.exportObjectUniversal(this.getDataFromResultPool(), undefined);
730
+ });
731
+
732
+ exportCtxFunction('getDataWithErrorsFromResultPool', (predicate) => {
733
+ return this.exportObjectUniversal(this.getDataWithErrorsFromResultPool(), undefined);
734
+ });
735
+
736
+ exportCtxFunction('getSpecsFromResultPool', (predicate) => {
737
+ return this.exportObjectUniversal(this.getSpecsFromResultPool(), undefined);
738
+ });
739
+
740
+ exportCtxFunction('calculateOptions', (predicate) => {
741
+ return this.exportObjectUniversal(
742
+ this.calculateOptions(this.importObjectViaJson(predicate) as PSpecPredicate),
743
+ undefined
744
+ );
745
+ });
746
+
747
+ //
748
+ // PFrames / PTables
749
+ //
750
+
751
+ exportCtxFunction('createPFrame', (def) => {
752
+ return this.exportSingleValue(
753
+ this.createPFrame(this.importObjectViaJson(def) as PFrameDef<string>),
754
+ undefined
755
+ );
756
+ });
757
+
758
+ exportCtxFunction('createPTable', (def) => {
759
+ return this.exportSingleValue(
760
+ this.createPTable(this.importObjectViaJson(def) as PTableDef<PColumn<string>>),
761
+ undefined
762
+ );
763
+ });
764
+
765
+ this.vm.setProp(this.vm.global, 'cfgRenderCtx', configCtx);
766
+ });
767
+ }
768
+ }