@milaboratories/pl-middle-layer 1.18.1 → 1.19.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.
- package/dist/block_registry/registry.d.ts.map +1 -1
- package/dist/block_registry/watcher.d.ts.map +1 -1
- package/dist/index.js +18 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +914 -864
- package/dist/index.mjs.map +1 -1
- package/dist/pool/driver.d.ts.map +1 -1
- package/package.json +10 -10
- package/src/block_registry/registry.ts +56 -17
- package/src/block_registry/watcher.ts +37 -2
- package/src/middle_layer/render.test.ts +54 -3
- package/src/pool/driver.ts +1 -0
- package/src/middle_layer/middle_layer.test.ts +0 -726
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../src/pool/driver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,OAAO,EAAE,kBAAkB,EAAgB,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAA2B,MAAM,4BAA4B,CAAC;AACpF,OAAO,EACL,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,EAEP,SAAS,EACT,SAAS,EACT,SAAS,EAKV,MAAM,sBAAsB,CAAC;AAqH9B,qBAAa,YAAa,YAAW,eAAe;IAOtC,OAAO,CAAC,QAAQ,CAAC,UAAU;IANvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyD;IACjF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsE;IAC9F,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA+B;IAChE,0FAA0F;IAC1F,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA8B;gBAEpC,UAAU,EAAE,cAAc;
|
|
1
|
+
{"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../src/pool/driver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,OAAO,EAAE,kBAAkB,EAAgB,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAA2B,MAAM,4BAA4B,CAAC;AACpF,OAAO,EACL,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,EAEP,SAAS,EACT,SAAS,EACT,SAAS,EAKV,MAAM,sBAAsB,CAAC;AAqH9B,qBAAa,YAAa,YAAW,eAAe;IAOtC,OAAO,CAAC,QAAQ,CAAC,UAAU;IANvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyD;IACjF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsE;IAC9F,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA+B;IAChE,0FAA0F;IAC1F,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA8B;gBAEpC,UAAU,EAAE,cAAc;IAoDhD,YAAY,CAAC,GAAG,EAAE,SAAS,CAAC,kBAAkB,CAAC,EAAE,GAAG,EAAE,aAAa,GAAG,YAAY;IAQlF,YAAY,CACjB,GAAG,EAAE,SAAS,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,EAC3C,GAAG,EAAE,aAAa,GACjB,YAAY;IAYF,WAAW,CACtB,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,mBAAmB,CAAC;IAiBlB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;IAM9E,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAM9D,kBAAkB,CAC7B,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,yBAAyB,CAAC,SAAS,CAAC,GAC5C,OAAO,CAAC,0BAA0B,CAAC;IA6BzB,eAAe,CAC1B,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,oBAAoB,CAAC;IAanB,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAKpD,OAAO,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAK1D,OAAO,CAClB,MAAM,EAAE,YAAY,EACpB,aAAa,EAAE,MAAM,EAAE,EACvB,KAAK,CAAC,EAAE,UAAU,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC;CAM3B;AA+CD,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAI/E"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milaboratories/pl-middle-layer",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.19.1",
|
|
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.6.1",
|
|
30
30
|
"zod": "^3.23.8",
|
|
31
|
-
"@milaboratories/computable": "^2.3.2",
|
|
32
31
|
"@milaboratories/resolve-helper": "^1.0.2",
|
|
33
|
-
"@
|
|
34
|
-
"@
|
|
32
|
+
"@milaboratories/pl-client": "^2.6.3",
|
|
33
|
+
"@platforma-sdk/block-tools": "^2.4.1",
|
|
35
34
|
"@milaboratories/pl-model-common": "^1.8.0",
|
|
36
|
-
"@milaboratories/pl-drivers": "^1.
|
|
37
|
-
"@milaboratories/pl-
|
|
38
|
-
"@milaboratories/pl-
|
|
35
|
+
"@milaboratories/pl-drivers": "^1.4.0",
|
|
36
|
+
"@milaboratories/pl-tree": "^1.4.18",
|
|
37
|
+
"@milaboratories/pl-model-middle-layer": "^1.6.0",
|
|
39
38
|
"@platforma-sdk/model": "^1.14.1",
|
|
40
|
-
"@milaboratories/
|
|
41
|
-
"@milaboratories/pl-config": "^1.3.1",
|
|
39
|
+
"@milaboratories/computable": "^2.3.3",
|
|
42
40
|
"@platforma-sdk/workflow-tengo": "2.5.0",
|
|
43
|
-
"@milaboratories/
|
|
41
|
+
"@milaboratories/ts-helpers": "^1.1.2",
|
|
42
|
+
"@milaboratories/pl-config": "^1.3.2",
|
|
43
|
+
"@milaboratories/pl-local": "^1.8.1"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"typescript": "~5.5.4",
|
|
@@ -13,11 +13,15 @@ import { LegacyDevBlockPackFiles } from '../dev_env';
|
|
|
13
13
|
import { tryLoadPackDescription } from '@platforma-sdk/block-tools';
|
|
14
14
|
import { V2RegistryProvider } from './registry-v2-provider';
|
|
15
15
|
import {
|
|
16
|
+
AnyChannel,
|
|
16
17
|
BlockPackListing,
|
|
17
18
|
BlockPackOverview,
|
|
18
19
|
RegistryEntry,
|
|
19
|
-
RegistryStatus
|
|
20
|
+
RegistryStatus,
|
|
21
|
+
SingleBlockPackOverview,
|
|
22
|
+
StableChannel
|
|
20
23
|
} from '@milaboratories/pl-model-middle-layer';
|
|
24
|
+
import { version } from 'node:process';
|
|
21
25
|
|
|
22
26
|
async function getFileContent(path: string) {
|
|
23
27
|
try {
|
|
@@ -88,8 +92,7 @@ export class BlockPackRegistry {
|
|
|
88
92
|
name: pkg,
|
|
89
93
|
version: latestVersion
|
|
90
94
|
};
|
|
91
|
-
|
|
92
|
-
registryId: regEntry.id,
|
|
95
|
+
const latestOverview: SingleBlockPackOverview = {
|
|
93
96
|
id,
|
|
94
97
|
meta: {
|
|
95
98
|
title: latestMeta['title'] ?? 'No title',
|
|
@@ -103,17 +106,36 @@ export class BlockPackRegistry {
|
|
|
103
106
|
type: 'from-registry-v1',
|
|
104
107
|
id,
|
|
105
108
|
registryUrl: regSpec.url
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
result.push({
|
|
112
|
+
registryId: regEntry.id,
|
|
113
|
+
id,
|
|
114
|
+
latestByChannel: {
|
|
115
|
+
[AnyChannel]: latestOverview,
|
|
116
|
+
[StableChannel]: latestOverview
|
|
106
117
|
},
|
|
107
|
-
|
|
118
|
+
allVersions: overviewEntry.allVersions.map((v) => ({ version: v, channels: [] }))
|
|
108
119
|
});
|
|
109
120
|
}
|
|
110
121
|
return result;
|
|
111
122
|
|
|
112
123
|
case 'remote-v2':
|
|
113
|
-
return (await this.v2Provider.getRegistry(regSpec.url).listBlockPacks()).map((e) =>
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
124
|
+
return (await this.v2Provider.getRegistry(regSpec.url).listBlockPacks()).map((e) =>
|
|
125
|
+
e.latestByChannel[StableChannel]
|
|
126
|
+
? {
|
|
127
|
+
...e,
|
|
128
|
+
registryId: regEntry.id
|
|
129
|
+
}
|
|
130
|
+
: {
|
|
131
|
+
...e,
|
|
132
|
+
latestByChannel: {
|
|
133
|
+
...e.latestByChannel,
|
|
134
|
+
[StableChannel]: e.latestByChannel[AnyChannel]
|
|
135
|
+
},
|
|
136
|
+
registryId: regEntry.id
|
|
137
|
+
}
|
|
138
|
+
);
|
|
117
139
|
|
|
118
140
|
case 'local-dev':
|
|
119
141
|
for (const entry of await fs.promises.readdir(regSpec.path, { withFileTypes: true })) {
|
|
@@ -134,8 +156,7 @@ export class BlockPackRegistry {
|
|
|
134
156
|
version: 'DEV'
|
|
135
157
|
};
|
|
136
158
|
|
|
137
|
-
|
|
138
|
-
registryId: regEntry.id,
|
|
159
|
+
const latestOverview: SingleBlockPackOverview = {
|
|
139
160
|
id,
|
|
140
161
|
meta: {
|
|
141
162
|
title: (config.meta['title'] as string) ?? 'No title',
|
|
@@ -149,33 +170,51 @@ export class BlockPackRegistry {
|
|
|
149
170
|
type: 'dev-v2',
|
|
150
171
|
folder: devPath,
|
|
151
172
|
mtime
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
result.push({
|
|
177
|
+
registryId: regEntry.id,
|
|
178
|
+
id,
|
|
179
|
+
latestByChannel: {
|
|
180
|
+
[AnyChannel]: latestOverview,
|
|
181
|
+
[StableChannel]: latestOverview
|
|
152
182
|
},
|
|
153
|
-
|
|
183
|
+
allVersions: []
|
|
154
184
|
});
|
|
155
185
|
} else {
|
|
156
186
|
let actualDevPath = devPath;
|
|
157
187
|
let v2Description = await tryLoadPackDescription(actualDevPath);
|
|
158
|
-
|
|
188
|
+
|
|
159
189
|
if (v2Description === undefined)
|
|
160
190
|
// iterating over expected subfolder names where block developer may put root block-pack package
|
|
161
191
|
for (const bpSubfolder of ['block', 'meta']) {
|
|
162
|
-
actualDevPath = path.join(devPath, bpSubfolder)
|
|
192
|
+
actualDevPath = path.join(devPath, bpSubfolder);
|
|
163
193
|
v2Description = await tryLoadPackDescription(actualDevPath);
|
|
164
194
|
if (v2Description !== undefined) break;
|
|
165
195
|
}
|
|
166
196
|
|
|
167
197
|
if (v2Description !== undefined) {
|
|
168
198
|
const mtime = await getDevV2PacketMtime(v2Description);
|
|
169
|
-
|
|
170
|
-
|
|
199
|
+
|
|
200
|
+
const latestOverview: SingleBlockPackOverview = {
|
|
171
201
|
id: v2Description.id,
|
|
172
202
|
meta: await BlockPackMetaEmbedAbsoluteBytes.parseAsync(v2Description.meta),
|
|
173
203
|
spec: {
|
|
174
204
|
type: 'dev-v2',
|
|
175
|
-
folder:
|
|
205
|
+
folder: devPath,
|
|
176
206
|
mtime
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
result.push({
|
|
211
|
+
registryId: regEntry.id,
|
|
212
|
+
id: v2Description.id,
|
|
213
|
+
latestByChannel: {
|
|
214
|
+
[AnyChannel]: latestOverview,
|
|
215
|
+
[StableChannel]: latestOverview
|
|
177
216
|
},
|
|
178
|
-
|
|
217
|
+
allVersions: []
|
|
179
218
|
});
|
|
180
219
|
}
|
|
181
220
|
}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { PollComputablePool, PollPoolOps } from '@milaboratories/computable';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
AnyChannel,
|
|
4
|
+
BlockPackFromRegistryV2,
|
|
5
|
+
blockPackIdEquals,
|
|
6
|
+
blockPackIdToString,
|
|
7
|
+
BlockPackSpec,
|
|
8
|
+
StableChannel
|
|
9
|
+
} from '@milaboratories/pl-model-middle-layer';
|
|
3
10
|
import { Dispatcher } from 'undici';
|
|
4
11
|
import { getDevV1PacketMtime, getDevV2PacketMtime } from './registry';
|
|
5
12
|
import { tryLoadPackDescription } from '@platforma-sdk/block-tools';
|
|
@@ -72,7 +79,35 @@ export class BlockUpdateWatcher extends PollComputablePool<
|
|
|
72
79
|
case 'from-registry-v2': {
|
|
73
80
|
try {
|
|
74
81
|
const registry = this.registryProvider.getRegistry(req.registryUrl);
|
|
75
|
-
|
|
82
|
+
let spec: BlockPackSpec | undefined;
|
|
83
|
+
|
|
84
|
+
if (req.channel === undefined) {
|
|
85
|
+
const a1 = await registry.getLatestOverview(req.id, StableChannel);
|
|
86
|
+
if (a1) spec = a1.spec;
|
|
87
|
+
else {
|
|
88
|
+
// forcing update from non-existent channel to stable
|
|
89
|
+
const a2 = await registry.getLatestOverview(req.id, AnyChannel);
|
|
90
|
+
if (a2 === undefined) {
|
|
91
|
+
this.logger.error(`No any channel record for ${blockPackIdToString(req.id)}`);
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
spec = { ...(a2.spec as BlockPackFromRegistryV2), channel: StableChannel };
|
|
95
|
+
}
|
|
96
|
+
} else {
|
|
97
|
+
const a1 = await registry.getLatestOverview(req.id, req.channel);
|
|
98
|
+
if (a1) spec = a1.spec;
|
|
99
|
+
else if(req.channel === StableChannel) {
|
|
100
|
+
// we were not able to find a stable package because there are none for the block pack yet
|
|
101
|
+
const a2 = await registry.getLatestOverview(req.id, AnyChannel);
|
|
102
|
+
if (a2 === undefined) {
|
|
103
|
+
this.logger.error(`No any channel record for ${blockPackIdToString(req.id)}`);
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
// providing "any" channel package as a substitute and marking it as stable
|
|
107
|
+
spec = { ...(a2.spec as BlockPackFromRegistryV2), channel: StableChannel };
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
76
111
|
if (spec?.type !== 'from-registry-v2') throw new Error('Unexpected');
|
|
77
112
|
if (blockPackIdEquals(spec.id, req.id)) return undefined;
|
|
78
113
|
|
|
@@ -1,7 +1,58 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { awaitBlockDone, withMl } from './middle_layer.test';
|
|
3
|
-
import { getQuickJS, Scope, shouldInterruptAfterDeadline } from 'quickjs-emscripten';
|
|
1
|
+
import { expect, test } from '@jest/globals';
|
|
4
2
|
import * as tp from 'node:timers/promises';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { getQuickJS, Scope, shouldInterruptAfterDeadline } from 'quickjs-emscripten';
|
|
5
|
+
import { randomUUID } from 'node:crypto';
|
|
6
|
+
import { MiddleLayer } from './middle_layer';
|
|
7
|
+
import { PlClient, TestHelpers } from '@milaboratories/pl-client';
|
|
8
|
+
import { Project } from './project';
|
|
9
|
+
|
|
10
|
+
export async function withMl(
|
|
11
|
+
cb: (ml: MiddleLayer, workFolder: string) => Promise<void>
|
|
12
|
+
): Promise<void> {
|
|
13
|
+
const workFolder = path.resolve(`work/${randomUUID()}`);
|
|
14
|
+
|
|
15
|
+
await TestHelpers.withTempRoot(async (pl: PlClient) => {
|
|
16
|
+
const ml = await MiddleLayer.init(pl, workFolder, {
|
|
17
|
+
defaultTreeOptions: { pollingInterval: 250, stopPollingDelay: 500 },
|
|
18
|
+
devBlockUpdateRecheckInterval: 300,
|
|
19
|
+
localSecret: MiddleLayer.generateLocalSecret(),
|
|
20
|
+
localProjections: [], // TODO must be different with local pl
|
|
21
|
+
openFileDialogCallback: () => {
|
|
22
|
+
throw new Error('Not implemented.');
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
try {
|
|
26
|
+
await cb(ml, workFolder);
|
|
27
|
+
} finally {
|
|
28
|
+
await ml.close();
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function awaitBlockDone(prj: Project, blockId: string, timeout: number = 2000) {
|
|
34
|
+
const abortSignal = AbortSignal.timeout(timeout);
|
|
35
|
+
const overview = prj.overview;
|
|
36
|
+
const state = prj.getBlockState(blockId);
|
|
37
|
+
// const stateAndOverview = Computable.make(() => ({ overview, state: undefined }));
|
|
38
|
+
while (true) {
|
|
39
|
+
// const {
|
|
40
|
+
// overview: overviewSnapshot,
|
|
41
|
+
// state: stateSnapshot
|
|
42
|
+
// } = await stateAndOverview.getValue();
|
|
43
|
+
const overviewSnapshot = (await overview.getValue())!;
|
|
44
|
+
const blockOverview = overviewSnapshot.blocks.find((b) => b.id == blockId);
|
|
45
|
+
if (blockOverview === undefined) throw new Error(`Blocks not found: ${blockId}`);
|
|
46
|
+
if (blockOverview.outputErrors) return;
|
|
47
|
+
if (blockOverview.calculationStatus === 'Done') return;
|
|
48
|
+
try {
|
|
49
|
+
await overview.awaitChange(abortSignal);
|
|
50
|
+
} catch (e: any) {
|
|
51
|
+
console.dir(await state.getValue(), { depth: 5 });
|
|
52
|
+
throw new Error('Aborted.', { cause: e });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
5
56
|
|
|
6
57
|
test('test JS render enter numbers', async () => {
|
|
7
58
|
await withMl(async (ml) => {
|
package/src/pool/driver.ts
CHANGED
|
@@ -162,6 +162,7 @@ export class PFrameDriver implements SdkPFrameDriver {
|
|
|
162
162
|
const concurrencyLimiter = new ConcurrencyLimitingExecutor(1);
|
|
163
163
|
this.blobContentCache = blobContentCache;
|
|
164
164
|
this.concurrencyLimiter = concurrencyLimiter;
|
|
165
|
+
|
|
165
166
|
this.pFrames = new (class extends RefCountResourcePool<InternalPFrameData, PFrameHolder> {
|
|
166
167
|
constructor(private readonly blobDriver: DownloadDriver) {
|
|
167
168
|
super();
|