@istar-ts/actions 0.15.0-beta.2 → 0.15.0-beta.4
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 +86 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -2
- package/dist/index.d.ts +65 -2
- package/dist/index.js +87 -18
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -19,7 +19,9 @@ const OPERATION_KIND_LIST = [
|
|
|
19
19
|
"istar.setLinkValue",
|
|
20
20
|
"istar.updateLinkDisplay",
|
|
21
21
|
"istar.changeLinkKind",
|
|
22
|
-
"istar.setFileMetamodel"
|
|
22
|
+
"istar.setFileMetamodel",
|
|
23
|
+
"istar.updateModelExtra",
|
|
24
|
+
"istar.replaceModel"
|
|
23
25
|
];
|
|
24
26
|
const REQUEST_KIND_LIST = [
|
|
25
27
|
"requestModel",
|
|
@@ -276,6 +278,11 @@ function rejectCheck(check, endpoints) {
|
|
|
276
278
|
function metaOf(model) {
|
|
277
279
|
return (0, _istar_ts_core.metamodelOf)(model);
|
|
278
280
|
}
|
|
281
|
+
/**
|
|
282
|
+
* Keys `istar.updateModelExtra`'s `set`/`remove` must not touch: every key core models itself
|
|
283
|
+
* (`TOP_LEVEL_KEYS`, which includes `tool`), and `"metamodel"` (`istar.setFileMetamodel`'s own).
|
|
284
|
+
*/
|
|
285
|
+
const RESERVED_EXTRA_KEYS = /* @__PURE__ */ new Set([..._istar_ts_core.TOP_LEVEL_KEYS, _istar_ts_core.FILE_METAMODEL_KEY]);
|
|
279
286
|
/** A model with `links` changed, as the core operations derive one. */
|
|
280
287
|
function withLinks(model, links) {
|
|
281
288
|
return (0, _istar_ts_core.inheritMetamodel)(model, (0, _istar_ts_core.inheritSourceLayout)(model, {
|
|
@@ -316,17 +323,25 @@ function createActionDispatcher(store, options = {}) {
|
|
|
316
323
|
const listeners = /* @__PURE__ */ new Set();
|
|
317
324
|
let saved = s.getModel();
|
|
318
325
|
let dirty = false;
|
|
326
|
+
/**
|
|
327
|
+
* The origin of the dispatch currently applying synchronously (set by `dispatch`, around the
|
|
328
|
+
* synchronous part of `run`): what the store's subscription below echoes on
|
|
329
|
+
* `sourceModelChanged`/`setDirtyState`. `undefined` for a change not caused by a dispatch (a
|
|
330
|
+
* host's direct `store.load`) or once `run`'s synchronous part has returned.
|
|
331
|
+
*/
|
|
332
|
+
let currentOrigin;
|
|
319
333
|
const emit = (action) => {
|
|
320
334
|
for (const listener of listeners) listener(action);
|
|
321
335
|
};
|
|
322
|
-
const updateDirty = (reason) => {
|
|
336
|
+
const updateDirty = (reason, origin) => {
|
|
323
337
|
const next = s.getModel() !== saved;
|
|
324
338
|
if (next === dirty) return;
|
|
325
339
|
dirty = next;
|
|
326
340
|
emit({
|
|
327
341
|
kind: "setDirtyState",
|
|
328
342
|
isDirty: next,
|
|
329
|
-
reason
|
|
343
|
+
reason,
|
|
344
|
+
...origin === void 0 ? {} : { origin }
|
|
330
345
|
});
|
|
331
346
|
};
|
|
332
347
|
const REASONS = {
|
|
@@ -346,9 +361,10 @@ function createActionDispatcher(store, options = {}) {
|
|
|
346
361
|
...options.sendModel ? {
|
|
347
362
|
canUndo: s.canUndo(),
|
|
348
363
|
canRedo: s.canRedo()
|
|
349
|
-
} : {}
|
|
364
|
+
} : {},
|
|
365
|
+
...currentOrigin === void 0 ? {} : { origin: currentOrigin }
|
|
350
366
|
});
|
|
351
|
-
updateDirty(REASONS[event.source]);
|
|
367
|
+
updateDirty(REASONS[event.source], currentOrigin);
|
|
352
368
|
});
|
|
353
369
|
const requireElement = (id) => s.getModel().elements.get(id) ?? reject(`unknown element "${id}"`, id, "unknown-element");
|
|
354
370
|
const runGuards = (operation, warnings) => {
|
|
@@ -573,6 +589,48 @@ function createActionDispatcher(store, options = {}) {
|
|
|
573
589
|
s.replace(next);
|
|
574
590
|
return;
|
|
575
591
|
}
|
|
592
|
+
case "istar.updateModelExtra": {
|
|
593
|
+
const { set, remove, tool } = operation;
|
|
594
|
+
for (const key of [...Object.keys(set ?? {}), ...remove ?? []]) {
|
|
595
|
+
if (!RESERVED_EXTRA_KEYS.has(key)) continue;
|
|
596
|
+
if (key === "tool") reject(`"tool" is a modelled field: set it with this operation's own "tool"`, "", "reserved-key");
|
|
597
|
+
if (key === _istar_ts_core.FILE_METAMODEL_KEY) reject(`"${key}" is set with istar.setFileMetamodel, not updateModelExtra`, "", "reserved-key");
|
|
598
|
+
reject(`"${key}" is modelled by the file itself and cannot be an extra key`, "", "reserved-key");
|
|
599
|
+
}
|
|
600
|
+
let withTool = model;
|
|
601
|
+
if (tool === null) {
|
|
602
|
+
const { tool: _tool, ...rest } = withTool;
|
|
603
|
+
withTool = rest;
|
|
604
|
+
} else if (tool !== void 0) withTool = {
|
|
605
|
+
...withTool,
|
|
606
|
+
tool
|
|
607
|
+
};
|
|
608
|
+
const extra = { ...withTool.extra };
|
|
609
|
+
if (set) for (const [key, value] of Object.entries(set)) extra[key] = value;
|
|
610
|
+
if (remove) for (const key of remove) delete extra[key];
|
|
611
|
+
const { extra: _extra, ...rest } = withTool;
|
|
612
|
+
const next = {
|
|
613
|
+
...rest,
|
|
614
|
+
...Object.keys(extra).length > 0 ? { extra } : {}
|
|
615
|
+
};
|
|
616
|
+
s.replace((0, _istar_ts_core.inheritMetamodel)(model, (0, _istar_ts_core.inheritSourceLayout)(model, next)));
|
|
617
|
+
return;
|
|
618
|
+
}
|
|
619
|
+
case "istar.replaceModel": {
|
|
620
|
+
const host = (0, _istar_ts_core.hostMetamodelOf)(model) ?? meta;
|
|
621
|
+
let next;
|
|
622
|
+
try {
|
|
623
|
+
next = (0, _istar_ts_core.parsePistar)(operation.model, {
|
|
624
|
+
metamodel: host,
|
|
625
|
+
fileMetamodel: operation.fileMetamodel ?? false
|
|
626
|
+
});
|
|
627
|
+
} catch (error) {
|
|
628
|
+
if (error instanceof _istar_ts_core.PistarParseError) reject(error.message, "", "parse-error");
|
|
629
|
+
throw error;
|
|
630
|
+
}
|
|
631
|
+
s.replace(next);
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
576
634
|
default: reject(`unknown operation "${operation.kind}"`, "", "unknown-action");
|
|
577
635
|
}
|
|
578
636
|
};
|
|
@@ -585,7 +643,8 @@ function createActionDispatcher(store, options = {}) {
|
|
|
585
643
|
for (const [key, value] of Object.entries(properties)) if (value === null) delete next[key];
|
|
586
644
|
else if (typeof value === "string") next[key] = value;
|
|
587
645
|
else reject(`the value of "${key}" must be a string or null`, id, "invalid-value");
|
|
588
|
-
|
|
646
|
+
if (Object.keys(next).length === 0 && owner.customProperties === void 0) return;
|
|
647
|
+
const customProperties = next;
|
|
589
648
|
if (model.elements.has(id)) s.updateElement(id, { customProperties });
|
|
590
649
|
else s.updateLink(id, { customProperties });
|
|
591
650
|
};
|
|
@@ -745,7 +804,7 @@ function createActionDispatcher(store, options = {}) {
|
|
|
745
804
|
default: return;
|
|
746
805
|
}
|
|
747
806
|
};
|
|
748
|
-
const run = async (action) => {
|
|
807
|
+
const run = async (action, origin) => {
|
|
749
808
|
if (isOperation(action)) return runOperation(action);
|
|
750
809
|
if (isRequestAction(action)) return {
|
|
751
810
|
ok: true,
|
|
@@ -770,7 +829,7 @@ function createActionDispatcher(store, options = {}) {
|
|
|
770
829
|
const model = s.getModel();
|
|
771
830
|
await options.save((0, _istar_ts_core.toPistarObject)(model, { saveDate: /* @__PURE__ */ new Date() }), action);
|
|
772
831
|
saved = model;
|
|
773
|
-
updateDirty("save");
|
|
832
|
+
updateDirty("save", origin);
|
|
774
833
|
return {
|
|
775
834
|
ok: true,
|
|
776
835
|
createdIds: []
|
|
@@ -790,9 +849,17 @@ function createActionDispatcher(store, options = {}) {
|
|
|
790
849
|
}
|
|
791
850
|
};
|
|
792
851
|
return {
|
|
793
|
-
async dispatch(action) {
|
|
852
|
+
async dispatch(action, dispatchOptions) {
|
|
853
|
+
const origin = dispatchOptions?.origin;
|
|
854
|
+
currentOrigin = origin;
|
|
855
|
+
let pending;
|
|
856
|
+
try {
|
|
857
|
+
pending = run(action, origin);
|
|
858
|
+
} finally {
|
|
859
|
+
currentOrigin = void 0;
|
|
860
|
+
}
|
|
794
861
|
try {
|
|
795
|
-
return await
|
|
862
|
+
return await pending;
|
|
796
863
|
} catch (error) {
|
|
797
864
|
if (error instanceof Rejection) return {
|
|
798
865
|
ok: false,
|
|
@@ -1016,8 +1083,8 @@ function createMirrorStore(remote, options = {}) {
|
|
|
1016
1083
|
return {
|
|
1017
1084
|
ready,
|
|
1018
1085
|
dispatcher: {
|
|
1019
|
-
async dispatch(action) {
|
|
1020
|
-
const result = await r.dispatch(action);
|
|
1086
|
+
async dispatch(action, options) {
|
|
1087
|
+
const result = await r.dispatch(action, options);
|
|
1021
1088
|
await tail;
|
|
1022
1089
|
return result;
|
|
1023
1090
|
},
|
|
@@ -1103,8 +1170,9 @@ function connectDispatcher(port, dispatcher) {
|
|
|
1103
1170
|
port.onmessage = (ev) => {
|
|
1104
1171
|
const message = ev.data;
|
|
1105
1172
|
if (!isRecord(message) || message.jsonrpc !== JSONRPC_VERSION) return;
|
|
1106
|
-
const { id, method, params } = message;
|
|
1173
|
+
const { id, method, params, origin } = message;
|
|
1107
1174
|
const hasId = isJsonRpcId(id);
|
|
1175
|
+
const dispatchOptions = typeof origin === "string" ? { origin } : void 0;
|
|
1108
1176
|
if (typeof method !== "string" || method.length === 0) {
|
|
1109
1177
|
if (hasId) port.postMessage(errorMessage(id, -32601, "method not found"));
|
|
1110
1178
|
return;
|
|
@@ -1115,10 +1183,10 @@ function connectDispatcher(port, dispatcher) {
|
|
|
1115
1183
|
}
|
|
1116
1184
|
const action = params;
|
|
1117
1185
|
if (!hasId) {
|
|
1118
|
-
dispatcher.dispatch(action);
|
|
1186
|
+
dispatcher.dispatch(action, dispatchOptions);
|
|
1119
1187
|
return;
|
|
1120
1188
|
}
|
|
1121
|
-
dispatcher.dispatch(action).then((result) => {
|
|
1189
|
+
dispatcher.dispatch(action, dispatchOptions).then((result) => {
|
|
1122
1190
|
port.postMessage({
|
|
1123
1191
|
jsonrpc: JSONRPC_VERSION,
|
|
1124
1192
|
id,
|
|
@@ -1162,7 +1230,7 @@ function createRemoteDispatcher(port) {
|
|
|
1162
1230
|
}
|
|
1163
1231
|
};
|
|
1164
1232
|
return {
|
|
1165
|
-
dispatch(action) {
|
|
1233
|
+
dispatch(action, dispatchOptions) {
|
|
1166
1234
|
const id = nextId++;
|
|
1167
1235
|
return new Promise((resolve, reject) => {
|
|
1168
1236
|
pending.set(id, {
|
|
@@ -1173,7 +1241,8 @@ function createRemoteDispatcher(port) {
|
|
|
1173
1241
|
jsonrpc: JSONRPC_VERSION,
|
|
1174
1242
|
id,
|
|
1175
1243
|
method: action.kind,
|
|
1176
|
-
params: action
|
|
1244
|
+
params: action,
|
|
1245
|
+
...dispatchOptions?.origin === void 0 ? {} : { origin: dispatchOptions.origin }
|
|
1177
1246
|
});
|
|
1178
1247
|
});
|
|
1179
1248
|
},
|