@milaboratories/pl-middle-layer 1.71.16 → 1.72.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +10 -5
- package/dist/index.d.ts +5 -4
- package/dist/index.js +3 -2
- package/dist/middle_layer/build_stamp.cjs +1 -1
- package/dist/middle_layer/build_stamp.js +1 -1
- package/dist/middle_layer/folders.cjs +631 -0
- package/dist/middle_layer/folders.cjs.map +1 -0
- package/dist/middle_layer/folders.d.ts +39 -0
- package/dist/middle_layer/folders.d.ts.map +1 -0
- package/dist/middle_layer/folders.js +613 -0
- package/dist/middle_layer/folders.js.map +1 -0
- package/dist/middle_layer/index.cjs +3 -0
- package/dist/middle_layer/index.d.ts +4 -3
- package/dist/middle_layer/index.js +2 -1
- package/dist/middle_layer/middle_layer.cjs +585 -370
- package/dist/middle_layer/middle_layer.cjs.map +1 -1
- package/dist/middle_layer/middle_layer.d.ts +215 -122
- package/dist/middle_layer/middle_layer.d.ts.map +1 -1
- package/dist/middle_layer/middle_layer.js +593 -378
- package/dist/middle_layer/middle_layer.js.map +1 -1
- package/dist/middle_layer/project_list.cjs +36 -19
- package/dist/middle_layer/project_list.cjs.map +1 -1
- package/dist/middle_layer/project_list.d.ts +1 -1
- package/dist/middle_layer/project_list.d.ts.map +1 -1
- package/dist/middle_layer/project_list.js +37 -21
- package/dist/middle_layer/project_list.js.map +1 -1
- package/dist/middle_layer/sharing_list.cjs +123 -93
- package/dist/middle_layer/sharing_list.cjs.map +1 -1
- package/dist/middle_layer/sharing_list.d.ts +43 -19
- package/dist/middle_layer/sharing_list.d.ts.map +1 -1
- package/dist/middle_layer/sharing_list.js +123 -93
- package/dist/middle_layer/sharing_list.js.map +1 -1
- package/dist/middle_layer/template_list.cjs +45 -20
- package/dist/middle_layer/template_list.cjs.map +1 -1
- package/dist/middle_layer/template_list.d.ts +7 -15
- package/dist/middle_layer/template_list.d.ts.map +1 -1
- package/dist/middle_layer/template_list.js +44 -21
- package/dist/middle_layer/template_list.js.map +1 -1
- package/dist/model/index.cjs +7 -5
- package/dist/model/index.d.ts +2 -2
- package/dist/model/index.js +2 -2
- package/dist/model/sharing_model.cjs +46 -20
- package/dist/model/sharing_model.cjs.map +1 -1
- package/dist/model/sharing_model.d.ts +125 -55
- package/dist/model/sharing_model.d.ts.map +1 -1
- package/dist/model/sharing_model.js +40 -16
- package/dist/model/sharing_model.js.map +1 -1
- package/dist/mutator/list.cjs +30 -0
- package/dist/mutator/list.cjs.map +1 -0
- package/dist/mutator/list.js +29 -0
- package/dist/mutator/list.js.map +1 -0
- package/dist/mutator/project.cjs +14 -1
- package/dist/mutator/project.cjs.map +1 -1
- package/dist/mutator/project.d.ts.map +1 -1
- package/dist/mutator/project.js +15 -2
- package/dist/mutator/project.js.map +1 -1
- package/dist/mutator/sharing.cjs +130 -76
- package/dist/mutator/sharing.cjs.map +1 -1
- package/dist/mutator/sharing.js +130 -76
- package/dist/mutator/sharing.js.map +1 -1
- package/dist/mutator/template.cjs +24 -17
- package/dist/mutator/template.cjs.map +1 -1
- package/dist/mutator/template.js +26 -20
- package/dist/mutator/template.js.map +1 -1
- package/package.json +19 -19
- package/src/middle_layer/folders.test.ts +1068 -0
- package/src/middle_layer/folders.ts +1059 -0
- package/src/middle_layer/folders_read.test.ts +359 -0
- package/src/middle_layer/index.ts +3 -2
- package/src/middle_layer/middle_layer.ts +813 -547
- package/src/middle_layer/project_list.test.ts +183 -0
- package/src/middle_layer/project_list.ts +58 -21
- package/src/middle_layer/sharing.test.ts +183 -0
- package/src/middle_layer/sharing_list.ts +208 -152
- package/src/middle_layer/template_list.test.ts +148 -0
- package/src/middle_layer/template_list.ts +72 -32
- package/src/middle_layer/templates.test.ts +76 -45
- package/src/model/sharing_model.test.ts +69 -2
- package/src/model/sharing_model.ts +161 -73
- package/src/mutator/list.ts +36 -0
- package/src/mutator/project-v3.test.ts +3 -1
- package/src/mutator/project.ts +13 -2
- package/src/mutator/sharing.ts +193 -120
- package/src/mutator/template.ts +37 -29
- package/src/test/with_ml.ts +73 -16
|
@@ -3,10 +3,11 @@ import { TemplateApplyReport } from "../model/template_apply.js";
|
|
|
3
3
|
import { BlockPackProvider, TemplateResolveOutcome } from "../model/template_resolve.js";
|
|
4
4
|
import "../block_registry/index.js";
|
|
5
5
|
import { ProjectId as ProjectId$1, ProjectListEntry as ProjectListEntry$1 } from "../model/project_model.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { CreateProjectFromTemplateOutcome, SaveProjectAsTemplateOutcome, StoredTemplateData, TemplateId as TemplateId$1, TemplateListEntry } from "./template_list.js";
|
|
7
|
+
import { FoldersListing } from "./folders.js";
|
|
8
8
|
import { ProjectTemplateExportOutcome } from "../model/template_serializer.js";
|
|
9
|
-
import {
|
|
9
|
+
import { ShareFolderOptions, ShareId, ShareOutcome, ShareProjectsOptions, ShareTemplateOptions } from "../model/sharing_model.js";
|
|
10
|
+
import { AvailableShare, OutgoingShare } from "./sharing_list.js";
|
|
10
11
|
import "../model/index.js";
|
|
11
12
|
import { BlockPackPreparer } from "../mutator/block-pack/block_pack.js";
|
|
12
13
|
import { Project } from "./project.js";
|
|
@@ -16,7 +17,7 @@ import { MiddleLayerDriverKit } from "./driver_kit.js";
|
|
|
16
17
|
import { ProjectHelper } from "../model/project_helper.js";
|
|
17
18
|
import { TreeSnapshotStat, TreeSnapshotStore } from "./tree_snapshot_store.js";
|
|
18
19
|
import { BlockCodeFeatureFlags, DriverKit, RuntimeCapabilities, SupportedRequirement } from "@platforma-sdk/model";
|
|
19
|
-
import { AuthorMarker, BlockPlatform, ProjectMeta } from "@milaboratories/pl-model-middle-layer";
|
|
20
|
+
import { AuthorMarker, BlockPlatform, FolderId, FoldersItem, FoldersMoveOutcome, FoldersMovePlan, FoldersMovePlanResult, FoldersRemoval, FoldersRemovalOutcome, FoldersRemovalPlanResult, ProjectMeta } from "@milaboratories/pl-model-middle-layer";
|
|
20
21
|
import { Dispatcher } from "undici";
|
|
21
22
|
import { BlockEventDispatcher, MiLogger, Signer } from "@milaboratories/ts-helpers";
|
|
22
23
|
import { ModelServiceRegistry, ProjectTemplateV1 } from "@milaboratories/pl-model-common";
|
|
@@ -66,25 +67,29 @@ export declare class MiddleLayer {
|
|
|
66
67
|
private readonly templateListResourceId;
|
|
67
68
|
private readonly sharingOutboxResourceId;
|
|
68
69
|
private readonly sharingStateResourceId;
|
|
70
|
+
private readonly foldersResourceId;
|
|
69
71
|
private readonly openedProjectsList;
|
|
70
72
|
private readonly projectListTree;
|
|
71
73
|
private readonly templateListTree;
|
|
74
|
+
private readonly foldersTree;
|
|
72
75
|
private readonly sharingOutboxTree;
|
|
73
76
|
private readonly sharingStateTree;
|
|
74
|
-
private readonly
|
|
77
|
+
private readonly availableSharesTree;
|
|
75
78
|
readonly blockRegistryProvider: V2RegistryProvider;
|
|
76
79
|
/** Contains a reactive list of projects along with their meta information. */
|
|
77
80
|
readonly projectList: ComputableStableDefined<ProjectListEntry$1[]>;
|
|
78
81
|
/** Contains a reactive list of stored templates along with their labels and provenance. */
|
|
79
82
|
readonly templateList: ComputableStableDefined<TemplateListEntry[]>;
|
|
80
|
-
/**
|
|
81
|
-
*
|
|
83
|
+
/** The folder tree and the project list, already joined. The desktop reads this and never
|
|
84
|
+
* the two halves, so it cannot render a list and a tree that are one refresh apart. */
|
|
85
|
+
readonly folders: ComputableStableDefined<FoldersListing>;
|
|
86
|
+
/** Reactive view of the donor's outbox — the shares this user has created. */
|
|
82
87
|
outgoingShares: Computable<OutgoingShare[] | undefined>;
|
|
83
|
-
/**
|
|
88
|
+
/** Shares granted to this user, hidden ones included and flagged as such. Fed by the
|
|
84
89
|
* shared-resource discovery tree. */
|
|
85
|
-
|
|
86
|
-
/** Internal: the
|
|
87
|
-
* discovery tree as {@link
|
|
90
|
+
availableShares: Computable<AvailableShare[] | undefined>;
|
|
91
|
+
/** Internal: the recipient's currently-live envelopes, read from the same shared-resource
|
|
92
|
+
* discovery tree as {@link availableShares}. The single source {@link copyShare} resolves
|
|
88
93
|
* live envelopes from — no second discovery path. */
|
|
89
94
|
private readonly liveEnvelopes;
|
|
90
95
|
readonly pl: PlClient;
|
|
@@ -109,7 +114,7 @@ export declare class MiddleLayer {
|
|
|
109
114
|
/**
|
|
110
115
|
* Whether the connected backend supports project sharing. Synthetic — computed
|
|
111
116
|
* in the middle layer from the backend capabilities the share flow needs (the
|
|
112
|
-
* cross-color field-reference relaxation
|
|
117
|
+
* cross-color field-reference relaxation a copy out of a share rests on). It can absorb
|
|
113
118
|
* additional required capabilities later without a UI change.
|
|
114
119
|
*/
|
|
115
120
|
get sharingSupported(): boolean;
|
|
@@ -147,10 +152,84 @@ export declare class MiddleLayer {
|
|
|
147
152
|
/** Resolves a ProjectId to a signed SignedResourceId.
|
|
148
153
|
* Uses LRU cache with TX-scan fallback. */
|
|
149
154
|
private resolveProjectId;
|
|
150
|
-
/**
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
155
|
+
/**
|
|
156
|
+
* Creates a project with initial state and adds it to project list.
|
|
157
|
+
*
|
|
158
|
+
* `folder` is where it lands, placed in the transaction that creates it so the project never
|
|
159
|
+
* shows up at the top level first. Left out, or naming a folder that is gone, it lands at the
|
|
160
|
+
* top level.
|
|
161
|
+
*/
|
|
162
|
+
createProject(meta: ProjectMeta, folder?: FolderId): Promise<ProjectId$1>;
|
|
163
|
+
/**
|
|
164
|
+
* Updates the project metadata fields the caller names, leaving the others as they are.
|
|
165
|
+
*
|
|
166
|
+
* A patch rather than a replacement because the label and the description are edited from two
|
|
167
|
+
* different places: a rename that carried a stale description alongside the new name would
|
|
168
|
+
* undo a description edit that happened in between, and the reverse.
|
|
169
|
+
*
|
|
170
|
+
* The label is stored trimmed, and it goes into the namespace folders share, so a label
|
|
171
|
+
* already carried by something else inside the same folder is refused rather than written — a
|
|
172
|
+
* human typed it, and a name that silently becomes a different name is worse than one that is
|
|
173
|
+
* turned down. The check and the write share one transaction, so two renames racing for the
|
|
174
|
+
* same name cannot both win. Duplicates an account already holds are tolerated and never
|
|
175
|
+
* rewritten; see the name check of {@link openFoldersTx}.
|
|
176
|
+
*/
|
|
177
|
+
setProjectMeta(id: ProjectId$1, meta: Partial<ProjectMeta>, author?: AuthorMarker): Promise<void>;
|
|
178
|
+
private get foldersRids();
|
|
179
|
+
/** Creates a folder inside `parent`, or at the top level, and returns its id. A name already
|
|
180
|
+
* used there is rejected. */
|
|
181
|
+
createFolder(name: string, parent?: FolderId): Promise<FolderId>;
|
|
182
|
+
/** Renames a folder. A name already used beside it is rejected. */
|
|
183
|
+
renameFolder(folder: FolderId, name: string): Promise<void>;
|
|
184
|
+
/** Sets what a folder says about itself; blank clears it. Descriptions are in no namespace, so
|
|
185
|
+
* nothing is refused here. */
|
|
186
|
+
setFolderDescription(folder: FolderId, description: string): Promise<void>;
|
|
187
|
+
/** The plan a move would produce — every item and the name it ends up with. Shown for
|
|
188
|
+
* confirmation, then handed back to {@link moveFolderItems} unchanged. */
|
|
189
|
+
previewFoldersMove(items: readonly FoldersItem[], destination?: FolderId): Promise<FoldersMovePlanResult>;
|
|
190
|
+
/**
|
|
191
|
+
* Moves folders, projects and templates into one destination.
|
|
192
|
+
*
|
|
193
|
+
* The plan is recomputed inside the write transaction and the move commits only when it is
|
|
194
|
+
* identical to `confirmedPlan`; otherwise nothing is written and the fresh plan comes back to
|
|
195
|
+
* be confirmed again.
|
|
196
|
+
*/
|
|
197
|
+
moveFolderItems(items: readonly FoldersItem[], destination: FolderId | undefined, confirmedPlan: FoldersMovePlan): Promise<FoldersMoveOutcome>;
|
|
198
|
+
/** What deleting a folder would destroy: the subtree of folders, and everything in it. */
|
|
199
|
+
previewFolderDeletion(folder: FolderId): Promise<FoldersRemovalPlanResult>;
|
|
200
|
+
/** Deletes a folder, every folder inside it, and every project and template held anywhere in
|
|
201
|
+
* that subtree.
|
|
202
|
+
* Refused as `needs-confirmation` until the removal it returns is passed back as
|
|
203
|
+
* `confirmedRemoval`, and as `plan-changed` if the subtree has changed since. */
|
|
204
|
+
deleteFolder(folder: FolderId, confirmedRemoval?: FoldersRemoval): Promise<FoldersRemovalOutcome>;
|
|
205
|
+
/**
|
|
206
|
+
* Replaces a folder document this build cannot read — one written by a newer version, or one
|
|
207
|
+
* nothing here can parse — with an empty one. Every folder is gone afterwards; every project and
|
|
208
|
+
* template stays and shows at the top level. Refused while the document can be read.
|
|
209
|
+
*/
|
|
210
|
+
resetFolders(): Promise<void>;
|
|
211
|
+
/**
|
|
212
|
+
* Duplicates a folder and everything under it: the folders inside, a duplicate of every project
|
|
213
|
+
* in them, and a copy of every template.
|
|
214
|
+
*
|
|
215
|
+
* The copy lands beside the source, so only its root needs a name of its own — `X (Copy)`.
|
|
216
|
+
* Nothing inside is renamed: names are compared among siblings, and a copied folder's children
|
|
217
|
+
* are only ever compared with each other, where they came in distinct already.
|
|
218
|
+
*
|
|
219
|
+
* The subtree is read first and rebuilt in one write transaction, so the folders and everything
|
|
220
|
+
* they hold appear together or not at all.
|
|
221
|
+
*/
|
|
222
|
+
duplicateFolder(folder: FolderId): Promise<void>;
|
|
223
|
+
/**
|
|
224
|
+
* A folder subtree as a copy needs it: the folders under ids local to this read, the key the
|
|
225
|
+
* subtree's root goes by, the resource of every project in them, every template read whole, and
|
|
226
|
+
* the folder the source sits in — which is where a duplicate lands.
|
|
227
|
+
*
|
|
228
|
+
* Read in a transaction of its own, before the write that copies it: every template is a read,
|
|
229
|
+
* and none of it has to be atomic with the copying, because a project or a template that
|
|
230
|
+
* disappears meanwhile fails that write on its own.
|
|
231
|
+
*/
|
|
232
|
+
private loadFolderSubtree;
|
|
154
233
|
/**
|
|
155
234
|
* Renders a project as a `template-v1` YAML document, or reports every reason it
|
|
156
235
|
* cannot be — the backing call for an "Export Project as Template…" command.
|
|
@@ -240,23 +319,40 @@ export declare class MiddleLayer {
|
|
|
240
319
|
* A block that cannot be expressed as a template entry stores nothing at all, and every
|
|
241
320
|
* such block is reported — fixing an unexportable project takes one pass, not one per block.
|
|
242
321
|
*
|
|
322
|
+
* The template lands beside its project, and is named by the rule everything there is named
|
|
323
|
+
* by: a label the caller chose is stored trimmed and refused if it is already used there, and
|
|
324
|
+
* without one the project's own label is taken — suffixed, since the project itself already
|
|
325
|
+
* answers to it.
|
|
326
|
+
*
|
|
327
|
+
* The template's description is the one the caller gives, stored trimmed; blank means none.
|
|
328
|
+
* Without one the template is stored undescribed, whatever the project's own description says.
|
|
329
|
+
*
|
|
243
330
|
* @param projectId project to snapshot
|
|
244
|
-
* @param label label for the template; defaults to the project's own label
|
|
331
|
+
* @param label label for the template; defaults to the project's own label, made free
|
|
332
|
+
* @param description what the template is for; blank or absent stores none
|
|
333
|
+
*/
|
|
334
|
+
saveProjectAsTemplate(projectId: ProjectId$1, label?: string, description?: string): Promise<SaveProjectAsTemplateOutcome>;
|
|
335
|
+
/**
|
|
336
|
+
* Changes a template's label. The stored document is immutable and stays untouched —
|
|
337
|
+
* improving a template means saving a new one.
|
|
338
|
+
*
|
|
339
|
+
* The label is stored trimmed. It is in the namespace folders, projects and templates share,
|
|
340
|
+
* so one already used beside the template is refused, in the transaction that writes it.
|
|
245
341
|
*/
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
*
|
|
249
|
-
|
|
342
|
+
renameTemplate(id: TemplateId$1, label: string): Promise<void>;
|
|
343
|
+
/** Sets what a stored template says about itself; blank clears it. The stored document is not
|
|
344
|
+
* touched, so it stays byte-identical. */
|
|
345
|
+
setTemplateDescription(id: TemplateId$1, description: string): Promise<void>;
|
|
250
346
|
/** Permanently deletes a template from the template list. */
|
|
251
|
-
deleteTemplate(id: TemplateId): Promise<void>;
|
|
347
|
+
deleteTemplate(id: TemplateId$1): Promise<void>;
|
|
252
348
|
/** Reads a stored template: its document plus what was true when it was taken. */
|
|
253
|
-
getTemplateData(id: TemplateId): Promise<StoredTemplateData>;
|
|
349
|
+
getTemplateData(id: TemplateId$1): Promise<StoredTemplateData>;
|
|
254
350
|
/**
|
|
255
351
|
* Where each entry of a stored template would get its block from, and which entries have
|
|
256
352
|
* nowhere to get one — resolution creates nothing, so this is the preview a UI shows before
|
|
257
353
|
* offering Apply. {@link createProjectFromTemplate} runs the same stage itself.
|
|
258
354
|
*/
|
|
259
|
-
resolveTemplate(id: TemplateId, provider: BlockPackProvider, options?: {
|
|
355
|
+
resolveTemplate(id: TemplateId$1, provider: BlockPackProvider, options?: {
|
|
260
356
|
allowUnstable?: boolean;
|
|
261
357
|
}): Promise<TemplateResolveOutcome>;
|
|
262
358
|
/**
|
|
@@ -269,11 +365,14 @@ export declare class MiddleLayer {
|
|
|
269
365
|
* @param id template to apply
|
|
270
366
|
* @param label label for the new project
|
|
271
367
|
* @param provider where each entry's block comes from
|
|
272
|
-
* @param options `allowUnstable` widens resolution to pre-release implementations
|
|
368
|
+
* @param options `allowUnstable` widens resolution to pre-release implementations; `folder` is
|
|
369
|
+
* where the new project lands
|
|
273
370
|
*/
|
|
274
|
-
createProjectFromTemplate(id: TemplateId, label: string, provider: BlockPackProvider, options?: {
|
|
371
|
+
createProjectFromTemplate(id: TemplateId$1, label: string, provider: BlockPackProvider, options?: {
|
|
275
372
|
allowUnstable?: boolean;
|
|
276
373
|
author?: AuthorMarker;
|
|
374
|
+
/** Where the project lands; the top level when left out. */
|
|
375
|
+
folder?: FolderId;
|
|
277
376
|
}): Promise<CreateProjectFromTemplateOutcome>;
|
|
278
377
|
/** Resolves a TemplateId to a signed SignedResourceId.
|
|
279
378
|
* Uses LRU cache with TX-scan fallback. */
|
|
@@ -282,62 +381,39 @@ export declare class MiddleLayer {
|
|
|
282
381
|
* destruction of all attached objects, like files, analysis results etc. */
|
|
283
382
|
deleteProject(id: ProjectId$1): Promise<void>;
|
|
284
383
|
/**
|
|
285
|
-
* Duplicates an existing project and adds the copy to this user's project list
|
|
384
|
+
* Duplicates an existing project and adds the copy to this user's project list, beside the
|
|
385
|
+
* project it was copied from.
|
|
386
|
+
*
|
|
387
|
+
* Without `rename` the copy is named by the rule everything beside the source is named by: the
|
|
388
|
+
* source's own label, suffixed to be free there — `X (Copy)`. The name is chosen inside the
|
|
389
|
+
* transaction that creates the copy, against the tree that transaction reads.
|
|
286
390
|
*
|
|
287
391
|
* @param srcProjectId - project id of the project to duplicate
|
|
288
392
|
* @param rename - optional function that receives the source label and all existing
|
|
289
|
-
* project labels (read within the same transaction), and returns the label for the copy
|
|
393
|
+
* project labels (read within the same transaction), and returns the label for the copy.
|
|
394
|
+
* A label chosen this way is the caller's and is never suffixed: when it is already taken
|
|
395
|
+
* beside the source, the copy lands at the top level instead.
|
|
290
396
|
*/
|
|
291
397
|
duplicateProject(srcProjectId: ProjectId$1, rename?: (previousLabel: string, existingLabels: string[]) => string): Promise<ProjectId$1>;
|
|
292
398
|
/**
|
|
293
399
|
* Duplicates a project into another user's root, minted in the TARGET user's color so the target
|
|
294
400
|
* owns it. Sibling of {@link duplicateProject}, but writes into a different root. The source
|
|
295
401
|
* project (on the current client root) is referenced cross-color for its block data, kept alive
|
|
296
|
-
* by refcounting, exactly like
|
|
402
|
+
* by refcounting, exactly like a project copied out of a share. Works both ways: pull (while
|
|
297
403
|
* impersonating a user, copy their project to yourself) and push (from your own root, copy a
|
|
298
404
|
* project to a user). Admin cross-root op; requires the crossTreeRefs:v1 backend capability.
|
|
299
405
|
*/
|
|
300
406
|
duplicateProjectToUser(srcProjectId: ProjectId$1, targetLogin: string, rename?: (previousLabel: string, existingLabels: string[]) => string): Promise<void>;
|
|
301
407
|
/**
|
|
302
|
-
* Shares the given projects (Copy & Share)
|
|
303
|
-
*
|
|
304
|
-
* and the outbox is left as it was.
|
|
305
|
-
*
|
|
306
|
-
* Two variants (see {@link ShareProjectsOptions}):
|
|
307
|
-
* - `{ recipients }` — one writable grant per named recipient; the envelope expires after the
|
|
308
|
-
* default TTL (`sharedAt + envelopeTtlMs`).
|
|
309
|
-
* - `{ everyone: true }` — one make-public grant (backend rewrites the target to the
|
|
310
|
-
* everyone-user); the envelope's `expiresAt` is `null`, so it never expires.
|
|
408
|
+
* Shares the given projects (Copy & Share): snapshots them into one envelope, in the transaction
|
|
409
|
+
* {@link shareEnvelope} describes.
|
|
311
410
|
*
|
|
312
411
|
* v1 always passes `mode: "copy"`.
|
|
313
412
|
*/
|
|
314
|
-
shareProjects(projectIds: ProjectId$1[], options: ShareProjectsOptions): Promise<
|
|
315
|
-
/**
|
|
316
|
-
* Mints a fresh share: snapshots the projects into one new envelope (a fresh shareId),
|
|
317
|
-
* supersedes prior shares of the same project, and grants it — all in one atomic write
|
|
318
|
-
* transaction, so a failed grant rolls the whole thing back and the outbox is left as it was.
|
|
319
|
-
* The everyone-refresh path is the {@link changeShare} branch of {@link shareProjects}; this is
|
|
320
|
-
* the mint-a-new-envelope branch.
|
|
321
|
-
*/
|
|
322
|
-
private createNewShare;
|
|
323
|
-
/**
|
|
324
|
-
* Grants one freshly built envelope inside the transaction that created it: a single make-public
|
|
325
|
-
* grant for an everyone-share (empty/ignored target, ANY_AUTHORISED — the backend rewrites the
|
|
326
|
-
* target to the everyone-user, gated by role + permission ceiling), or one grant per named
|
|
327
|
-
* recipient.
|
|
328
|
-
*
|
|
329
|
-
* `writable` is not a preference. A project pack needs a writable grant because accepting copies
|
|
330
|
-
* the snapshots out of the envelope, and the cross-color attach rule permits that only to a
|
|
331
|
-
* writable grant holder. A template share copies nothing — the document sits in the envelope's
|
|
332
|
-
* own immutable data — so it is granted read-only, and must be: a writable everyone-grant would
|
|
333
|
-
* hand every user on the server write access to the envelope.
|
|
334
|
-
*/
|
|
335
|
-
private grantShareEnvelope;
|
|
413
|
+
shareProjects(projectIds: ProjectId$1[], options: ShareProjectsOptions): Promise<ShareOutcome>;
|
|
336
414
|
/**
|
|
337
415
|
* Shares one stored template. The envelope carries the document itself, so there is no project
|
|
338
416
|
* snapshot and no resource for the recipient to copy out — which is why the grant is read-only.
|
|
339
|
-
* The cost of that is the donor's receipt: nobody can write an acceptance onto a read-only
|
|
340
|
-
* envelope, so a template share never reports who accepted it.
|
|
341
417
|
*
|
|
342
418
|
* Nothing about the document is checked: a stored template is shareable by virtue of existing.
|
|
343
419
|
* An entry the recipient cannot resolve — a block installed from a folder on the sender's
|
|
@@ -347,49 +423,58 @@ export declare class MiddleLayer {
|
|
|
347
423
|
* @param id template to share
|
|
348
424
|
* @param options recipients XOR everyone, plus the title recipients see
|
|
349
425
|
*/
|
|
350
|
-
shareTemplate(id: TemplateId, options: ShareTemplateOptions): Promise<
|
|
351
|
-
/**
|
|
352
|
-
*
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
*
|
|
356
|
-
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
*
|
|
363
|
-
*
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
*
|
|
368
|
-
*
|
|
369
|
-
*
|
|
370
|
-
*
|
|
371
|
-
*
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
*/
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
*
|
|
386
|
-
* everyone-share
|
|
387
|
-
|
|
388
|
-
|
|
426
|
+
shareTemplate(id: TemplateId$1, options: ShareTemplateOptions): Promise<ShareOutcome>;
|
|
427
|
+
/**
|
|
428
|
+
* Shares one folder and everything under it: the subtree's folders, every project in them
|
|
429
|
+
* snapshotted, and every template carried whole.
|
|
430
|
+
*
|
|
431
|
+
* The grant is writable, because a folder holding projects is copied out of the envelope the
|
|
432
|
+
* way a project pack is. An everyone-share of a folder therefore hands every user on the server
|
|
433
|
+
* write access to the envelope — the same trade a project share already makes.
|
|
434
|
+
*
|
|
435
|
+
* Folder ids do not travel. What the recipient gets is the shape of the subtree, rebuilt under
|
|
436
|
+
* a folder of their own choosing with ids their own document mints.
|
|
437
|
+
*
|
|
438
|
+
* @param folder folder to share; everything beneath it goes with it
|
|
439
|
+
* @param options recipients XOR everyone, plus the title recipients see
|
|
440
|
+
*/
|
|
441
|
+
shareFolder(folder: FolderId, options: ShareFolderOptions): Promise<ShareOutcome>;
|
|
442
|
+
/**
|
|
443
|
+
* The one transaction every share is made in: the shares named by `options.replace` are
|
|
444
|
+
* dropped, the envelope `build` makes is created, and it is granted — all at once, so a failed
|
|
445
|
+
* grant rolls the whole thing back and the outbox is left as it was.
|
|
446
|
+
*
|
|
447
|
+
* A share with named recipients grants each of them and expires after the default TTL
|
|
448
|
+
* (`sharedAt + envelopeTtlMs`). A share with everyone is one make-public grant, and its
|
|
449
|
+
* `expiresAt` is `null`, so it never expires.
|
|
450
|
+
*/
|
|
451
|
+
private shareEnvelope;
|
|
452
|
+
/**
|
|
453
|
+
* Detaches the named shares from the donor's outbox inside the caller's transaction, so a
|
|
454
|
+
* replacement and the shares it supersedes land together or not at all.
|
|
455
|
+
*
|
|
456
|
+
* A share that no longer resolves is skipped rather than reported: the caller names shares the
|
|
457
|
+
* author saw a moment ago, and one revoked meanwhile is already in the wanted state.
|
|
458
|
+
*/
|
|
459
|
+
private dropShares;
|
|
460
|
+
/**
|
|
461
|
+
* Grants one freshly built envelope inside the transaction that created it: a single make-public
|
|
462
|
+
* grant for an everyone-share (empty/ignored target, ANY_AUTHORISED — the backend rewrites the
|
|
463
|
+
* target to the everyone-user, gated by role + permission ceiling), or one grant per named
|
|
464
|
+
* recipient.
|
|
465
|
+
*
|
|
466
|
+
* `writable` is not a preference. A project pack needs a writable grant because a copy out of
|
|
467
|
+
* it takes the snapshots out of the envelope, and the cross-color attach rule permits that only
|
|
468
|
+
* to a writable grant holder. A template share copies nothing — the document sits in the
|
|
469
|
+
* envelope's own immutable data — so it is granted read-only, and must be: a writable
|
|
470
|
+
* everyone-grant would hand every user on the server write access to the envelope.
|
|
471
|
+
*/
|
|
472
|
+
private grantShareEnvelope;
|
|
389
473
|
/**
|
|
390
474
|
* Revokes and deletes an outgoing share for all recipients: detaches and deletes the envelope, and
|
|
391
|
-
* its grants are revoked along with it.
|
|
392
|
-
* the
|
|
475
|
+
* its grants are revoked along with it. Copies recipients already took out of it are unaffected
|
|
476
|
+
* (ref-counting keeps the resources they point at alive). Idempotent — revoking a share that is
|
|
477
|
+
* already gone is a no-op.
|
|
393
478
|
*/
|
|
394
479
|
revokeShare(shareId: ShareId): Promise<void>;
|
|
395
480
|
/**
|
|
@@ -404,35 +489,43 @@ export declare class MiddleLayer {
|
|
|
404
489
|
* the envelope's logical `shareId`.
|
|
405
490
|
*
|
|
406
491
|
* Reads the {@link liveEnvelopes} Computable — the same shared-resource discovery tree that
|
|
407
|
-
* feeds {@link
|
|
408
|
-
* `ListUserResources` re-stream on every
|
|
492
|
+
* feeds {@link availableShares}. This is the single discovery mechanism: there is no separate
|
|
493
|
+
* `ListUserResources` re-stream on every copy. `refreshState()` is awaited first so a
|
|
409
494
|
* just-granted envelope is observed (the tree's discovery poll may otherwise lag a freshly
|
|
410
495
|
* landed grant). The tree is gRPC-only, so this is empty on a REST-connected client.
|
|
411
496
|
*/
|
|
412
497
|
private resolveLiveEnvelopes;
|
|
413
498
|
/**
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
*
|
|
419
|
-
*
|
|
420
|
-
*
|
|
421
|
-
*
|
|
422
|
-
*
|
|
423
|
-
*
|
|
424
|
-
*
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
499
|
+
* Copies what one or more shares carry into this user's own tree, optionally into a folder.
|
|
500
|
+
*
|
|
501
|
+
* A share is a shelf, not an invitation: copying takes nothing off it and records no decision,
|
|
502
|
+
* so the same share can be copied from again, by this user or anyone else it was granted to.
|
|
503
|
+
* What a copy produces depends on the payload — a pack of projects lands in the project list,
|
|
504
|
+
* a template among their templates, building nothing until the recipient applies it, and a
|
|
505
|
+
* folder is rebuilt whole with everything it held.
|
|
506
|
+
*
|
|
507
|
+
* Names are chosen against the destination folder, since that is where the uniqueness rule
|
|
508
|
+
* applies, and a project and a template follow the same rule. A destination deleted meanwhile
|
|
509
|
+
* fails the copy rather than spilling it at the top level.
|
|
510
|
+
* Per-share failures (a revoked envelope, say) are collected rather than short-circuited, so
|
|
511
|
+
* one dead share does not cost the others.
|
|
512
|
+
*/
|
|
513
|
+
copyShare(shareIds: ShareId[], destination?: FolderId): Promise<{
|
|
514
|
+
projects: ProjectId$1[];
|
|
515
|
+
templates: TemplateId$1[];
|
|
429
516
|
failed: {
|
|
430
517
|
shareId: ShareId;
|
|
431
518
|
error: string;
|
|
432
519
|
}[];
|
|
433
520
|
}>;
|
|
434
|
-
/**
|
|
435
|
-
|
|
521
|
+
/**
|
|
522
|
+
* Puts a share out of this user's sight. Private to them and reversible with
|
|
523
|
+
* {@link unhideShare}: nothing is deleted, the donor is not told, and what was already copied
|
|
524
|
+
* out of it is unaffected.
|
|
525
|
+
*/
|
|
526
|
+
hideShare(shareId: ShareId): Promise<void>;
|
|
527
|
+
/** Brings a hidden share back into this user's list. */
|
|
528
|
+
unhideShare(shareId: ShareId): Promise<void>;
|
|
436
529
|
private static readonly EnvelopeCleanupIntervalMs;
|
|
437
530
|
private envelopeCleanupTimer;
|
|
438
531
|
/** On ML start and every 6h, delete envelopes whose immutable `expiresAt` has passed. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middle_layer.d.ts","names":[],"sources":["../../src/middle_layer/middle_layer.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"middle_layer.d.ts","names":[],"sources":["../../src/middle_layer/middle_layer.ts"],"mappings":"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"}
|