@milaboratories/pl-middle-layer 1.10.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/dist/block_registry/index.d.ts +4 -0
  2. package/dist/block_registry/index.d.ts.map +1 -0
  3. package/dist/block_registry/registry.d.ts +37 -0
  4. package/dist/block_registry/registry.d.ts.map +1 -0
  5. package/dist/block_registry/registry_spec.d.ts +12 -0
  6. package/dist/block_registry/registry_spec.d.ts.map +1 -0
  7. package/dist/block_registry/watcher.d.ts +15 -0
  8. package/dist/block_registry/watcher.d.ts.map +1 -0
  9. package/dist/block_registry/well_known_registries.d.ts +4 -0
  10. package/dist/block_registry/well_known_registries.d.ts.map +1 -0
  11. package/dist/cfg_render/executor.d.ts +8 -0
  12. package/dist/cfg_render/executor.d.ts.map +1 -0
  13. package/dist/cfg_render/operation.d.ts +29 -0
  14. package/dist/cfg_render/operation.d.ts.map +1 -0
  15. package/dist/cfg_render/renderer.d.ts +6 -0
  16. package/dist/cfg_render/renderer.d.ts.map +1 -0
  17. package/dist/cfg_render/traverse.d.ts +3 -0
  18. package/dist/cfg_render/traverse.d.ts.map +1 -0
  19. package/dist/cfg_render/util.d.ts +5 -0
  20. package/dist/cfg_render/util.d.ts.map +1 -0
  21. package/dist/dev/index.d.ts +21 -0
  22. package/dist/dev/index.d.ts.map +1 -0
  23. package/dist/dev/util.d.ts +3 -0
  24. package/dist/dev/util.d.ts.map +1 -0
  25. package/dist/index.d.ts +13 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +2 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/index.mjs +3587 -0
  30. package/dist/index.mjs.map +1 -0
  31. package/dist/js_render/context.d.ts +68 -0
  32. package/dist/js_render/context.d.ts.map +1 -0
  33. package/dist/js_render/index.d.ts +6 -0
  34. package/dist/js_render/index.d.ts.map +1 -0
  35. package/dist/middle_layer/active_cfg.d.ts +6 -0
  36. package/dist/middle_layer/active_cfg.d.ts.map +1 -0
  37. package/dist/middle_layer/block.d.ts +9 -0
  38. package/dist/middle_layer/block.d.ts.map +1 -0
  39. package/dist/middle_layer/block_ctx.d.ts +20 -0
  40. package/dist/middle_layer/block_ctx.d.ts.map +1 -0
  41. package/dist/middle_layer/block_ctx_unsafe.d.ts +16 -0
  42. package/dist/middle_layer/block_ctx_unsafe.d.ts.map +1 -0
  43. package/dist/middle_layer/driver_kit.d.ts +31 -0
  44. package/dist/middle_layer/driver_kit.d.ts.map +1 -0
  45. package/dist/middle_layer/frontend_path.d.ts +6 -0
  46. package/dist/middle_layer/frontend_path.d.ts.map +1 -0
  47. package/dist/middle_layer/index.d.ts +5 -0
  48. package/dist/middle_layer/index.d.ts.map +1 -0
  49. package/dist/middle_layer/middle_layer.d.ts +78 -0
  50. package/dist/middle_layer/middle_layer.d.ts.map +1 -0
  51. package/dist/middle_layer/navigation_states.d.ts +10 -0
  52. package/dist/middle_layer/navigation_states.d.ts.map +1 -0
  53. package/dist/middle_layer/ops.d.ts +64 -0
  54. package/dist/middle_layer/ops.d.ts.map +1 -0
  55. package/dist/middle_layer/project.d.ts +110 -0
  56. package/dist/middle_layer/project.d.ts.map +1 -0
  57. package/dist/middle_layer/project_list.d.ts +11 -0
  58. package/dist/middle_layer/project_list.d.ts.map +1 -0
  59. package/dist/middle_layer/project_overview.d.ts +8 -0
  60. package/dist/middle_layer/project_overview.d.ts.map +1 -0
  61. package/dist/middle_layer/render.d.ts +6 -0
  62. package/dist/middle_layer/render.d.ts.map +1 -0
  63. package/dist/middle_layer/types.d.ts +11 -0
  64. package/dist/middle_layer/types.d.ts.map +1 -0
  65. package/dist/middle_layer/util.d.ts +3 -0
  66. package/dist/middle_layer/util.d.ts.map +1 -0
  67. package/dist/model/args.d.ts +12 -0
  68. package/dist/model/args.d.ts.map +1 -0
  69. package/dist/model/block_pack.d.ts +8 -0
  70. package/dist/model/block_pack.d.ts.map +1 -0
  71. package/dist/model/block_pack_spec.d.ts +40 -0
  72. package/dist/model/block_pack_spec.d.ts.map +1 -0
  73. package/dist/model/frontend.d.ts +10 -0
  74. package/dist/model/frontend.d.ts.map +1 -0
  75. package/dist/model/index.d.ts +3 -0
  76. package/dist/model/index.d.ts.map +1 -0
  77. package/dist/model/project_model.d.ts +67 -0
  78. package/dist/model/project_model.d.ts.map +1 -0
  79. package/dist/model/project_model_util.d.ts +29 -0
  80. package/dist/model/project_model_util.d.ts.map +1 -0
  81. package/dist/model/template_spec.d.ts +16 -0
  82. package/dist/model/template_spec.d.ts.map +1 -0
  83. package/dist/mutator/block-pack/block_pack.d.ts +17 -0
  84. package/dist/mutator/block-pack/block_pack.d.ts.map +1 -0
  85. package/dist/mutator/block-pack/frontend.d.ts +4 -0
  86. package/dist/mutator/block-pack/frontend.d.ts.map +1 -0
  87. package/dist/mutator/context_export.d.ts +9 -0
  88. package/dist/mutator/context_export.d.ts.map +1 -0
  89. package/dist/mutator/project.d.ts +121 -0
  90. package/dist/mutator/project.d.ts.map +1 -0
  91. package/dist/mutator/template/render_block.d.ts +32 -0
  92. package/dist/mutator/template/render_block.d.ts.map +1 -0
  93. package/dist/mutator/template/render_template.d.ts +12 -0
  94. package/dist/mutator/template/render_template.d.ts.map +1 -0
  95. package/dist/mutator/template/template_loading.d.ts +13 -0
  96. package/dist/mutator/template/template_loading.d.ts.map +1 -0
  97. package/dist/pool/data.d.ts +24 -0
  98. package/dist/pool/data.d.ts.map +1 -0
  99. package/dist/pool/driver.d.ts +22 -0
  100. package/dist/pool/driver.d.ts.map +1 -0
  101. package/dist/pool/index.d.ts +3 -0
  102. package/dist/pool/index.d.ts.map +1 -0
  103. package/dist/pool/p_object_collection.d.ts +29 -0
  104. package/dist/pool/p_object_collection.d.ts.map +1 -0
  105. package/dist/pool/ref_count_pool.d.ts +25 -0
  106. package/dist/pool/ref_count_pool.d.ts.map +1 -0
  107. package/dist/pool/result_pool.d.ts +25 -0
  108. package/dist/pool/result_pool.d.ts.map +1 -0
  109. package/dist/test/block_packs.d.ts +6 -0
  110. package/dist/test/block_packs.d.ts.map +1 -0
  111. package/dist/test/explicit_templates.d.ts +3 -0
  112. package/dist/test/explicit_templates.d.ts.map +1 -0
  113. package/dist/test/known_templates.d.ts +6 -0
  114. package/dist/test/known_templates.d.ts.map +1 -0
  115. package/package.json +55 -0
  116. package/src/block_registry/index.ts +3 -0
  117. package/src/block_registry/registry.test.ts +35 -0
  118. package/src/block_registry/registry.ts +180 -0
  119. package/src/block_registry/registry_spec.ts +13 -0
  120. package/src/block_registry/watcher.ts +72 -0
  121. package/src/block_registry/well_known_registries.ts +13 -0
  122. package/src/cfg_render/executor.test.ts +120 -0
  123. package/src/cfg_render/executor.ts +253 -0
  124. package/src/cfg_render/operation.ts +38 -0
  125. package/src/cfg_render/renderer.ts +540 -0
  126. package/src/cfg_render/traverse.ts +58 -0
  127. package/src/cfg_render/util.ts +29 -0
  128. package/src/dev/index.ts +89 -0
  129. package/src/dev/util.ts +13 -0
  130. package/src/index.ts +21 -0
  131. package/src/js_render/context.ts +768 -0
  132. package/src/js_render/index.ts +41 -0
  133. package/src/middle_layer/active_cfg.ts +56 -0
  134. package/src/middle_layer/block.ts +70 -0
  135. package/src/middle_layer/block_ctx.ts +90 -0
  136. package/src/middle_layer/block_ctx_unsafe.ts +29 -0
  137. package/src/middle_layer/driver_kit.ts +107 -0
  138. package/src/middle_layer/frontend_path.ts +83 -0
  139. package/src/middle_layer/index.ts +4 -0
  140. package/src/middle_layer/middle_layer.test.ts +720 -0
  141. package/src/middle_layer/middle_layer.ts +235 -0
  142. package/src/middle_layer/navigation_states.ts +48 -0
  143. package/src/middle_layer/ops.ts +147 -0
  144. package/src/middle_layer/project.ts +380 -0
  145. package/src/middle_layer/project_list.ts +59 -0
  146. package/src/middle_layer/project_overview.ts +220 -0
  147. package/src/middle_layer/render.test.ts +129 -0
  148. package/src/middle_layer/render.ts +19 -0
  149. package/src/middle_layer/types.ts +16 -0
  150. package/src/middle_layer/util.ts +22 -0
  151. package/src/model/args.ts +62 -0
  152. package/src/model/block_pack.ts +8 -0
  153. package/src/model/block_pack_spec.ts +52 -0
  154. package/src/model/frontend.ts +10 -0
  155. package/src/model/index.ts +2 -0
  156. package/src/model/project_model.test.ts +26 -0
  157. package/src/model/project_model.ts +142 -0
  158. package/src/model/project_model_util.test.ts +88 -0
  159. package/src/model/project_model_util.ts +169 -0
  160. package/src/model/template_spec.ts +18 -0
  161. package/src/mutator/block-pack/block_pack.test.ts +53 -0
  162. package/src/mutator/block-pack/block_pack.ts +187 -0
  163. package/src/mutator/block-pack/frontend.ts +29 -0
  164. package/src/mutator/context_export.ts +25 -0
  165. package/src/mutator/project.test.ts +272 -0
  166. package/src/mutator/project.ts +1112 -0
  167. package/src/mutator/template/render_block.ts +91 -0
  168. package/src/mutator/template/render_template.ts +40 -0
  169. package/src/mutator/template/template_loading.ts +77 -0
  170. package/src/mutator/template/template_render.test.ts +272 -0
  171. package/src/pool/data.ts +239 -0
  172. package/src/pool/driver.ts +325 -0
  173. package/src/pool/index.ts +2 -0
  174. package/src/pool/p_object_collection.ts +122 -0
  175. package/src/pool/ref_count_pool.ts +76 -0
  176. package/src/pool/result_pool.ts +284 -0
  177. package/src/test/block_packs.ts +23 -0
  178. package/src/test/explicit_templates.ts +8 -0
  179. package/src/test/known_templates.ts +24 -0
@@ -0,0 +1,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
+ }
@@ -0,0 +1,4 @@
1
+ export { MiddleLayer } from './middle_layer';
2
+ export { Project } from './project';
3
+ export * from './driver_kit';
4
+ export * from './ops';