@istar-ts/actions 0.15.0-beta.1 → 0.15.0-beta.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.
package/dist/index.cjs CHANGED
@@ -186,6 +186,36 @@ function contextActionsFor(palette, metamodel) {
186
186
  groups: palette.groups
187
187
  };
188
188
  }
189
+ /**
190
+ * A minimal palette for a metamodel with none of its own: one toolbar entry per visible kind
191
+ * (declaration order, actors first), labelled from the kind's own `label`. Kinds generated for
192
+ * an n-ary link (a hub, leg or end — `role` set) are hidden, as a hand-written palette would
193
+ * hide them (`KAOS_PALETTE`'s `RefinementLinkHub: false`, for instance). The fallback
194
+ * `createActionDispatcher` and `contributionFor` (`@istar-ts/glsp`) both use when no palette
195
+ * was given.
196
+ */
197
+ function paletteFromMetamodel(metamodel) {
198
+ const elements = {};
199
+ let order = 0;
200
+ for (const definition of metamodel.elements.values()) elements[definition.kind] = definition.role !== void 0 ? false : {
201
+ label: definition.label,
202
+ order: order++,
203
+ section: definition.category === "actor" ? "actors" : "elements",
204
+ ...definition.category === "actor" ? { group: "actors" } : {}
205
+ };
206
+ const links = {};
207
+ order = 0;
208
+ for (const definition of metamodel.links.values()) links[definition.kind] = definition.role !== void 0 ? false : [{
209
+ label: definition.label,
210
+ order: order++,
211
+ section: "elements"
212
+ }];
213
+ return {
214
+ elements,
215
+ links,
216
+ groups: { actors: { label: "Actor" } }
217
+ };
218
+ }
189
219
  //#endregion
190
220
  //#region src/markers.ts
191
221
  /** A `GoalDiagnostic` as a GLSP marker: `kind` is its severity, `label` its message. */
@@ -277,22 +307,34 @@ function createActionDispatcher(store, options = {}) {
277
307
  const s = store;
278
308
  const guards = options.guards ?? [];
279
309
  const postGuards = options.postGuards ?? [];
280
- const palette = options.palette ?? _istar_ts_core.DEFAULT_PALETTE;
310
+ const resolvePalette = (meta) => {
311
+ const option = options.palette;
312
+ if (typeof option === "function") return option();
313
+ return option ?? paletteFromMetamodel(meta);
314
+ };
281
315
  const sourceModelName = options.sourceModelName ?? "";
282
316
  const listeners = /* @__PURE__ */ new Set();
283
317
  let saved = s.getModel();
284
318
  let dirty = false;
319
+ /**
320
+ * The origin of the dispatch currently applying synchronously (set by `dispatch`, around the
321
+ * synchronous part of `run`): what the store's subscription below echoes on
322
+ * `sourceModelChanged`/`setDirtyState`. `undefined` for a change not caused by a dispatch (a
323
+ * host's direct `store.load`) or once `run`'s synchronous part has returned.
324
+ */
325
+ let currentOrigin;
285
326
  const emit = (action) => {
286
327
  for (const listener of listeners) listener(action);
287
328
  };
288
- const updateDirty = (reason) => {
329
+ const updateDirty = (reason, origin) => {
289
330
  const next = s.getModel() !== saved;
290
331
  if (next === dirty) return;
291
332
  dirty = next;
292
333
  emit({
293
334
  kind: "setDirtyState",
294
335
  isDirty: next,
295
- reason
336
+ reason,
337
+ ...origin === void 0 ? {} : { origin }
296
338
  });
297
339
  };
298
340
  const REASONS = {
@@ -312,9 +354,10 @@ function createActionDispatcher(store, options = {}) {
312
354
  ...options.sendModel ? {
313
355
  canUndo: s.canUndo(),
314
356
  canRedo: s.canRedo()
315
- } : {}
357
+ } : {},
358
+ ...currentOrigin === void 0 ? {} : { origin: currentOrigin }
316
359
  });
317
- updateDirty(REASONS[event.source]);
360
+ updateDirty(REASONS[event.source], currentOrigin);
318
361
  });
319
362
  const requireElement = (id) => s.getModel().elements.get(id) ?? reject(`unknown element "${id}"`, id, "unknown-element");
320
363
  const runGuards = (operation, warnings) => {
@@ -699,16 +742,19 @@ function createActionDispatcher(store, options = {}) {
699
742
  ...typeHintsFor(metaOf(model))
700
743
  };
701
744
  case "requestCheckEdge": return checkEdge(action);
702
- case "requestContextActions": return {
703
- kind: "setContextActions",
704
- responseId: action.requestId,
705
- ...contextActionsFor(palette, metaOf(model))
706
- };
745
+ case "requestContextActions": {
746
+ const meta = metaOf(model);
747
+ return {
748
+ kind: "setContextActions",
749
+ responseId: action.requestId,
750
+ ...contextActionsFor(resolvePalette(meta), meta)
751
+ };
752
+ }
707
753
  case "requestMarkers": return markers(action);
708
754
  default: return;
709
755
  }
