@timeax/digital-service-engine 0.3.1 → 0.3.3

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.
@@ -37,6 +37,7 @@ __export(workspace_exports, {
37
37
  WorkspaceProvider: () => WorkspaceProvider,
38
38
  createMemoryWorkspaceBackend: () => createMemoryWorkspaceBackend,
39
39
  createPollAdapter: () => createPollAdapter,
40
+ deriveSelectionCapabilities: () => deriveSelectionCapabilities,
40
41
  useCanvas: () => useCanvas,
41
42
  useCanvasAPI: () => useCanvasAPI,
42
43
  useCanvasFromBuilder: () => useCanvasFromBuilder,
@@ -151,7 +152,7 @@ function useAuthorsSlice(params) {
151
152
  });
152
153
  const refreshAuthors = React3.useCallback(async () => {
153
154
  setAuthors((s) => ({ ...s, loading: true }));
154
- const res = await backend.authors.refresh(workspaceId);
155
+ const res = await backend.authors.refresh({ workspaceId });
155
156
  if (res.ok) {
156
157
  setAuthors({
157
158
  data: res.value,
@@ -185,21 +186,29 @@ function usePermissionsSlice(params) {
185
186
  loading: false,
186
187
  updatedAt: initialPermissions ? runtime.now() : void 0
187
188
  });
188
- const refreshPermissions = React4.useCallback(async () => {
189
- setPermissions((s) => ({ ...s, loading: true }));
190
- const res = await backend.permissions.refresh(workspaceId, actor);
191
- if (res.ok) {
192
- setPermissions({
193
- data: res.value,
194
- loading: false,
195
- updatedAt: runtime.now()
189
+ const refreshPermissions = React4.useCallback(
190
+ async (params2) => {
191
+ setPermissions((s) => ({ ...s, loading: true }));
192
+ const res = await backend.permissions.refresh({
193
+ workspaceId,
194
+ actorId: actor.id,
195
+ branchId: params2 == null ? void 0 : params2.branchId,
196
+ since: params2 == null ? void 0 : params2.since
196
197
  });
197
- return res;
198
- } else {
199
- setLoadableError2(setPermissions, res.error);
200
- return res;
201
- }
202
- }, [backend.permissions, workspaceId, actor, runtime]);
198
+ if (res.ok) {
199
+ setPermissions({
200
+ data: res.value,
201
+ loading: false,
202
+ updatedAt: runtime.now()
203
+ });
204
+ return res;
205
+ } else {
206
+ setLoadableError2(setPermissions, res.error);
207
+ return res;
208
+ }
209
+ },
210
+ [backend.permissions, workspaceId, actor.id, runtime]
211
+ );
203
212
  const invalidatePermissions = React4.useCallback(() => {
204
213
  setPermissions((s) => ({ ...s, updatedAt: void 0 }));
205
214
  }, []);
@@ -268,7 +277,7 @@ function useBranchesSlice(params) {
268
277
  const refreshBranches = React5.useCallback(async () => {
269
278
  var _a;
270
279
  setBranches((s) => ({ ...s, loading: true }));
271
- const res = await backend.branches.refresh(workspaceId);
280
+ const res = await backend.branches.refresh({ workspaceId });
272
281
  if (!res.ok) {
273
282
  setBranches((s) => ({ ...s, loading: false, error: res.error }));
274
283
  return res;
@@ -303,11 +312,11 @@ function useBranchesSlice(params) {
303
312
  };
304
313
  }
305
314
  setParticipants((s) => ({ ...s, loading: true }));
306
- const res = await backend.access.refreshParticipants(
315
+ const res = await backend.access.refreshParticipants({
307
316
  workspaceId,
308
317
  branchId,
309
- { since: (_b = params2 == null ? void 0 : params2.since) != null ? _b : participants.updatedAt }
310
- );
318
+ since: (_b = params2 == null ? void 0 : params2.since) != null ? _b : participants.updatedAt
319
+ });
311
320
  if (res.ok) {
312
321
  setParticipants({
313
322
  data: res.value,
@@ -622,23 +631,29 @@ function useServicesSlice(params) {
622
631
  loading: false,
623
632
  updatedAt: initialServices ? runtime.now() : void 0
624
633
  });
625
- const refreshServices = React7.useCallback(async () => {
626
- setServices((s) => ({ ...s, loading: true }));
627
- const res = await backend.services.refresh(workspaceId, {
628
- since: services.updatedAt
629
- });
630
- if (!res.ok) {
631
- setLoadableError5(setServices, res.error);
632
- return res;
633
- }
634
- const map = toServiceMap(res.value);
635
- setServices({
636
- data: map != null ? map : {},
637
- loading: false,
638
- updatedAt: runtime.now()
639
- });
640
- return { ok: true, value: map != null ? map : {} };
641
- }, [backend.services, workspaceId, services.updatedAt, runtime]);
634
+ const refreshServices = React7.useCallback(
635
+ async (params2) => {
636
+ var _a;
637
+ setServices((s) => ({ ...s, loading: true }));
638
+ const res = await backend.services.refresh({
639
+ workspaceId,
640
+ branchId: params2 == null ? void 0 : params2.branchId,
641
+ since: (_a = params2 == null ? void 0 : params2.since) != null ? _a : services.updatedAt
642
+ });
643
+ if (!res.ok) {
644
+ setLoadableError5(setServices, res.error);
645
+ return res;
646
+ }
647
+ const map = toServiceMap(res.value);
648
+ setServices({
649
+ data: map != null ? map : {},
650
+ loading: false,
651
+ updatedAt: runtime.now()
652
+ });
653
+ return { ok: true, value: map != null ? map : {} };
654
+ },
655
+ [backend.services, workspaceId, services.updatedAt, runtime]
656
+ );
642
657
  const invalidateServices = React7.useCallback(() => {
643
658
  setServices((s) => ({ ...s, updatedAt: void 0 }));
644
659
  }, []);
@@ -2091,6 +2106,7 @@ function useWorkspaceBoot2(params) {
2091
2106
  setCurrentBranchId,
2092
2107
  refreshAuthors,
2093
2108
  refreshPermissions,
2109
+ refreshPermissionsWithBranch,
2094
2110
  refreshBranches,
2095
2111
  refreshServices,
2096
2112
  refreshParticipants,
@@ -2229,8 +2245,11 @@ function useWorkspaceBoot2(params) {
2229
2245
  const branchId = (_b = resolveActiveBranch(opts == null ? void 0 : opts.branchId)) != null ? _b : opts == null ? void 0 : opts.branchId;
2230
2246
  if ((_c = opts == null ? void 0 : opts.includeWorkspaceData) != null ? _c : true) {
2231
2247
  tasks.push(["authors", refreshAuthors]);
2232
- tasks.push(["permissions", refreshPermissions]);
2233
- tasks.push(["services", refreshServices]);
2248
+ tasks.push([
2249
+ "permissions",
2250
+ () => refreshPermissionsWithBranch(branchId)
2251
+ ]);
2252
+ tasks.push(["services", () => refreshServices(branchId)]);
2234
2253
  }
2235
2254
  if (!branchId) {
2236
2255
  markBranchScopedNoBranch();
@@ -2361,6 +2380,7 @@ function useWorkspaceBoot2(params) {
2361
2380
  refreshComments,
2362
2381
  refreshParticipants,
2363
2382
  refreshPermissions,
2383
+ refreshPermissionsWithBranch,
2364
2384
  refreshPolicies,
2365
2385
  refreshServices,
2366
2386
  refreshSnapshotPointers,
@@ -2620,8 +2640,9 @@ function WorkspaceProvider(props) {
2620
2640
  setCurrentBranchId: branchesSlice.setCurrentBranchId,
2621
2641
  refreshAuthors: authorsSlice.refreshAuthors,
2622
2642
  refreshPermissions: permissionsSlice.refreshPermissions,
2643
+ refreshPermissionsWithBranch: (branchId) => permissionsSlice.refreshPermissions({ branchId }),
2623
2644
  refreshBranches: branchesSlice.refreshBranches,
2624
- refreshServices: servicesSlice.refreshServices,
2645
+ refreshServices: (branchId) => servicesSlice.refreshServices({ branchId }),
2625
2646
  refreshParticipants: (branchId) => branchesSlice.refreshParticipants({ branchId }),
2626
2647
  refreshTemplates: (branchId) => templatesSlice.refreshTemplates({ branchId }),
2627
2648
  refreshSnapshotPointers: (branchId) => snapshotsSlice.refreshSnapshotPointersForBranch(branchId),
@@ -7522,13 +7543,7 @@ function duplicate(ctx, ref, opts = {}) {
7522
7543
  try {
7523
7544
  let newId2 = "";
7524
7545
  ctx.transact("duplicate", () => {
7525
- if (ref.kind === "tag") {
7526
- newId2 = duplicateTag(ctx, ref.id, opts);
7527
- } else if (ref.kind === "field") {
7528
- newId2 = duplicateField(ctx, ref.id, opts);
7529
- } else {
7530
- newId2 = duplicateOption(ctx, ref.fieldId, ref.id, opts);
7531
- }
7546
+ newId2 = duplicateInPlace(ctx, ref, opts);
7532
7547
  });
7533
7548
  return newId2;
7534
7549
  } catch (err) {
@@ -7536,6 +7551,74 @@ function duplicate(ctx, ref, opts = {}) {
7536
7551
  throw err;
7537
7552
  }
7538
7553
  }
7554
+ function duplicateMany(ctx, ids, opts = {}) {
7555
+ const ordered = Array.from(new Set((ids != null ? ids : []).map((id) => String(id))));
7556
+ if (!ordered.length) return [];
7557
+ const snapBefore = ctx.makeSnapshot("duplicateMany:before");
7558
+ try {
7559
+ const created = [];
7560
+ ctx.transact("duplicateMany", () => {
7561
+ var _a, _b, _c;
7562
+ const props = ctx.getProps();
7563
+ const selectedFields = /* @__PURE__ */ new Set();
7564
+ for (const id of ordered) {
7565
+ if (ctx.isFieldId(id) && ((_a = props.fields) != null ? _a : []).some((f) => f.id === id)) {
7566
+ selectedFields.add(id);
7567
+ }
7568
+ }
7569
+ for (const id of ordered) {
7570
+ if (ctx.isTagId(id)) {
7571
+ if (!((_b = ctx.getProps().filters) != null ? _b : []).some((t) => t.id === id)) continue;
7572
+ created.push(
7573
+ duplicateInPlace(ctx, { kind: "tag", id }, opts)
7574
+ );
7575
+ continue;
7576
+ }
7577
+ if (ctx.isFieldId(id)) {
7578
+ if (!((_c = ctx.getProps().fields) != null ? _c : []).some((f) => f.id === id)) continue;
7579
+ created.push(
7580
+ duplicateInPlace(ctx, { kind: "field", id }, opts)
7581
+ );
7582
+ continue;
7583
+ }
7584
+ if (ctx.isOptionId(id)) {
7585
+ const owner = ownerFieldOfOption(ctx.getProps(), id);
7586
+ if (!owner) continue;
7587
+ if (selectedFields.has(owner.fieldId)) continue;
7588
+ created.push(
7589
+ duplicateInPlace(
7590
+ ctx,
7591
+ { kind: "option", fieldId: owner.fieldId, id },
7592
+ opts
7593
+ )
7594
+ );
7595
+ }
7596
+ }
7597
+ });
7598
+ return created;
7599
+ } catch (err) {
7600
+ ctx.loadSnapshot(snapBefore, "undo");
7601
+ throw err;
7602
+ }
7603
+ }
7604
+ function duplicateInPlace(ctx, ref, opts = {}) {
7605
+ if (ref.kind === "tag") {
7606
+ return duplicateTag(ctx, ref.id, opts);
7607
+ }
7608
+ if (ref.kind === "field") {
7609
+ return duplicateField(ctx, ref.id, opts);
7610
+ }
7611
+ return duplicateOption(ctx, ref.fieldId, ref.id, opts);
7612
+ }
7613
+ function ownerFieldOfOption(props, optionId) {
7614
+ var _a, _b;
7615
+ for (const field of (_a = props.fields) != null ? _a : []) {
7616
+ if (((_b = field.options) != null ? _b : []).some((o) => o.id === optionId)) {
7617
+ return { fieldId: field.id };
7618
+ }
7619
+ }
7620
+ return null;
7621
+ }
7539
7622
  function duplicateTag(ctx, tagId, opts) {
7540
7623
  var _a, _b, _c, _d;
7541
7624
  const props = ctx.getProps();
@@ -7822,6 +7905,129 @@ function ensureServiceExists(opts, id) {
7822
7905
  }
7823
7906
 
7824
7907
  // src/react/canvas/editor/editor-nodes.ts
7908
+ var RELATION_MAP_KEYS = [
7909
+ "includes_for_buttons",
7910
+ "excludes_for_buttons",
7911
+ "includes_for_options",
7912
+ "excludes_for_options"
7913
+ ];
7914
+ function stripDeletedIds(ids) {
7915
+ const ordered = Array.from(new Set((ids != null ? ids : []).map((id) => String(id))));
7916
+ return { ordered, set: new Set(ordered) };
7917
+ }
7918
+ function cleanTagRelationsForDeleted(p, deleted) {
7919
+ var _a;
7920
+ for (const t of (_a = p.filters) != null ? _a : []) {
7921
+ if (t.bind_id && deleted.has(String(t.bind_id))) delete t.bind_id;
7922
+ if (t.includes) {
7923
+ const next = t.includes.filter((x) => !deleted.has(String(x)));
7924
+ if (next.length) t.includes = next;
7925
+ else delete t.includes;
7926
+ }
7927
+ if (t.excludes) {
7928
+ const next = t.excludes.filter((x) => !deleted.has(String(x)));
7929
+ if (next.length) t.excludes = next;
7930
+ else delete t.excludes;
7931
+ }
7932
+ }
7933
+ }
7934
+ function cleanFieldBindsForDeleted(p, deleted) {
7935
+ var _a;
7936
+ for (const f of (_a = p.fields) != null ? _a : []) {
7937
+ const bind = f.bind_id;
7938
+ if (!bind) continue;
7939
+ if (Array.isArray(bind)) {
7940
+ const next = bind.filter((x) => !deleted.has(String(x)));
7941
+ if (next.length) f.bind_id = next;
7942
+ else delete f.bind_id;
7943
+ continue;
7944
+ }
7945
+ if (deleted.has(String(bind))) delete f.bind_id;
7946
+ }
7947
+ }
7948
+ function cleanRelationMapsForDeleted(p, deleted) {
7949
+ var _a;
7950
+ for (const key of RELATION_MAP_KEYS) {
7951
+ const map = p[key];
7952
+ if (!map) continue;
7953
+ for (const mapKey of Object.keys(map)) {
7954
+ if (deleted.has(String(mapKey))) {
7955
+ delete map[mapKey];
7956
+ continue;
7957
+ }
7958
+ const next = ((_a = map[mapKey]) != null ? _a : []).filter(
7959
+ (item) => !deleted.has(String(item))
7960
+ );
7961
+ if (next.length) map[mapKey] = next;
7962
+ else delete map[mapKey];
7963
+ }
7964
+ if (!Object.keys(map).length) delete p[key];
7965
+ }
7966
+ }
7967
+ function cleanOrderForTagsForDeleted(p, deleted) {
7968
+ var _a, _b;
7969
+ const map = p.order_for_tags;
7970
+ if (!map) return;
7971
+ const fieldIds = new Set(((_a = p.fields) != null ? _a : []).map((f) => String(f.id)));
7972
+ for (const key of Object.keys(map)) {
7973
+ if (deleted.has(String(key))) {
7974
+ delete map[key];
7975
+ continue;
7976
+ }
7977
+ const next = ((_b = map[key]) != null ? _b : []).filter(
7978
+ (fid) => !deleted.has(String(fid)) && fieldIds.has(String(fid))
7979
+ );
7980
+ if (next.length) map[key] = next;
7981
+ else delete map[key];
7982
+ }
7983
+ if (!Object.keys(map).length) delete p.order_for_tags;
7984
+ }
7985
+ function cleanNoticesForDeleted(p, deleted) {
7986
+ var _a;
7987
+ if (!((_a = p.notices) == null ? void 0 : _a.length)) return;
7988
+ p.notices = p.notices.filter((n) => {
7989
+ const target = n.target;
7990
+ if (!target || target.scope === "global") return true;
7991
+ if (target.scope === "node" && deleted.has(String(target.node_id))) {
7992
+ return false;
7993
+ }
7994
+ return true;
7995
+ });
7996
+ if (!p.notices.length) delete p.notices;
7997
+ }
7998
+ function applyDeleteCleanup(p, deleted) {
7999
+ cleanTagRelationsForDeleted(p, deleted);
8000
+ cleanFieldBindsForDeleted(p, deleted);
8001
+ cleanRelationMapsForDeleted(p, deleted);
8002
+ cleanOrderForTagsForDeleted(p, deleted);
8003
+ cleanNoticesForDeleted(p, deleted);
8004
+ }
8005
+ function removeOptionInPlace(p, optionId) {
8006
+ var _a;
8007
+ const owner = ownerOfOption(p, optionId);
8008
+ if (!owner) return false;
8009
+ const f = ((_a = p.fields) != null ? _a : []).find((x) => x.id === owner.fieldId);
8010
+ if (!(f == null ? void 0 : f.options)) return false;
8011
+ const before = f.options.length;
8012
+ f.options = f.options.filter((o) => o.id !== optionId);
8013
+ return f.options.length !== before;
8014
+ }
8015
+ function removeFieldInPlace(p, fieldId) {
8016
+ var _a, _b, _c, _d, _e;
8017
+ const field = ((_a = p.fields) != null ? _a : []).find((f) => f.id === fieldId);
8018
+ if (!field) return [];
8019
+ const deleted = [fieldId, ...((_b = field.options) != null ? _b : []).map((o) => String(o.id))];
8020
+ const before = ((_c = p.fields) != null ? _c : []).length;
8021
+ p.fields = ((_d = p.fields) != null ? _d : []).filter((f) => f.id !== fieldId);
8022
+ clearFieldButtonReceiverMaps(p, fieldId);
8023
+ return ((_e = p.fields) != null ? _e : []).length !== before ? deleted : [];
8024
+ }
8025
+ function removeTagInPlace(p, tagId) {
8026
+ var _a, _b, _c;
8027
+ const before = ((_a = p.filters) != null ? _a : []).length;
8028
+ p.filters = ((_b = p.filters) != null ? _b : []).filter((t) => t.id !== tagId);
8029
+ return ((_c = p.filters) != null ? _c : []).length !== before;
8030
+ }
7825
8031
  function reLabel(ctx, id, nextLabel) {
7826
8032
  const label = String(nextLabel != null ? nextLabel : "").trim();
7827
8033
  ctx.exec({
@@ -7956,22 +8162,9 @@ function removeOption(ctx, optionId) {
7956
8162
  ctx.exec({
7957
8163
  name: "removeOption",
7958
8164
  do: () => ctx.patchProps((p) => {
7959
- var _a;
7960
- const owner = ownerOfOption(p, optionId);
7961
- if (!owner) return;
7962
- const f = ((_a = p.fields) != null ? _a : []).find((x) => x.id === owner.fieldId);
7963
- if (!(f == null ? void 0 : f.options)) return;
7964
- f.options = f.options.filter((o) => o.id !== optionId);
7965
- const maps = [
7966
- "includes_for_options",
7967
- "excludes_for_options"
7968
- ];
7969
- for (const m of maps) {
7970
- const map = p[m];
7971
- if (!map) continue;
7972
- if (map[optionId]) delete map[optionId];
7973
- if (!Object.keys(map).length) delete p[m];
7974
- }
8165
+ const removed = removeOptionInPlace(p, optionId);
8166
+ if (!removed) return;
8167
+ applyDeleteCleanup(p, /* @__PURE__ */ new Set([optionId]));
7975
8168
  }),
7976
8169
  undo: () => ctx.undo()
7977
8170
  });
@@ -8160,21 +8353,10 @@ function removeTag(ctx, id) {
8160
8353
  ctx.exec({
8161
8354
  name: "removeTag",
8162
8355
  do: () => ctx.patchProps((p) => {
8163
- var _a, _b, _c, _d, _e;
8164
8356
  prevSlice = (0, import_lodash_es3.cloneDeep)(p);
8165
- p.filters = ((_a = p.filters) != null ? _a : []).filter((t) => t.id !== id);
8166
- for (const t of (_b = p.filters) != null ? _b : []) {
8167
- if (t.bind_id === id) delete t.bind_id;
8168
- t.includes = ((_c = t.includes) != null ? _c : []).filter((x) => x !== id);
8169
- t.excludes = ((_d = t.excludes) != null ? _d : []).filter((x) => x !== id);
8170
- }
8171
- for (const f of (_e = p.fields) != null ? _e : []) {
8172
- if (Array.isArray(f.bind_id)) {
8173
- f.bind_id = f.bind_id.filter((x) => x !== id);
8174
- } else if (f.bind_id === id) {
8175
- delete f.bind_id;
8176
- }
8177
- }
8357
+ const removed = removeTagInPlace(p, id);
8358
+ if (!removed) return;
8359
+ applyDeleteCleanup(p, /* @__PURE__ */ new Set([id]));
8178
8360
  }),
8179
8361
  undo: () => ctx.replaceProps(prevSlice)
8180
8362
  });
@@ -8242,58 +8424,23 @@ function removeField(ctx, id) {
8242
8424
  ctx.exec({
8243
8425
  name: "removeField",
8244
8426
  do: () => ctx.patchProps((p) => {
8245
- var _a, _b, _c, _d, _e, _f;
8246
8427
  prevSlice = (0, import_lodash_es3.cloneDeep)(p);
8247
- p.fields = ((_a = p.fields) != null ? _a : []).filter((f) => f.id !== id);
8248
- clearFieldButtonReceiverMaps(p, id);
8249
- for (const mapKey of [
8250
- "includes_for_buttons",
8251
- "excludes_for_buttons"
8252
- ]) {
8253
- const m = p[mapKey];
8254
- if (!m) continue;
8255
- for (const k of Object.keys(m)) {
8256
- m[k] = ((_b = m[k]) != null ? _b : []).filter((fid) => fid !== id);
8257
- if (!((_c = m[k]) == null ? void 0 : _c.length)) delete m[k];
8258
- }
8259
- }
8260
- for (const t of (_d = p.filters) != null ? _d : []) {
8261
- t.includes = ((_e = t.includes) != null ? _e : []).filter((x) => x !== id);
8262
- t.excludes = ((_f = t.excludes) != null ? _f : []).filter((x) => x !== id);
8263
- }
8428
+ const removedIds = removeFieldInPlace(p, id);
8429
+ if (!removedIds.length) return;
8430
+ applyDeleteCleanup(p, new Set(removedIds));
8264
8431
  }),
8265
8432
  undo: () => ctx.replaceProps(prevSlice)
8266
8433
  });
8267
8434
  }
8268
8435
  function remove(ctx, id) {
8436
+ const key = String(id);
8269
8437
  if (ctx.isTagId(id)) {
8270
8438
  ctx.exec({
8271
8439
  name: "removeTag",
8272
8440
  do: () => ctx.patchProps((p) => {
8273
- var _a, _b, _c, _d, _e, _f, _g, _h;
8274
- p.filters = ((_a = p.filters) != null ? _a : []).filter((t) => t.id !== id);
8275
- for (const t of (_b = p.filters) != null ? _b : []) {
8276
- if (t.bind_id === id) delete t.bind_id;
8277
- t.includes = ((_c = t.includes) != null ? _c : []).filter((x) => x !== id);
8278
- t.excludes = ((_d = t.excludes) != null ? _d : []).filter((x) => x !== id);
8279
- }
8280
- for (const f of (_e = p.fields) != null ? _e : []) {
8281
- if (Array.isArray(f.bind_id)) {
8282
- f.bind_id = f.bind_id.filter((x) => x !== id);
8283
- } else if (f.bind_id === id) {
8284
- delete f.bind_id;
8285
- }
8286
- }
8287
- if ((_f = p.order_for_tags) == null ? void 0 : _f[id]) delete p.order_for_tags[id];
8288
- for (const k of Object.keys((_g = p.order_for_tags) != null ? _g : {})) {
8289
- p.order_for_tags[k] = ((_h = p.order_for_tags[k]) != null ? _h : []).filter(
8290
- (fid) => {
8291
- var _a2;
8292
- return ((_a2 = p.fields) != null ? _a2 : []).some((f) => f.id === fid);
8293
- }
8294
- );
8295
- if (!p.order_for_tags[k].length) delete p.order_for_tags[k];
8296
- }
8441
+ const removed = removeTagInPlace(p, key);
8442
+ if (!removed) return;
8443
+ applyDeleteCleanup(p, /* @__PURE__ */ new Set([key]));
8297
8444
  }),
8298
8445
  undo: () => ctx.undo()
8299
8446
  });
@@ -8303,42 +8450,67 @@ function remove(ctx, id) {
8303
8450
  ctx.exec({
8304
8451
  name: "removeField",
8305
8452
  do: () => ctx.patchProps((p) => {
8306
- var _a, _b, _c, _d, _e, _f, _g, _h;
8307
- p.fields = ((_a = p.fields) != null ? _a : []).filter((f) => f.id !== id);
8308
- for (const t of (_b = p.filters) != null ? _b : []) {
8309
- t.includes = ((_c = t.includes) != null ? _c : []).filter((x) => x !== id);
8310
- t.excludes = ((_d = t.excludes) != null ? _d : []).filter((x) => x !== id);
8311
- }
8312
- for (const k of Object.keys((_e = p.order_for_tags) != null ? _e : {})) {
8313
- p.order_for_tags[k] = ((_f = p.order_for_tags[k]) != null ? _f : []).filter(
8314
- (fid) => fid !== id
8315
- );
8316
- if (!p.order_for_tags[k].length) delete p.order_for_tags[k];
8317
- }
8318
- const maps = [
8319
- "includes_for_options",
8320
- "excludes_for_options"
8321
- ];
8322
- for (const m of maps) {
8323
- const map = p[m];
8324
- if (!map) continue;
8325
- for (const key of Object.keys(map)) {
8326
- map[key] = ((_g = map[key]) != null ? _g : []).filter((fid) => fid !== id);
8327
- if (!((_h = map[key]) == null ? void 0 : _h.length)) delete map[key];
8328
- }
8329
- if (!Object.keys(map).length) delete p[m];
8330
- }
8453
+ const removedIds = removeFieldInPlace(p, key);
8454
+ if (!removedIds.length) return;
8455
+ applyDeleteCleanup(p, new Set(removedIds));
8331
8456
  }),
8332
8457
  undo: () => ctx.undo()
8333
8458
  });
8334
8459
  return;
8335
8460
  }
8336
8461
  if (ctx.isOptionId(id)) {
8337
- removeOption(ctx, id);
8462
+ ctx.exec({
8463
+ name: "removeOption",
8464
+ do: () => ctx.patchProps((p) => {
8465
+ const removed = removeOptionInPlace(p, key);
8466
+ if (!removed) return;
8467
+ applyDeleteCleanup(p, /* @__PURE__ */ new Set([key]));
8468
+ }),
8469
+ undo: () => ctx.undo()
8470
+ });
8338
8471
  return;
8339
8472
  }
8340
8473
  throw new Error("remove: unknown id prefix");
8341
8474
  }
8475
+ function removeMany(ctx, ids) {
8476
+ const { ordered } = stripDeletedIds(ids);
8477
+ if (!ordered.length) return;
8478
+ ctx.transact("removeMany", () => {
8479
+ ctx.patchProps((p) => {
8480
+ var _a, _b, _c;
8481
+ const existingFieldIds = new Set(((_a = p.fields) != null ? _a : []).map((f) => String(f.id)));
8482
+ const existingTagIds = new Set(((_b = p.filters) != null ? _b : []).map((t) => String(t.id)));
8483
+ const existingOptionIds = new Set(
8484
+ ((_c = p.fields) != null ? _c : []).flatMap((f) => {
8485
+ var _a2;
8486
+ return ((_a2 = f.options) != null ? _a2 : []).map((o) => String(o.id));
8487
+ })
8488
+ );
8489
+ const fieldIds = ordered.filter((id) => ctx.isFieldId(id) && existingFieldIds.has(id));
8490
+ const fieldIdSet = new Set(fieldIds);
8491
+ const tagIds = ordered.filter((id) => ctx.isTagId(id) && existingTagIds.has(id));
8492
+ const optionIds = ordered.filter((id) => {
8493
+ if (!ctx.isOptionId(id) || !existingOptionIds.has(id)) return false;
8494
+ const owner = ownerOfOption(p, id);
8495
+ if (!owner) return false;
8496
+ return !fieldIdSet.has(String(owner.fieldId));
8497
+ });
8498
+ const deleted = /* @__PURE__ */ new Set();
8499
+ for (const optionId of optionIds) {
8500
+ if (removeOptionInPlace(p, optionId)) deleted.add(optionId);
8501
+ }
8502
+ for (const fieldId of fieldIds) {
8503
+ const removedIds = removeFieldInPlace(p, fieldId);
8504
+ for (const rid of removedIds) deleted.add(rid);
8505
+ }
8506
+ for (const tagId of tagIds) {
8507
+ if (removeTagInPlace(p, tagId)) deleted.add(tagId);
8508
+ }
8509
+ if (!deleted.size) return;
8510
+ applyDeleteCleanup(p, deleted);
8511
+ });
8512
+ });
8513
+ }
8342
8514
  function getNode(ctx, id) {
8343
8515
  var _a, _b, _c, _d;
8344
8516
  const props = ctx.getProps();
@@ -9583,6 +9755,9 @@ var Editor = class {
9583
9755
  duplicate(ref, opts = {}) {
9584
9756
  return duplicate(this.moduleCtx(), ref, opts);
9585
9757
  }
9758
+ duplicateMany(ids, opts = {}) {
9759
+ return duplicateMany(this.moduleCtx(), ids, opts);
9760
+ }
9586
9761
  reLabel(id, nextLabel) {
9587
9762
  return reLabel(this.moduleCtx(), id, nextLabel);
9588
9763
  }
@@ -9646,6 +9821,260 @@ var Editor = class {
9646
9821
  remove(id) {
9647
9822
  return remove(this.moduleCtx(), id);
9648
9823
  }
9824
+ removeMany(ids) {
9825
+ return removeMany(this.moduleCtx(), ids);
9826
+ }
9827
+ clearServiceMany(ids) {
9828
+ const ordered = Array.from(new Set((ids != null ? ids : []).map((id) => String(id))));
9829
+ if (!ordered.length) return;
9830
+ this.transact("clearServiceMany", () => {
9831
+ this.patchProps((p) => {
9832
+ var _a, _b, _c, _d;
9833
+ for (const id of ordered) {
9834
+ if (this.isTagId(id)) {
9835
+ const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
9836
+ if (t && "service_id" in t) delete t.service_id;
9837
+ continue;
9838
+ }
9839
+ if (this.isFieldId(id)) {
9840
+ const f = ((_b = p.fields) != null ? _b : []).find((x) => x.id === id);
9841
+ if (f && "service_id" in f) delete f.service_id;
9842
+ continue;
9843
+ }
9844
+ if (this.isOptionId(id)) {
9845
+ const own = ownerOfOption(p, id);
9846
+ if (!own) continue;
9847
+ const f = ((_c = p.fields) != null ? _c : []).find((x) => x.id === own.fieldId);
9848
+ const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
9849
+ if (o && "service_id" in o) delete o.service_id;
9850
+ }
9851
+ }
9852
+ });
9853
+ });
9854
+ }
9855
+ rebindMany(ids, targetTagId, opts) {
9856
+ const ordered = Array.from(new Set((ids != null ? ids : []).map((id) => String(id))));
9857
+ if (!ordered.length) return;
9858
+ this.transact("rebindMany", () => {
9859
+ this.patchProps((p) => {
9860
+ var _a, _b, _c;
9861
+ const targetExists = ((_a = p.filters) != null ? _a : []).some((t) => t.id === targetTagId);
9862
+ if (!targetExists) return;
9863
+ for (const id of ordered) {
9864
+ if (this.isFieldId(id)) {
9865
+ const f = ((_b = p.fields) != null ? _b : []).find((x) => x.id === id);
9866
+ if (!f) continue;
9867
+ f.bind_id = targetTagId;
9868
+ continue;
9869
+ }
9870
+ if (this.isTagId(id)) {
9871
+ const t = ((_c = p.filters) != null ? _c : []).find((x) => x.id === id);
9872
+ if (!t) continue;
9873
+ if (!(opts == null ? void 0 : opts.allowTagCycles) && wouldCreateTagCycle(this.moduleCtx(), p, targetTagId, id)) {
9874
+ continue;
9875
+ }
9876
+ t.bind_id = targetTagId;
9877
+ }
9878
+ }
9879
+ });
9880
+ });
9881
+ }
9882
+ includeMany(receiverId, ids) {
9883
+ const accepted = Array.from(new Set((ids != null ? ids : []).map((id) => String(id)))).filter((id) => id !== receiverId).filter((id) => this.getNode(id).data != null);
9884
+ if (!accepted.length) return;
9885
+ include(this.moduleCtx(), receiverId, accepted);
9886
+ }
9887
+ excludeMany(receiverId, ids) {
9888
+ const accepted = Array.from(new Set((ids != null ? ids : []).map((id) => String(id)))).filter((id) => id !== receiverId).filter((id) => this.getNode(id).data != null);
9889
+ if (!accepted.length) return;
9890
+ exclude(this.moduleCtx(), receiverId, accepted);
9891
+ }
9892
+ clearRelationsMany(ids, mode = "both") {
9893
+ const selected = new Set(Array.from(new Set((ids != null ? ids : []).map((id) => String(id)))));
9894
+ if (!selected.size) return;
9895
+ this.transact("clearRelationsMany", () => {
9896
+ this.patchProps((p) => {
9897
+ var _a, _b, _c;
9898
+ const clearOwned = mode === "owned" || mode === "both";
9899
+ const clearIncoming = mode === "incoming" || mode === "both";
9900
+ for (const t of (_a = p.filters) != null ? _a : []) {
9901
+ if (clearOwned && selected.has(t.id)) {
9902
+ delete t.includes;
9903
+ delete t.excludes;
9904
+ }
9905
+ if (clearIncoming) {
9906
+ if (t.includes) {
9907
+ t.includes = t.includes.filter((x) => !selected.has(String(x)));
9908
+ if (!t.includes.length) delete t.includes;
9909
+ }
9910
+ if (t.excludes) {
9911
+ t.excludes = t.excludes.filter((x) => !selected.has(String(x)));
9912
+ if (!t.excludes.length) delete t.excludes;
9913
+ }
9914
+ }
9915
+ }
9916
+ const maps = [
9917
+ "includes_for_buttons",
9918
+ "excludes_for_buttons",
9919
+ "includes_for_options",
9920
+ "excludes_for_options"
9921
+ ];
9922
+ for (const k of maps) {
9923
+ const map = p[k];
9924
+ if (!map) continue;
9925
+ for (const key of Object.keys(map)) {
9926
+ if (clearOwned && selected.has(String(key))) {
9927
+ delete map[key];
9928
+ continue;
9929
+ }
9930
+ if (clearIncoming) {
9931
+ map[key] = ((_b = map[key]) != null ? _b : []).filter((x) => !selected.has(String(x)));
9932
+ if (!((_c = map[key]) == null ? void 0 : _c.length)) delete map[key];
9933
+ }
9934
+ }
9935
+ if (!Object.keys(map).length) delete p[k];
9936
+ }
9937
+ });
9938
+ });
9939
+ }
9940
+ renameLabelsMany(ids, input) {
9941
+ var _a, _b;
9942
+ const ordered = Array.from(new Set((ids != null ? ids : []).map((id) => String(id))));
9943
+ if (!ordered.length) return;
9944
+ const prefix = (_a = input.prefix) != null ? _a : "";
9945
+ const suffix = (_b = input.suffix) != null ? _b : "";
9946
+ this.transact("renameLabelsMany", () => {
9947
+ this.patchProps((p) => {
9948
+ var _a2, _b2, _c, _d, _e, _f, _g;
9949
+ for (const id of ordered) {
9950
+ if (this.isTagId(id)) {
9951
+ const t = ((_a2 = p.filters) != null ? _a2 : []).find((x) => x.id === id);
9952
+ if (t) t.label = `${prefix}${(_b2 = t.label) != null ? _b2 : ""}${suffix}`.trim();
9953
+ continue;
9954
+ }
9955
+ if (this.isFieldId(id)) {
9956
+ const f = ((_c = p.fields) != null ? _c : []).find((x) => x.id === id);
9957
+ if (f) f.label = `${prefix}${(_d = f.label) != null ? _d : ""}${suffix}`.trim();
9958
+ continue;
9959
+ }
9960
+ if (this.isOptionId(id)) {
9961
+ const own = ownerOfOption(p, id);
9962
+ if (!own) continue;
9963
+ const f = ((_e = p.fields) != null ? _e : []).find((x) => x.id === own.fieldId);
9964
+ const o = (_f = f == null ? void 0 : f.options) == null ? void 0 : _f.find((x) => x.id === id);
9965
+ if (o) o.label = `${prefix}${(_g = o.label) != null ? _g : ""}${suffix}`.trim();
9966
+ }
9967
+ }
9968
+ });
9969
+ });
9970
+ }
9971
+ setPricingRoleMany(ids, role) {
9972
+ const ordered = Array.from(new Set((ids != null ? ids : []).map((id) => String(id))));
9973
+ if (!ordered.length) return;
9974
+ this.transact("setPricingRoleMany", () => {
9975
+ for (const id of ordered) {
9976
+ if (this.isFieldId(id) || this.isOptionId(id)) {
9977
+ this.setService(id, { pricing_role: role });
9978
+ }
9979
+ }
9980
+ });
9981
+ }
9982
+ clearFieldDefaultsMany(ids) {
9983
+ const ordered = Array.from(new Set((ids != null ? ids : []).map((id) => String(id))));
9984
+ if (!ordered.length) return;
9985
+ this.transact("clearFieldDefaultsMany", () => {
9986
+ this.patchProps((p) => {
9987
+ var _a;
9988
+ for (const id of ordered) {
9989
+ if (!this.isFieldId(id)) continue;
9990
+ const f = ((_a = p.fields) != null ? _a : []).find((x) => x.id === id);
9991
+ if (f && "defaults" in f) delete f.defaults;
9992
+ }
9993
+ });
9994
+ });
9995
+ }
9996
+ clearFieldValidationMany(ids) {
9997
+ const ordered = Array.from(new Set((ids != null ? ids : []).map((id) => String(id))));
9998
+ if (!ordered.length) return;
9999
+ this.transact("clearFieldValidationMany", () => {
10000
+ this.patchProps((p) => {
10001
+ var _a;
10002
+ for (const id of ordered) {
10003
+ if (!this.isFieldId(id)) continue;
10004
+ const f = ((_a = p.fields) != null ? _a : []).find((x) => x.id === id);
10005
+ if (f && "validation" in f) delete f.validation;
10006
+ }
10007
+ });
10008
+ });
10009
+ }
10010
+ autoCreateOptionsMany(ids, makeOption) {
10011
+ const ordered = Array.from(new Set((ids != null ? ids : []).map((id) => String(id))));
10012
+ if (!ordered.length) return;
10013
+ this.transact("autoCreateOptionsMany", () => {
10014
+ this.patchProps((p) => {
10015
+ var _a, _b, _c, _d;
10016
+ for (const id of ordered) {
10017
+ if (!this.isFieldId(id)) continue;
10018
+ const f = ((_a = p.fields) != null ? _a : []).find((x) => x.id === id);
10019
+ if (!f) continue;
10020
+ const opts = (_b = f.options) != null ? _b : f.options = [];
10021
+ if (opts.length > 0) continue;
10022
+ const next = (_c = makeOption == null ? void 0 : makeOption(id)) != null ? _c : { label: "Option label", value: "option" };
10023
+ opts.push({
10024
+ id: (_d = next.id) != null ? _d : this.moduleCtx().genId("o"),
10025
+ label: next.label,
10026
+ value: next.value
10027
+ });
10028
+ }
10029
+ });
10030
+ });
10031
+ }
10032
+ clearAllOptionsMany(ids) {
10033
+ var _a, _b;
10034
+ const ordered = Array.from(new Set((ids != null ? ids : []).map((id) => String(id))));
10035
+ if (!ordered.length) return;
10036
+ const optionIds = [];
10037
+ const props = this.getProps();
10038
+ for (const id of ordered) {
10039
+ if (!this.isFieldId(id)) continue;
10040
+ const f = ((_a = props.fields) != null ? _a : []).find((x) => x.id === id);
10041
+ for (const o of (_b = f == null ? void 0 : f.options) != null ? _b : []) optionIds.push(o.id);
10042
+ }
10043
+ if (!optionIds.length) return;
10044
+ removeMany(this.moduleCtx(), optionIds);
10045
+ }
10046
+ removeNoticesForNodes(ids) {
10047
+ const selected = new Set(Array.from(new Set((ids != null ? ids : []).map((id) => String(id)))));
10048
+ if (!selected.size) return;
10049
+ this.transact("removeNoticesForNodes", () => {
10050
+ this.patchProps((p) => {
10051
+ var _a;
10052
+ if (!((_a = p.notices) == null ? void 0 : _a.length)) return;
10053
+ p.notices = p.notices.filter((n) => {
10054
+ const target = n.target;
10055
+ if (!target || target.scope === "global") return true;
10056
+ if (target.scope === "node") return !selected.has(String(target.node_id));
10057
+ return true;
10058
+ });
10059
+ if (!p.notices.length) delete p.notices;
10060
+ });
10061
+ });
10062
+ }
10063
+ setNoticesVisibilityForNodes(ids, type) {
10064
+ const selected = new Set(Array.from(new Set((ids != null ? ids : []).map((id) => String(id)))));
10065
+ if (!selected.size) return;
10066
+ this.transact("setNoticesVisibilityForNodes", () => {
10067
+ this.patchProps((p) => {
10068
+ var _a;
10069
+ for (const n of (_a = p.notices) != null ? _a : []) {
10070
+ const target = n.target;
10071
+ if ((target == null ? void 0 : target.scope) === "node" && selected.has(String(target.node_id))) {
10072
+ n.type = type;
10073
+ }
10074
+ }
10075
+ });
10076
+ });
10077
+ }
9649
10078
  getNode(id) {
9650
10079
  return getNode(this.moduleCtx(), id);
9651
10080
  }
@@ -9889,9 +10318,8 @@ var Editor = class {
9889
10318
  Array.isArray(canvas.selection) ? canvas.selection : Array.from(canvas.selection)
9890
10319
  );
9891
10320
  }
9892
- } else {
9893
- this.api.refreshGraph();
9894
10321
  }
10322
+ this.api.refreshGraph();
9895
10323
  this.emit("editor:change", { props: s.props, reason, snapshot: s });
9896
10324
  }
9897
10325
  pushHistory(snap) {
@@ -10979,12 +11407,12 @@ function useCanvasOwned(initialProps, canvasOpts, builderOpts) {
10979
11407
  // src/react/workspace/context/hooks/use-canvas.ts
10980
11408
  var React16 = __toESM(require("react"), 1);
10981
11409
  var import_react4 = require("react");
10982
- function deriveSelectionInfo(props, ids) {
11410
+ function deriveSelectionInfo(nodeMap, ids) {
10983
11411
  const tags = [];
10984
11412
  const fields = [];
10985
11413
  const options = [];
10986
11414
  for (const id of ids) {
10987
- const node = props.get(id);
11415
+ const node = nodeMap.get(id);
10988
11416
  if (!node) continue;
10989
11417
  if (node.kind == "tag") {
10990
11418
  tags.push(id);
@@ -11011,6 +11439,49 @@ function deriveSelectionInfo(props, ids) {
11011
11439
  optionIds: uniq2(options)
11012
11440
  };
11013
11441
  }
11442
+ function noticeTargetsSelection(notice, selected) {
11443
+ const target = notice.target;
11444
+ if (target.scope === "global") return false;
11445
+ return selected.has(String(target.node_id));
11446
+ }
11447
+ function deriveSelectionCapabilities(props, selectionInfo) {
11448
+ var _a, _b, _c;
11449
+ const selected = new Set(selectionInfo.ids.map(String));
11450
+ const fields = (_a = props == null ? void 0 : props.fields) != null ? _a : [];
11451
+ const tags = (_b = props == null ? void 0 : props.filters) != null ? _b : [];
11452
+ const notices = (_c = props == null ? void 0 : props.notices) != null ? _c : [];
11453
+ const hasSelectedFieldWithOptions = fields.some(
11454
+ (f) => {
11455
+ var _a2, _b2;
11456
+ return selected.has(String(f.id)) && ((_b2 = (_a2 = f.options) == null ? void 0 : _a2.length) != null ? _b2 : 0) > 0;
11457
+ }
11458
+ );
11459
+ const hasServiceBearingNodes = tags.some(
11460
+ (t) => selected.has(String(t.id)) && t.service_id !== void 0 && t.service_id !== null
11461
+ ) || fields.some(
11462
+ (f) => selected.has(String(f.id)) && f.service_id !== void 0 && f.service_id !== null
11463
+ ) || fields.some(
11464
+ (f) => {
11465
+ var _a2;
11466
+ return ((_a2 = f.options) != null ? _a2 : []).some(
11467
+ (o) => selected.has(String(o.id)) && o.service_id !== void 0 && o.service_id !== null
11468
+ );
11469
+ }
11470
+ );
11471
+ const hasNoticesForSelection = notices.some(
11472
+ (n) => noticeTargetsSelection(n, selected)
11473
+ );
11474
+ return {
11475
+ hasTags: selectionInfo.tagIds.length > 0,
11476
+ hasFields: selectionInfo.fieldIds.length > 0,
11477
+ hasOptions: selectionInfo.optionIds.length > 0,
11478
+ hasServiceBearingNodes,
11479
+ hasSelectedFieldWithOptions,
11480
+ hasNoticesForSelection,
11481
+ canIncludeExcludeTargets: selectionInfo.tagIds.length + selectionInfo.fieldIds.length + selectionInfo.optionIds.length > 0,
11482
+ canRebind: selectionInfo.fieldIds.length > 0 || selectionInfo.tagIds.length > 0
11483
+ };
11484
+ }
11014
11485
  function tagBindIds(tag) {
11015
11486
  const bind = tag.bind_id;
11016
11487
  if (!bind) return [];
@@ -11150,7 +11621,11 @@ function useCanvas() {
11150
11621
  });
11151
11622
  return off;
11152
11623
  }, [api]);
11153
- const selector = (0, import_react4.useMemo)(() => createNodeIndex(api.builder), [props]);
11624
+ const selector = (0, import_react4.useMemo)(() => createNodeIndex(api.builder), [api.builder, props]);
11625
+ const selectionCapabilities = React16.useMemo(
11626
+ () => deriveSelectionCapabilities(props, selectionInfo),
11627
+ [props, selectionInfo]
11628
+ );
11154
11629
  return React16.useMemo(
11155
11630
  () => ({
11156
11631
  api,
@@ -11159,6 +11634,7 @@ function useCanvas() {
11159
11634
  props,
11160
11635
  selection,
11161
11636
  selectionInfo,
11637
+ selectionCapabilities,
11162
11638
  selector,
11163
11639
  activeId,
11164
11640
  setActive
@@ -11170,6 +11646,7 @@ function useCanvas() {
11170
11646
  props,
11171
11647
  selection,
11172
11648
  selectionInfo,
11649
+ selectionCapabilities,
11173
11650
  selector,
11174
11651
  activeId,
11175
11652
  setActive
@@ -11983,8 +12460,8 @@ function createMemoryWorkspaceBackend(opts) {
11983
12460
  };
11984
12461
  void initStore();
11985
12462
  const authorsBase = {
11986
- list: async (workspaceId) => {
11987
- if (workspaceId !== info.id)
12463
+ list: async (ctx) => {
12464
+ if (ctx.workspaceId !== info.id)
11988
12465
  return fail("not_found", "Workspace not found.");
11989
12466
  return ok(Array.from(store.authors.values()));
11990
12467
  },
@@ -11992,8 +12469,8 @@ function createMemoryWorkspaceBackend(opts) {
11992
12469
  const a = store.authors.get(authorId);
11993
12470
  return ok(a != null ? a : null);
11994
12471
  },
11995
- refresh: async (workspaceId) => {
11996
- if (workspaceId !== info.id)
12472
+ refresh: async (ctx) => {
12473
+ if (ctx.workspaceId !== info.id)
11997
12474
  return fail("not_found", "Workspace not found.");
11998
12475
  return ok(Array.from(store.authors.values()));
11999
12476
  }
@@ -12005,18 +12482,18 @@ function createMemoryWorkspaceBackend(opts) {
12005
12482
  []
12006
12483
  );
12007
12484
  const permissionsBase = {
12008
- get: async (workspaceId, actor) => {
12485
+ get: async (ctx) => {
12009
12486
  var _a, _b;
12010
- if (workspaceId !== info.id)
12487
+ if (ctx.workspaceId !== info.id)
12011
12488
  return fail("not_found", "Workspace not found.");
12012
- const seeded = (_b = (_a = store.permissionsByActor.get(actor.id)) != null ? _a : store.permissionsByActor.get("*")) != null ? _b : void 0;
12489
+ const seeded = (_b = (_a = store.permissionsByActor.get(ctx.actorId)) != null ? _a : store.permissionsByActor.get("*")) != null ? _b : void 0;
12013
12490
  return ok(seeded != null ? seeded : permissivePermissions());
12014
12491
  },
12015
- refresh: async (workspaceId, actor) => {
12492
+ refresh: async (ctx) => {
12016
12493
  var _a, _b;
12017
- if (workspaceId !== info.id)
12494
+ if (ctx.workspaceId !== info.id)
12018
12495
  return fail("not_found", "Workspace not found.");
12019
- const seeded = (_b = (_a = store.permissionsByActor.get(actor.id)) != null ? _a : store.permissionsByActor.get("*")) != null ? _b : void 0;
12496
+ const seeded = (_b = (_a = store.permissionsByActor.get(ctx.actorId)) != null ? _a : store.permissionsByActor.get("*")) != null ? _b : void 0;
12020
12497
  return ok(seeded != null ? seeded : permissivePermissions());
12021
12498
  }
12022
12499
  };
@@ -12027,8 +12504,8 @@ function createMemoryWorkspaceBackend(opts) {
12027
12504
  []
12028
12505
  );
12029
12506
  const branchesBase = {
12030
- list: async (workspaceId) => {
12031
- if (workspaceId !== info.id)
12507
+ list: async (ctx) => {
12508
+ if (ctx.workspaceId !== info.id)
12032
12509
  return fail("not_found", "Workspace not found.");
12033
12510
  return ok(Array.from(store.branches.values()));
12034
12511
  },
@@ -12134,8 +12611,8 @@ function createMemoryWorkspaceBackend(opts) {
12134
12611
  store.policiesByBranch.delete(branchId);
12135
12612
  return ok(void 0);
12136
12613
  },
12137
- refresh: async (workspaceId) => {
12138
- if (workspaceId !== info.id)
12614
+ refresh: async (ctx) => {
12615
+ if (ctx.workspaceId !== info.id)
12139
12616
  return fail("not_found", "Workspace not found.");
12140
12617
  return ok(Array.from(store.branches.values()));
12141
12618
  }
@@ -12147,18 +12624,18 @@ function createMemoryWorkspaceBackend(opts) {
12147
12624
  ["create", "setMain", "merge", "delete"]
12148
12625
  );
12149
12626
  const accessBase = {
12150
- listParticipants: async (workspaceId, branchId) => {
12627
+ listParticipants: async (ctx) => {
12151
12628
  var _a;
12152
- if (workspaceId !== info.id)
12629
+ if (ctx.workspaceId !== info.id)
12153
12630
  return fail("not_found", "Workspace not found.");
12154
- const list = (_a = store.participantsByBranch.get(branchId)) != null ? _a : [];
12631
+ const list = (_a = store.participantsByBranch.get(ctx.branchId)) != null ? _a : [];
12155
12632
  return ok(list);
12156
12633
  },
12157
- refreshParticipants: async (workspaceId, branchId) => {
12634
+ refreshParticipants: async (ctx) => {
12158
12635
  var _a;
12159
- if (workspaceId !== info.id)
12636
+ if (ctx.workspaceId !== info.id)
12160
12637
  return fail("not_found", "Workspace not found.");
12161
- const list = (_a = store.participantsByBranch.get(branchId)) != null ? _a : [];
12638
+ const list = (_a = store.participantsByBranch.get(ctx.branchId)) != null ? _a : [];
12162
12639
  return ok(list);
12163
12640
  }
12164
12641
  };
@@ -12169,14 +12646,14 @@ function createMemoryWorkspaceBackend(opts) {
12169
12646
  []
12170
12647
  );
12171
12648
  const servicesBase = {
12172
- get: async (workspaceId) => {
12173
- if (workspaceId !== info.id)
12649
+ get: async (ctx) => {
12650
+ if (ctx.workspaceId !== info.id)
12174
12651
  return fail("not_found", "Workspace not found.");
12175
12652
  if (!store.services) return ok([]);
12176
12653
  return ok(store.services);
12177
12654
  },
12178
- refresh: async (workspaceId) => {
12179
- if (workspaceId !== info.id)
12655
+ refresh: async (ctx) => {
12656
+ if (ctx.workspaceId !== info.id)
12180
12657
  return fail("not_found", "Workspace not found.");
12181
12658
  if (!store.services) return ok([]);
12182
12659
  return ok(store.services);
@@ -13857,6 +14334,7 @@ var import_jsx_runtime11 = require("react/jsx-runtime");
13857
14334
  WorkspaceProvider,
13858
14335
  createMemoryWorkspaceBackend,
13859
14336
  createPollAdapter,
14337
+ deriveSelectionCapabilities,
13860
14338
  useCanvas,
13861
14339
  useCanvasAPI,
13862
14340
  useCanvasFromBuilder,