@milaboratories/pl-middle-layer 1.43.8 → 1.43.10

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.
@@ -112,12 +112,16 @@ export class Project {
112
112
  this.activeConfigs = activeConfigs(projectTree.entry(), env);
113
113
  }
114
114
 
115
+ get projectLockId(): string {
116
+ return 'project:' + this.rid.toString();
117
+ }
118
+
115
119
  private async refreshLoop(): Promise<void> {
116
120
  while (!this.destroyed) {
117
121
  try {
118
122
  await withProject(this.env.projectHelper, this.env.pl, this.rid, (prj) => {
119
123
  prj.doRefresh(this.env.ops.stagingRenderingRate);
120
- });
124
+ }, { name: 'doRefresh', lockId: this.projectLockId });
121
125
  await this.activeConfigs.getValue();
122
126
  await setTimeout(this.env.ops.projectRefreshInterval, this.abortController.signal);
123
127
 
@@ -165,8 +169,8 @@ export class Project {
165
169
  const preparedBp = await this.env.bpPreparer.prepare(blockPackSpec);
166
170
  const blockCfgContainer = await this.env.bpPreparer.getBlockConfigContainer(blockPackSpec);
167
171
  const blockCfg = extractConfig(blockCfgContainer); // full content of this var should never be persisted
168
- await withProjectAuthored(this.env.projectHelper, this.env.pl, this.rid, author, (mut) =>
169
- mut.addBlock(
172
+ await withProjectAuthored(this.env.projectHelper, this.env.pl, this.rid, author, (mut) => {
173
+ return mut.addBlock(
170
174
  {
171
175
  id: blockId,
172
176
  label: blockLabel,
@@ -178,12 +182,17 @@ export class Project {
178
182
  blockPack: preparedBp,
179
183
  },
180
184
  before,
181
- ),
182
- { retryOptions: {
183
- ...DefaultRetryOptions,
184
- backoffMultiplier: DefaultRetryOptions.backoffMultiplier * 1.1,
185
- } },
186
- );
185
+ );
186
+ },
187
+ {
188
+ retryOptions: {
189
+ ...DefaultRetryOptions,
190
+ backoffMultiplier: DefaultRetryOptions.backoffMultiplier * 1.1,
191
+ },
192
+ name: 'addBlock',
193
+ lockId: this.projectLockId,
194
+ });
195
+
187
196
  await this.projectTree.refreshState();
188
197
 
189
198
  return blockId;
@@ -209,6 +218,7 @@ export class Project {
209
218
  ): Promise<string> {
210
219
  await withProjectAuthored(this.env.projectHelper, this.env.pl, this.rid, author, (mut) =>
211
220
  mut.duplicateBlock(originalBlockId, newBlockId, before),
221
+ { name: 'duplicateBlock', lockId: this.projectLockId },
212
222
  );
213
223
  await this.projectTree.refreshState();
214
224
 
@@ -233,13 +243,14 @@ export class Project {
233
243
  preparedBp,
234
244
  resetArgs ? { args: blockCfg.initialArgs, uiState: blockCfg.initialUiState } : undefined,
235
245
  ),
246
+ { name: 'updateBlockPack', lockId: this.projectLockId },
236
247
  );
237
248
  await this.projectTree.refreshState();
238
249
  }
239
250
 
240
251
  /** Deletes a block with all associated data. */
241
252
  public async deleteBlock(blockId: string, author?: AuthorMarker): Promise<void> {
242
- await withProjectAuthored(this.env.projectHelper, this.env.pl, this.rid, author, (mut) => mut.deleteBlock(blockId));
253
+ await withProjectAuthored(this.env.projectHelper, this.env.pl, this.rid, author, (mut) => mut.deleteBlock(blockId), { name: 'deleteBlock', lockId: this.projectLockId });
243
254
  this.navigationStates.deleteBlock(blockId);
244
255
  await this.projectTree.refreshState();
245
256
  }
@@ -254,10 +265,10 @@ export class Project {
254
265
  await withProjectAuthored(this.env.projectHelper, this.env.pl, this.rid, author, (mut) => {
255
266
  const currentStructure = mut.structure;
256
267
  if (currentStructure.groups.length !== 1)
257
- throw new Error('Unexpected project structure, non-sinular block group');
268
+ throw new Error('Unexpected project structure, non-singular block group');
258
269
  const currentGroup = currentStructure.groups[0];
259
270
  if (currentGroup.blocks.length !== blocks.length)
260
- throw new Error(`Lengh mismatch: ${currentGroup.blocks.length} !== ${blocks.length}`);
271
+ throw new Error(`Length mismatch: ${currentGroup.blocks.length} !== ${blocks.length}`);
261
272
  if (new Set<string>(blocks).size !== blocks.length) throw new Error(`Repeated block ids`);
262
273
  const newStructure: ProjectStructure = {
263
274
  groups: [
@@ -273,7 +284,7 @@ export class Project {
273
284
  ],
274
285
  };
275
286
  mut.updateStructure(newStructure);
276
- });
287
+ }, { name: 'reorderBlocks', lockId: this.projectLockId });
277
288
  await this.projectTree.refreshState();
278
289
  }
279
290
 
@@ -283,7 +294,7 @@ export class Project {
283
294
  * stale state.
284
295
  * */
285
296
  public async runBlock(blockId: string): Promise<void> {
286
- await withProject(this.env.projectHelper, this.env.pl, this.rid, (mut) => mut.renderProduction([blockId], true));
297
+ await withProject(this.env.projectHelper, this.env.pl, this.rid, (mut) => mut.renderProduction([blockId], true), { name: 'runBlock', lockId: this.projectLockId });
287
298
  await this.projectTree.refreshState();
288
299
  }
289
300
 
@@ -293,7 +304,7 @@ export class Project {
293
304
  * calculated.
294
305
  * */
295
306
  public async stopBlock(blockId: string): Promise<void> {
296
- await withProject(this.env.projectHelper, this.env.pl, this.rid, (mut) => mut.stopProduction(blockId));
307
+ await withProject(this.env.projectHelper, this.env.pl, this.rid, (mut) => mut.stopProduction(blockId), { name: 'stopBlock', lockId: this.projectLockId });
297
308
  await this.projectTree.refreshState();
298
309
  }
299
310
 
@@ -314,7 +325,7 @@ export class Project {
314
325
  public async setBlockArgs(blockId: string, args: unknown, author?: AuthorMarker) {
315
326
  await withProjectAuthored(this.env.projectHelper, this.env.pl, this.rid, author, (mut) =>
316
327
  mut.setStates([{ blockId, args }]),
317
- );
328
+ { name: 'setBlockArgs', lockId: this.projectLockId });
318
329
  await this.projectTree.refreshState();
319
330
  }
320
331
 
@@ -327,7 +338,7 @@ export class Project {
327
338
  public async setUiState(blockId: string, uiState: unknown, author?: AuthorMarker) {
328
339
  await withProjectAuthored(this.env.projectHelper, this.env.pl, this.rid, author, (mut) =>
329
340
  mut.setStates([{ blockId, uiState }]),
330
- );
341
+ { name: 'setUiState', lockId: this.projectLockId });
331
342
  await this.projectTree.refreshState();
332
343
  }
333
344
 
@@ -353,7 +364,7 @@ export class Project {
353
364
  ) {
354
365
  await withProjectAuthored(this.env.projectHelper, this.env.pl, this.rid, author, (mut) => {
355
366
  mut.setStates([{ blockId, args, uiState }]);
356
- });
367
+ }, { name: 'setBlockArgsAndUiState', lockId: this.projectLockId });
357
368
  await this.projectTree.refreshState();
358
369
  }
359
370
 
@@ -361,7 +372,7 @@ export class Project {
361
372
  public async setBlockSettings(blockId: string, newValue: BlockSettings) {
362
373
  await withProjectAuthored(this.env.projectHelper, this.env.pl, this.rid, undefined, (mut) => {
363
374
  mut.setBlockSettings(blockId, newValue);
364
- });
375
+ }, { name: 'setBlockSettings' });
365
376
  await this.projectTree.refreshState();
366
377
  }
