@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.
@@ -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, every {@link DefaultActionDispatcher.dispatch} call is
14
- * wrapped in a {@link Tracer.time} pair that records the dispatch direction
15
- * (`→ client` vs `→ server`) and timing.
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 each action with timing and direction — especially when bringing
20
- * up a new adopter against an empty/partial diagram before its submission
21
- * flow is complete. Providing this dispatcher in the framework gives every
22
- * adopter the same observability primitive from the very first GLSP-head
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 the bracketed timing line is suppressed). Default
28
- * `undefined` times every action's dispatch while debug is enabled.
29
- * - {@link summarize} — return a non-empty string to append `[summary]`
30
- * to the log line; default returns `''` (no extra bracket).
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 log line is emitted only when `action.kind` is in
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
- * Override to enrich the log line with payload-specific detail. Return an
42
- * empty string to suppress the bracket. Default returns `''`. Called only
43
- * when debug is enabled, so it may serialise the payload.
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(_action: Action): string;
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;AAE5E,OAAO,EAAU,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG1D;;;;;;;;;;;;;;;;;;;;GAoBG;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;;;;OAIG;IACH,SAAS,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE3C;IAEQ,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/C;CACH"}
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, every {@link DefaultActionDispatcher.dispatch} call is
25
- * wrapped in a {@link Tracer.time} pair that records the dispatch direction
26
- * (`→ client` vs `→ server`) and timing.
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 each action with timing and direction — especially when bringing
31
- * up a new adopter against an empty/partial diagram before its submission
32
- * flow is complete. Providing this dispatcher in the framework gives every
33
- * adopter the same observability primitive from the very first GLSP-head
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 the bracketed timing line is suppressed). Default
39
- * `undefined` times every action's dispatch while debug is enabled.
40
- * - {@link summarize} — return a non-empty string to append `[summary]`
41
- * to the log line; default returns `''` (no extra bracket).
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 log line is emitted only when `action.kind` is in
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
- * Override to enrich the log line with payload-specific detail. Return an
53
- * empty string to suppress the bracket. Default returns `''`. Called only
54
- * when debug is enabled, so it may serialise the payload.
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(_action) {
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
- const label = summary
66
- ? `Dispatch action '${action.kind}' ${direction} [${summary}]`
67
- : `Dispatch action '${action.kind}' ${direction}`;
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;AAC5E,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;;;;;;;;;;;;;;;;;;;;GAoBG;AAEI,IAAM,mCAAmC,GAAzC,MAAM,mCAAoC,SAAQ,uBAAuB;IAC7E,qFAAqF;IACnC,MAAM,CAAU;IAElE;;;OAGG;IACgB,WAAW,GAAoC,SAAS,CAAC;IAE5E;;;;OAIG;IACO,SAAS,CAAC,OAAe;QAChC,OAAO,EAAE,CAAC;IACb,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,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,KAAK,GAAG,OAAO;YAClB,CAAC,CAAC,oBAAoB,MAAM,CAAC,IAAI,KAAK,SAAS,KAAK,OAAO,GAAG;YAC9D,CAAC,CAAC,oBAAoB,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACrD,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;AA5BoD;IAAjD,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC;;mEAAoC;AAFxD,mCAAmC;IAD/C,UAAU,EAAE;GACA,mCAAmC,CA8B/C"}
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.279",
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.279",
74
- "@hydranium/langium": "1.0.0-next.279",
75
- "@hydranium/protocol": "1.0.0-next.279",
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.279",
86
- "@hydranium/langium": "1.0.0-next.279",
87
- "@hydranium/protocol": "1.0.0-next.279",
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, every {@link DefaultActionDispatcher.dispatch} call is
18
- * wrapped in a {@link Tracer.time} pair that records the dispatch direction
19
- * (`→ client` vs `→ server`) and timing.
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 each action with timing and direction — especially when bringing
24
- * up a new adopter against an empty/partial diagram before its submission
25
- * flow is complete. Providing this dispatcher in the framework gives every
26
- * adopter the same observability primitive from the very first GLSP-head
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 the bracketed timing line is suppressed). Default
32
- * `undefined` times every action's dispatch while debug is enabled.
33
- * - {@link summarize} — return a non-empty string to append `[summary]`
34
- * to the log line; default returns `''` (no extra bracket).
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 log line is emitted only when `action.kind` is in
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
- * Override to enrich the log line with payload-specific detail. Return an
49
- * empty string to suppress the bracket. Default returns `''`. Called only
50
- * when debug is enabled, so it may serialise the payload.
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(_action: Action): string {
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
- const label = summary
63
- ? `Dispatch action '${action.kind}' ${direction} [${summary}]`
64
- : `Dispatch action '${action.kind}' ${direction}`;
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
  }