@istar-ts/actions 0.15.0-beta.2 → 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 +34 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -1
- package/dist/index.d.ts +33 -1
- package/dist/index.js +34 -15
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -281,6 +281,11 @@ export interface ModelSourceChangedAction extends Action {
|
|
|
281
281
|
* created with `sendModel`). An iStar extra; a mirror uses this to know the exact state.
|
|
282
282
|
*/
|
|
283
283
|
readonly canRedo?: boolean;
|
|
284
|
+
/**
|
|
285
|
+
* The `origin` the causing `dispatch` was given, echoed back; absent for a change with none
|
|
286
|
+
* (a host's direct `store.load`, for instance). See `ActionDispatcher.dispatch`.
|
|
287
|
+
*/
|
|
288
|
+
readonly origin?: string;
|
|
284
289
|
}
|
|
285
290
|
/** Saves the model through the host's `save` callback. */
|
|
286
291
|
export interface SaveModelAction extends Action {
|
|
@@ -293,6 +298,8 @@ export interface SetDirtyStateAction extends Action {
|
|
|
293
298
|
readonly kind: "setDirtyState";
|
|
294
299
|
readonly isDirty: boolean;
|
|
295
300
|
readonly reason?: DirtyStateChangeReason;
|
|
301
|
+
/** The `origin` of the dispatch that caused this dirty-state change, echoed back; see `ModelSourceChangedAction.origin`. */
|
|
302
|
+
readonly origin?: string;
|
|
296
303
|
}
|
|
297
304
|
export interface UndoAction extends Action {
|
|
298
305
|
readonly kind: "glspUndo";
|
|
@@ -489,8 +496,31 @@ export type ActionListener<EK extends string = ElementKind, LK extends string =
|
|
|
489
496
|
* Sends actions and hears what the other side sends back. Implemented in-process by
|
|
490
497
|
* `createActionDispatcher`; a transport implements it over a message port.
|
|
491
498
|
*/
|
|
499
|
+
/** `dispatch`'s second argument. */
|
|
500
|
+
export interface DispatchOptions {
|
|
501
|
+
/**
|
|
502
|
+
* Echoed back as `origin` on every `ModelSourceChangedAction` and `SetDirtyStateAction` this
|
|
503
|
+
* dispatch causes (each change of a compound, both events of an undo or redo), so a listener
|
|
504
|
+
* can tell which surface or client made a change without tracking it itself. Carried through
|
|
505
|
+
* `createRemoteDispatcher`/`connectDispatcher` and by `createMirrorStore`'s dispatcher, so it
|
|
506
|
+
* survives a round trip to a remote host. Optional: a change with no origin (a host's direct
|
|
507
|
+
* `store.load`, for instance) has none.
|
|
508
|
+
*/
|
|
509
|
+
readonly origin?: string;
|
|
510
|
+
}
|
|
492
511
|
export interface ActionDispatcher<EK extends string = ElementKind, LK extends string = LinkKind> {
|
|
493
|
-
|
|
512
|
+
/**
|
|
513
|
+
* For a **local** dispatcher (`createActionDispatcher`), an operation, `glspUndo`/`glspRedo`,
|
|
514
|
+
* and the guards and postGuards around them, are applied to the store and every listener
|
|
515
|
+
* (`subscribe`, the store's own) is notified synchronously, before this call's promise is
|
|
516
|
+
* created to resolve — only `saveModel` awaits. Code that needs to see the result of an action
|
|
517
|
+
* before its own next statement (not just before `await dispatch(...)` resolves) can rely on
|
|
518
|
+
* this for a local dispatcher; it does **not** hold across a `createRemoteDispatcher`/
|
|
519
|
+
* `connectDispatcher` transport or a `createMirrorStore` mirror, where a change always arrives
|
|
520
|
+
* after a message round trip. Use `origin` ({@link DispatchOptions}) instead where that
|
|
521
|
+
* portability matters — it is carried through both.
|
|
522
|
+
*/
|
|
523
|
+
dispatch<A extends IstarAction<EK, LK>>(action: A, options?: DispatchOptions): Promise<ActionResult<ResponseFor<A>>>;
|
|
494
524
|
/**
|
|
495
525
|
* Hears the actions the dispatcher sends: `ModelSourceChangedAction` after every model change,
|
|
496
526
|
* `SetDirtyStateAction` when the dirty state flips, and the notifications dispatched to it.
|
|
@@ -724,6 +754,8 @@ export interface JsonRpcRequest {
|
|
|
724
754
|
readonly id: JsonRpcId;
|
|
725
755
|
readonly method: string;
|
|
726
756
|
readonly params?: unknown;
|
|
757
|
+
/** The dispatch's `origin` (`DispatchOptions.origin`), carried to the server's `dispatch`. */
|
|
758
|
+
readonly origin?: string;
|
|
727
759
|
}
|
|
728
760
|
/** A subscriber event, sent with no `id`: it expects no response. */
|
|
729
761
|
export interface JsonRpcNotification {
|
package/dist/index.d.ts
CHANGED
|
@@ -281,6 +281,11 @@ export interface ModelSourceChangedAction extends Action {
|
|
|
281
281
|
* created with `sendModel`). An iStar extra; a mirror uses this to know the exact state.
|
|
282
282
|
*/
|
|
283
283
|
readonly canRedo?: boolean;
|
|
284
|
+
/**
|
|
285
|
+
* The `origin` the causing `dispatch` was given, echoed back; absent for a change with none
|
|
286
|
+
* (a host's direct `store.load`, for instance). See `ActionDispatcher.dispatch`.
|
|
287
|
+
*/
|
|
288
|
+
readonly origin?: string;
|
|
284
289
|
}
|
|
285
290
|
/** Saves the model through the host's `save` callback. */
|
|
286
291
|
export interface SaveModelAction extends Action {
|
|
@@ -293,6 +298,8 @@ export interface SetDirtyStateAction extends Action {
|
|
|
293
298
|
readonly kind: "setDirtyState";
|
|
294
299
|
readonly isDirty: boolean;
|
|
295
300
|
readonly reason?: DirtyStateChangeReason;
|
|
301
|
+
/** The `origin` of the dispatch that caused this dirty-state change, echoed back; see `ModelSourceChangedAction.origin`. */
|
|
302
|
+
readonly origin?: string;
|
|
296
303
|
}
|
|
297
304
|
export interface UndoAction extends Action {
|
|
298
305
|
readonly kind: "glspUndo";
|
|
@@ -489,8 +496,31 @@ export type ActionListener<EK extends string = ElementKind, LK extends string =
|
|
|
489
496
|
* Sends actions and hears what the other side sends back. Implemented in-process by
|
|
490
497
|
* `createActionDispatcher`; a transport implements it over a message port.
|
|
491
498
|
*/
|
|
499
|
+
/** `dispatch`'s second argument. */
|
|
500
|
+
export interface DispatchOptions {
|
|
501
|
+
/**
|
|
502
|
+
* Echoed back as `origin` on every `ModelSourceChangedAction` and `SetDirtyStateAction` this
|
|
503
|
+
* dispatch causes (each change of a compound, both events of an undo or redo), so a listener
|
|
504
|
+
* can tell which surface or client made a change without tracking it itself. Carried through
|
|
505
|
+
* `createRemoteDispatcher`/`connectDispatcher` and by `createMirrorStore`'s dispatcher, so it
|
|
506
|
+
* survives a round trip to a remote host. Optional: a change with no origin (a host's direct
|
|
507
|
+
* `store.load`, for instance) has none.
|
|
508
|
+
*/
|
|
509
|
+
readonly origin?: string;
|
|
510
|
+
}
|
|
492
511
|
export interface ActionDispatcher<EK extends string = ElementKind, LK extends string = LinkKind> {
|
|
493
|
-
|
|
512
|
+
/**
|
|
513
|
+
* For a **local** dispatcher (`createActionDispatcher`), an operation, `glspUndo`/`glspRedo`,
|
|
514
|
+
* and the guards and postGuards around them, are applied to the store and every listener
|
|
515
|
+
* (`subscribe`, the store's own) is notified synchronously, before this call's promise is
|
|
516
|
+
* created to resolve — only `saveModel` awaits. Code that needs to see the result of an action
|
|
517
|
+
* before its own next statement (not just before `await dispatch(...)` resolves) can rely on
|
|
518
|
+
* this for a local dispatcher; it does **not** hold across a `createRemoteDispatcher`/
|
|
519
|
+
* `connectDispatcher` transport or a `createMirrorStore` mirror, where a change always arrives
|
|
520
|
+
* after a message round trip. Use `origin` ({@link DispatchOptions}) instead where that
|
|
521
|
+
* portability matters — it is carried through both.
|
|
522
|
+
*/
|
|
523
|
+
dispatch<A extends IstarAction<EK, LK>>(action: A, options?: DispatchOptions): Promise<ActionResult<ResponseFor<A>>>;
|
|
494
524
|
/**
|
|
495
525
|
* Hears the actions the dispatcher sends: `ModelSourceChangedAction` after every model change,
|
|
496
526
|
* `SetDirtyStateAction` when the dirty state flips, and the notifications dispatched to it.
|
|
@@ -724,6 +754,8 @@ export interface JsonRpcRequest {
|
|
|
724
754
|
readonly id: JsonRpcId;
|
|
725
755
|
readonly method: string;
|
|
726
756
|
readonly params?: unknown;
|
|
757
|
+
/** The dispatch's `origin` (`DispatchOptions.origin`), carried to the server's `dispatch`. */
|
|
758
|
+
readonly origin?: string;
|
|
727
759
|
}
|
|
728
760
|
/** A subscriber event, sent with no `id`: it expects no response. */
|
|
729
761
|
export interface JsonRpcNotification {
|
package/dist/index.js
CHANGED
|
@@ -315,17 +315,25 @@ function createActionDispatcher(store, options = {}) {
|
|
|
315
315
|
const listeners = /* @__PURE__ */ new Set();
|
|
316
316
|
let saved = s.getModel();
|
|
317
317
|
let dirty = false;
|
|
318
|
+
/**
|
|
319
|
+
* The origin of the dispatch currently applying synchronously (set by `dispatch`, around the
|
|
320
|
+
* synchronous part of `run`): what the store's subscription below echoes on
|
|
321
|
+
* `sourceModelChanged`/`setDirtyState`. `undefined` for a change not caused by a dispatch (a
|
|
322
|
+
* host's direct `store.load`) or once `run`'s synchronous part has returned.
|
|
323
|
+
*/
|
|
324
|
+
let currentOrigin;
|
|
318
325
|
const emit = (action) => {
|
|
319
326
|
for (const listener of listeners) listener(action);
|
|
320
327
|
};
|
|
321
|
-
const updateDirty = (reason) => {
|
|
328
|
+
const updateDirty = (reason, origin) => {
|
|
322
329
|
const next = s.getModel() !== saved;
|
|
323
330
|
if (next === dirty) return;
|
|
324
331
|
dirty = next;
|
|
325
332
|
emit({
|
|
326
333
|
kind: "setDirtyState",
|
|
327
334
|
isDirty: next,
|
|
328
|
-
reason
|
|
335
|
+
reason,
|
|
336
|
+
...origin === void 0 ? {} : { origin }
|
|
329
337
|
});
|
|
330
338
|
};
|
|
331
339
|
const REASONS = {
|
|
@@ -345,9 +353,10 @@ function createActionDispatcher(store, options = {}) {
|
|
|
345
353
|
...options.sendModel ? {
|
|
346
354
|
canUndo: s.canUndo(),
|
|
347
355
|
canRedo: s.canRedo()
|
|
348
|
-
} : {}
|
|
356
|
+
} : {},
|
|
357
|
+
...currentOrigin === void 0 ? {} : { origin: currentOrigin }
|
|
349
358
|
});
|
|
350
|
-
updateDirty(REASONS[event.source]);
|
|
359
|
+
updateDirty(REASONS[event.source], currentOrigin);
|
|
351
360
|
});
|
|
352
361
|
const requireElement = (id) => s.getModel().elements.get(id) ?? reject(`unknown element "${id}"`, id, "unknown-element");
|
|
353
362
|
const runGuards = (operation, warnings) => {
|
|
@@ -744,7 +753,7 @@ function createActionDispatcher(store, options = {}) {
|
|
|
744
753
|
default: return;
|
|
745
754
|
}
|
|
746
755
|
};
|
|
747
|
-
const run = async (action) => {
|
|
756
|
+
const run = async (action, origin) => {
|
|
748
757
|
if (isOperation(action)) return runOperation(action);
|
|
749
758
|
if (isRequestAction(action)) return {
|
|
750
759
|
ok: true,
|
|
@@ -769,7 +778,7 @@ function createActionDispatcher(store, options = {}) {
|
|
|
769
778
|
const model = s.getModel();
|
|
770
779
|
await options.save(toPistarObject(model, { saveDate: /* @__PURE__ */ new Date() }), action);
|
|
771
780
|
saved = model;
|
|
772
|
-
updateDirty("save");
|
|
781
|
+
updateDirty("save", origin);
|
|
773
782
|
return {
|
|
774
783
|
ok: true,
|
|
775
784
|
createdIds: []
|
|
@@ -789,9 +798,17 @@ function createActionDispatcher(store, options = {}) {
|
|
|
789
798
|
}
|
|
790
799
|
};
|
|
791
800
|
return {
|
|
792
|
-
async dispatch(action) {
|
|
801
|
+
async dispatch(action, dispatchOptions) {
|
|
802
|
+
const origin = dispatchOptions?.origin;
|
|
803
|
+
currentOrigin = origin;
|
|
804
|
+
let pending;
|
|
805
|
+
try {
|
|
806
|
+
pending = run(action, origin);
|
|
807
|
+
} finally {
|
|
808
|
+
currentOrigin = void 0;
|
|
809
|
+
}
|
|
793
810
|
try {
|
|
794
|
-
return await
|
|
811
|
+
return await pending;
|
|
795
812
|
} catch (error) {
|
|
796
813
|
if (error instanceof Rejection) return {
|
|
797
814
|
ok: false,
|
|
@@ -1015,8 +1032,8 @@ function createMirrorStore(remote, options = {}) {
|
|
|
1015
1032
|
return {
|
|
1016
1033
|
ready,
|
|
1017
1034
|
dispatcher: {
|
|
1018
|
-
async dispatch(action) {
|
|
1019
|
-
const result = await r.dispatch(action);
|
|
1035
|
+
async dispatch(action, options) {
|
|
1036
|
+
const result = await r.dispatch(action, options);
|
|
1020
1037
|
await tail;
|
|
1021
1038
|
return result;
|
|
1022
1039
|
},
|
|
@@ -1102,8 +1119,9 @@ function connectDispatcher(port, dispatcher) {
|
|
|
1102
1119
|
port.onmessage = (ev) => {
|
|
1103
1120
|
const message = ev.data;
|
|
1104
1121
|
if (!isRecord(message) || message.jsonrpc !== JSONRPC_VERSION) return;
|
|
1105
|
-
const { id, method, params } = message;
|
|
1122
|
+
const { id, method, params, origin } = message;
|
|
1106
1123
|
const hasId = isJsonRpcId(id);
|
|
1124
|
+
const dispatchOptions = typeof origin === "string" ? { origin } : void 0;
|
|
1107
1125
|
if (typeof method !== "string" || method.length === 0) {
|
|
1108
1126
|
if (hasId) port.postMessage(errorMessage(id, -32601, "method not found"));
|
|
1109
1127
|
return;
|
|
@@ -1114,10 +1132,10 @@ function connectDispatcher(port, dispatcher) {
|
|
|
1114
1132
|
}
|
|
1115
1133
|
const action = params;
|
|
1116
1134
|
if (!hasId) {
|
|
1117
|
-
dispatcher.dispatch(action);
|
|
1135
|
+
dispatcher.dispatch(action, dispatchOptions);
|
|
1118
1136
|
return;
|
|
1119
1137
|
}
|
|
1120
|
-
dispatcher.dispatch(action).then((result) => {
|
|
1138
|
+
dispatcher.dispatch(action, dispatchOptions).then((result) => {
|
|
1121
1139
|
port.postMessage({
|
|
1122
1140
|
jsonrpc: JSONRPC_VERSION,
|
|
1123
1141
|
id,
|
|
@@ -1161,7 +1179,7 @@ function createRemoteDispatcher(port) {
|
|
|
1161
1179
|
}
|
|
1162
1180
|
};
|
|
1163
1181
|
return {
|
|
1164
|
-
dispatch(action) {
|
|
1182
|
+
dispatch(action, dispatchOptions) {
|
|
1165
1183
|
const id = nextId++;
|
|
1166
1184
|
return new Promise((resolve, reject) => {
|
|
1167
1185
|
pending.set(id, {
|
|
@@ -1172,7 +1190,8 @@ function createRemoteDispatcher(port) {
|
|
|
1172
1190
|
jsonrpc: JSONRPC_VERSION,
|
|
1173
1191
|
id,
|
|
1174
1192
|
method: action.kind,
|
|
1175
|
-
params: action
|
|
1193
|
+
params: action,
|
|
1194
|
+
...dispatchOptions?.origin === void 0 ? {} : { origin: dispatchOptions.origin }
|
|
1176
1195
|
});
|
|
1177
1196
|
});
|
|
1178
1197
|
},
|