367
378
 
@@ -379,7 +390,7 @@ export class Project {
379
390
  const config = extractConfig(cachedDeserialize<BlockPackInfo>(notEmpty(bpData.data)).config);
380
391
  await withProjectAuthored(this.env.projectHelper, tx, this.rid, author, (prj) => {
381
392
  prj.setStates([{ blockId, args: config.initialArgs, uiState: config.initialUiState }]);
382
- });
393
+ }, { name: 'resetBlockArgsAndUiState', lockId: this.projectLockId });
383
394
  await tx.commit();
384
395
  });
385
396
  await this.projectTree.refreshState();
@@ -484,7 +495,7 @@ export class Project {
484
495
  await applyProjectMigrations(env.pl, rid);
485
496
 
486
497
  // Doing a no-op mutation to apply all migration and schema fixes
487
- await withProject(env.projectHelper, env.pl, rid, (_) => {});
498
+ await withProject(env.projectHelper, env.pl, rid, (_) => {}, { name: 'init' });
488
499
 
489
500
  // Loading project tree
490
501
  const projectTree = await SynchronizedTreeState.init(
@@ -1349,8 +1349,9 @@ export async function withProject<T>(
1349
1349
  txOrPl: PlTransaction | PlClient,
1350
1350
  rid: ResourceId,
1351
1351
  cb: (p: ProjectMutator) => T | Promise<T>,
1352
+ ops?: Partial<TxOps>,
1352
1353
  ): Promise<T> {
1353
- return withProjectAuthored(projectHelper, txOrPl, rid, undefined, cb);
1354
+ return withProjectAuthored(projectHelper, txOrPl, rid, undefined, cb, ops);
1354
1355
  }
1355
1356
 
1356
1357
  export async function withProjectAuthored<T>(
@@ -1362,7 +1363,7 @@ export async function withProjectAuthored<T>(
1362
1363
  ops: Partial<TxOps> = {},
1363
1364
  ): Promise<T> {
1364
1365
  if (txOrPl instanceof PlClient) {
1365
- return await txOrPl.withWriteTx('ProjectAction', async (tx) => {
1366
+ return await txOrPl.withWriteTx('ProjectAction' + (ops.name ? `: ${ops.name}` : ''), async (tx) => {
1366
1367
  const mut = await ProjectMutator.load(projectHelper, tx, rid, author);
1367
1368
  const result = await cb(mut);
1368
1369
  if (!mut.wasModified)