@milaboratories/pl-middle-layer 1.38.1 → 1.39.1

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.
@@ -3,6 +3,54 @@ import { BlockCodeWithInfo, ConfigRenderLambda } from '@platforma-sdk/model';
3
3
  import { ComputableRenderingOps, Computable } from '@milaboratories/computable';
4
4
  import { QuickJSWASMModule } from 'quickjs-emscripten';
5
5
  import { BlockContextAny } from '../middle_layer/block_ctx';
6
+ /**
7
+ * Creates a Computable that executes a render function (`fh`) from a block's code in a QuickJS virtual machine.
8
+ * This function handles both synchronous and asynchronous execution patterns of the sandboxed JS code.
9
+ *
10
+ * The overall data flow is as follows:
11
+ * 1. A QuickJS VM is initialized.
12
+ * 2. A `JsExecutionContext` is created to bridge the host (TypeScript) and guest (QuickJS) environments. It injects a
13
+ * context object (`cfgRenderCtx`) into the VM, providing helper methods for the sandboxed code to interact with the
14
+ * platform (e.g., to request data).
15
+ * 3. The block's Javascript bundle is evaluated in the VM.
16
+ * 4. The specified render function (`fh.handle`) is executed.
17
+ *
18
+ * Two execution paths are possible depending on the behavior of the render function:
19
+ *
20
+ * ### Synchronous Path
21
+ * If the render function computes its result without requesting any external data requiring asynchronous calculations,
22
+ * it executes synchronously.
23
+ * - The `computablesToResolve` map in `JsExecutionContext` remains empty.
24
+ * - The function returns an object with an `ir` field holding the result (`{ ir: importedResult }`).
25
+ * Since `postprocessValue` is not specified, `ir` is treated as the final resolved value of the Computable.
26
+ * - The QuickJS VM is disposed of immediately as it's no longer needed.
27
+ *
28
+ * ### Asynchronous Path (with `postprocessValue`)
29
+ * If the render function needs external data requiring asynchronous calculations (e.g., fetching a file), it calls
30
+ * one of the injected helper methods. These methods don't return data directly. Instead, they:
31
+ * a. Create a new `Computable` for the data request (e.g., to fetch a blob).
32
+ * b. Register this new `Computable` in the `computablesToResolve` map.
33
+ * c. Return a handle (string) to the sandboxed code.
34
+ *
35
+ * In this case:
36
+ * - The initial execution of the render function returns a scaffold of the final result, which depends on the pending
37
+ * computables.
38
+ * - The `computablesToResolve` map is passed as the `ir` (initial result) to `Computable.makeRaw`.
39
+ * - The `postprocessValue` function is provided to handle the results once the computables are resolved.
40
+ * - The QuickJS VM is kept alive (`keepVmAlive = true`) because its state is needed in `postprocessValue`.
41
+ * - Once the `computable` framework resolves all dependencies, it calls `postprocessValue` with the resolved data.
42
+ * - `postprocessValue` feeds the resolved data back into the VM, allowing the sandboxed code to compute the final
43
+ * result.
44
+ * - The VM is eventually disposed of when the host Computable is destroyed.
45
+ *
46
+ * @param env The middle layer environment.
47
+ * @param ctx The block context.
48
+ * @param fh The config render lambda to execute.
49
+ * @param codeWithInfo The block's code and feature flags.
50
+ * @param configKey A key for the configuration, used for cache busting.
51
+ * @param ops Options for the computable.
52
+ * @returns A `Computable` that will resolve to the result of the lambda execution.
53
+ */
6
54
  export declare function computableFromRF(env: MiddleLayerEnvironment, ctx: BlockContextAny, fh: ConfigRenderLambda, codeWithInfo: BlockCodeWithInfo, configKey: string, ops?: Partial<ComputableRenderingOps>): Computable<unknown>;
7
55
  export declare function executeSingleLambda(quickJs: QuickJSWASMModule, fh: ConfigRenderLambda, codeWithInfo: BlockCodeWithInfo, ...args: unknown[]): unknown;
