@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.
- package/dist/block_registry/index.d.ts +4 -0
- package/dist/block_registry/index.d.ts.map +1 -0
- package/dist/block_registry/registry.d.ts +37 -0
- package/dist/block_registry/registry.d.ts.map +1 -0
- package/dist/block_registry/registry_spec.d.ts +12 -0
- package/dist/block_registry/registry_spec.d.ts.map +1 -0
- package/dist/block_registry/watcher.d.ts +15 -0
- package/dist/block_registry/watcher.d.ts.map +1 -0
- package/dist/block_registry/well_known_registries.d.ts +4 -0
- package/dist/block_registry/well_known_registries.d.ts.map +1 -0
- package/dist/cfg_render/executor.d.ts +8 -0
- package/dist/cfg_render/executor.d.ts.map +1 -0
- package/dist/cfg_render/operation.d.ts +29 -0
- package/dist/cfg_render/operation.d.ts.map +1 -0
- package/dist/cfg_render/renderer.d.ts +6 -0
- package/dist/cfg_render/renderer.d.ts.map +1 -0
- package/dist/cfg_render/traverse.d.ts +3 -0
- package/dist/cfg_render/traverse.d.ts.map +1 -0
- package/dist/cfg_render/util.d.ts +5 -0
- package/dist/cfg_render/util.d.ts.map +1 -0
- package/dist/dev/index.d.ts +21 -0
- package/dist/dev/index.d.ts.map +1 -0
- package/dist/dev/util.d.ts +3 -0
- package/dist/dev/util.d.ts.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3587 -0
- package/dist/index.mjs.map +1 -0
- package/dist/js_render/context.d.ts +68 -0
- package/dist/js_render/context.d.ts.map +1 -0
- package/dist/js_render/index.d.ts +6 -0
- package/dist/js_render/index.d.ts.map +1 -0
- package/dist/middle_layer/active_cfg.d.ts +6 -0
- package/dist/middle_layer/active_cfg.d.ts.map +1 -0
- package/dist/middle_layer/block.d.ts +9 -0
- package/dist/middle_layer/block.d.ts.map +1 -0
- package/dist/middle_layer/block_ctx.d.ts +20 -0
- package/dist/middle_layer/block_ctx.d.ts.map +1 -0
- package/dist/middle_layer/block_ctx_unsafe.d.ts +16 -0
- package/dist/middle_layer/block_ctx_unsafe.d.ts.map +1 -0
- package/dist/middle_layer/driver_kit.d.ts +31 -0
- package/dist/middle_layer/driver_kit.d.ts.map +1 -0
- package/dist/middle_layer/frontend_path.d.ts +6 -0
- package/dist/middle_layer/frontend_path.d.ts.map +1 -0
- package/dist/middle_layer/index.d.ts +5 -0
- package/dist/middle_layer/index.d.ts.map +1 -0
- package/dist/middle_layer/middle_layer.d.ts +78 -0
- package/dist/middle_layer/middle_layer.d.ts.map +1 -0
- package/dist/middle_layer/navigation_states.d.ts +10 -0
- package/dist/middle_layer/navigation_states.d.ts.map +1 -0
- package/dist/middle_layer/ops.d.ts +64 -0
- package/dist/middle_layer/ops.d.ts.map +1 -0
- package/dist/middle_layer/project.d.ts +110 -0
- package/dist/middle_layer/project.d.ts.map +1 -0
- package/dist/middle_layer/project_list.d.ts +11 -0
- package/dist/middle_layer/project_list.d.ts.map +1 -0
- package/dist/middle_layer/project_overview.d.ts +8 -0
- package/dist/middle_layer/project_overview.d.ts.map +1 -0
- package/dist/middle_layer/render.d.ts +6 -0
- package/dist/middle_layer/render.d.ts.map +1 -0
- package/dist/middle_layer/types.d.ts +11 -0
- package/dist/middle_layer/types.d.ts.map +1 -0
- package/dist/middle_layer/util.d.ts +3 -0
- package/dist/middle_layer/util.d.ts.map +1 -0
- package/dist/model/args.d.ts +12 -0
- package/dist/model/args.d.ts.map +1 -0
- package/dist/model/block_pack.d.ts +8 -0
- package/dist/model/block_pack.d.ts.map +1 -0
- package/dist/model/block_pack_spec.d.ts +40 -0
- package/dist/model/block_pack_spec.d.ts.map +1 -0
- package/dist/model/frontend.d.ts +10 -0
- package/dist/model/frontend.d.ts.map +1 -0
- package/dist/model/index.d.ts +3 -0
- package/dist/model/index.d.ts.map +1 -0
- package/dist/model/project_model.d.ts +67 -0
- package/dist/model/project_model.d.ts.map +1 -0
- package/dist/model/project_model_util.d.ts +29 -0
- package/dist/model/project_model_util.d.ts.map +1 -0
- package/dist/model/template_spec.d.ts +16 -0
- package/dist/model/template_spec.d.ts.map +1 -0
- package/dist/mutator/block-pack/block_pack.d.ts +17 -0
- package/dist/mutator/block-pack/block_pack.d.ts.map +1 -0
- package/dist/mutator/block-pack/frontend.d.ts +4 -0
- package/dist/mutator/block-pack/frontend.d.ts.map +1 -0
- package/dist/mutator/context_export.d.ts +9 -0
- package/dist/mutator/context_export.d.ts.map +1 -0
- package/dist/mutator/project.d.ts +121 -0
- package/dist/mutator/project.d.ts.map +1 -0
- package/dist/mutator/template/render_block.d.ts +32 -0
- package/dist/mutator/template/render_block.d.ts.map +1 -0
- package/dist/mutator/template/render_template.d.ts +12 -0
- package/dist/mutator/template/render_template.d.ts.map +1 -0
- package/dist/mutator/template/template_loading.d.ts +13 -0
- package/dist/mutator/template/template_loading.d.ts.map +1 -0
- package/dist/pool/data.d.ts +24 -0
- package/dist/pool/data.d.ts.map +1 -0
- package/dist/pool/driver.d.ts +22 -0
- package/dist/pool/driver.d.ts.map +1 -0
- package/dist/pool/index.d.ts +3 -0
- package/dist/pool/index.d.ts.map +1 -0
- package/dist/pool/p_object_collection.d.ts +29 -0
- package/dist/pool/p_object_collection.d.ts.map +1 -0
- package/dist/pool/ref_count_pool.d.ts +25 -0
- package/dist/pool/ref_count_pool.d.ts.map +1 -0
- package/dist/pool/result_pool.d.ts +25 -0
- package/dist/pool/result_pool.d.ts.map +1 -0
- package/dist/test/block_packs.d.ts +6 -0
- package/dist/test/block_packs.d.ts.map +1 -0
- package/dist/test/explicit_templates.d.ts +3 -0
- package/dist/test/explicit_templates.d.ts.map +1 -0
- package/dist/test/known_templates.d.ts +6 -0
- package/dist/test/known_templates.d.ts.map +1 -0
- package/package.json +55 -0
- package/src/block_registry/index.ts +3 -0
- package/src/block_registry/registry.test.ts +35 -0
- package/src/block_registry/registry.ts +180 -0
- package/src/block_registry/registry_spec.ts +13 -0
- package/src/block_registry/watcher.ts +72 -0
- package/src/block_registry/well_known_registries.ts +13 -0
- package/src/cfg_render/executor.test.ts +120 -0
- package/src/cfg_render/executor.ts +253 -0
- package/src/cfg_render/operation.ts +38 -0
- package/src/cfg_render/renderer.ts +540 -0
- package/src/cfg_render/traverse.ts +58 -0
- package/src/cfg_render/util.ts +29 -0
- package/src/dev/index.ts +89 -0
- package/src/dev/util.ts +13 -0
- package/src/index.ts +21 -0
- package/src/js_render/context.ts +768 -0
- package/src/js_render/index.ts +41 -0
- package/src/middle_layer/active_cfg.ts +56 -0
- package/src/middle_layer/block.ts +70 -0
- package/src/middle_layer/block_ctx.ts +90 -0
- package/src/middle_layer/block_ctx_unsafe.ts +29 -0
- package/src/middle_layer/driver_kit.ts +107 -0
- package/src/middle_layer/frontend_path.ts +83 -0
- package/src/middle_layer/index.ts +4 -0
- package/src/middle_layer/middle_layer.test.ts +720 -0
- package/src/middle_layer/middle_layer.ts +235 -0
- package/src/middle_layer/navigation_states.ts +48 -0
- package/src/middle_layer/ops.ts +147 -0
- package/src/middle_layer/project.ts +380 -0
- package/src/middle_layer/project_list.ts +59 -0
- package/src/middle_layer/project_overview.ts +220 -0
- package/src/middle_layer/render.test.ts +129 -0
- package/src/middle_layer/render.ts +19 -0
- package/src/middle_layer/types.ts +16 -0
- package/src/middle_layer/util.ts +22 -0
- package/src/model/args.ts +62 -0
- package/src/model/block_pack.ts +8 -0
- package/src/model/block_pack_spec.ts +52 -0
- package/src/model/frontend.ts +10 -0
- package/src/model/index.ts +2 -0
- package/src/model/project_model.test.ts +26 -0
- package/src/model/project_model.ts +142 -0
- package/src/model/project_model_util.test.ts +88 -0
- package/src/model/project_model_util.ts +169 -0
- package/src/model/template_spec.ts +18 -0
- package/src/mutator/block-pack/block_pack.test.ts +53 -0
- package/src/mutator/block-pack/block_pack.ts +187 -0
- package/src/mutator/block-pack/frontend.ts +29 -0
- package/src/mutator/context_export.ts +25 -0
- package/src/mutator/project.test.ts +272 -0
- package/src/mutator/project.ts +1112 -0
- package/src/mutator/template/render_block.ts +91 -0
- package/src/mutator/template/render_template.ts +40 -0
- package/src/mutator/template/template_loading.ts +77 -0
- package/src/mutator/template/template_render.test.ts +272 -0
- package/src/pool/data.ts +239 -0
- package/src/pool/driver.ts +325 -0
- package/src/pool/index.ts +2 -0
- package/src/pool/p_object_collection.ts +122 -0
- package/src/pool/ref_count_pool.ts +76 -0
- package/src/pool/result_pool.ts +284 -0
- package/src/test/block_packs.ts +23 -0
- package/src/test/explicit_templates.ts +8 -0
- package/src/test/known_templates.ts +24 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { MiddleLayerEnvironment } from '../middle_layer/middle_layer';
|
|
2
|
+
import { Code, FunctionHandle } from '@platforma-sdk/model';
|
|
3
|
+
import { Computable, ComputableRenderingOps } from '@milaboratories/computable';
|
|
4
|
+
import { Scope } from 'quickjs-emscripten';
|
|
5
|
+
import { JsExecutionContext } from './context';
|
|
6
|
+
import { BlockContextAny } from '../middle_layer/block_ctx';
|
|
7
|
+
|
|
8
|
+
export function computableFromRF(
|
|
9
|
+
env: MiddleLayerEnvironment,
|
|
10
|
+
ctx: BlockContextAny,
|
|
11
|
+
fh: FunctionHandle,
|
|
12
|
+
code: Code,
|
|
13
|
+
ops: Partial<ComputableRenderingOps> = {}
|
|
14
|
+
): Computable<unknown> {
|
|
15
|
+
return Computable.makeRaw((cCtx) => {
|
|
16
|
+
const scope = new Scope();
|
|
17
|
+
cCtx.addOnDestroy(() => scope.dispose());
|
|
18
|
+
|
|
19
|
+
const runtime = scope.manage(env.quickJs.newRuntime());
|
|
20
|
+
runtime.setMemoryLimit(1024 * 640);
|
|
21
|
+
runtime.setMaxStackSize(1024 * 320);
|
|
22
|
+
const vm = scope.manage(runtime.newContext());
|
|
23
|
+
const rCtx = new JsExecutionContext(scope, vm, ctx, env, cCtx);
|
|
24
|
+
|
|
25
|
+
rCtx.evaluateBundle(code.content);
|
|
26
|
+
const result = rCtx.runCallback(fh);
|
|
27
|
+
|
|
28
|
+
rCtx.resetComputableCtx();
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
ir: rCtx.computablesToResolve,
|
|
32
|
+
postprocessValue: async (resolved: Record<string, unknown>) => {
|
|
33
|
+
// resolving futures
|
|
34
|
+
for (const [handle, value] of Object.entries(resolved)) rCtx.runCallback(handle, value);
|
|
35
|
+
|
|
36
|
+
// rendering result
|
|
37
|
+
return rCtx.importObjectUniversal(result);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}, ops);
|
|
41
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { notEmpty } from '@milaboratories/ts-helpers';
|
|
2
|
+
import { PlTreeEntry } from '@milaboratories/pl-tree';
|
|
3
|
+
import { MiddleLayerEnvironment } from './middle_layer';
|
|
4
|
+
import { Computable } from '@milaboratories/computable';
|
|
5
|
+
import { projectFieldName, ProjectStructure, ProjectStructureKey } from '../model/project_model';
|
|
6
|
+
import { allBlocks } from '../model/project_model_util';
|
|
7
|
+
import { Pl } from '@milaboratories/pl-client';
|
|
8
|
+
import { BlockPackInfo } from '../model/block_pack';
|
|
9
|
+
import { hasActiveCfgComponents } from '../cfg_render/util';
|
|
10
|
+
import { Cfg, isFunctionHandle, normalizeBlockConfig } from '@platforma-sdk/model';
|
|
11
|
+
import { constructBlockContext } from './block_ctx';
|
|
12
|
+
import { computableFromCfg } from '../cfg_render/executor';
|
|
13
|
+
|
|
14
|
+
/** Returns derived general project state form the project resource */
|
|
15
|
+
export function activeConfigs(
|
|
16
|
+
prjEntry: PlTreeEntry,
|
|
17
|
+
env: MiddleLayerEnvironment
|
|
18
|
+
): Computable<unknown[]> {
|
|
19
|
+
return Computable.make((ctx) => {
|
|
20
|
+
const prj = ctx.accessor(prjEntry).node();
|
|
21
|
+
|
|
22
|
+
const structure = notEmpty(prj.getKeyValueAsJson<ProjectStructure>(ProjectStructureKey));
|
|
23
|
+
const ret: Computable<unknown>[] = [];
|
|
24
|
+
for (const { id, renderingMode } of allBlocks(structure)) {
|
|
25
|
+
// block-pack
|
|
26
|
+
const blockPack = prj.traverse(
|
|
27
|
+
{
|
|
28
|
+
field: projectFieldName(id, 'blockPack'),
|
|
29
|
+
assertFieldType: 'Dynamic',
|
|
30
|
+
errorIfFieldNotSet: true
|
|
31
|
+
},
|
|
32
|
+
{ field: Pl.HolderRefField, assertFieldType: 'Input', errorIfFieldNotFound: true }
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const bpInfo = blockPack?.getDataAsJson<BlockPackInfo>();
|
|
36
|
+
if (bpInfo?.config === undefined) continue;
|
|
37
|
+
|
|
38
|
+
const blockConf = normalizeBlockConfig(bpInfo.config);
|
|
39
|
+
const activeOutputConfigs = Object.entries(blockConf.outputs)
|
|
40
|
+
.map(([, cfg]) => cfg)
|
|
41
|
+
.filter((cfg) => !isFunctionHandle(cfg) && hasActiveCfgComponents(cfg))
|
|
42
|
+
.map((cfg) => cfg as Cfg);
|
|
43
|
+
|
|
44
|
+
if (activeOutputConfigs.length === 0) continue;
|
|
45
|
+
|
|
46
|
+
const blockCtx = constructBlockContext(prj, id);
|
|
47
|
+
|
|
48
|
+
// console.log(blockCtx.prod(ctx));
|
|
49
|
+
|
|
50
|
+
for (const cfg of activeOutputConfigs)
|
|
51
|
+
ret.push(Computable.wrapError(computableFromCfg(env.driverKit, blockCtx, cfg)));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return ret;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { PlTreeEntry } from '@milaboratories/pl-tree';
|
|
2
|
+
import {
|
|
3
|
+
Computable,
|
|
4
|
+
ComputableCtx,
|
|
5
|
+
ComputableStableDefined,
|
|
6
|
+
ComputableValueOrErrors
|
|
7
|
+
} from '@milaboratories/computable';
|
|
8
|
+
import { constructBlockContext, constructBlockContextArgsOnly } from './block_ctx';
|
|
9
|
+
import { blockArgsAuthorKey } from '../model/project_model';
|
|
10
|
+
import { ifNotUndef } from '../cfg_render/util';
|
|
11
|
+
import { MiddleLayerEnvironment } from './middle_layer';
|
|
12
|
+
import { getBlockCfg } from './util';
|
|
13
|
+
import { AuthorMarker, BlockStateInternal } from '@milaboratories/pl-model-middle-layer';
|
|
14
|
+
import { computableFromCfgOrRF } from './render';
|
|
15
|
+
import { resourceIdToString } from '@milaboratories/pl-client';
|
|
16
|
+
|
|
17
|
+
export type BlockArgsAndUiState = Omit<BlockStateInternal, 'outputs' | 'navigationState'>;
|
|
18
|
+
|
|
19
|
+
export function blockArgsAndUiState(
|
|
20
|
+
projectEntry: PlTreeEntry,
|
|
21
|
+
id: string
|
|
22
|
+
): Computable<BlockArgsAndUiState>;
|
|
23
|
+
export function blockArgsAndUiState(
|
|
24
|
+
projectEntry: PlTreeEntry,
|
|
25
|
+
id: string,
|
|
26
|
+
cCtx: ComputableCtx
|
|
27
|
+
): BlockArgsAndUiState;
|
|
28
|
+
export function blockArgsAndUiState(
|
|
29
|
+
projectEntry: PlTreeEntry,
|
|
30
|
+
id: string,
|
|
31
|
+
cCtx?: ComputableCtx
|
|
32
|
+
): BlockArgsAndUiState | Computable<BlockArgsAndUiState> {
|
|
33
|
+
return Computable.make(
|
|
34
|
+
(c) => {
|
|
35
|
+
const prj = c.accessor(projectEntry).node();
|
|
36
|
+
const ctx = constructBlockContextArgsOnly(prj, id);
|
|
37
|
+
return {
|
|
38
|
+
author: prj.getKeyValueAsJson<AuthorMarker>(blockArgsAuthorKey(id)),
|
|
39
|
+
args: JSON.parse(ctx.args),
|
|
40
|
+
ui: ctx.uiState !== undefined ? JSON.parse(ctx.uiState) : undefined
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
{ key: 'inputs#' + resourceIdToString(projectEntry.rid) + id }
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function blockOutputs(
|
|
48
|
+
projectEntry: PlTreeEntry,
|
|
49
|
+
id: string,
|
|
50
|
+
env: MiddleLayerEnvironment
|
|
51
|
+
): ComputableStableDefined<Record<string, ComputableValueOrErrors<unknown>>> {
|
|
52
|
+
return Computable.make(
|
|
53
|
+
(c) => {
|
|
54
|
+
const prj = c.accessor(projectEntry).node();
|
|
55
|
+
const ctx = constructBlockContext(prj, id);
|
|
56
|
+
|
|
57
|
+
const blockCfg = getBlockCfg(prj, id);
|
|
58
|
+
|
|
59
|
+
return ifNotUndef(blockCfg, (cfg) => {
|
|
60
|
+
const outputs: Record<string, Computable<any>> = {};
|
|
61
|
+
for (const [cellId, cellCfg] of Object.entries(cfg.outputs))
|
|
62
|
+
outputs[cellId] = Computable.wrapError(
|
|
63
|
+
computableFromCfgOrRF(env, ctx, cellCfg, cfg.code)
|
|
64
|
+
);
|
|
65
|
+
return outputs;
|
|
66
|
+
});
|
|
67
|
+
},
|
|
68
|
+
{ key: 'outputs#' + resourceIdToString(projectEntry.rid) + id }
|
|
69
|
+
).withStableType();
|
|
70
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { ComputableCtx } from '@milaboratories/computable';
|
|
2
|
+
import { PlTreeEntry, PlTreeNodeAccessor } from '@milaboratories/pl-tree';
|
|
3
|
+
import { notEmpty } from '@milaboratories/ts-helpers';
|
|
4
|
+
import { Optional } from 'utility-types';
|
|
5
|
+
import {
|
|
6
|
+
Block,
|
|
7
|
+
ProjectStructure,
|
|
8
|
+
ProjectStructureKey,
|
|
9
|
+
blockFrontendStateKey,
|
|
10
|
+
projectFieldName
|
|
11
|
+
} from '../model/project_model';
|
|
12
|
+
import { allBlocks } from '../model/project_model_util';
|
|
13
|
+
import { ResultPool } from '../pool/result_pool';
|
|
14
|
+
|
|
15
|
+
export type BlockContextArgsOnly = {
|
|
16
|
+
readonly blockId: string;
|
|
17
|
+
readonly args: string;
|
|
18
|
+
readonly uiState: string | undefined;
|
|
19
|
+
readonly blockMeta: (cCtx: ComputableCtx) => Map<string, Block>;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type BlockContextFull = BlockContextArgsOnly & {
|
|
23
|
+
readonly prod: (cCtx: ComputableCtx) => PlTreeEntry | undefined;
|
|
24
|
+
readonly staging: (cCtx: ComputableCtx) => PlTreeEntry | undefined;
|
|
25
|
+
readonly getResultsPool: (cCtx: ComputableCtx) => ResultPool;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type BlockContextAny = Optional<BlockContextFull, 'prod' | 'staging' | 'getResultsPool'>;
|
|
29
|
+
|
|
30
|
+
export function constructBlockContextArgsOnly(
|
|
31
|
+
projectNode: PlTreeNodeAccessor,
|
|
32
|
+
blockId: string
|
|
33
|
+
): BlockContextArgsOnly {
|
|
34
|
+
const projectEntry = projectNode.persist();
|
|
35
|
+
const args = notEmpty(
|
|
36
|
+
projectNode
|
|
37
|
+
.traverse({
|
|
38
|
+
field: projectFieldName(blockId, 'currentArgs'),
|
|
39
|
+
errorIfFieldNotSet: true
|
|
40
|
+
})
|
|
41
|
+
.getDataAsString()
|
|
42
|
+
);
|
|
43
|
+
const uiState = projectNode.getKeyValueAsString(blockFrontendStateKey(blockId));
|
|
44
|
+
return {
|
|
45
|
+
blockId,
|
|
46
|
+
args,
|
|
47
|
+
uiState,
|
|
48
|
+
blockMeta: (cCtx: ComputableCtx) => {
|
|
49
|
+
const prj = cCtx.accessor(projectEntry).node();
|
|
50
|
+
const structure = notEmpty(prj.getKeyValueAsJson<ProjectStructure>(ProjectStructureKey));
|
|
51
|
+
const result = new Map<string, Block>();
|
|
52
|
+
for (const block of allBlocks(structure)) result.set(block.id, block);
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function constructBlockContext(
|
|
59
|
+
projectNode: PlTreeNodeAccessor,
|
|
60
|
+
blockId: string
|
|
61
|
+
): BlockContextFull {
|
|
62
|
+
const projectEntry = projectNode.persist();
|
|
63
|
+
return {
|
|
64
|
+
...constructBlockContextArgsOnly(projectNode, blockId),
|
|
65
|
+
prod: (cCtx: ComputableCtx) => {
|
|
66
|
+
return cCtx
|
|
67
|
+
.accessor(projectEntry)
|
|
68
|
+
.node({ ignoreError: true })
|
|
69
|
+
.traverse({
|
|
70
|
+
field: projectFieldName(blockId, 'prodOutput'),
|
|
71
|
+
stableIfNotFound: true,
|
|
72
|
+
ignoreError: true
|
|
73
|
+
})
|
|
74
|
+
?.persist();
|
|
75
|
+
},
|
|
76
|
+
staging: (cCtx: ComputableCtx) => {
|
|
77
|
+
const result = cCtx
|
|
78
|
+
.accessor(projectEntry)
|
|
79
|
+
.node({ ignoreError: true })
|
|
80
|
+
.traverse({
|
|
81
|
+
field: projectFieldName(blockId, 'stagingOutput'),
|
|
82
|
+
ignoreError: true
|
|
83
|
+
})
|
|
84
|
+
?.persist();
|
|
85
|
+
if (result === undefined) cCtx.markUnstable('staging_not_rendered');
|
|
86
|
+
return result;
|
|
87
|
+
},
|
|
88
|
+
getResultsPool: (cCtx: ComputableCtx) => ResultPool.create(cCtx, projectEntry, blockId)
|
|
89
|
+
};
|
|
90
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ComputableCtx } from '@milaboratories/computable';
|
|
2
|
+
import { PlTreeEntry } from '@milaboratories/pl-tree';
|
|
3
|
+
import { PlResourceEntry, StdCtx } from '@platforma-sdk/model';
|
|
4
|
+
import { BlockContextAny } from './block_ctx';
|
|
5
|
+
|
|
6
|
+
type SC = StdCtx<unknown, unknown>;
|
|
7
|
+
type SCAO = Pick<SC, '$blockId' | '$ui' | '$args'>;
|
|
8
|
+
export type MatStdCtxArgsOnly = {
|
|
9
|
+
[Var in keyof SCAO]: SCAO[Var] extends PlResourceEntry
|
|
10
|
+
? PlTreeEntry | ((cCtx: ComputableCtx) => PlTreeEntry | undefined) | undefined
|
|
11
|
+
: SCAO[Var];
|
|
12
|
+
};
|
|
13
|
+
export type MatStdCtx = {
|
|
14
|
+
[Var in keyof SC]: SC[Var] extends PlResourceEntry
|
|
15
|
+
? PlTreeEntry | ((cCtx: ComputableCtx) => PlTreeEntry | undefined) | undefined
|
|
16
|
+
: SC[Var];
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const NonKeyCtxFields = ['$prod', '$staging'];
|
|
20
|
+
|
|
21
|
+
export function toCfgContext(ctx: BlockContextAny): MatStdCtx {
|
|
22
|
+
return {
|
|
23
|
+
$blockId: ctx.blockId,
|
|
24
|
+
$args: JSON.parse(ctx.args),
|
|
25
|
+
$ui: ctx.uiState !== undefined ? JSON.parse(ctx.uiState) : undefined,
|
|
26
|
+
$prod: ctx.prod,
|
|
27
|
+
$staging: ctx.staging
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { PlClient } from '@milaboratories/pl-client';
|
|
2
|
+
import {
|
|
3
|
+
createDownloadClient, createLogsClient, createLsFilesClient, createUploadBlobClient, createUploadProgressClient, DownloadDriver,
|
|
4
|
+
InternalLsDriver,
|
|
5
|
+
LogsDriver,
|
|
6
|
+
LogsStreamDriver,
|
|
7
|
+
LsDriver,
|
|
8
|
+
UploadDriver
|
|
9
|
+
} from '@milaboratories/pl-drivers';
|
|
10
|
+
import * as Sdk from '@milaboratories/pl-model-common';
|
|
11
|
+
import { HmacSha256Signer, MiLogger, Signer } from '@milaboratories/ts-helpers';
|
|
12
|
+
import * as os from 'node:os';
|
|
13
|
+
import { PFrameDriver } from '../pool';
|
|
14
|
+
import { DefaultDriverKitOps, DriverKitOps, DriverKitOpsConstructor } from './ops';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Drivers offered by the middle-layer for internal consumers,
|
|
18
|
+
* like configuration rendering routines.
|
|
19
|
+
*
|
|
20
|
+
* This intertface is basically a version of the DriverKit from
|
|
21
|
+
* UI SDK with extended API.
|
|
22
|
+
* */
|
|
23
|
+
export interface MiddleLayerDriverKit extends Sdk.DriverKit {
|
|
24
|
+
// override with wider interface
|
|
25
|
+
readonly blobDriver: DownloadDriver;
|
|
26
|
+
// override with wider interface
|
|
27
|
+
readonly logDriver: LogsDriver;
|
|
28
|
+
// override with wider interface
|
|
29
|
+
readonly lsDriver: InternalLsDriver;
|
|
30
|
+
// override with wider interface
|
|
31
|
+
readonly pFrameDriver: PFrameDriver;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Signer is initialized from local secret in drivers initialization routine,
|
|
35
|
+
* so constitutes a part of the driver kit
|
|
36
|
+
* */
|
|
37
|
+
readonly signer: Signer;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Used to retrieve upload progress, and initiate upload porecesses driven by
|
|
41
|
+
* upload requests from block outputs.
|
|
42
|
+
* */
|
|
43
|
+
readonly uploadDriver: UploadDriver;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export async function initDriverKit(
|
|
47
|
+
pl: PlClient,
|
|
48
|
+
logger: MiLogger,
|
|
49
|
+
_ops: DriverKitOpsConstructor
|
|
50
|
+
): Promise<MiddleLayerDriverKit> {
|
|
51
|
+
const ops: DriverKitOps = { ...DefaultDriverKitOps, ..._ops };
|
|
52
|
+
checkStorageNamesDoNotIntersect(logger, ops);
|
|
53
|
+
|
|
54
|
+
const signer = new HmacSha256Signer(ops.localSecret);
|
|
55
|
+
|
|
56
|
+
const downloadClient = createDownloadClient(logger, pl, ops.platformLocalStorageNameToPath);
|
|
57
|
+
const logsClient = createLogsClient(pl, logger);
|
|
58
|
+
const uploadBlobClient = createUploadBlobClient(pl, logger);
|
|
59
|
+
const uploadProgressClient = createUploadProgressClient(pl, logger);
|
|
60
|
+
const lsClient = createLsFilesClient(pl, logger);
|
|
61
|
+
|
|
62
|
+
const blobDriver = new DownloadDriver(
|
|
63
|
+
logger,
|
|
64
|
+
downloadClient,
|
|
65
|
+
logsClient,
|
|
66
|
+
ops.blobDownloadPath,
|
|
67
|
+
signer,
|
|
68
|
+
ops.blobDriverOps
|
|
69
|
+
);
|
|
70
|
+
const uploadDriver = new UploadDriver(
|
|
71
|
+
logger,
|
|
72
|
+
signer,
|
|
73
|
+
uploadBlobClient,
|
|
74
|
+
uploadProgressClient,
|
|
75
|
+
ops.uploadDriverOps
|
|
76
|
+
);
|
|
77
|
+
const logsStreamDriver = new LogsStreamDriver(logsClient, ops.logStreamDriverOps);
|
|
78
|
+
const logDriver = new LogsDriver(logsStreamDriver, blobDriver);
|
|
79
|
+
const lsDriver = new LsDriver(logger, lsClient, pl, signer, ops.localStorageNameToPath);
|
|
80
|
+
|
|
81
|
+
const pFrameDriver = new PFrameDriver(blobDriver);
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
blobDriver,
|
|
85
|
+
logDriver,
|
|
86
|
+
lsDriver,
|
|
87
|
+
signer,
|
|
88
|
+
uploadDriver,
|
|
89
|
+
pFrameDriver
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function checkStorageNamesDoNotIntersect(logger: MiLogger, ops: DriverKitOps) {
|
|
94
|
+
if (ops.localStorageNameToPath.local != os.homedir())
|
|
95
|
+
logger.warn(`'local' storage with homedir was overwrote: ${ops.localStorageNameToPath.local}`);
|
|
96
|
+
|
|
97
|
+
const platformStorages = Object.keys(ops.platformLocalStorageNameToPath);
|
|
98
|
+
const intersected = Object.keys(ops.localStorageNameToPath).find((name) =>
|
|
99
|
+
platformStorages.includes(name)
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
if (intersected)
|
|
103
|
+
throw new Error(
|
|
104
|
+
`Platform local storages include one or more local storages: ` +
|
|
105
|
+
` ${intersected}. Note that we automatically included 'local' storage with user's home directory.`
|
|
106
|
+
);
|
|
107
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { PlTreeEntry, PlTreeEntryAccessor } from '@milaboratories/pl-tree';
|
|
2
|
+
import { MiddleLayerEnvironment } from './middle_layer';
|
|
3
|
+
import { Computable, ComputableStableDefined } from '@milaboratories/computable';
|
|
4
|
+
import { Pl, resourceTypesEqual } from '@milaboratories/pl-client';
|
|
5
|
+
import {
|
|
6
|
+
FrontendFromFolderData,
|
|
7
|
+
FrontendFromFolderResourceType,
|
|
8
|
+
FrontendFromUrlData,
|
|
9
|
+
FrontendFromUrlResourceType
|
|
10
|
+
} from '../model';
|
|
11
|
+
import { PathResult } from '@milaboratories/pl-drivers';
|
|
12
|
+
import { projectFieldName } from '../model/project_model';
|
|
13
|
+
import { BlockPackFrontendField } from '../mutator/block-pack/block_pack';
|
|
14
|
+
import { getBlockCfg } from './util';
|
|
15
|
+
import { FrontendData } from '../model/frontend';
|
|
16
|
+
|
|
17
|
+
function kernel(
|
|
18
|
+
frontendRes: PlTreeEntryAccessor,
|
|
19
|
+
env: MiddleLayerEnvironment
|
|
20
|
+
): undefined | string | ComputableStableDefined<PathResult> {
|
|
21
|
+
const node = frontendRes.node();
|
|
22
|
+
if (resourceTypesEqual(node.resourceType, FrontendFromUrlResourceType)) {
|
|
23
|
+
const data = node.getDataAsJson<FrontendFromUrlData>();
|
|
24
|
+
if (data === undefined) throw new Error(`No resource data.`);
|
|
25
|
+
return env.frontendDownloadDriver.getPath(new URL(data.url)).withStableType();
|
|
26
|
+
} else if (resourceTypesEqual(node.resourceType, FrontendFromFolderResourceType)) {
|
|
27
|
+
const data = node.getDataAsJson<FrontendFromFolderData>();
|
|
28
|
+
if (data === undefined) throw new Error(`No resource data.`);
|
|
29
|
+
env.signer.verify(
|
|
30
|
+
data.path,
|
|
31
|
+
data.signature,
|
|
32
|
+
`Frontend path signature mismatch for: ${data.path}`
|
|
33
|
+
);
|
|
34
|
+
return data.path;
|
|
35
|
+
} else {
|
|
36
|
+
throw new Error(`Unsupported resource type: ${JSON.stringify(node.resourceType)}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function frontendPathComputable(
|
|
41
|
+
entry: PlTreeEntry | undefined,
|
|
42
|
+
env: MiddleLayerEnvironment
|
|
43
|
+
): ComputableStableDefined<string> | undefined {
|
|
44
|
+
if (entry === undefined) return undefined;
|
|
45
|
+
return Computable.make(
|
|
46
|
+
(c) => {
|
|
47
|
+
return kernel(c.accessor(entry), env);
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
postprocessValue: (v) => {
|
|
51
|
+
if (v === undefined) return undefined;
|
|
52
|
+
if (typeof v === 'string') return v;
|
|
53
|
+
if (v.error !== undefined) throw new Error(v.error);
|
|
54
|
+
return v.path;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
).withStableType();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function frontendData(
|
|
61
|
+
projectEntry: PlTreeEntry,
|
|
62
|
+
id: string,
|
|
63
|
+
env: MiddleLayerEnvironment
|
|
64
|
+
): ComputableStableDefined<FrontendData> {
|
|
65
|
+
return Computable.make(
|
|
66
|
+
(ctx) => {
|
|
67
|
+
const prj = ctx.accessor(projectEntry).node();
|
|
68
|
+
const blockCfg = getBlockCfg(prj, id);
|
|
69
|
+
const frontendEntry = prj
|
|
70
|
+
.traverse(
|
|
71
|
+
{
|
|
72
|
+
field: projectFieldName(id, 'blockPack'),
|
|
73
|
+
assertFieldType: 'Dynamic'
|
|
74
|
+
},
|
|
75
|
+
{ field: Pl.HolderRefField, assertFieldType: 'Input', errorIfFieldNotFound: true },
|
|
76
|
+
{ field: BlockPackFrontendField, assertFieldType: 'Input' }
|
|
77
|
+
)
|
|
78
|
+
?.persist();
|
|
79
|
+
return { path: frontendPathComputable(frontendEntry, env), sdkVersion: blockCfg?.sdkVersion };
|
|
80
|
+
},
|
|
81
|
+
{ mode: 'StableOnlyLive' }
|
|
82
|
+
) as ComputableStableDefined<FrontendData>;
|
|
83
|
+
}
|