@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,235 @@
|
|
|
1
|
+
import {
|
|
2
|
+
field,
|
|
3
|
+
isNullResourceId,
|
|
4
|
+
PlClient,
|
|
5
|
+
ResourceId,
|
|
6
|
+
toGlobalResourceId
|
|
7
|
+
} from '@milaboratories/pl-client';
|
|
8
|
+
import { createProjectList, ProjectsField, ProjectsResourceType } from './project_list';
|
|
9
|
+
import { createProject, withProject, withProjectAuthored } from '../mutator/project';
|
|
10
|
+
import { SynchronizedTreeState } from '@milaboratories/pl-tree';
|
|
11
|
+
import { BlockPackPreparer } from '../mutator/block-pack/block_pack';
|
|
12
|
+
import { ConsoleLoggerAdapter, HmacSha256Signer, Signer } from '@milaboratories/ts-helpers';
|
|
13
|
+
import { ComputableStableDefined, WatchableValue } from '@milaboratories/computable';
|
|
14
|
+
import { Project } from './project';
|
|
15
|
+
import { DefaultMiddleLayerOps, MiddleLayerOps, MiddleLayerOpsConstructor } from './ops';
|
|
16
|
+
import { randomUUID } from 'node:crypto';
|
|
17
|
+
import { ProjectListEntry } from '../model';
|
|
18
|
+
import { AuthorMarker, ProjectMeta } from '@milaboratories/pl-model-middle-layer';
|
|
19
|
+
import { BlockUpdateWatcher } from '../block_registry/watcher';
|
|
20
|
+
import { getQuickJS, QuickJSWASMModule } from 'quickjs-emscripten';
|
|
21
|
+
import { initDriverKit, MiddleLayerDriverKit } from './driver_kit';
|
|
22
|
+
import { DriverKit } from '@platforma-sdk/model';
|
|
23
|
+
import { DownloadUrlDriver } from '@milaboratories/pl-drivers';
|
|
24
|
+
|
|
25
|
+
export interface MiddleLayerEnvironment {
|
|
26
|
+
readonly pl: PlClient;
|
|
27
|
+
readonly signer: Signer;
|
|
28
|
+
readonly ops: MiddleLayerOps;
|
|
29
|
+
readonly bpPreparer: BlockPackPreparer;
|
|
30
|
+
readonly frontendDownloadDriver: DownloadUrlDriver;
|
|
31
|
+
readonly blockUpdateWatcher: BlockUpdateWatcher;
|
|
32
|
+
readonly quickJs: QuickJSWASMModule;
|
|
33
|
+
readonly driverKit: MiddleLayerDriverKit;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Main access object to work with pl from UI.
|
|
38
|
+
*
|
|
39
|
+
* It implements an abstraction layer of projects and blocks.
|
|
40
|
+
*
|
|
41
|
+
* As a main entry point inside the pl, this object uses a resource attached
|
|
42
|
+
* via the {@link ProjectsField} to the pl client's root, this resource
|
|
43
|
+
* contains project list.
|
|
44
|
+
*
|
|
45
|
+
* Read about alternative roots, if isolated project lists (working environments)
|
|
46
|
+
* are required.
|
|
47
|
+
* */
|
|
48
|
+
export class MiddleLayer {
|
|
49
|
+
private readonly pl: PlClient;
|
|
50
|
+
|
|
51
|
+
/** Contains a reactive list of projects along with their meta information. */
|
|
52
|
+
public readonly projectList: ComputableStableDefined<ProjectListEntry[]>;
|
|
53
|
+
|
|
54
|
+
private constructor(
|
|
55
|
+
private readonly env: MiddleLayerEnvironment,
|
|
56
|
+
public readonly driverKit: DriverKit,
|
|
57
|
+
public readonly signer: Signer,
|
|
58
|
+
private readonly projectListResourceId: ResourceId,
|
|
59
|
+
private readonly openedProjectsList: WatchableValue<ResourceId[]>,
|
|
60
|
+
private readonly projectListTree: SynchronizedTreeState,
|
|
61
|
+
projectList: ComputableStableDefined<ProjectListEntry[]>
|
|
62
|
+
) {
|
|
63
|
+
this.projectList = projectList;
|
|
64
|
+
this.pl = this.env.pl;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Returns extended API driver kit used internally by middle layer. */
|
|
68
|
+
public get internalDriverKit(): MiddleLayerDriverKit {
|
|
69
|
+
return this.env.driverKit;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
//
|
|
73
|
+
// Project List Manipulation
|
|
74
|
+
//
|
|
75
|
+
|
|
76
|
+
/** Creates a project with initial state and adds it to project list. */
|
|
77
|
+
public async createProject(meta: ProjectMeta, id: string = randomUUID()): Promise<ResourceId> {
|
|
78
|
+
const resource = await this.pl.withWriteTx('MLCreateProject', async (tx) => {
|
|
79
|
+
const prj = await createProject(tx, meta);
|
|
80
|
+
tx.createField(field(this.projectListResourceId, id), 'Dynamic', prj);
|
|
81
|
+
await tx.commit();
|
|
82
|
+
return await toGlobalResourceId(prj);
|
|
83
|
+
});
|
|
84
|
+
await this.projectListTree.refreshState();
|
|
85
|
+
return resource;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Updates project metadata */
|
|
89
|
+
public async setProjectMeta(
|
|
90
|
+
rid: ResourceId,
|
|
91
|
+
meta: ProjectMeta,
|
|
92
|
+
author?: AuthorMarker
|
|
93
|
+
): Promise<void> {
|
|
94
|
+
await withProjectAuthored(this.pl, rid, author, async (prj) => {
|
|
95
|
+
prj.setMeta(meta);
|
|
96
|
+
});
|
|
97
|
+
await this.projectListTree.refreshState();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Permanently deletes project from the project list, this will result in
|
|
101
|
+
* destruction of all attached objects, like files, analysis results etc. */
|
|
102
|
+
public async deleteProject(id: string): Promise<void> {
|
|
103
|
+
await this.pl.withWriteTx('MLRemoveProject', async (tx) => {
|
|
104
|
+
tx.removeField(field(this.projectListResourceId, id));
|
|
105
|
+
await tx.commit();
|
|
106
|
+
});
|
|
107
|
+
await this.projectListTree.refreshState();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
//
|
|
111
|
+
// Projects
|
|
112
|
+
//
|
|
113
|
+
|
|
114
|
+
private readonly openedProjectsByRid = new Map<ResourceId, Project>();
|
|
115
|
+
|
|
116
|
+
private async projectIdToResourceId(id: string): Promise<ResourceId> {
|
|
117
|
+
return await this.pl.withReadTx('Project id to resource id', async (tx) => {
|
|
118
|
+
const rid = (await tx.getField(field(this.projectListResourceId, id))).value;
|
|
119
|
+
if (isNullResourceId(rid)) throw new Error('Unexpected project list structure.');
|
|
120
|
+
return rid;
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private async ensureProjectRid(id: ResourceId | string): Promise<ResourceId> {
|
|
125
|
+
if (typeof id === 'string') return await this.projectIdToResourceId(id);
|
|
126
|
+
else return id;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** Opens a project, and starts corresponding project maintenance loop. */
|
|
130
|
+
public async openProject(id: ResourceId | string) {
|
|
131
|
+
const rid = await this.ensureProjectRid(id);
|
|
132
|
+
if (this.openedProjectsByRid.has(rid)) throw new Error(`Project ${rid} already opened`);
|
|
133
|
+
this.openedProjectsByRid.set(rid, await Project.init(this.env, rid));
|
|
134
|
+
this.openedProjectsList.setValue([...this.openedProjectsByRid.keys()]);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** Closes the project, and deallocate all corresponding resources. */
|
|
138
|
+
public async closeProject(rid: ResourceId): Promise<void> {
|
|
139
|
+
const prj = this.openedProjectsByRid.get(rid);
|
|
140
|
+
if (prj === undefined) throw new Error(`Project ${rid} not found among opened projects`);
|
|
141
|
+
this.openedProjectsByRid.delete(rid);
|
|
142
|
+
await prj.destroy();
|
|
143
|
+
this.openedProjectsList.setValue([...this.openedProjectsByRid.keys()]);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** Returns a project access object for opened project, for the given project
|
|
147
|
+
* resource id. */
|
|
148
|
+
public getOpenedProject(rid: ResourceId): Project {
|
|
149
|
+
const prj = this.openedProjectsByRid.get(rid);
|
|
150
|
+
if (prj === undefined) throw new Error(`Project ${rid} not found among opened projects`);
|
|
151
|
+
return prj;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** Deallocates all runtime resources consumed by this object and awaits
|
|
155
|
+
* actual termination of event loops and other processes associated with
|
|
156
|
+
* them. */
|
|
157
|
+
public async close() {
|
|
158
|
+
await Promise.all([...this.openedProjectsByRid.values()].map((prj) => prj.destroy()));
|
|
159
|
+
this.env.quickJs;
|
|
160
|
+
await this.projectListTree.terminate();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** @deprecated */
|
|
164
|
+
public async closeAndAwaitTermination() {
|
|
165
|
+
await this.close();
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** Generates sufficiently random string to be used as local secret for the
|
|
169
|
+
* middle layer */
|
|
170
|
+
public static generateLocalSecret(): string {
|
|
171
|
+
return HmacSha256Signer.generateSecret();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Initialize middle layer */
|
|
175
|
+
public static async init(pl: PlClient, _ops: MiddleLayerOpsConstructor): Promise<MiddleLayer> {
|
|
176
|
+
const ops: MiddleLayerOps = { ...DefaultMiddleLayerOps, ..._ops };
|
|
177
|
+
|
|
178
|
+
const projects = await pl.withWriteTx('MLInitialization', async (tx) => {
|
|
179
|
+
const projectsField = field(tx.clientRoot, ProjectsField);
|
|
180
|
+
tx.createField(projectsField, 'Dynamic');
|
|
181
|
+
const projectsFieldData = await tx.getField(projectsField);
|
|
182
|
+
if (isNullResourceId(projectsFieldData.value)) {
|
|
183
|
+
const projects = tx.createEphemeral(ProjectsResourceType);
|
|
184
|
+
tx.lock(projects);
|
|
185
|
+
|
|
186
|
+
tx.setField(projectsField, projects);
|
|
187
|
+
|
|
188
|
+
await tx.commit();
|
|
189
|
+
|
|
190
|
+
return await projects.globalId;
|
|
191
|
+
} else {
|
|
192
|
+
return projectsFieldData.value;
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
const logger = new ConsoleLoggerAdapter(console);
|
|
197
|
+
|
|
198
|
+
const driverKit = await initDriverKit(pl, logger, ops);
|
|
199
|
+
|
|
200
|
+
const bpPreparer = new BlockPackPreparer(driverKit.signer);
|
|
201
|
+
|
|
202
|
+
const frontendDownloadDriver = new DownloadUrlDriver(
|
|
203
|
+
logger,
|
|
204
|
+
pl.httpDispatcher,
|
|
205
|
+
ops.frontendDownloadPath
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
const env: MiddleLayerEnvironment = {
|
|
209
|
+
pl,
|
|
210
|
+
signer: driverKit.signer,
|
|
211
|
+
ops,
|
|
212
|
+
bpPreparer,
|
|
213
|
+
frontendDownloadDriver,
|
|
214
|
+
driverKit,
|
|
215
|
+
blockUpdateWatcher: new BlockUpdateWatcher({
|
|
216
|
+
minDelay: ops.devBlockUpdateRecheckInterval,
|
|
217
|
+
http: pl.httpDispatcher
|
|
218
|
+
}),
|
|
219
|
+
quickJs: await getQuickJS()
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
const openedProjects = new WatchableValue<ResourceId[]>([]);
|
|
223
|
+
const projectListTC = await createProjectList(pl, projects, openedProjects, env);
|
|
224
|
+
|
|
225
|
+
return new MiddleLayer(
|
|
226
|
+
env,
|
|
227
|
+
driverKit,
|
|
228
|
+
driverKit.signer,
|
|
229
|
+
projects,
|
|
230
|
+
openedProjects,
|
|
231
|
+
projectListTC.tree,
|
|
232
|
+
projectListTC.computable
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ChangeSource, Computable, ComputableCtx } from '@milaboratories/computable';
|
|
2
|
+
import { NavigationState, DefaultNavigationState } from '@platforma-sdk/model';
|
|
3
|
+
|
|
4
|
+
type NavigationStateEntry = {
|
|
5
|
+
state: NavigationState;
|
|
6
|
+
readonly change: ChangeSource;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export class NavigationStates {
|
|
10
|
+
private readonly states = new Map<string, NavigationStateEntry>();
|
|
11
|
+
|
|
12
|
+
public setState(blockId: string, state: NavigationState) {
|
|
13
|
+
const entry = this.states.get(blockId);
|
|
14
|
+
if (entry === undefined) {
|
|
15
|
+
this.states.set(blockId, { state, change: new ChangeSource() });
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
entry.state = { ...state };
|
|
19
|
+
entry.change.markChanged();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
private readState(ctx: ComputableCtx, blockId: string): NavigationState {
|
|
23
|
+
let entry = this.states.get(blockId);
|
|
24
|
+
if (entry === undefined) {
|
|
25
|
+
entry = { state: { ...DefaultNavigationState }, change: new ChangeSource() };
|
|
26
|
+
this.states.set(blockId, entry);
|
|
27
|
+
}
|
|
28
|
+
entry.change.attachWatcher(ctx.watcher);
|
|
29
|
+
return entry.state;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public getState(blockId: string): Computable<NavigationState> {
|
|
33
|
+
return Computable.make(
|
|
34
|
+
(ctx) => {
|
|
35
|
+
return this.readState(ctx, blockId);
|
|
36
|
+
},
|
|
37
|
+
{ key: `navigationState#${blockId}` }
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public deleteBlock(blockId: string) {
|
|
42
|
+
const entry = this.states.get(blockId);
|
|
43
|
+
if (entry !== undefined) {
|
|
44
|
+
this.states.delete(blockId);
|
|
45
|
+
entry.change.markChanged();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { TemporalSynchronizedTreeOps } from './types';
|
|
2
|
+
import { DownloadDriverOps } from '@milaboratories/pl-drivers';
|
|
3
|
+
import { UploadDriverOps } from '@milaboratories/pl-drivers';
|
|
4
|
+
import { LogsStreamDriverOps } from '@milaboratories/pl-drivers';
|
|
5
|
+
import * as os from 'node:os';
|
|
6
|
+
|
|
7
|
+
/** Options required to initialize full set of middle layer driver kit */
|
|
8
|
+
export type DriverKitOps = {
|
|
9
|
+
//
|
|
10
|
+
// Signer
|
|
11
|
+
//
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Local secret, that is used to sign and verify different pieces of information
|
|
15
|
+
* that can be used to access local data, like local paths for ongoing uploads.
|
|
16
|
+
*
|
|
17
|
+
* Use {@link MiddleLayer.generateLocalSecret} to generate sufficiently random string.
|
|
18
|
+
* */
|
|
19
|
+
readonly localSecret: string;
|
|
20
|
+
|
|
21
|
+
//
|
|
22
|
+
// Blob Driver
|
|
23
|
+
//
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Settings related to the download driver making operations with blobs. This driver is also used
|
|
27
|
+
* to download logs when source process terminates and log terns into a blob
|
|
28
|
+
*/
|
|
29
|
+
readonly blobDriverOps: DownloadDriverOps;
|
|
30
|
+
|
|
31
|
+
/** Common root where to put downloaded blobs. */
|
|
32
|
+
readonly blobDownloadPath: string;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* If Platforma is running in local mode and a download driver
|
|
36
|
+
* needs to download files from local storage, it will open files
|
|
37
|
+
* from the specified directory. Otherwise, it should be empty.
|
|
38
|
+
* */
|
|
39
|
+
readonly platformLocalStorageNameToPath: Record<string, string>;
|
|
40
|
+
|
|
41
|
+
//
|
|
42
|
+
// Upload Driver
|
|
43
|
+
//
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Settings related to the upload driver that actually performs upload and helps render upload
|
|
47
|
+
* and indexing progresses from related pl resources.
|
|
48
|
+
* */
|
|
49
|
+
readonly uploadDriverOps: UploadDriverOps;
|
|
50
|
+
|
|
51
|
+
//
|
|
52
|
+
// Log streaming ops
|
|
53
|
+
// (static logs are served via the blob driver)
|
|
54
|
+
//
|
|
55
|
+
|
|
56
|
+
/** Settings related to the streaming log driver */
|
|
57
|
+
readonly logStreamDriverOps: LogsStreamDriverOps;
|
|
58
|
+
|
|
59
|
+
//
|
|
60
|
+
// LS Driver
|
|
61
|
+
//
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* If the client wants to upload files from their local machine to Platforma,
|
|
65
|
+
* this option should be set. Set any unique storage names
|
|
66
|
+
* to any paths from where the client will upload files,
|
|
67
|
+
* e.g., {'local': '/'}.
|
|
68
|
+
* */
|
|
69
|
+
readonly localStorageNameToPath: Record<string, string>;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/** Some defaults fot MiddleLayerOps. */
|
|
73
|
+
export const DefaultDriverKitOps: Pick<
|
|
74
|
+
DriverKitOps,
|
|
75
|
+
| 'platformLocalStorageNameToPath'
|
|
76
|
+
| 'blobDriverOps'
|
|
77
|
+
| 'uploadDriverOps'
|
|
78
|
+
| 'logStreamDriverOps'
|
|
79
|
+
| 'localStorageNameToPath'
|
|
80
|
+
> = {
|
|
81
|
+
platformLocalStorageNameToPath: {},
|
|
82
|
+
localStorageNameToPath: { local: os.homedir() },
|
|
83
|
+
blobDriverOps: {
|
|
84
|
+
cacheSoftSizeBytes: 100 * 1024 * 1024, // 100MB
|
|
85
|
+
nConcurrentDownloads: 10
|
|
86
|
+
},
|
|
87
|
+
uploadDriverOps: {
|
|
88
|
+
nConcurrentPartUploads: 10,
|
|
89
|
+
nConcurrentGetProgresses: 10,
|
|
90
|
+
pollingInterval: 1000,
|
|
91
|
+
stopPollingDelay: 1000
|
|
92
|
+
},
|
|
93
|
+
logStreamDriverOps: {
|
|
94
|
+
nConcurrentGetLogs: 10,
|
|
95
|
+
pollingInterval: 1000,
|
|
96
|
+
stopPollingDelay: 1000
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/** Fields with default values are marked as optional here. */
|
|
101
|
+
export type DriverKitOpsConstructor = Omit<DriverKitOps, keyof typeof DefaultDriverKitOps> &
|
|
102
|
+
Partial<typeof DefaultDriverKitOps>;
|
|
103
|
+
|
|
104
|
+
/** Configuration controlling different aspects of middle layer behaviour. */
|
|
105
|
+
export type MiddleLayerOps = DriverKitOps & {
|
|
106
|
+
/** Contain temporal options controlling how often should pl trees be
|
|
107
|
+
* synchronized with the pl server. */
|
|
108
|
+
readonly defaultTreeOptions: TemporalSynchronizedTreeOps;
|
|
109
|
+
|
|
110
|
+
/** Defines interval in milliseconds for running periodic project maintenance job.
|
|
111
|
+
* Project maintenance includes gradual staging rendering and cached outputs cleanup. */
|
|
112
|
+
readonly projectRefreshInterval: number;
|
|
113
|
+
|
|
114
|
+
/** This controls average number of block staging states that are rendered per
|
|
115
|
+
* second during project maintenance job execution. */
|
|
116
|
+
readonly stagingRenderingRate: number;
|
|
117
|
+
|
|
118
|
+
/** How often to check for dev block updates */
|
|
119
|
+
readonly devBlockUpdateRecheckInterval: number;
|
|
120
|
+
|
|
121
|
+
/** Common root where to put frontend code. */
|
|
122
|
+
readonly frontendDownloadPath: string;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/** Some defaults fot MiddleLayerOps. */
|
|
126
|
+
export const DefaultMiddleLayerOps: Pick<
|
|
127
|
+
MiddleLayerOps,
|
|
128
|
+
| keyof typeof DefaultDriverKitOps
|
|
129
|
+
| 'defaultTreeOptions'
|
|
130
|
+
| 'projectRefreshInterval'
|
|
131
|
+
| 'stagingRenderingRate'
|
|
132
|
+
| 'platformLocalStorageNameToPath'
|
|
133
|
+
| 'devBlockUpdateRecheckInterval'
|
|
134
|
+
> = {
|
|
135
|
+
...DefaultDriverKitOps,
|
|
136
|
+
defaultTreeOptions: {
|
|
137
|
+
pollingInterval: 350,
|
|
138
|
+
stopPollingDelay: 2500
|
|
139
|
+
},
|
|
140
|
+
devBlockUpdateRecheckInterval: 1000,
|
|
141
|
+
projectRefreshInterval: 700,
|
|
142
|
+
stagingRenderingRate: 5
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/** Fields with default values are marked as optional here. */
|
|
146
|
+
export type MiddleLayerOpsConstructor = Omit<MiddleLayerOps, keyof typeof DefaultMiddleLayerOps> &
|
|
147
|
+
Partial<typeof DefaultMiddleLayerOps>;
|