@hydranium/glsp-server 1.0.0-next.279 → 1.0.0-next.280
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/lib/dispatcher/server-action-dispatcher.d.ts +24 -19
- package/lib/dispatcher/server-action-dispatcher.d.ts.map +1 -1
- package/lib/dispatcher/server-action-dispatcher.js +34 -22
- package/lib/dispatcher/server-action-dispatcher.js.map +1 -1
- package/package.json +7 -7
- package/src/dispatcher/server-action-dispatcher.ts +35 -22
|
@@ -6,43 +6,48 @@
|
|
|
6
6
|
*
|
|
7
7
|
* SPDX-License-Identifier: MIT
|
|
8
8
|
********************************************************************************/
|
|
9
|
-
import { type Action, DefaultActionDispatcher } from '@eclipse-glsp/server';
|
|
9
|
+
import { type Action, CheckEdgeResultAction, DefaultActionDispatcher } from '@eclipse-glsp/server';
|
|
10
10
|
import { type Tracer } from '@hydranium/protocol';
|
|
11
11
|
/**
|
|
12
12
|
* Server-side action dispatcher with built-in traffic observability: while
|
|
13
|
-
* debug is enabled,
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* debug is enabled, each {@link DefaultActionDispatcher.dispatch} call runs
|
|
14
|
+
* inside {@link Tracer.time}, which logs it with its direction (`→ client` vs
|
|
15
|
+
* `→ server`) and timing only when it is slow or fails, and an action that
|
|
16
|
+
* {@link summarize} details gets its own debug line whatever its duration.
|
|
16
17
|
*
|
|
17
18
|
* **Why this lives in the framework (vs left as an adopter override).**
|
|
18
19
|
* Debugging GLSP state, storage, and submission flows depends heavily on
|
|
19
|
-
* seeing
|
|
20
|
-
* up a new adopter against an empty/partial diagram before its
|
|
21
|
-
* flow is complete. Providing this dispatcher in the framework
|
|
22
|
-
* adopter the same observability primitive from the very first
|
|
23
|
-
* launch.
|
|
20
|
+
* seeing slow or failing actions with timing and direction — especially when
|
|
21
|
+
* bringing up a new adopter against an empty/partial diagram before its
|
|
22
|
+
* submission flow is complete. Providing this dispatcher in the framework
|
|
23
|
+
* gives every adopter the same observability primitive from the very first
|
|
24
|
+
* GLSP-head launch.
|
|
24
25
|
*
|
|
25
26
|
* **Extension points.**
|
|
26
27
|
* - {@link loggedKinds} — if set, filter the log lines (the dispatch
|
|
27
|
-
* still happens; only
|
|
28
|
-
* `undefined` times every action's dispatch while debug is enabled.
|
|
29
|
-
* - {@link summarize} — return a non-empty string to
|
|
30
|
-
*
|
|
28
|
+
* still happens; only its timing and summary lines are suppressed).
|
|
29
|
+
* Default `undefined` times every action's dispatch while debug is enabled.
|
|
30
|
+
* - {@link summarize} — return a non-empty string to log it as a debug line
|
|
31
|
+
* for the dispatch; `''` logs none.
|
|
31
32
|
*/
|
|
32
33
|
export declare class HydraniumGlspServerActionDispatcher extends DefaultActionDispatcher {
|
|
33
34
|
/** Caller-tagged tracer (auto-componented with this class name, like the logger). */
|
|
34
35
|
protected readonly tracer: Tracer;
|
|
35
36
|
/**
|
|
36
|
-
* If set, the timing
|
|
37
|
-
* this set. Subclasses override via field reassignment.
|
|
37
|
+
* If set, the timing and summary lines are emitted only when `action.kind`
|
|
38
|
+
* is in this set. Subclasses override via field reassignment.
|
|
38
39
|
*/
|
|
39
40
|
protected readonly loggedKinds: ReadonlySet<string> | undefined;
|
|
40
41
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
42
|
+
* Payload detail logged at debug before the dispatch, as
|
|
43
|
+
* `Dispatch action '<kind>' <direction> [<summary>]`, on every dispatch,
|
|
44
|
+
* fast or slow; `''` logs no line. The default details only an action whose
|
|
45
|
+
* outcome the log otherwise loses, each through a `format*` method. Called
|
|
46
|
+
* only when debug is enabled, so it may serialise the payload.
|
|
44
47
|
*/
|
|
45
|
-
protected summarize(
|
|
48
|
+
protected summarize(action: Action): string;
|
|
49
|
+
/** An edge check's verdict, so the log shows whether the server let an edge tool connect. */
|
|
50
|
+
protected formatEdgeCheck(action: CheckEdgeResultAction): string;
|
|
46
51
|
dispatch(action: Action): Promise<void>;
|
|
47
52
|
}
|
|
48
53
|
//# sourceMappingURL=server-action-dispatcher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-action-dispatcher.d.ts","sourceRoot":"","sources":["../../src/dispatcher/server-action-dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,KAAK,MAAM,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"server-action-dispatcher.d.ts","sourceRoot":"","sources":["../../src/dispatcher/server-action-dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,KAAK,MAAM,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAEnG,OAAO,EAAU,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG1D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBACa,mCAAoC,SAAQ,uBAAuB;IAC7E,qFAAqF;IACtD,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAG,MAAM,CAAC;IAElE;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,SAAS,CAAa;IAE5E;;;;;;OAMG;IACH,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAK1C;IAED,6FAA6F;IAC7F,SAAS,CAAC,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAE/D;IAEQ,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAY/C;CACH"}
|
|
@@ -15,56 +15,68 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
15
15
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
16
16
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
17
17
|
};
|
|
18
|
-
import { DefaultActionDispatcher } from '@eclipse-glsp/server';
|
|
18
|
+
import { CheckEdgeResultAction, DefaultActionDispatcher } from '@eclipse-glsp/server';
|
|
19
19
|
import { inject, injectable } from 'inversify';
|
|
20
20
|
import { Logger } from '@hydranium/protocol';
|
|
21
21
|
import { HydraniumTypes } from '../state/hydranium-shared-core-services.js';
|
|
22
22
|
/**
|
|
23
23
|
* Server-side action dispatcher with built-in traffic observability: while
|
|
24
|
-
* debug is enabled,
|
|
25
|
-
*
|
|
26
|
-
*
|
|
24
|
+
* debug is enabled, each {@link DefaultActionDispatcher.dispatch} call runs
|
|
25
|
+
* inside {@link Tracer.time}, which logs it with its direction (`→ client` vs
|
|
26
|
+
* `→ server`) and timing only when it is slow or fails, and an action that
|
|
27
|
+
* {@link summarize} details gets its own debug line whatever its duration.
|
|
27
28
|
*
|
|
28
29
|
* **Why this lives in the framework (vs left as an adopter override).**
|
|
29
30
|
* Debugging GLSP state, storage, and submission flows depends heavily on
|
|
30
|
-
* seeing
|
|
31
|
-
* up a new adopter against an empty/partial diagram before its
|
|
32
|
-
* flow is complete. Providing this dispatcher in the framework
|
|
33
|
-
* adopter the same observability primitive from the very first
|
|
34
|
-
* launch.
|
|
31
|
+
* seeing slow or failing actions with timing and direction — especially when
|
|
32
|
+
* bringing up a new adopter against an empty/partial diagram before its
|
|
33
|
+
* submission flow is complete. Providing this dispatcher in the framework
|
|
34
|
+
* gives every adopter the same observability primitive from the very first
|
|
35
|
+
* GLSP-head launch.
|
|
35
36
|
*
|
|
36
37
|
* **Extension points.**
|
|
37
38
|
* - {@link loggedKinds} — if set, filter the log lines (the dispatch
|
|
38
|
-
* still happens; only
|
|
39
|
-
* `undefined` times every action's dispatch while debug is enabled.
|
|
40
|
-
* - {@link summarize} — return a non-empty string to
|
|
41
|
-
*
|
|
39
|
+
* still happens; only its timing and summary lines are suppressed).
|
|
40
|
+
* Default `undefined` times every action's dispatch while debug is enabled.
|
|
41
|
+
* - {@link summarize} — return a non-empty string to log it as a debug line
|
|
42
|
+
* for the dispatch; `''` logs none.
|
|
42
43
|
*/
|
|
43
44
|
let HydraniumGlspServerActionDispatcher = class HydraniumGlspServerActionDispatcher extends DefaultActionDispatcher {
|
|
44
45
|
/** Caller-tagged tracer (auto-componented with this class name, like the logger). */
|
|
45
46
|
tracer;
|
|
46
47
|
/**
|
|
47
|
-
* If set, the timing
|
|
48
|
-
* this set. Subclasses override via field reassignment.
|
|
48
|
+
* If set, the timing and summary lines are emitted only when `action.kind`
|
|
49
|
+
* is in this set. Subclasses override via field reassignment.
|
|
49
50
|
*/
|
|
50
51
|
loggedKinds = undefined;
|
|
51
52
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
53
|
+
* Payload detail logged at debug before the dispatch, as
|
|
54
|
+
* `Dispatch action '<kind>' <direction> [<summary>]`, on every dispatch,
|
|
55
|
+
* fast or slow; `''` logs no line. The default details only an action whose
|
|
56
|
+
* outcome the log otherwise loses, each through a `format*` method. Called
|
|
57
|
+
* only when debug is enabled, so it may serialise the payload.
|
|
55
58
|
*/
|
|
56
|
-
summarize(
|
|
59
|
+
summarize(action) {
|
|
60
|
+
if (CheckEdgeResultAction.is(action)) {
|
|
61
|
+
return this.formatEdgeCheck(action);
|
|
62
|
+
}
|
|
57
63
|
return '';
|
|
58
64
|
}
|
|
65
|
+
/** An edge check's verdict, so the log shows whether the server let an edge tool connect. */
|
|
66
|
+
formatEdgeCheck(action) {
|
|
67
|
+
return `edgeType=${action.edgeType} source=${action.sourceElementId} target=${action.targetElementId ?? 'none'} isValid=${action.isValid}`;
|
|
68
|
+
}
|
|
59
69
|
dispatch(action) {
|
|
60
70
|
if (!Logger.isLevelEnabled('debug') || (this.loggedKinds && !this.loggedKinds.has(action.kind))) {
|
|
61
71
|
return super.dispatch(action);
|
|
62
72
|
}
|
|
63
73
|
const direction = this.clientActionForwarder.shouldForwardToClient(action) ? '→ client' : '→ server';
|
|
74
|
+
const label = `Dispatch action '${action.kind}' ${direction}`;
|
|
64
75
|
const summary = this.summarize(action);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
76
|
+
if (summary) {
|
|
77
|
+
// Its own line: `time` is silent on a fast success.
|
|
78
|
+
this.tracer.debug(`${label} [${summary}]`);
|
|
79
|
+
}
|
|
68
80
|
return this.tracer.time(label, () => super.dispatch(action), 'debug');
|
|
69
81
|
}
|
|
70
82
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-action-dispatcher.js","sourceRoot":"","sources":["../../src/dispatcher/server-action-dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;;;;;;;;;;AAElF,OAAO,EAAe,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"server-action-dispatcher.js","sourceRoot":"","sources":["../../src/dispatcher/server-action-dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;;;;;;;;;;AAElF,OAAO,EAAe,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACnG,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEI,IAAM,mCAAmC,GAAzC,MAAM,mCAAoC,SAAQ,uBAAuB;IAC7E,qFAAqF;IACnC,MAAM,CAAU;IAElE;;;OAGG;IACgB,WAAW,GAAoC,SAAS,CAAC;IAE5E;;;;;;OAMG;IACO,SAAS,CAAC,MAAc;QAC/B,IAAI,qBAAqB,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;QACD,OAAO,EAAE,CAAC;IACb,CAAC;IAED,6FAA6F;IACnF,eAAe,CAAC,MAA6B;QACpD,OAAO,YAAY,MAAM,CAAC,QAAQ,WAAW,MAAM,CAAC,eAAe,WAAW,MAAM,CAAC,eAAe,IAAI,MAAM,YAAY,MAAM,CAAC,OAAO,EAAE,CAAC;IAC9I,CAAC;IAEQ,QAAQ,CAAC,MAAc;QAC7B,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAC/F,OAAO,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;QACrG,MAAM,KAAK,GAAG,oBAAoB,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,OAAO,EAAE,CAAC;YACX,oDAAoD;YACpD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,KAAK,OAAO,GAAG,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;IACzE,CAAC;CACH,CAAA;AAxCoD;IAAjD,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC;;mEAAoC;AAFxD,mCAAmC;IAD/C,UAAU,EAAE;GACA,mCAAmC,CA0C/C"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hydranium/glsp-server",
|
|
3
|
-
"version": "1.0.0-next.
|
|
3
|
+
"version": "1.0.0-next.280",
|
|
4
4
|
"description": "GLSP protocol head for the hydranium framework. Peer of @hydranium/core/lsp and @hydranium/data-server; built on @hydranium/core.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"diagram",
|
|
@@ -70,9 +70,9 @@
|
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@eclipse-glsp/server": "2.7.0",
|
|
73
|
-
"@hydranium/core": "1.0.0-next.
|
|
74
|
-
"@hydranium/langium": "1.0.0-next.
|
|
75
|
-
"@hydranium/protocol": "1.0.0-next.
|
|
73
|
+
"@hydranium/core": "1.0.0-next.280",
|
|
74
|
+
"@hydranium/langium": "1.0.0-next.280",
|
|
75
|
+
"@hydranium/protocol": "1.0.0-next.280",
|
|
76
76
|
"inversify": "6.2.2",
|
|
77
77
|
"reflect-metadata": "0.2.2",
|
|
78
78
|
"rimraf": "^5.0.0",
|
|
@@ -82,9 +82,9 @@
|
|
|
82
82
|
},
|
|
83
83
|
"peerDependencies": {
|
|
84
84
|
"@eclipse-glsp/server": "^2.6.0",
|
|
85
|
-
"@hydranium/core": "1.0.0-next.
|
|
86
|
-
"@hydranium/langium": "1.0.0-next.
|
|
87
|
-
"@hydranium/protocol": "1.0.0-next.
|
|
85
|
+
"@hydranium/core": "1.0.0-next.280",
|
|
86
|
+
"@hydranium/langium": "1.0.0-next.280",
|
|
87
|
+
"@hydranium/protocol": "1.0.0-next.280",
|
|
88
88
|
"inversify": "^6.0.0",
|
|
89
89
|
"reflect-metadata": "^0.2.2",
|
|
90
90
|
"vscode-jsonrpc": "^9.0.0",
|
|
@@ -7,31 +7,32 @@
|
|
|
7
7
|
* SPDX-License-Identifier: MIT
|
|
8
8
|
********************************************************************************/
|
|
9
9
|
|
|
10
|
-
import { type Action, DefaultActionDispatcher } from '@eclipse-glsp/server';
|
|
10
|
+
import { type Action, CheckEdgeResultAction, DefaultActionDispatcher } from '@eclipse-glsp/server';
|
|
11
11
|
import { inject, injectable } from 'inversify';
|
|
12
12
|
import { Logger, type Tracer } from '@hydranium/protocol';
|
|
13
13
|
import { HydraniumTypes } from '../state/hydranium-shared-core-services.js';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Server-side action dispatcher with built-in traffic observability: while
|
|
17
|
-
* debug is enabled,
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* debug is enabled, each {@link DefaultActionDispatcher.dispatch} call runs
|
|
18
|
+
* inside {@link Tracer.time}, which logs it with its direction (`→ client` vs
|
|
19
|
+
* `→ server`) and timing only when it is slow or fails, and an action that
|
|
20
|
+
* {@link summarize} details gets its own debug line whatever its duration.
|
|
20
21
|
*
|
|
21
22
|
* **Why this lives in the framework (vs left as an adopter override).**
|
|
22
23
|
* Debugging GLSP state, storage, and submission flows depends heavily on
|
|
23
|
-
* seeing
|
|
24
|
-
* up a new adopter against an empty/partial diagram before its
|
|
25
|
-
* flow is complete. Providing this dispatcher in the framework
|
|
26
|
-
* adopter the same observability primitive from the very first
|
|
27
|
-
* launch.
|
|
24
|
+
* seeing slow or failing actions with timing and direction — especially when
|
|
25
|
+
* bringing up a new adopter against an empty/partial diagram before its
|
|
26
|
+
* submission flow is complete. Providing this dispatcher in the framework
|
|
27
|
+
* gives every adopter the same observability primitive from the very first
|
|
28
|
+
* GLSP-head launch.
|
|
28
29
|
*
|
|
29
30
|
* **Extension points.**
|
|
30
31
|
* - {@link loggedKinds} — if set, filter the log lines (the dispatch
|
|
31
|
-
* still happens; only
|
|
32
|
-
* `undefined` times every action's dispatch while debug is enabled.
|
|
33
|
-
* - {@link summarize} — return a non-empty string to
|
|
34
|
-
*
|
|
32
|
+
* still happens; only its timing and summary lines are suppressed).
|
|
33
|
+
* Default `undefined` times every action's dispatch while debug is enabled.
|
|
34
|
+
* - {@link summarize} — return a non-empty string to log it as a debug line
|
|
35
|
+
* for the dispatch; `''` logs none.
|
|
35
36
|
*/
|
|
36
37
|
@injectable()
|
|
37
38
|
export class HydraniumGlspServerActionDispatcher extends DefaultActionDispatcher {
|
|
@@ -39,29 +40,41 @@ export class HydraniumGlspServerActionDispatcher extends DefaultActionDispatcher
|
|
|
39
40
|
@inject(HydraniumTypes.Tracer) protected readonly tracer!: Tracer;
|
|
40
41
|
|
|
41
42
|
/**
|
|
42
|
-
* If set, the timing
|
|
43
|
-
* this set. Subclasses override via field reassignment.
|
|
43
|
+
* If set, the timing and summary lines are emitted only when `action.kind`
|
|
44
|
+
* is in this set. Subclasses override via field reassignment.
|
|
44
45
|
*/
|
|
45
46
|
protected readonly loggedKinds: ReadonlySet<string> | undefined = undefined;
|
|
46
47
|
|
|
47
48
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
49
|
+
* Payload detail logged at debug before the dispatch, as
|
|
50
|
+
* `Dispatch action '<kind>' <direction> [<summary>]`, on every dispatch,
|
|
51
|
+
* fast or slow; `''` logs no line. The default details only an action whose
|
|
52
|
+
* outcome the log otherwise loses, each through a `format*` method. Called
|
|
53
|
+
* only when debug is enabled, so it may serialise the payload.
|
|
51
54
|
*/
|
|
52
|
-
protected summarize(
|
|
55
|
+
protected summarize(action: Action): string {
|
|
56
|
+
if (CheckEdgeResultAction.is(action)) {
|
|
57
|
+
return this.formatEdgeCheck(action);
|
|
58
|
+
}
|
|
53
59
|
return '';
|
|
54
60
|
}
|
|
55
61
|
|
|
62
|
+
/** An edge check's verdict, so the log shows whether the server let an edge tool connect. */
|
|
63
|
+
protected formatEdgeCheck(action: CheckEdgeResultAction): string {
|
|
64
|
+
return `edgeType=${action.edgeType} source=${action.sourceElementId} target=${action.targetElementId ?? 'none'} isValid=${action.isValid}`;
|
|
65
|
+
}
|
|
66
|
+
|
|
56
67
|
override dispatch(action: Action): Promise<void> {
|
|
57
68
|
if (!Logger.isLevelEnabled('debug') || (this.loggedKinds && !this.loggedKinds.has(action.kind))) {
|
|
58
69
|
return super.dispatch(action);
|
|
59
70
|
}
|
|
60
71
|
const direction = this.clientActionForwarder.shouldForwardToClient(action) ? '→ client' : '→ server';
|
|
72
|
+
const label = `Dispatch action '${action.kind}' ${direction}`;
|
|
61
73
|
const summary = this.summarize(action);
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
74
|
+
if (summary) {
|
|
75
|
+
// Its own line: `time` is silent on a fast success.
|
|
76
|
+
this.tracer.debug(`${label} [${summary}]`);
|
|
77
|
+
}
|
|
65
78
|
return this.tracer.time(label, () => super.dispatch(action), 'debug');
|
|
66
79
|
}
|
|
67
80
|
}
|