710
756
  };
711
- const run = async (action) => {
757
+ const run = async (action, origin) => {
712
758
  if (isOperation(action)) return runOperation(action);
713
759
  if (isRequestAction(action)) return {
714
760
  ok: true,
@@ -733,7 +779,7 @@ function createActionDispatcher(store, options = {}) {
733
779
  const model = s.getModel();
734
780
  await options.save((0, _istar_ts_core.toPistarObject)(model, { saveDate: /* @__PURE__ */ new Date() }), action);
735
781
  saved = model;
736
- updateDirty("save");
782
+ updateDirty("save", origin);
737
783
  return {
738
784
  ok: true,
739
785
  createdIds: []
@@ -753,9 +799,17 @@ function createActionDispatcher(store, options = {}) {
753
799
  }
754
800
  };
755
801
  return {
756
- async dispatch(action) {
802
+ async dispatch(action, dispatchOptions) {
803
+ const origin = dispatchOptions?.origin;
804
+ currentOrigin = origin;
805
+ let pending;
806
+ try {
807
+ pending = run(action, origin);
808
+ } finally {
809
+ currentOrigin = void 0;
810
+ }
757
811
  try {
758
- return await run(action);
812
+ return await pending;
759
813
  } catch (error) {
760
814
  if (error instanceof Rejection) return {
761
815
  ok: false,
@@ -979,8 +1033,8 @@ function createMirrorStore(remote, options = {}) {
979
1033
  return {
980
1034
  ready,
981
1035
  dispatcher: {
982
- async dispatch(action) {
983
- const result = await r.dispatch(action);
1036
+ async dispatch(action, options) {
1037
+ const result = await r.dispatch(action, options);
984
1038
  await tail;
985
1039
  return result;
986
1040
  },
@@ -1066,8 +1120,9 @@ function connectDispatcher(port, dispatcher) {
1066
1120
  port.onmessage = (ev) => {
1067
1121
  const message = ev.data;
1068
1122
  if (!isRecord(message) || message.jsonrpc !== JSONRPC_VERSION) return;
1069
- const { id, method, params } = message;
1123
+ const { id, method, params, origin } = message;
1070
1124
  const hasId = isJsonRpcId(id);
1125
+ const dispatchOptions = typeof origin === "string" ? { origin } : void 0;
1071
1126
  if (typeof method !== "string" || method.length === 0) {
1072
1127
  if (hasId) port.postMessage(errorMessage(id, -32601, "method not found"));
1073
1128
  return;
@@ -1078,10 +1133,10 @@ function connectDispatcher(port, dispatcher) {
1078
1133
  }
1079
1134
  const action = params;
1080
1135
  if (!hasId) {
1081
- dispatcher.dispatch(action);
1136
+ dispatcher.dispatch(action, dispatchOptions);
1082
1137
  return;
1083
1138
  }
1084
- dispatcher.dispatch(action).then((result) => {
1139
+ dispatcher.dispatch(action, dispatchOptions).then((result) => {
1085
1140
  port.postMessage({
1086
1141
  jsonrpc: JSONRPC_VERSION,
1087
1142
  id,
@@ -1125,7 +1180,7 @@ function createRemoteDispatcher(port) {
1125
1180
  }
1126
1181
  };
1127
1182
  return {
1128
- dispatch(action) {
1183
+ dispatch(action, dispatchOptions) {
1129
1184
  const id = nextId++;
1130
1185
  return new Promise((resolve, reject) => {
1131
1186
  pending.set(id, {
@@ -1136,7 +1191,8 @@ function createRemoteDispatcher(port) {
1136
1191
  jsonrpc: JSONRPC_VERSION,
1137
1192
  id,
1138
1193
  method: action.kind,
1139
- params: action
1194
+ params: action,
1195
+ ...dispatchOptions?.origin === void 0 ? {} : { origin: dispatchOptions.origin }
1140
1196
  });
1141
1197
  });
1142
1198
  },
@@ -1164,6 +1220,7 @@ exports.hostToolContext = hostToolContext;
1164
1220
  exports.isOperation = isOperation;
1165
1221
  exports.isRequestAction = isRequestAction;
1166
1222
  exports.markerToDiagnostic = markerToDiagnostic;
1223
+ exports.paletteFromMetamodel = paletteFromMetamodel;
1167
1224
  exports.readOnlyDispatcher = readOnlyDispatcher;
1168
1225
  exports.typeHintsFor = typeHintsFor;
1169
1226