@milaboratories/pl-middle-layer 1.12.4 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +436 -420
- package/dist/index.mjs.map +1 -1
- package/dist/middle_layer/driver_kit.d.ts +1 -1
- package/dist/middle_layer/driver_kit.d.ts.map +1 -1
- package/dist/middle_layer/middle_layer.d.ts +2 -2
- package/dist/middle_layer/middle_layer.d.ts.map +1 -1
- package/dist/middle_layer/ops.d.ts +40 -24
- package/dist/middle_layer/ops.d.ts.map +1 -1
- package/package.json +11 -11
- package/src/middle_layer/driver_kit.ts +22 -22
- package/src/middle_layer/middle_layer.test.ts +7 -9
- package/src/middle_layer/middle_layer.ts +18 -6
- package/src/middle_layer/ops.ts +91 -42
|
@@ -27,5 +27,5 @@ export interface MiddleLayerDriverKit extends Sdk.DriverKit {
|
|
|
27
27
|
* */
|
|
28
28
|
readonly uploadDriver: UploadDriver;
|
|
29
29
|
}
|
|
30
|
-
export declare function initDriverKit(pl: PlClient, _ops: DriverKitOpsConstructor): Promise<MiddleLayerDriverKit>;
|
|
30
|
+
export declare function initDriverKit(pl: PlClient, workdir: string, _ops: DriverKitOpsConstructor): Promise<MiddleLayerDriverKit>;
|
|
31
31
|
//# sourceMappingURL=driver_kit.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"driver_kit.d.ts","sourceRoot":"","sources":["../../src/middle_layer/driver_kit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAML,cAAc,EACd,gBAAgB,EAChB,UAAU,
|
|
1
|
+
{"version":3,"file":"driver_kit.d.ts","sourceRoot":"","sources":["../../src/middle_layer/driver_kit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAML,cAAc,EACd,gBAAgB,EAChB,UAAU,EAIV,YAAY,EACb,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,GAAG,MAAM,iCAAiC,CAAC;AACvD,OAAO,EAA8B,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAEhF,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAIL,uBAAuB,EACxB,MAAM,OAAO,CAAC;AAEf;;;;;;KAMK;AACL,MAAM,WAAW,oBAAqB,SAAQ,GAAG,CAAC,SAAS;IAEzD,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;IAEpC,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;IAE/B,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IAEpC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IAEpC;;;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,CAkD/B"}
|
|
@@ -11,7 +11,7 @@ import { QuickJSWASMModule } from 'quickjs-emscripten';
|
|
|
11
11
|
import { MiddleLayerDriverKit } from './driver_kit';
|
|
12
12
|
import { DriverKit } from '@platforma-sdk/model';
|
|
13
13
|
import { DownloadUrlDriver } from '@milaboratories/pl-drivers';
|
|
14
|
-
import { V2RegistryProvider } from '../block_registry
|
|
14
|
+
import { V2RegistryProvider } from '../block_registry';
|
|
15
15
|
import { Dispatcher } from 'undici';
|
|
16
16
|
export interface MiddleLayerEnvironment {
|
|
17
17
|
readonly pl: PlClient;
|
|
@@ -79,6 +79,6 @@ export declare class MiddleLayer {
|
|
|
79
79
|
* middle layer */
|
|
80
80
|
static generateLocalSecret(): string;
|
|
81
81
|
/** Initialize middle layer */
|
|
82
|
-
static init(pl: PlClient, _ops: MiddleLayerOpsConstructor): Promise<MiddleLayer>;
|
|
82
|
+
static init(pl: PlClient, workdir: string, _ops: MiddleLayerOpsConstructor): Promise<MiddleLayer>;
|
|
83
83
|
}
|
|
84
84
|
//# sourceMappingURL=middle_layer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middle_layer.d.ts","sourceRoot":"","sources":["../../src/middle_layer/middle_layer.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,QAAQ,EACR,UAAU,EAEX,MAAM,2BAA2B,CAAC;AAInC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,
|
|
1
|
+
{"version":3,"file":"middle_layer.d.ts","sourceRoot":"","sources":["../../src/middle_layer/middle_layer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,28 @@
|
|
|
1
1
|
import { TemporalSynchronizedTreeOps } from './types';
|
|
2
|
-
import { DownloadDriverOps, UploadDriverOps, LogsStreamDriverOps } from '@milaboratories/pl-drivers';
|
|
2
|
+
import { DownloadDriverOps, OpenFileDialogCallback, VirtualLocalStorageSpec, UploadDriverOps, LogsStreamDriverOps, LocalStorageProjection } from '@milaboratories/pl-drivers';
|
|
3
3
|
import { MiLogger } from '@milaboratories/ts-helpers';
|
|
4
|
+
/** Paths part of {@link DriverKitOps}. */
|
|
5
|
+
export type DriverKitOpsPaths = {
|
|
6
|
+
/** Common root where to put downloaded blobs / downloaded blob cache */
|
|
7
|
+
readonly blobDownloadPath: string;
|
|
8
|
+
/**
|
|
9
|
+
* List of pl storages that have projections in local file system.
|
|
10
|
+
*
|
|
11
|
+
* This option affect two drivers:
|
|
12
|
+
*
|
|
13
|
+
* (1) LS driver generates "index" handles instead of "upload" for paths inside those locations
|
|
14
|
+
*
|
|
15
|
+
* (2) Download driver directly serves content retrieval requests for blobs from listed storages,
|
|
16
|
+
* and don't apply any caching for such blobs (i.e. preventing duplication of files for Downloaded
|
|
17
|
+
* type handles, making OnDemand and Downloaded handles equivalent)
|
|
18
|
+
*
|
|
19
|
+
* */
|
|
20
|
+
readonly localProjections: LocalStorageProjection[];
|
|
21
|
+
/** List of virtual storages that will allow homogeneous access to local FSs through LS API. */
|
|
22
|
+
readonly virtualLocalStorages: VirtualLocalStorageSpec[];
|
|
23
|
+
};
|
|
4
24
|
/** Options required to initialize full set of middle layer driver kit */
|
|
5
|
-
export type
|
|
25
|
+
export type DriverKitOpsSettings = {
|
|
6
26
|
readonly logger: MiLogger;
|
|
7
27
|
/**
|
|
8
28
|
* Local secret, that is used to sign and verify different pieces of information
|
|
@@ -16,14 +36,6 @@ export type DriverKitOps = {
|
|
|
16
36
|
* to download logs when source process terminates and log terns into a blob
|
|
17
37
|
*/
|
|
18
38
|
readonly blobDriverOps: DownloadDriverOps;
|
|
19
|
-
/** Common root where to put downloaded blobs. */
|
|
20
|
-
readonly blobDownloadPath: string;
|
|
21
|
-
/**
|
|
22
|
-
* If Platforma is running in local mode and a download driver
|
|
23
|
-
* needs to download files from local storage, it will open files
|
|
24
|
-
* from the specified directory. Otherwise, it should be empty.
|
|
25
|
-
* */
|
|
26
|
-
readonly platformLocalStorageNameToPath: Record<string, string>;
|
|
27
39
|
/**
|
|
28
40
|
* Settings related to the upload driver that actually performs upload and helps render upload
|
|
29
41
|
* and indexing progresses from related pl resources.
|
|
@@ -32,19 +44,24 @@ export type DriverKitOps = {
|
|
|
32
44
|
/** Settings related to the streaming log driver */
|
|
33
45
|
readonly logStreamDriverOps: LogsStreamDriverOps;
|
|
34
46
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
readonly localStorageNameToPath: Record<string, string>;
|
|
47
|
+
* Callback to access system file open dialog, must be provided by the environment,
|
|
48
|
+
* to allow for {@link showOpenSingleFileDialog} / {@link showOpenMultipleFilesDialog}
|
|
49
|
+
* calls from the UI.
|
|
50
|
+
*/
|
|
51
|
+
readonly openFileDialogCallback: OpenFileDialogCallback;
|
|
41
52
|
};
|
|
53
|
+
export type DriverKitOps = DriverKitOpsPaths & DriverKitOpsSettings;
|
|
42
54
|
/** Some defaults fot MiddleLayerOps. */
|
|
43
|
-
export declare const
|
|
55
|
+
export declare const DefaultDriverKitOpsSettings: Pick<DriverKitOpsSettings, 'logger' | 'blobDriverOps' | 'uploadDriverOps' | 'logStreamDriverOps'>;
|
|
56
|
+
export declare function DefaultDriverKitOpsPaths(workDir: string): Pick<DriverKitOpsPaths, 'blobDownloadPath' | 'virtualLocalStorages'>;
|
|
44
57
|
/** Fields with default values are marked as optional here. */
|
|
45
|
-
export type DriverKitOpsConstructor = Omit<
|
|
58
|
+
export type DriverKitOpsConstructor = Omit<DriverKitOpsSettings, keyof typeof DefaultDriverKitOpsSettings> & Partial<typeof DefaultDriverKitOpsSettings> & Omit<DriverKitOpsPaths, keyof ReturnType<typeof DefaultDriverKitOpsPaths>> & Partial<ReturnType<typeof DefaultDriverKitOpsPaths>>;
|
|
59
|
+
export type MiddleLayerOpsPaths = DriverKitOpsPaths & {
|
|
60
|
+
/** Common root where to put frontend code. */
|
|
61
|
+
readonly frontendDownloadPath: string;
|
|
62
|
+
};
|
|
46
63
|
/** Configuration controlling different aspects of middle layer behaviour. */
|
|
47
|
-
export type
|
|
64
|
+
export type MiddleLayerOpsSettings = DriverKitOpsSettings & {
|
|
48
65
|
/** Contain temporal options controlling how often should pl trees be
|
|
49
66
|
* synchronized with the pl server. */
|
|
50
67
|
readonly defaultTreeOptions: TemporalSynchronizedTreeOps;
|
|
@@ -56,11 +73,10 @@ export type MiddleLayerOps = DriverKitOps & {
|
|
|
56
73
|
readonly stagingRenderingRate: number;
|
|
57
74
|
/** How often to check for dev block updates */
|
|
58
75
|
readonly devBlockUpdateRecheckInterval: number;
|
|
59
|
-
/** Common root where to put frontend code. */
|
|
60
|
-
readonly frontendDownloadPath: string;
|
|
61
76
|
};
|
|
77
|
+
export type MiddleLayerOps = MiddleLayerOpsSettings & MiddleLayerOpsPaths;
|
|
62
78
|
/** Some defaults fot MiddleLayerOps. */
|
|
63
|
-
export declare const
|
|
64
|
-
|
|
65
|
-
export type MiddleLayerOpsConstructor = Omit<
|
|
79
|
+
export declare const DefaultMiddleLayerOpsSettings: Pick<MiddleLayerOps, keyof typeof DefaultDriverKitOpsSettings | 'defaultTreeOptions' | 'projectRefreshInterval' | 'stagingRenderingRate' | 'devBlockUpdateRecheckInterval'>;
|
|
80
|
+
export declare function DefaultMiddleLayerOpsPaths(workDir: string): Pick<MiddleLayerOpsPaths, keyof ReturnType<typeof DefaultDriverKitOpsPaths> | 'frontendDownloadPath'>;
|
|
81
|
+
export type MiddleLayerOpsConstructor = Omit<MiddleLayerOpsSettings, keyof typeof DefaultMiddleLayerOpsSettings> & Partial<typeof DefaultMiddleLayerOpsSettings> & Omit<MiddleLayerOpsPaths, keyof ReturnType<typeof DefaultMiddleLayerOpsPaths>> & Partial<ReturnType<typeof DefaultMiddleLayerOpsPaths>>;
|
|
66
82
|
//# sourceMappingURL=ops.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../../src/middle_layer/ops.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,
|
|
1
|
+
{"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../../src/middle_layer/ops.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.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"description": "Pl Middle Layer",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -28,19 +28,19 @@
|
|
|
28
28
|
"utility-types": "^3.11.0",
|
|
29
29
|
"yaml": "^2.5.1",
|
|
30
30
|
"zod": "^3.23.8",
|
|
31
|
-
"@milaboratories/computable": "^2.1.13",
|
|
32
31
|
"@milaboratories/resolve-helper": "^1.0.1",
|
|
33
|
-
"@
|
|
34
|
-
"@
|
|
35
|
-
"@milaboratories/pl-
|
|
36
|
-
"@milaboratories/pl-
|
|
37
|
-
"@milaboratories/pl-model-common": "^1.
|
|
38
|
-
"@
|
|
39
|
-
"@milaboratories/pl-tree": "^1.4.
|
|
32
|
+
"@milaboratories/computable": "^2.2.0",
|
|
33
|
+
"@platforma-sdk/block-tools": "^2.3.16",
|
|
34
|
+
"@milaboratories/pl-client": "^2.5.3",
|
|
35
|
+
"@milaboratories/pl-drivers": "^1.3.0",
|
|
36
|
+
"@milaboratories/pl-model-common": "^1.4.0",
|
|
37
|
+
"@milaboratories/pl-model-middle-layer": "^1.5.2",
|
|
38
|
+
"@milaboratories/pl-tree": "^1.4.4",
|
|
39
|
+
"@platforma-sdk/model": "^1.7.0",
|
|
40
40
|
"@milaboratories/ts-helpers": "^1.1.0",
|
|
41
|
+
"@milaboratories/pl-config": "^1.3.0",
|
|
41
42
|
"@platforma-sdk/workflow-tengo": "1.5.0",
|
|
42
|
-
"@milaboratories/pl-local": "^1.
|
|
43
|
-
"@milaboratories/pl-config": "^1.2.7"
|
|
43
|
+
"@milaboratories/pl-local": "^1.4.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"typescript": "~5.5.4",
|
|
@@ -10,13 +10,19 @@ import {
|
|
|
10
10
|
LogsDriver,
|
|
11
11
|
LogsStreamDriver,
|
|
12
12
|
LsDriver,
|
|
13
|
+
OpenFileDialogCallback,
|
|
13
14
|
UploadDriver
|
|
14
15
|
} from '@milaboratories/pl-drivers';
|
|
15
16
|
import * as Sdk from '@milaboratories/pl-model-common';
|
|
16
17
|
import { HmacSha256Signer, MiLogger, Signer } from '@milaboratories/ts-helpers';
|
|
17
18
|
import * as os from 'node:os';
|
|
18
19
|
import { PFrameDriver } from '../pool';
|
|
19
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
DefaultDriverKitOpsPaths,
|
|
22
|
+
DefaultDriverKitOpsSettings,
|
|
23
|
+
DriverKitOps,
|
|
24
|
+
DriverKitOpsConstructor
|
|
25
|
+
} from './ops';
|
|
20
26
|
|
|
21
27
|
/**
|
|
22
28
|
* Drivers offered by the middle-layer for internal consumers,
|
|
@@ -50,18 +56,21 @@ export interface MiddleLayerDriverKit extends Sdk.DriverKit {
|
|
|
50
56
|
|
|
51
57
|
export async function initDriverKit(
|
|
52
58
|
pl: PlClient,
|
|
59
|
+
workdir: string,
|
|
53
60
|
_ops: DriverKitOpsConstructor
|
|
54
61
|
): Promise<MiddleLayerDriverKit> {
|
|
55
|
-
const ops: DriverKitOps = {
|
|
56
|
-
|
|
62
|
+
const ops: DriverKitOps = {
|
|
63
|
+
...DefaultDriverKitOpsSettings,
|
|
64
|
+
...DefaultDriverKitOpsPaths(workdir),
|
|
65
|
+
..._ops
|
|
66
|
+
};
|
|
57
67
|
|
|
58
68
|
const signer = new HmacSha256Signer(ops.localSecret);
|
|
59
69
|
|
|
60
|
-
const downloadClient = createDownloadClient(ops.logger, pl, ops.
|
|
70
|
+
const downloadClient = createDownloadClient(ops.logger, pl, ops.localProjections);
|
|
61
71
|
const logsClient = createLogsClient(pl, ops.logger);
|
|
62
72
|
const uploadBlobClient = createUploadBlobClient(pl, ops.logger);
|
|
63
73
|
const uploadProgressClient = createUploadProgressClient(pl, ops.logger);
|
|
64
|
-
const lsClient = createLsFilesClient(pl, ops.logger);
|
|
65
74
|
|
|
66
75
|
const blobDriver = new DownloadDriver(
|
|
67
76
|
ops.logger,
|
|
@@ -80,7 +89,14 @@ export async function initDriverKit(
|
|
|
80
89
|
);
|
|
81
90
|
const logsStreamDriver = new LogsStreamDriver(logsClient, ops.logStreamDriverOps);
|
|
82
91
|
const logDriver = new LogsDriver(logsStreamDriver, blobDriver);
|
|
83
|
-
const lsDriver =
|
|
92
|
+
const lsDriver = await LsDriver.init(
|
|
93
|
+
ops.logger,
|
|
94
|
+
pl,
|
|
95
|
+
signer,
|
|
96
|
+
ops.virtualLocalStorages,
|
|
97
|
+
ops.localProjections,
|
|
98
|
+
ops.openFileDialogCallback
|
|
99
|
+
);
|
|
84
100
|
|
|
85
101
|
const pFrameDriver = new PFrameDriver(blobDriver);
|
|
86
102
|
|
|
@@ -93,19 +109,3 @@ export async function initDriverKit(
|
|
|
93
109
|
pFrameDriver
|
|
94
110
|
};
|
|
95
111
|
}
|
|
96
|
-
|
|
97
|
-
function checkStorageNamesDoNotIntersect(logger: MiLogger, ops: DriverKitOps) {
|
|
98
|
-
if (ops.localStorageNameToPath.local != os.homedir())
|
|
99
|
-
logger.info(`'local' storage with homedir was overwrote: ${ops.localStorageNameToPath.local}`);
|
|
100
|
-
|
|
101
|
-
const platformStorages = Object.keys(ops.platformLocalStorageNameToPath);
|
|
102
|
-
const intersected = Object.keys(ops.localStorageNameToPath).find((name) =>
|
|
103
|
-
platformStorages.includes(name)
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
if (intersected)
|
|
107
|
-
throw new Error(
|
|
108
|
-
`Platform local storages include one or more local storages: ` +
|
|
109
|
-
` ${intersected}. Note that we automatically included 'local' storage with user's home directory.`
|
|
110
|
-
);
|
|
111
|
-
}
|
|
@@ -69,17 +69,16 @@ export async function withMl(
|
|
|
69
69
|
cb: (ml: MiddleLayer, workFolder: string) => Promise<void>
|
|
70
70
|
): Promise<void> {
|
|
71
71
|
const workFolder = path.resolve(`work/${randomUUID()}`);
|
|
72
|
-
const frontendFolder = path.join(workFolder, 'frontend');
|
|
73
|
-
const downloadFolder = path.join(workFolder, 'download');
|
|
74
|
-
await fs.promises.mkdir(frontendFolder, { recursive: true });
|
|
75
72
|
|
|
76
73
|
await TestHelpers.withTempRoot(async (pl) => {
|
|
77
|
-
const ml = await MiddleLayer.init(pl, {
|
|
74
|
+
const ml = await MiddleLayer.init(pl, workFolder, {
|
|
78
75
|
defaultTreeOptions: { pollingInterval: 250, stopPollingDelay: 500 },
|
|
79
76
|
devBlockUpdateRecheckInterval: 300,
|
|
80
|
-
frontendDownloadPath: path.resolve(frontendFolder),
|
|
81
77
|
localSecret: MiddleLayer.generateLocalSecret(),
|
|
82
|
-
|
|
78
|
+
localProjections: [], // TODO must be different with local pl
|
|
79
|
+
openFileDialogCallback: () => {
|
|
80
|
+
throw new Error('Not implemented.');
|
|
81
|
+
}
|
|
83
82
|
});
|
|
84
83
|
try {
|
|
85
84
|
await cb(ml, workFolder);
|
|
@@ -592,9 +591,9 @@ test('should create download-file block, render it and gets outputs from its con
|
|
|
592
591
|
|
|
593
592
|
expect((block3StableState.value.outputs!['contentAsJson'] as any).value).toStrictEqual(42);
|
|
594
593
|
const localBlob = (block3StableState.value.outputs!['downloadedBlobContent'] as any)
|
|
595
|
-
|
|
594
|
+
.value as LocalBlobHandleAndSize;
|
|
596
595
|
const remoteBlob = (block3StableState.value.outputs!['onDemandBlobContent'] as any)
|
|
597
|
-
|
|
596
|
+
.value as RemoteBlobHandleAndSize;
|
|
598
597
|
|
|
599
598
|
expect(
|
|
600
599
|
Buffer.from(await ml.driverKit.blobDriver.getContent(localBlob.handle)).toString('utf-8')
|
|
@@ -603,7 +602,6 @@ test('should create download-file block, render it and gets outputs from its con
|
|
|
603
602
|
expect(
|
|
604
603
|
Buffer.from(await ml.driverKit.blobDriver.getContent(remoteBlob.handle)).toString('utf-8')
|
|
605
604
|
).toEqual('42\n');
|
|
606
|
-
|
|
607
605
|
});
|
|
608
606
|
});
|
|
609
607
|
|
|
@@ -10,14 +10,18 @@ import { createProject, withProject, withProjectAuthored } from '../mutator/proj
|
|
|
10
10
|
import { SynchronizedTreeState } from '@milaboratories/pl-tree';
|
|
11
11
|
import { BlockPackPreparer } from '../mutator/block-pack/block_pack';
|
|
12
12
|
import {
|
|
13
|
-
ConsoleLoggerAdapter,
|
|
14
13
|
HmacSha256Signer,
|
|
15
14
|
MiLogger,
|
|
16
15
|
Signer
|
|
17
16
|
} from '@milaboratories/ts-helpers';
|
|
18
17
|
import { ComputableStableDefined, WatchableValue } from '@milaboratories/computable';
|
|
19
18
|
import { Project } from './project';
|
|
20
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
DefaultMiddleLayerOpsPaths,
|
|
21
|
+
DefaultMiddleLayerOpsSettings,
|
|
22
|
+
MiddleLayerOps,
|
|
23
|
+
MiddleLayerOpsConstructor
|
|
24
|
+
} from './ops';
|
|
21
25
|
import { randomUUID } from 'node:crypto';
|
|
22
26
|
import { ProjectListEntry } from '../model';
|
|
23
27
|
import { AuthorMarker, ProjectMeta } from '@milaboratories/pl-model-middle-layer';
|
|
@@ -26,7 +30,7 @@ import { getQuickJS, QuickJSWASMModule } from 'quickjs-emscripten';
|
|
|
26
30
|
import { initDriverKit, MiddleLayerDriverKit } from './driver_kit';
|
|
27
31
|
import { DriverKit } from '@platforma-sdk/model';
|
|
28
32
|
import { DownloadUrlDriver } from '@milaboratories/pl-drivers';
|
|
29
|
-
import { V2RegistryProvider } from '../block_registry
|
|
33
|
+
import { V2RegistryProvider } from '../block_registry';
|
|
30
34
|
import { Dispatcher, RetryAgent } from 'undici';
|
|
31
35
|
|
|
32
36
|
export interface MiddleLayerEnvironment {
|
|
@@ -185,8 +189,16 @@ export class MiddleLayer {
|
|
|
185
189
|
}
|
|
186
190
|
|
|
187
191
|
/** Initialize middle layer */
|
|
188
|
-
public static async init(
|
|
189
|
-
|
|
192
|
+
public static async init(
|
|
193
|
+
pl: PlClient,
|
|
194
|
+
workdir: string,
|
|
195
|
+
_ops: MiddleLayerOpsConstructor
|
|
196
|
+
): Promise<MiddleLayer> {
|
|
197
|
+
const ops: MiddleLayerOps = {
|
|
198
|
+
...DefaultMiddleLayerOpsSettings,
|
|
199
|
+
...DefaultMiddleLayerOpsPaths(workdir),
|
|
200
|
+
..._ops
|
|
201
|
+
};
|
|
190
202
|
|
|
191
203
|
if (process.env.MI_LOG_TREE_STAT)
|
|
192
204
|
ops.defaultTreeOptions.logStat =
|
|
@@ -212,7 +224,7 @@ export class MiddleLayer {
|
|
|
212
224
|
|
|
213
225
|
const logger = ops.logger;
|
|
214
226
|
|
|
215
|
-
const driverKit = await initDriverKit(pl, ops);
|
|
227
|
+
const driverKit = await initDriverKit(pl, workdir, ops);
|
|
216
228
|
|
|
217
229
|
// passed to components having no own retry logic
|
|
218
230
|
const retryHttpDispatcher = new RetryAgent(pl.httpDispatcher, {
|
package/src/middle_layer/ops.ts
CHANGED
|
@@ -1,12 +1,41 @@
|
|
|
1
1
|
import { TemporalSynchronizedTreeOps } from './types';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
DefaultVirtualLocalStorages,
|
|
4
|
+
DownloadDriverOps,
|
|
5
|
+
OpenFileDialogCallback,
|
|
6
|
+
VirtualLocalStorageSpec
|
|
7
|
+
} from '@milaboratories/pl-drivers';
|
|
3
8
|
import { UploadDriverOps } from '@milaboratories/pl-drivers';
|
|
4
9
|
import { LogsStreamDriverOps } from '@milaboratories/pl-drivers';
|
|
5
10
|
import { ConsoleLoggerAdapter, MiLogger } from '@milaboratories/ts-helpers';
|
|
6
|
-
import
|
|
11
|
+
import { LocalStorageProjection } from '@milaboratories/pl-drivers';
|
|
12
|
+
import path from 'node:path';
|
|
13
|
+
|
|
14
|
+
/** Paths part of {@link DriverKitOps}. */
|
|
15
|
+
export type DriverKitOpsPaths = {
|
|
16
|
+
/** Common root where to put downloaded blobs / downloaded blob cache */
|
|
17
|
+
readonly blobDownloadPath: string;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* List of pl storages that have projections in local file system.
|
|
21
|
+
*
|
|
22
|
+
* This option affect two drivers:
|
|
23
|
+
*
|
|
24
|
+
* (1) LS driver generates "index" handles instead of "upload" for paths inside those locations
|
|
25
|
+
*
|
|
26
|
+
* (2) Download driver directly serves content retrieval requests for blobs from listed storages,
|
|
27
|
+
* and don't apply any caching for such blobs (i.e. preventing duplication of files for Downloaded
|
|
28
|
+
* type handles, making OnDemand and Downloaded handles equivalent)
|
|
29
|
+
*
|
|
30
|
+
* */
|
|
31
|
+
readonly localProjections: LocalStorageProjection[];
|
|
32
|
+
|
|
33
|
+
/** List of virtual storages that will allow homogeneous access to local FSs through LS API. */
|
|
34
|
+
readonly virtualLocalStorages: VirtualLocalStorageSpec[];
|
|
35
|
+
};
|
|
7
36
|
|
|
8
37
|
/** Options required to initialize full set of middle layer driver kit */
|
|
9
|
-
export type
|
|
38
|
+
export type DriverKitOpsSettings = {
|
|
10
39
|
//
|
|
11
40
|
// Common
|
|
12
41
|
//
|
|
@@ -35,16 +64,6 @@ export type DriverKitOps = {
|
|
|
35
64
|
*/
|
|
36
65
|
readonly blobDriverOps: DownloadDriverOps;
|
|
37
66
|
|
|
38
|
-
/** Common root where to put downloaded blobs. */
|
|
39
|
-
readonly blobDownloadPath: string;
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* If Platforma is running in local mode and a download driver
|
|
43
|
-
* needs to download files from local storage, it will open files
|
|
44
|
-
* from the specified directory. Otherwise, it should be empty.
|
|
45
|
-
* */
|
|
46
|
-
readonly platformLocalStorageNameToPath: Record<string, string>;
|
|
47
|
-
|
|
48
67
|
//
|
|
49
68
|
// Upload Driver
|
|
50
69
|
//
|
|
@@ -68,27 +87,21 @@ export type DriverKitOps = {
|
|
|
68
87
|
//
|
|
69
88
|
|
|
70
89
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
readonly localStorageNameToPath: Record<string, string>;
|
|
90
|
+
* Callback to access system file open dialog, must be provided by the environment,
|
|
91
|
+
* to allow for {@link showOpenSingleFileDialog} / {@link showOpenMultipleFilesDialog}
|
|
92
|
+
* calls from the UI.
|
|
93
|
+
*/
|
|
94
|
+
readonly openFileDialogCallback: OpenFileDialogCallback;
|
|
77
95
|
};
|
|
78
96
|
|
|
97
|
+
export type DriverKitOps = DriverKitOpsPaths & DriverKitOpsSettings;
|
|
98
|
+
|
|
79
99
|
/** Some defaults fot MiddleLayerOps. */
|
|
80
|
-
export const
|
|
81
|
-
|
|
82
|
-
| '
|
|
83
|
-
| 'platformLocalStorageNameToPath'
|
|
84
|
-
| 'blobDriverOps'
|
|
85
|
-
| 'uploadDriverOps'
|
|
86
|
-
| 'logStreamDriverOps'
|
|
87
|
-
| 'localStorageNameToPath'
|
|
100
|
+
export const DefaultDriverKitOpsSettings: Pick<
|
|
101
|
+
DriverKitOpsSettings,
|
|
102
|
+
'logger' | 'blobDriverOps' | 'uploadDriverOps' | 'logStreamDriverOps'
|
|
88
103
|
> = {
|
|
89
104
|
logger: new ConsoleLoggerAdapter(),
|
|
90
|
-
platformLocalStorageNameToPath: {},
|
|
91
|
-
localStorageNameToPath: { local: os.homedir() },
|
|
92
105
|
blobDriverOps: {
|
|
93
106
|
cacheSoftSizeBytes: 100 * 1024 * 1024, // 100MB
|
|
94
107
|
nConcurrentDownloads: 10
|
|
@@ -106,12 +119,30 @@ export const DefaultDriverKitOps: Pick<
|
|
|
106
119
|
}
|
|
107
120
|
};
|
|
108
121
|
|
|
122
|
+
export function DefaultDriverKitOpsPaths(
|
|
123
|
+
workDir: string
|
|
124
|
+
): Pick<DriverKitOpsPaths, 'blobDownloadPath' | 'virtualLocalStorages'> {
|
|
125
|
+
return {
|
|
126
|
+
blobDownloadPath: path.join(workDir, 'download'),
|
|
127
|
+
virtualLocalStorages: DefaultVirtualLocalStorages()
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
109
131
|
/** Fields with default values are marked as optional here. */
|
|
110
|
-
|
|
111
|
-
|
|
132
|
+
// prettier-ignore
|
|
133
|
+
export type DriverKitOpsConstructor =
|
|
134
|
+
Omit<DriverKitOpsSettings, keyof typeof DefaultDriverKitOpsSettings>
|
|
135
|
+
& Partial<typeof DefaultDriverKitOpsSettings>
|
|
136
|
+
& Omit<DriverKitOpsPaths, keyof ReturnType<typeof DefaultDriverKitOpsPaths>>
|
|
137
|
+
& Partial<ReturnType<typeof DefaultDriverKitOpsPaths>>;
|
|
138
|
+
|
|
139
|
+
export type MiddleLayerOpsPaths = DriverKitOpsPaths & {
|
|
140
|
+
/** Common root where to put frontend code. */
|
|
141
|
+
readonly frontendDownloadPath: string;
|
|
142
|
+
};
|
|
112
143
|
|
|
113
144
|
/** Configuration controlling different aspects of middle layer behaviour. */
|
|
114
|
-
export type
|
|
145
|
+
export type MiddleLayerOpsSettings = DriverKitOpsSettings & {
|
|
115
146
|
/** Contain temporal options controlling how often should pl trees be
|
|
116
147
|
* synchronized with the pl server. */
|
|
117
148
|
readonly defaultTreeOptions: TemporalSynchronizedTreeOps;
|
|
@@ -126,22 +157,20 @@ export type MiddleLayerOps = DriverKitOps & {
|
|
|
126
157
|
|
|
127
158
|
/** How often to check for dev block updates */
|
|
128
159
|
readonly devBlockUpdateRecheckInterval: number;
|
|
129
|
-
|
|
130
|
-
/** Common root where to put frontend code. */
|
|
131
|
-
readonly frontendDownloadPath: string;
|
|
132
160
|
};
|
|
133
161
|
|
|
162
|
+
export type MiddleLayerOps = MiddleLayerOpsSettings & MiddleLayerOpsPaths;
|
|
163
|
+
|
|
134
164
|
/** Some defaults fot MiddleLayerOps. */
|
|
135
|
-
export const
|
|
165
|
+
export const DefaultMiddleLayerOpsSettings: Pick<
|
|
136
166
|
MiddleLayerOps,
|
|
137
|
-
| keyof typeof
|
|
167
|
+
| keyof typeof DefaultDriverKitOpsSettings
|
|
138
168
|
| 'defaultTreeOptions'
|
|
139
169
|
| 'projectRefreshInterval'
|
|
140
170
|
| 'stagingRenderingRate'
|
|
141
|
-
| 'platformLocalStorageNameToPath'
|
|
142
171
|
| 'devBlockUpdateRecheckInterval'
|
|
143
172
|
> = {
|
|
144
|
-
...
|
|
173
|
+
...DefaultDriverKitOpsSettings,
|
|
145
174
|
defaultTreeOptions: {
|
|
146
175
|
pollingInterval: 350,
|
|
147
176
|
stopPollingDelay: 2500
|
|
@@ -151,6 +180,26 @@ export const DefaultMiddleLayerOps: Pick<
|
|
|
151
180
|
stagingRenderingRate: 5
|
|
152
181
|
};
|
|
153
182
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
183
|
+
export function DefaultMiddleLayerOpsPaths(
|
|
184
|
+
workDir: string
|
|
185
|
+
): Pick<
|
|
186
|
+
MiddleLayerOpsPaths,
|
|
187
|
+
keyof ReturnType<typeof DefaultDriverKitOpsPaths> | 'frontendDownloadPath'
|
|
188
|
+
> {
|
|
189
|
+
return {
|
|
190
|
+
...DefaultDriverKitOpsPaths(workDir),
|
|
191
|
+
frontendDownloadPath: path.join(workDir, 'frontend')
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export type MiddleLayerOpsConstructor = Omit<
|
|
196
|
+
MiddleLayerOpsSettings,
|
|
197
|
+
keyof typeof DefaultMiddleLayerOpsSettings
|
|
198
|
+
> &
|
|
199
|
+
Partial<typeof DefaultMiddleLayerOpsSettings> &
|
|
200
|
+
Omit<MiddleLayerOpsPaths, keyof ReturnType<typeof DefaultMiddleLayerOpsPaths>> &
|
|
201
|
+
Partial<ReturnType<typeof DefaultMiddleLayerOpsPaths>>;
|
|
202
|
+
|
|
203
|
+
// /** Fields with default values are marked as optional here. */
|
|
204
|
+
// export type MiddleLayerOpsConstructor = Omit<MiddleLayerOps, keyof typeof DefaultMiddleLayerOps> &
|
|
205
|
+
// Partial<typeof DefaultMiddleLayerOps>;
|