8
56
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/js_render/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAI5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAGjE,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,sBAAsB,EAC3B,GAAG,EAAE,eAAe,EACpB,EAAE,EAAE,kBAAkB,EACtB,YAAY,EAAE,iBAAiB,EAC/B,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,OAAO,CAAC,sBAAsB,CAAM,GACxC,UAAU,CAAC,OAAO,CAAC,CAiErB;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,iBAAiB,EAC1B,EAAE,EAAE,kBAAkB,EACtB,YAAY,EAAE,iBAAiB,EAC/B,GAAG,IAAI,EAAE,OAAO,EAAE,GACjB,OAAO,CA4BT"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/js_render/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAI5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAYjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,sBAAsB,EAC3B,GAAG,EAAE,eAAe,EACpB,EAAE,EAAE,kBAAkB,EACtB,YAAY,EAAE,iBAAiB,EAC/B,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,OAAO,CAAC,sBAAsB,CAAM,GACxC,UAAU,CAAC,OAAO,CAAC,CA4ErB;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,iBAAiB,EAC1B,EAAE,EAAE,kBAAkB,EACtB,YAAY,EAAE,iBAAiB,EAC/B,GAAG,IAAI,EAAE,OAAO,EAAE,GACjB,OAAO,CA4BT"}
@@ -1 +1 @@
1
- {"version":3,"file":"driver_kit.d.ts","sourceRoot":"","sources":["../../src/middle_layer/driver_kit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,KAAK,EACV,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAKL,cAAc,EACd,uBAAuB,EACvB,UAAU,EAGV,YAAY,EACb,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,KAAK,GAAG,MAAM,iCAAiC,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAEzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEpD,OAAO,KAAK,EAEV,uBAAuB,EACxB,MAAM,OAAO,CAAC;AAMf;;;;;;KAMK;AACL,MAAM,WAAW,oBAAqB,SAAQ,GAAG,CAAC,SAAS;IAEzD,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;IAEpC,QAAQ,CAAC,eAAe,EAAE,uBAAuB,CAAC;IAElD,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;IAE/B,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IAEpC,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAC;IAE5C;;;SAGK;IACL,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB;;;SAGK;IACL,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;CACrC;AAED,wBAAsB,aAAa,CACjC,EAAE,EAAE,QAAQ,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,oBAAoB,CAAC,CAiE/B"}
1
+ {"version":3,"file":"driver_kit.d.ts","sourceRoot":"","sources":["../../src/middle_layer/driver_kit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,KAAK,EACV,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAKL,cAAc,EACd,uBAAuB,EACvB,UAAU,EAGV,YAAY,EACb,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,KAAK,GAAG,MAAM,iCAAiC,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAEzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEpD,OAAO,KAAK,EAEV,uBAAuB,EACxB,MAAM,OAAO,CAAC;AAMf;;;;;;KAMK;AACL,MAAM,WAAW,oBAAqB,SAAQ,GAAG,CAAC,SAAS;IAEzD,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;IAEpC,QAAQ,CAAC,eAAe,EAAE,uBAAuB,CAAC;IAElD,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;IAE/B,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IAEpC,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAC;IAE5C;;;SAGK;IACL,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB;;;SAGK;IACL,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;CACrC;AAED,wBAAsB,aAAa,CACjC,EAAE,EAAE,QAAQ,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,oBAAoB,CAAC,CAkE/B"}
@@ -1,6 +1,7 @@
1
1
  import { TemporalSynchronizedTreeOps } from './types';
2
2
  import { DownloadBlobToURLDriverOps, DownloadDriverOps, OpenFileDialogCallback, VirtualLocalStorageSpec, UploadDriverOps, LogsStreamDriverOps, LocalStorageProjection } from '@milaboratories/pl-drivers';
3
3
  import { MiLogger } from '@milaboratories/ts-helpers';
4
+ import { PFrameDriverOps } from '../pool/driver';
4
5
  /** Paths part of {@link DriverKitOps}. */
5
6
  export type DriverKitOpsPaths = {
6
7
  /** Common root where to put downloaded blobs / downloaded blob cache */
@@ -59,10 +60,12 @@ export type DriverKitOpsSettings = {
59
60
  * calls from the UI.
60
61
  */
61
62
  readonly openFileDialogCallback: OpenFileDialogCallback;
63
+ /** Settings related to the PFrame driver */
64
+ readonly pFrameDriverOps: PFrameDriverOps;
62
65
  };
63
66
  export type DriverKitOps = DriverKitOpsPaths & DriverKitOpsSettings;
64
67
  /** Some defaults fot MiddleLayerOps. */
65
- export declare const DefaultDriverKitOpsSettings: Pick<DriverKitOpsSettings, 'logger' | 'blobDriverOps' | 'downloadBlobToURLDriverOps' | 'uploadDriverOps' | 'logStreamDriverOps'>;
68
+ export declare const DefaultDriverKitOpsSettings: Pick<DriverKitOpsSettings, 'logger' | 'blobDriverOps' | 'downloadBlobToURLDriverOps' | 'uploadDriverOps' | 'logStreamDriverOps' | 'pFrameDriverOps'>;
66
69
  export declare function DefaultDriverKitOpsPaths(workDir: string): Pick<DriverKitOpsPaths, 'blobDownloadPath' | 'blobDownloadRangesCachePath' | 'downloadBlobToURLPath' | 'pframesSpillPath'>;
67
70
  /** Fields with default values are marked as optional here. */
68
71
  export type DriverKitOpsConstructor = Omit<DriverKitOpsSettings, keyof typeof DefaultDriverKitOpsSettings> & Partial<typeof DefaultDriverKitOpsSettings> & Omit<DriverKitOpsPaths, keyof ReturnType<typeof DefaultDriverKitOpsPaths>> & Partial<ReturnType<typeof DefaultDriverKitOpsPaths>>;
@@ -1 +1 @@
1
- {"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../../src/middle_layer/ops.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../../src/middle_layer/ops.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,13 @@ import { PlTreeNodeAccessor } from '@milaboratories/pl-tree';
3
3
  import { ComputableCtx } from '@milaboratories/computable';
4
4
  import { CalculateTableDataRequest, CalculateTableDataResponse, FindColumnsRequest, FindColumnsResponse, PColumnIdAndSpec, PColumnSpec, PFrameHandle, PObjectId, PTableColumnSpec, PTableHandle, PTableShape, PTableVector, TableRange, UniqueValuesRequest, UniqueValuesResponse, PFrameDriver as SdkPFrameDriver, PColumn, PFrameDef, PTableDef, PColumnValues, DataInfo } from '@platforma-sdk/model';
5
5
  import { MiLogger } from '@milaboratories/ts-helpers';
6
- export type PColumnDataUniversal = PlTreeNodeAccessor | DataInfo<PlTreeNodeAccessor> | PColumnValues;
6
+ type PColumnDataUniversal = PlTreeNodeAccessor | DataInfo<PlTreeNodeAccessor> | PColumnValues;
7
+ export type PFrameDriverOps = {
8
+ pFrameConcurrency: number;
9
+ pTableConcurrency: number;
10
+ pFrameCacheMaxCount: number;
11
+ pFramesCacheMaxSize: number;
12
+ };
7
13
  /**
8
14
  * Extends public and safe SDK's driver API with methods used internally in the middle
9
15
  * layer and in tests.
@@ -43,10 +49,11 @@ export declare class PFrameDriver implements InternalPFrameDriver {
43
49
  private readonly spillPath;
44
50
  private readonly pFrames;
45
51
  private readonly pTables;
52
+ private readonly pTableCache;
46
53
  private readonly frameConcurrencyLimiter;
47
54
  private readonly tableConcurrencyLimiter;
48
55
  pprofDump(): Promise<Uint8Array>;
49
- static init(blobDriver: DownloadDriver, logger: MiLogger, spillPath: string): Promise<PFrameDriver>;
56
+ static init(blobDriver: DownloadDriver, logger: MiLogger, spillPath: string, ops: PFrameDriverOps): Promise<PFrameDriver>;
50
57
  private constructor();
51
58
  createPFrame(def: PFrameDef<PColumnDataUniversal>, ctx: ComputableCtx): PFrameHandle;
52
59
  createPTable(rawDef: PTableDef<PColumn<PColumnDataUniversal>>, ctx: ComputableCtx): PTableHandle;
@@ -59,4 +66,5 @@ export declare class PFrameDriver implements InternalPFrameDriver {
59
66
  getShape(handle: PTableHandle, signal?: AbortSignal): Promise<PTableShape>;
60
67
  getData(handle: PTableHandle, columnIndices: number[], range: TableRange | undefined, signal?: AbortSignal): Promise<PTableVector[]>;
61
68
  }
69
+ export {};
62
70
  //# sourceMappingURL=driver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../src/pool/driver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAEjE,OAAO,KAAK,EAAE,kBAAkB,EAAgB,MAAM,yBAAyB,CAAC;AAEhF,OAAO,KAAK,EAAE,aAAa,EAA2B,MAAM,4BAA4B,CAAC;AACzF,OAAO,KAAK,EACV,yBAAyB,EACzB,0BAA0B,EAC1B,kBAAkB,EAClB,mBAAmB,EAEnB,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,UAAU,EACV,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,IAAI,eAAe,EAC/B,OAAO,EACP,SAAS,EAET,SAAS,EAIT,aAAa,EACb,QAAQ,EAET,MAAM,sBAAsB,CAAC;AAc9B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAQ3D,MAAM,MAAM,oBAAoB,GAAG,kBAAkB,GAAG,QAAQ,CAAC,kBAAkB,CAAC,GAAG,aAAa,CAAC;AA+KrG;;;GAGG;AACH,MAAM,WAAW,oBAAqB,SAAQ,eAAe;IAC3D;;;;;;OAMG;IACH,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAEjC,0BAA0B;IAC1B,YAAY,CACV,GAAG,EAAE,SAAS,CAAC,oBAAoB,CAAC,EACpC,GAAG,EAAE,aAAa,GACjB,YAAY,CAAC;IAEhB,0BAA0B;IAC1B,YAAY,CACV,GAAG,EAAE,SAAS,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,EAC7C,GAAG,EAAE,aAAa,GACjB,YAAY,CAAC;IAEhB,mFAAmF;IACnF,kBAAkB,CAChB,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,yBAAyB,CAAC,SAAS,CAAC,EAC7C,KAAK,EAAE,UAAU,GAAG,SAAS,EAC7B,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAEvC,yFAAyF;IACzF,eAAe,CACb,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,mBAAmB,EAC5B,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC,0BAA0B;IAC1B,QAAQ,CACN,MAAM,EAAE,YAAY,EACpB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,WAAW,CAAC,CAAC;IAExB;;;;;;;SAOK;IACL,OAAO,CACL,MAAM,EAAE,YAAY,EACpB,aAAa,EAAE,MAAM,EAAE,EACvB,KAAK,EAAE,UAAU,GAAG,SAAS,EAC7B,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CAC5B;AAED,qBAAa,YAAa,YAAW,oBAAoB;IAqBrD,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAtB5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyD;IACjF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoD;IAC5E,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAA8B;IACtE,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAA8B;IAEzD,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC;WAIzB,IAAI,CACtB,UAAU,EAAE,cAAc,EAC1B,MAAM,EAAE,QAAQ,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,CAAC;IAMxB,OAAO;IA+FA,YAAY,CACjB,GAAG,EAAE,SAAS,CAAC,oBAAoB,CAAC,EACpC,GAAG,EAAE,aAAa,GACjB,YAAY;IAiBR,YAAY,CACjB,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,EAChD,GAAG,EAAE,aAAa,GACjB,YAAY;IAoBF,WAAW,CACtB,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,mBAAmB,CAAC;IA4BlB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;IAK9E,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAK9D,kBAAkB,CAC7B,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,yBAAyB,CAAC,SAAS,CAAC,EAC7C,KAAK,EAAE,UAAU,GAAG,SAAS,EAC7B,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,0BAA0B,CAAC;IA2BzB,eAAe,CAC1B,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,mBAAmB,EAC5B,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,oBAAoB,CAAC;IAwBzB,OAAO,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAUpD,QAAQ,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAW1E,OAAO,CAClB,MAAM,EAAE,YAAY,EACpB,aAAa,EAAE,MAAM,EAAE,EACvB,KAAK,EAAE,UAAU,GAAG,SAAS,EAC7B,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,YAAY,EAAE,CAAC;CAW3B"}
1
+ {"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../src/pool/driver.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milaboratories/pl-middle-layer",
3
- "version": "1.38.1",
3
+ "version": "1.39.1",
4
4
  "description": "Pl Middle Layer",
5
5
  "engines": {
6
6
  "node": ">=20.16.0"
@@ -22,7 +22,7 @@
22
22
  "keywords": [],
23
23
  "license": "UNLICENSED",
24
24
  "dependencies": {
25
- "@milaboratories/pframes-rs-node": "1.0.49",
25
+ "@milaboratories/pframes-rs-node": "1.0.50",
26
26
  "canonicalize": "~2.1.0",
27
27
  "denque": "^2.1.0",
28
28
  "lru-cache": "^11.1.0",
@@ -32,22 +32,22 @@
32
32
  "yaml": "^2.7.0",
33
33
  "zod": "~3.23.8",
34
34
  "remeda": "^2.22.6",
35
- "@milaboratories/computable": "^2.6.0",
36
35
  "@milaboratories/pl-http": "^1.1.4",
36
+ "@platforma-sdk/block-tools": "^2.5.64",
37
37
  "@milaboratories/resolve-helper": "^1.1.0",
38
- "@platforma-sdk/block-tools": "^2.5.63",
39
- "@milaboratories/pl-drivers": "^1.6.0",
40
- "@milaboratories/pl-model-backend": "~1.1.2",
38
+ "@milaboratories/computable": "^2.6.0",
39
+ "@milaboratories/pl-model-common": "~1.16.0",
41
40
  "@milaboratories/pl-client": "^2.11.2",
41
+ "@milaboratories/pl-model-middle-layer": "~1.7.46",
42
+ "@milaboratories/pl-model-backend": "~1.1.2",
43
+ "@milaboratories/pl-drivers": "^1.6.0",
42
44
  "@milaboratories/pl-tree": "~1.7.0",
43
45
  "@platforma-sdk/model": "~1.39.0",
44
- "@milaboratories/pl-model-middle-layer": "~1.7.45",
45
46
  "@milaboratories/ts-helpers": "^1.4.1",
46
- "@milaboratories/pl-model-common": "~1.16.0",
47
47
  "@platforma-sdk/workflow-tengo": "4.9.2",
48
48
  "@milaboratories/pl-config": "^1.6.1",
49
- "@milaboratories/pl-deployments": "^2.4.3",
50
- "@milaboratories/pl-errors": "^1.1.9"
49
+ "@milaboratories/pl-errors": "^1.1.9",
50
+ "@milaboratories/pl-deployments": "^2.4.3"
51
51
  },
52
52
  "devDependencies": {
53
53
  "semver": "^7.7.2",
@@ -9,6 +9,63 @@ import { JsExecutionContext } from './context';
9
9
  import type { BlockContextAny } from '../middle_layer/block_ctx';
10
10
  import { getDebugFlags } from '../debug';
11
11
 
12
+ function logOutputStatus(handle: string, renderedResult: unknown, stable: boolean, recalculationCounter: number, unstableMarker?: string) {
13
+ if (getDebugFlags().logOutputStatus && (getDebugFlags().logOutputStatus === 'any' || !stable)) {
14
+ if (stable)
15
+ console.log(`Stable output ${handle} calculated ${renderedResult !== undefined ? 'defined' : 'undefined'}; (#${recalculationCounter})`);
16
+ else
17
+ console.log(`Unstable output ${handle}; marker = ${unstableMarker}; ${renderedResult !== undefined ? 'defined' : 'undefined'} (#${recalculationCounter})`);
18
+ }
19
+ }
20
+
21
+ /**
22
+ * Creates a Computable that executes a render function (`fh`) from a block's code in a QuickJS virtual machine.
23
+ * This function handles both synchronous and asynchronous execution patterns of the sandboxed JS code.
24
+ *
25
+ * The overall data flow is as follows:
26
+ * 1. A QuickJS VM is initialized.
27
+ * 2. A `JsExecutionContext` is created to bridge the host (TypeScript) and guest (QuickJS) environments. It injects a
28
+ * context object (`cfgRenderCtx`) into the VM, providing helper methods for the sandboxed code to interact with the
29
+ * platform (e.g., to request data).
30
+ * 3. The block's Javascript bundle is evaluated in the VM.
31
+ * 4. The specified render function (`fh.handle`) is executed.
32
+ *
33
+ * Two execution paths are possible depending on the behavior of the render function:
34
+ *
35
+ * ### Synchronous Path
36
+ * If the render function computes its result without requesting any external data requiring asynchronous calculations,
37
+ * it executes synchronously.
38
+ * - The `computablesToResolve` map in `JsExecutionContext` remains empty.
39
+ * - The function returns an object with an `ir` field holding the result (`{ ir: importedResult }`).
40
+ * Since `postprocessValue` is not specified, `ir` is treated as the final resolved value of the Computable.
41
+ * - The QuickJS VM is disposed of immediately as it's no longer needed.
42
+ *
43
+ * ### Asynchronous Path (with `postprocessValue`)
44
+ * If the render function needs external data requiring asynchronous calculations (e.g., fetching a file), it calls
45
+ * one of the injected helper methods. These methods don't return data directly. Instead, they:
46
+ * a. Create a new `Computable` for the data request (e.g., to fetch a blob).
47
+ * b. Register this new `Computable` in the `computablesToResolve` map.
48
+ * c. Return a handle (string) to the sandboxed code.
49
+ *
50
+ * In this case:
51
+ * - The initial execution of the render function returns a scaffold of the final result, which depends on the pending
52
+ * computables.
53
+ * - The `computablesToResolve` map is passed as the `ir` (initial result) to `Computable.makeRaw`.
54
+ * - The `postprocessValue` function is provided to handle the results once the computables are resolved.
55
+ * - The QuickJS VM is kept alive (`keepVmAlive = true`) because its state is needed in `postprocessValue`.
56
+ * - Once the `computable` framework resolves all dependencies, it calls `postprocessValue` with the resolved data.
57
+ * - `postprocessValue` feeds the resolved data back into the VM, allowing the sandboxed code to compute the final
58
+ * result.
59
+ * - The VM is eventually disposed of when the host Computable is destroyed.
60
+ *
61
+ * @param env The middle layer environment.
62
+ * @param ctx The block context.
63
+ * @param fh The config render lambda to execute.
64
+ * @param codeWithInfo The block's code and feature flags.
65
+ * @param configKey A key for the configuration, used for cache busting.
66
+ * @param ops Options for the computable.
67
+ * @returns A `Computable` that will resolve to the result of the lambda execution.
68
+ */
12
69
  export function computableFromRF(
13
70
  env: MiddleLayerEnvironment,
14
71
  ctx: BlockContextAny,
@@ -27,59 +84,70 @@ export function computableFromRF(
27
84
  console.log(`Block lambda recalculation : ${key} (${cCtx.changeSourceMarker}; ${cCtx.bodyInvocations} invocations)`);
28
85
 
29
86
  const scope = new Scope();
30
- cCtx.addOnDestroy(() => scope.dispose());
31
-
32
- const runtime = scope.manage(env.quickJs.newRuntime());
33
- runtime.setMemoryLimit(1024 * 1024 * 8);
34
- runtime.setMaxStackSize(1024 * 320);
35
-
36
- let deadlineSettings: DeadlineSettings | undefined;
37
- runtime.setInterruptHandler(() => {
38
- if (deadlineSettings === undefined) return false;
39
- if (Date.now() > deadlineSettings.deadline) return true;
40
- return false;
87
+ let keepVmAlive = false;
88
+ cCtx.addOnDestroy(() => {
89
+ // If keepVmAlive is false, the scope will be disposed by the finally block,
90
+ // no need to dispose it here.
91
+ if (keepVmAlive) scope.dispose();
41
92
  });
42
- const vm = scope.manage(runtime.newContext());
43
- const rCtx = new JsExecutionContext(scope, vm,
44
- (s) => { deadlineSettings = s; },
45
- featureFlags,
46
- { computableCtx: cCtx, blockCtx: ctx, mlEnv: env });
47
-
48
- rCtx.evaluateBundle(code.content);
49
- const result = rCtx.runCallback(fh.handle);
50
-
51
- rCtx.resetComputableCtx();
52
-
53
- let recalculationCounter = 0;
54
-
55
- if (getDebugFlags().logOutputStatus === 'any')
56
- console.log(`Output ${fh.handle} scaffold calculated.`);
57
93
 
58
- return {
59
- ir: rCtx.computableHelper!.computablesToResolve,
60
- postprocessValue: (resolved: Record<string, unknown>, { unstableMarker, stable }) => {
94
+ try {
95
+ const runtime = scope.manage(env.quickJs.newRuntime());
96
+ runtime.setMemoryLimit(1024 * 1024 * 8);
97
+ runtime.setMaxStackSize(1024 * 320);
98
+
99
+ let deadlineSettings: DeadlineSettings | undefined;
100
+ runtime.setInterruptHandler(() => {
101
+ if (deadlineSettings === undefined) return false;
102
+ if (Date.now() > deadlineSettings.deadline) return true;
103
+ return false;
104
+ });
105
+ const vm = scope.manage(runtime.newContext());
106
+ const rCtx = new JsExecutionContext(scope, vm,
107
+ (s) => { deadlineSettings = s; },
108
+ featureFlags,
109
+ { computableCtx: cCtx, blockCtx: ctx, mlEnv: env });
110
+
111
+ rCtx.evaluateBundle(code.content);
112
+ const result = rCtx.runCallback(fh.handle);
113
+
114
+ rCtx.resetComputableCtx();
115
+
116
+ const toBeResolved = rCtx.computableHelper!.computablesToResolve;
117
+
118
+ if (Object.keys(toBeResolved).length === 0) {
119
+ const importedResult = rCtx.importObjectUniversal(result);
120
+ logOutputStatus(fh.handle, importedResult, cCtx.unstableMarker === undefined, -1, cCtx.unstableMarker);
121
+ return { ir: importedResult };
122
+ }
123
+
124
+ let recalculationCounter = 0;
125
+ if (getDebugFlags().logOutputStatus)
126
+ console.log(`Output ${fh.handle} scaffold calculated (not all computables resolved yet).`);
127
+ keepVmAlive = true;
128
+
129
+ return {
130
+ ir: toBeResolved,
131
+ postprocessValue: (resolved: Record<string, unknown>, { unstableMarker, stable }) => {
61
132
  // resolving futures
62
- for (const [handle, value] of Object.entries(resolved)) rCtx.runCallback(handle, value);
63
-
64
- // rendering result
65
- const renderedResult = rCtx.importObjectUniversal(result);
66
-
67
- // logging
68
- recalculationCounter++;
69
- if (getDebugFlags().logOutputStatus && (getDebugFlags().logOutputStatus === 'any' || !stable)) {
70
- if (stable)
71
- console.log(
72
- `Stable output ${fh.handle} calculated ${renderedResult !== undefined ? 'defined' : 'undefined'}; (#${recalculationCounter})`,
73
- );
74
- else
75
- console.log(
76
- `Unstable output ${fh.handle}; marker = ${unstableMarker}; ${renderedResult !== undefined ? 'defined' : 'undefined'} (#${recalculationCounter})`,
77
- );
78
- }
79
-
80
- return renderedResult;
81
- },
82
- };
133
+ for (const [handle, value] of Object.entries(resolved)) rCtx.runCallback(handle, value);
134
+
135
+ // rendering result
136
+ const renderedResult = rCtx.importObjectUniversal(result);
137
+
138
+ // logging
139
+ recalculationCounter++;
140
+ logOutputStatus(fh.handle, renderedResult, stable, recalculationCounter, unstableMarker);
141
+
142
+ return renderedResult;
143
+ },
144
+ };
145
+ } catch (e) {
146
+ keepVmAlive = false;
147
+ throw e;
148
+ } finally {
149
+ if (!keepVmAlive) scope.dispose();
150
+ }
83
151
  }, ops);
84
152
  }
85
153
 
@@ -117,6 +117,7 @@ export async function initDriverKit(
117
117
  blobDriver,
118
118
  ops.logger,
119
119
  ops.pframesSpillPath,
120
+ ops.pFrameDriverOps,
120
121
  );
121
122
 
122
123
  return {
@@ -11,6 +11,7 @@ import type { MiLogger } from '@milaboratories/ts-helpers';
11
11
  import { ConsoleLoggerAdapter } from '@milaboratories/ts-helpers';
12
12
  import type { LocalStorageProjection } from '@milaboratories/pl-drivers';
13
13
  import path from 'node:path';
14
+ import type { PFrameDriverOps } from '../pool/driver';
14
15
 
15
16
  /** Paths part of {@link DriverKitOps}. */
16
17
  export type DriverKitOpsPaths = {
@@ -111,6 +112,13 @@ export type DriverKitOpsSettings = {
111
112
  * calls from the UI.
112
113
  */
113
114
  readonly openFileDialogCallback: OpenFileDialogCallback;
115
+
116
+ //
117
+ // PFrame Driver
118
+ //
119
+
120
+ /** Settings related to the PFrame driver */
121
+ readonly pFrameDriverOps: PFrameDriverOps;
114
122
  };
115
123
 
116
124
  export type DriverKitOps = DriverKitOpsPaths & DriverKitOpsSettings;
@@ -123,6 +131,7 @@ export const DefaultDriverKitOpsSettings: Pick<
123
131
  | 'downloadBlobToURLDriverOps'
124
132
  | 'uploadDriverOps'
125
133
  | 'logStreamDriverOps'
134
+ | 'pFrameDriverOps'
126
135
  > = {
127
136
  logger: new ConsoleLoggerAdapter(),
128
137
  blobDriverOps: {
@@ -145,6 +154,12 @@ export const DefaultDriverKitOpsSettings: Pick<
145
154
  pollingInterval: 1000,
146
155
  stopPollingDelay: 1000,
147
156
  },
157
+ pFrameDriverOps: {
158
+ pFrameConcurrency: 1,
159
+ pTableConcurrency: 1,
160
+ pFrameCacheMaxCount: 18, // SHM trees create 3 PTables per graphic, we want to cache 6 graphics per PFrame
161
+ pFramesCacheMaxSize: 8 * 1024 * 1024 * 1024, // 8 GB
162
+ },
148
163
  };
149
164
 
150
165
  export function DefaultDriverKitOpsPaths(