@hydranium/glsp-client-theia 1.0.0-next.32 → 1.0.0-next.321

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.
Files changed (87) hide show
  1. package/README.md +60 -98
  2. package/lib/browser/client-contribution.d.ts +87 -25
  3. package/lib/browser/client-contribution.d.ts.map +1 -1
  4. package/lib/browser/client-contribution.js +233 -53
  5. package/lib/browser/client-contribution.js.map +1 -1
  6. package/lib/browser/diagram-only-marker-manager.d.ts.map +1 -1
  7. package/lib/browser/diagram-only-marker-manager.js.map +1 -1
  8. package/lib/browser/diagram-widget.d.ts +43 -25
  9. package/lib/browser/diagram-widget.d.ts.map +1 -1
  10. package/lib/browser/diagram-widget.js +76 -26
  11. package/lib/browser/diagram-widget.js.map +1 -1
  12. package/lib/browser/glsp-client-theia-module.d.ts +12 -5
  13. package/lib/browser/glsp-client-theia-module.d.ts.map +1 -1
  14. package/lib/browser/glsp-client-theia-module.js +27 -12
  15. package/lib/browser/glsp-client-theia-module.js.map +1 -1
  16. package/lib/browser/glsp-diagram-manager.d.ts +40 -1
  17. package/lib/browser/glsp-diagram-manager.d.ts.map +1 -1
  18. package/lib/browser/glsp-diagram-manager.js +100 -0
  19. package/lib/browser/glsp-diagram-manager.js.map +1 -1
  20. package/lib/browser/glsp-message-service.d.ts.map +1 -1
  21. package/lib/browser/glsp-message-service.js.map +1 -1
  22. package/lib/browser/glsp-saveable.d.ts +67 -0
  23. package/lib/browser/glsp-saveable.d.ts.map +1 -0
  24. package/lib/browser/glsp-saveable.js +110 -0
  25. package/lib/browser/glsp-saveable.js.map +1 -0
  26. package/lib/browser/glsp-theia-frontend-module.d.ts.map +1 -1
  27. package/lib/browser/glsp-theia-frontend-module.js +4 -1
  28. package/lib/browser/glsp-theia-frontend-module.js.map +1 -1
  29. package/lib/browser/hydranium-glsp-diagram-configuration.d.ts +3 -1
  30. package/lib/browser/hydranium-glsp-diagram-configuration.d.ts.map +1 -1
  31. package/lib/browser/hydranium-glsp-diagram-configuration.js +3 -1
  32. package/lib/browser/hydranium-glsp-diagram-configuration.js.map +1 -1
  33. package/lib/browser/index.d.ts +4 -3
  34. package/lib/browser/index.d.ts.map +1 -1
  35. package/lib/browser/index.js +7 -5
  36. package/lib/browser/index.js.map +1 -1
  37. package/lib/browser/theia-diagram-loader.d.ts +25 -0
  38. package/lib/browser/theia-diagram-loader.d.ts.map +1 -0
  39. package/lib/browser/theia-diagram-loader.js +42 -0
  40. package/lib/browser/theia-diagram-loader.js.map +1 -0
  41. package/lib/browser/window-session.d.ts +57 -0
  42. package/lib/browser/window-session.d.ts.map +1 -0
  43. package/lib/browser/window-session.js +102 -0
  44. package/lib/browser/window-session.js.map +1 -0
  45. package/lib/node/connection-container-module.js.map +1 -1
  46. package/lib/node/glsp-server-connection-handler.d.ts +11 -20
  47. package/lib/node/glsp-server-connection-handler.d.ts.map +1 -1
  48. package/lib/node/glsp-server-connection-handler.js +12 -15
  49. package/lib/node/glsp-server-connection-handler.js.map +1 -1
  50. package/package.json +37 -46
  51. package/src/browser/client-contribution.ts +254 -55
  52. package/src/browser/diagram-widget.ts +80 -28
  53. package/src/browser/glsp-client-theia-module.ts +34 -13
  54. package/src/browser/glsp-diagram-manager.ts +112 -3
  55. package/src/browser/glsp-saveable.ts +111 -0
  56. package/src/browser/glsp-theia-frontend-module.ts +4 -1
  57. package/src/browser/hydranium-glsp-diagram-configuration.ts +3 -1
  58. package/src/browser/index.ts +12 -5
  59. package/src/browser/theia-diagram-loader.ts +31 -0
  60. package/src/browser/window-session.ts +114 -0
  61. package/src/node/glsp-server-connection-handler.ts +12 -24
  62. package/style/diagram-loading.css +2 -5
  63. package/lib/browser/action-dispatcher.d.ts +0 -85
  64. package/lib/browser/action-dispatcher.d.ts.map +0 -1
  65. package/lib/browser/action-dispatcher.js +0 -238
  66. package/lib/browser/action-dispatcher.js.map +0 -1
  67. package/lib/browser/diagram-loader.d.ts +0 -123
  68. package/lib/browser/diagram-loader.d.ts.map +0 -1
  69. package/lib/browser/diagram-loader.js +0 -153
  70. package/lib/browser/diagram-loader.js.map +0 -1
  71. package/lib/browser/hidden-bounds-updater.d.ts +0 -122
  72. package/lib/browser/hidden-bounds-updater.d.ts.map +0 -1
  73. package/lib/browser/hidden-bounds-updater.js +0 -207
  74. package/lib/browser/hidden-bounds-updater.js.map +0 -1
  75. package/lib/testing/bind-recorder.d.ts +0 -67
  76. package/lib/testing/bind-recorder.d.ts.map +0 -1
  77. package/lib/testing/bind-recorder.js +0 -72
  78. package/lib/testing/bind-recorder.js.map +0 -1
  79. package/lib/testing/index.d.ts +0 -10
  80. package/lib/testing/index.d.ts.map +0 -1
  81. package/lib/testing/index.js +0 -30
  82. package/lib/testing/index.js.map +0 -1
  83. package/src/browser/action-dispatcher.ts +0 -257
  84. package/src/browser/diagram-loader.ts +0 -173
  85. package/src/browser/hidden-bounds-updater.ts +0 -212
  86. package/src/testing/bind-recorder.ts +0 -126
  87. package/src/testing/index.ts +0 -15
@@ -0,0 +1,114 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+
10
+ import { randomUuid } from '@hydranium/protocol';
11
+ // Not the `@theia/core/lib/browser` barrel, which touches DOM globals at load.
12
+ import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application-contribution';
13
+ import { injectable, type interfaces } from '@theia/core/shared/inversify';
14
+
15
+ /** The `sessionStorage` key of the window's {@link WindowSession}. */
16
+ export const WINDOW_SESSION_KEY = 'hydranium.glsp.windowSession';
17
+ /** Holds the id of the window session the last page in the tab left, for the next page to take up. */
18
+ export const RELEASED_WINDOW_SESSION_KEY = 'hydranium.glsp.releasedWindowSession';
19
+
20
+ /** The window's part of every diagram client id it opens, and the token its diagrams resume with. */
21
+ export interface WindowSession {
22
+ readonly id: string;
23
+ readonly resumeToken: string;
24
+ }
25
+
26
+ export function isWindowSession(value: unknown): value is WindowSession {
27
+ return (
28
+ typeof value === 'object' &&
29
+ value !== null &&
30
+ typeof (value as WindowSession).id === 'string' &&
31
+ typeof (value as WindowSession).resumeToken === 'string'
32
+ );
33
+ }
34
+
35
+ export const WindowSessionService = Symbol('WindowSessionService');
36
+
37
+ /**
38
+ * The page's window session: the one the last page in this tab left, so a
39
+ * reload resumes its diagrams, and a new one otherwise.
40
+ *
41
+ * A reload only has a session to resume on a server that outlives the page; a
42
+ * server started per frontend, as a Theia plugin host's is, is new after one.
43
+ */
44
+ export interface WindowSessionService {
45
+ current(): WindowSession;
46
+ }
47
+
48
+ /**
49
+ * Keeps the window session in `sessionStorage` and hands it on only as the page
50
+ * leaves. A duplicated tab copies `sessionStorage` while the original page is
51
+ * still live, so the copy finds no released session and draws its own; taking
52
+ * the original's would end the original's diagram sessions. Where
53
+ * `sessionStorage` is unavailable the session lasts for the page, and a reload
54
+ * resumes nothing.
55
+ *
56
+ * Claimed as the frontend starts, not with the first diagram: until then the
57
+ * released mark stays, and a tab duplicated meanwhile would take it too. A page
58
+ * restored from the back-forward cache takes the mark back, since Theia
59
+ * before 1.75 leaves it live without a reload.
60
+ */
61
+ @injectable()
62
+ export class DefaultWindowSessionService implements WindowSessionService, FrontendApplicationContribution {
63
+ protected session?: WindowSession;
64
+
65
+ initialize(): void {
66
+ this.current();
67
+ }
68
+
69
+ current(): WindowSession {
70
+ this.session ??= this.claim();
71
+ return this.session;
72
+ }
73
+
74
+ protected claim(): WindowSession {
75
+ const created: WindowSession = { id: randomUuid(), resumeToken: randomUuid() };
76
+ try {
77
+ const storage = globalThis.sessionStorage;
78
+ const stored = this.parse(storage.getItem(WINDOW_SESSION_KEY));
79
+ const session = stored && storage.getItem(RELEASED_WINDOW_SESSION_KEY) === stored.id ? stored : created;
80
+ storage.setItem(WINDOW_SESSION_KEY, JSON.stringify(session));
81
+ storage.removeItem(RELEASED_WINDOW_SESSION_KEY);
82
+ globalThis.addEventListener?.('pagehide', () => storage.setItem(RELEASED_WINDOW_SESSION_KEY, session.id));
83
+ globalThis.addEventListener?.('pageshow', event => {
84
+ if ((event as PageTransitionEvent).persisted) {
85
+ storage.removeItem(RELEASED_WINDOW_SESSION_KEY);
86
+ }
87
+ });
88
+ return session;
89
+ } catch {
90
+ return created;
91
+ }
92
+ }
93
+
94
+ protected parse(text: string | null): WindowSession | undefined {
95
+ try {
96
+ const value: unknown = text ? JSON.parse(text) : undefined;
97
+ return isWindowSession(value) ? value : undefined;
98
+ } catch {
99
+ return undefined;
100
+ }
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Bind {@link WindowSessionService} once per container, and claim it as the
106
+ * frontend starts. An adopter rebinds {@link WindowSessionService}.
107
+ */
108
+ export function bindWindowSessionService(bind: interfaces.Bind, isBound: interfaces.IsBound): void {
109
+ if (!isBound(WindowSessionService)) {
110
+ bind(DefaultWindowSessionService).toSelf().inSingletonScope();
111
+ bind(WindowSessionService).toService(DefaultWindowSessionService);
112
+ bind(FrontendApplicationContribution).toService(WindowSessionService);
113
+ }
114
+ }
@@ -8,9 +8,7 @@
8
8
  ********************************************************************************/
9
9
 
10
10
  import { GLSPContribution } from '@eclipse-glsp/theia-integration/lib/common';
11
- import { SocketConnectionForwarder } from '@eclipse-glsp/theia-integration/lib/node';
12
- import { AbstractSocketForwardingConnectionHandler } from '@hydranium/client-theia/lib/node';
13
- import { type Channel, type Disposable } from '@theia/core';
11
+ import { AbstractSocketForwardingConnectionHandler } from '@hydranium/client-theia/node';
14
12
  import { injectable, unmanaged } from '@theia/core/shared/inversify';
15
13
  import type * as net from 'net';
16
14
 
@@ -21,15 +19,7 @@ import type * as net from 'net';
21
19
  export interface GlspServerConnectionHandlerOptions {
22
20
  readonly languageContributionId: string;
23
21
  readonly portCommand: string;
24
- /**
25
- * Product name for the connect-failure dialog this handler raises.
26
- *
27
- * It reaches the adopter's UI verbatim, so the framework default leaks a
28
- * framework noun into a product that is not ours. Not a translation concern —
29
- * routing it through a catalogue would ask an adopter to "translate" English
30
- * into their own product name, and would make their branding
31
- * locale-dependent.
32
- */
22
+ /** Name of the server in this handler's log lines. */
33
23
  readonly serverName?: string;
34
24
  readonly findPortTimeout?: number;
35
25
  readonly findPortAttempts?: number;
@@ -48,15 +38,13 @@ export interface GlspServerConnectionHandlerOptions {
48
38
  /**
49
39
  * Bridges a Theia browser-frontend channel to a GLSP server's TCP socket.
50
40
  *
51
- * The port-discovery + buffer-and-replay race fix + connect orchestration live
52
- * on the cross-head {@link AbstractSocketForwardingConnectionHandler} base; this
53
- * subclass supplies only the GLSP specifics — the per-language servicePath
41
+ * The port discovery, the buffer-and-replay race fix, the connect orchestration
42
+ * and the byte forwarder live on the cross-head
43
+ * {@link AbstractSocketForwardingConnectionHandler} base; this subclass supplies
44
+ * only the GLSP specifics — the per-language servicePath
54
45
  * (`GLSPContribution.servicePath + '/' + languageContributionId`), the port
55
- * command, the log labels — and plugs in `@eclipse-glsp/theia-integration`'s
56
- * `SocketConnectionForwarder` as the byte relay. Adopters with different
57
- * language ids or command names subclass with a one-line `super({...})` call.
58
- * Sibling of `@hydranium/data-client-theia`'s `DataServerConnectionHandler`,
59
- * which subclasses the same base with its own GLSP-free forwarder.
46
+ * command, the log labels. Adopters with different language ids or command
47
+ * names subclass with a one-line `super({...})` call.
60
48
  */
61
49
  @injectable()
62
50
  export class GlspServerConnectionHandler extends AbstractSocketForwardingConnectionHandler {
@@ -65,7 +53,7 @@ export class GlspServerConnectionHandler extends AbstractSocketForwardingConnect
65
53
  path: GLSPContribution.servicePath + '/' + options.languageContributionId,
66
54
  portCommand: options.portCommand,
67
55
  logComponent: 'GLSP',
68
- serverName: options.serverName ?? 'Graphical Server',
56
+ serverName: options.serverName ?? 'Diagram Server',
69
57
  findPortTimeout: options.findPortTimeout,
70
58
  findPortAttempts: options.findPortAttempts,
71
59
  connectTimeoutMs: options.connectTimeoutMs,
@@ -73,7 +61,7 @@ export class GlspServerConnectionHandler extends AbstractSocketForwardingConnect
73
61
  });
74
62
  }
75
63
 
76
- protected forwardToSocketConnection(clientChannel: Channel, socket: net.Socket): Disposable {
77
- return new SocketConnectionForwarder(clientChannel, socket);
78
- }
64
+ /** Logged only: the frontend contribution reports the failed start, and a
65
+ * second notification would duplicate it. */
66
+ protected override reportConnectFailure(): void {}
79
67
  }
@@ -49,11 +49,8 @@
49
49
  }
50
50
  }
51
51
 
52
- /* Failure state: set only when the loader could NOT dispatch its error
53
- StatusAction, so this overlay is the single remaining surface for the message.
54
- The spinner goes (nothing is pending any more) and the text takes the error
55
- colour. A load that failed and WAS reported never reaches this state — the
56
- overlay is removed and GLSP's own status overlay shows it instead. */
52
+ /* Failure state: the spinner goes, since nothing is pending any more, and the
53
+ text takes the error colour. */
57
54
  .hydranium-diagram-loading-failed .hydranium-diagram-loading-spinner {
58
55
  display: none;
59
56
  }
@@ -1,85 +0,0 @@
1
- /********************************************************************************
2
- * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
- *
4
- * This program and the accompanying materials are made available under the
5
- * terms of the MIT License which is available in the project root.
6
- *
7
- * SPDX-License-Identifier: MIT
8
- ********************************************************************************/
9
- import { type Action, GLSPActionDispatcher } from '@eclipse-glsp/client';
10
- import { ChannelLogger } from '@hydranium/client-theia/lib/browser';
11
- import { type Tracer } from '@hydranium/protocol';
12
- /** Default subset of action kinds the framework dispatcher will log: the GLSP
13
- * traffic an observer reading the Output channel typically wants to see. All
14
- * are standard `@eclipse-glsp/client` kinds; adopters with custom action kinds
15
- * extend via `extraLoggedKinds`. */
16
- export declare const HYDRANIUM_DEFAULT_LOGGED_KINDS: ReadonlySet<string>;
17
- /** Default request → response kind pairs for GLSP 'flow' actions that do NOT
18
- * carry a requestId/responseId — so the dispatcher matches by kind (FIFO).
19
- * Id-based matching still wins when a requestId is present. */
20
- export declare const HYDRANIUM_DEFAULT_KIND_PAIRS: ReadonlyMap<string, string>;
21
- /** Additive options. Adopters with custom action kinds pass extras here; the
22
- * framework defaults always apply (you cannot un-log a kind the framework
23
- * considers worth logging — subclass + override `dispatch` if you must). */
24
- export interface HydraniumGlspActionDispatcherOptions {
25
- readonly extraLoggedKinds?: Iterable<string>;
26
- readonly extraKindPairs?: Iterable<readonly [string, string]>;
27
- /** Replaces the default `summarize` body entirely. Use for adopter-domain
28
- * action kinds where the framework default returns ''. */
29
- readonly summarize?: (action: Action) => string;
30
- }
31
- /**
32
- * Wraps every dispatch so action traffic appears in the framework Output
33
- * channel, interleaved with server log lines. Instrumenting the dispatcher
34
- * (rather than per-kind handlers) catches ResponseActions that bypass the
35
- * handler pipeline.
36
- *
37
- * The framework defaults cover the standard GLSP kinds worth logging, not every
38
- * kind the protocol defines. Adopters with custom kinds either pass
39
- * `extraLoggedKinds` / `extraKindPairs` to the constructor (via a
40
- * `toDynamicValue` binding) or subclass and override.
41
- */
42
- export declare class HydraniumGlspActionDispatcher extends GLSPActionDispatcher {
43
- protected readonly channel: ChannelLogger;
44
- protected readonly tracer: Tracer;
45
- protected readonly loggedKinds: ReadonlySet<string>;
46
- protected readonly kindPairs: ReadonlyMap<string, string>;
47
- protected readonly kindPairsReverse: ReadonlyMap<string, string>;
48
- protected pairCounter: number;
49
- /** Pending requests keyed by requestId (for actions that carry one). */
50
- protected pendingById: Map<string, {
51
- id: number;
52
- start: number;
53
- }>;
54
- /** FIFO queue per response kind, used for `flow` pairs without requestId/responseId. */
55
- protected pendingByKind: Map<string, {
56
- id: number;
57
- start: number;
58
- }[]>;
59
- constructor(options?: HydraniumGlspActionDispatcherOptions);
60
- initialize(): Promise<void>;
61
- /**
62
- * Register the one-shot 'model initialized' timing line. Instrumentation
63
- * only — guarded so a tracer failure degrades logging rather than aborting
64
- * diagram init. `initialize()` runs inside `DiagramLoader.load()`, whose
65
- * caller (`GLSPDiagramWidget.onAfterAttach`) neither awaits nor catches the
66
- * returned promise; an error thrown here would therefore escape as an
67
- * uncaught rejection that blanks the diagram with no server-side signal.
68
- */
69
- protected registerInitTiming(): void;
70
- dispatch(action: Action): Promise<void>;
71
- protected logAction(action: Action): void;
72
- protected classify(action: Action): {
73
- verb: string;
74
- direction: string;
75
- };
76
- /** Emit `[request #N]` on the request side, `[response #N, Xms]` on the matching response side.
77
- * Match first by requestId/responseId, then by known kind pairs (FIFO). */
78
- protected trackPair(action: Action): string;
79
- protected formatResponse(entry: {
80
- id: number;
81
- start: number;
82
- }): string;
83
- protected summarize(action: Action): string;
84
- }
85
- //# sourceMappingURL=action-dispatcher.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"action-dispatcher.d.ts","sourceRoot":"","sources":["../../src/browser/action-dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EACJ,KAAK,MAAM,EAEX,oBAAoB,EAmBtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAiB,MAAM,qCAAqC,CAAC;AACnF,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGlD;;;qCAGqC;AACrC,eAAO,MAAM,8BAA8B,EAAE,WAAW,CAAC,MAAM,CAe7D,CAAC;AAEH;;gEAEgE;AAChE,eAAO,MAAM,4BAA4B,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAInE,CAAC;AAEH;;6EAE6E;AAC7E,MAAM,WAAW,oCAAoC;IAClD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC7C,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9D;+DAC2D;IAC3D,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;CAClD;AAED;;;;;;;;;;GAUG;AACH,qBACa,6BAA8B,SAAQ,oBAAoB;IAC7C,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAG,aAAa,CAAC;IAC3C,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAG,MAAM,CAAC;IAE1D,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACpD,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1D,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjE,SAAS,CAAC,WAAW,SAAK;IAC1B,wEAAwE;IACxE,SAAS,CAAC,WAAW;YAAyB,MAAM;eAAS,MAAM;OAAM;IACzE,wFAAwF;IACxF,SAAS,CAAC,aAAa;YAA+B,MAAM;eAAS,MAAM;SAAO;gBAEzD,OAAO,CAAC,EAAE,oCAAoC;IAa9D,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IASpC;;;;;;;OAOG;IACH,SAAS,CAAC,kBAAkB,IAAI,IAAI;IAQ3B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhD,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAczC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;IAkBvE;gFAC4E;IAC5E,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAiC3C,SAAS,CAAC,cAAc,CAAC,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM;IAKtE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;CAoC7C"}
@@ -1,238 +0,0 @@
1
- "use strict";
2
- /********************************************************************************
3
- * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
4
- *
5
- * This program and the accompanying materials are made available under the
6
- * terms of the MIT License which is available in the project root.
7
- *
8
- * SPDX-License-Identifier: MIT
9
- ********************************************************************************/
10
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
11
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
12
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
13
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
14
- return c > 3 && r && Object.defineProperty(target, key, r), r;
15
- };
16
- var __metadata = (this && this.__metadata) || function (k, v) {
17
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
18
- };
19
- var __param = (this && this.__param) || function (paramIndex, decorator) {
20
- return function (target, key) { decorator(target, key, paramIndex); }
21
- };
22
- Object.defineProperty(exports, "__esModule", { value: true });
23
- exports.HydraniumGlspActionDispatcher = exports.HYDRANIUM_DEFAULT_KIND_PAIRS = exports.HYDRANIUM_DEFAULT_LOGGED_KINDS = void 0;
24
- const client_1 = require("@eclipse-glsp/client");
25
- const browser_1 = require("@hydranium/client-theia/lib/browser");
26
- const inversify_1 = require("@theia/core/shared/inversify");
27
- /** Default subset of action kinds the framework dispatcher will log: the GLSP
28
- * traffic an observer reading the Output channel typically wants to see. All
29
- * are standard `@eclipse-glsp/client` kinds; adopters with custom action kinds
30
- * extend via `extraLoggedKinds`. */
31
- exports.HYDRANIUM_DEFAULT_LOGGED_KINDS = new Set([
32
- client_1.SetModelAction.KIND,
33
- client_1.UpdateModelAction.KIND,
34
- client_1.RequestBoundsAction.KIND,
35
- client_1.ComputedBoundsAction.KIND,
36
- client_1.SetDirtyStateAction.KIND,
37
- client_1.SetEditModeAction.KIND,
38
- client_1.SetMarkersAction.KIND,
39
- client_1.SetTypeHintsAction.KIND,
40
- client_1.StatusAction.KIND,
41
- client_1.MessageAction.KIND,
42
- client_1.RejectAction.KIND,
43
- client_1.RequestContextActions.KIND,
44
- client_1.RequestModelAction.KIND,
45
- client_1.RequestTypeHintsAction.KIND
46
- ]);
47
- /** Default request → response kind pairs for GLSP 'flow' actions that do NOT
48
- * carry a requestId/responseId — so the dispatcher matches by kind (FIFO).
49
- * Id-based matching still wins when a requestId is present. */
50
- exports.HYDRANIUM_DEFAULT_KIND_PAIRS = new Map([
51
- [client_1.RequestModelAction.KIND, client_1.SetModelAction.KIND],
52
- [client_1.RequestTypeHintsAction.KIND, client_1.SetTypeHintsAction.KIND],
53
- [client_1.RequestBoundsAction.KIND, client_1.ComputedBoundsAction.KIND]
54
- ]);
55
- /**
56
- * Wraps every dispatch so action traffic appears in the framework Output
57
- * channel, interleaved with server log lines. Instrumenting the dispatcher
58
- * (rather than per-kind handlers) catches ResponseActions that bypass the
59
- * handler pipeline.
60
- *
61
- * The framework defaults cover the standard GLSP kinds worth logging, not every
62
- * kind the protocol defines. Adopters with custom kinds either pass
63
- * `extraLoggedKinds` / `extraKindPairs` to the constructor (via a
64
- * `toDynamicValue` binding) or subclass and override.
65
- */
66
- let HydraniumGlspActionDispatcher = class HydraniumGlspActionDispatcher extends client_1.GLSPActionDispatcher {
67
- channel;
68
- tracer;
69
- loggedKinds;
70
- kindPairs;
71
- kindPairsReverse;
72
- pairCounter = 0;
73
- /** Pending requests keyed by requestId (for actions that carry one). */
74
- pendingById = new Map();
75
- /** FIFO queue per response kind, used for `flow` pairs without requestId/responseId. */
76
- pendingByKind = new Map();
77
- constructor(options) {
78
- super();
79
- const extraLogged = options?.extraLoggedKinds ? Array.from(options.extraLoggedKinds) : [];
80
- this.loggedKinds = new Set([...exports.HYDRANIUM_DEFAULT_LOGGED_KINDS, ...extraLogged]);
81
- const extraPairs = options?.extraKindPairs ? Array.from(options.extraKindPairs) : [];
82
- const pairs = new Map([...exports.HYDRANIUM_DEFAULT_KIND_PAIRS, ...extraPairs]);
83
- this.kindPairs = pairs;
84
- this.kindPairsReverse = new Map(Array.from(pairs, ([req, res]) => [res, req]));
85
- if (options?.summarize) {
86
- this.summarize = options.summarize;
87
- }
88
- }
89
- initialize() {
90
- // `initialize()` is called many times; super is idempotent, but our callback registration
91
- // isn't. Register the timing log only on the first call (when super.initialized is unset).
92
- if (!this.initialized) {
93
- this.registerInitTiming();
94
- }
95
- return super.initialize();
96
- }
97
- /**
98
- * Register the one-shot 'model initialized' timing line. Instrumentation
99
- * only — guarded so a tracer failure degrades logging rather than aborting
100
- * diagram init. `initialize()` runs inside `DiagramLoader.load()`, whose
101
- * caller (`GLSPDiagramWidget.onAfterAttach`) neither awaits nor catches the
102
- * returned promise; an error thrown here would therefore escape as an
103
- * uncaught rejection that blanks the diagram with no server-side signal.
104
- */
105
- registerInitTiming() {
106
- try {
107
- this.tracer.time('Model initialized', () => this.onceModelInitialized(), 'info', { logAfterMs: 0 });
108
- }
109
- catch (err) {
110
- this.channel.error('Failed to register model-initialized timing instrumentation', err);
111
- }
112
- }
113
- dispatch(action) {
114
- if (this.loggedKinds.has(action.kind)) {
115
- this.logAction(action);
116
- }
117
- return super.dispatch(action);
118
- }
119
- logAction(action) {
120
- const { verb, direction } = this.classify(action);
121
- const summary = this.summarize(action);
122
- const timing = this.trackPair(action);
123
- const parts = [`${verb} action '${action.kind}'`, `[${direction}]`];
124
- if (summary) {
125
- parts.push(`[${summary}]`);
126
- }
127
- if (timing) {
128
- parts.push(timing);
129
- }
130
- this.channel.trace(parts.join(' '));
131
- }
132
- classify(action) {
133
- // GLSP marks client-produced computedBounds as ServerAction to suppress forwarding; stays local.
134
- if (client_1.LocalComputedBoundsAction.is(action)) {
135
- return { verb: 'Process', direction: 'client → client' };
136
- }
137
- // Marked by GLSPModelSource.messageReceived — arrived from the server.
138
- if (client_1.ServerAction.is(action)) {
139
- return { verb: 'Receive', direction: 'server → client' };
140
- }
141
- // GLSPModelSource is registered as handler for every server-handled kind (configureServeActions),
142
- // so its presence means the action will be forwarded to the server.
143
- const handlers = this.actionHandlerRegistry.get(action.kind);
144
- if (handlers.some(handler => handler instanceof client_1.GLSPModelSource)) {
145
- return { verb: 'Send', direction: 'client → server' };
146
- }
147
- return { verb: 'Process', direction: 'client → client' };
148
- }
149
- /** Emit `[request #N]` on the request side, `[response #N, Xms]` on the matching response side.
150
- * Match first by requestId/responseId, then by known kind pairs (FIFO). */
151
- trackPair(action) {
152
- // Response side.
153
- if (client_1.ResponseAction.hasValidResponseId(action)) {
154
- const entry = this.pendingById.get(action.responseId);
155
- if (entry) {
156
- this.pendingById.delete(action.responseId);
157
- return this.formatResponse(entry);
158
- }
159
- }
160
- if (this.kindPairsReverse.has(action.kind)) {
161
- const queue = this.pendingByKind.get(action.kind);
162
- const entry = queue?.shift();
163
- if (entry) {
164
- return this.formatResponse(entry);
165
- }
166
- }
167
- // Request side.
168
- if (client_1.RequestAction.is(action) && action.requestId) {
169
- const entry = { id: ++this.pairCounter, start: performance.now() };
170
- this.pendingById.set(action.requestId, entry);
171
- return `[request #${entry.id}]`;
172
- }
173
- if (this.kindPairs.has(action.kind)) {
174
- const responseKind = this.kindPairs.get(action.kind);
175
- const entry = { id: ++this.pairCounter, start: performance.now() };
176
- const queue = this.pendingByKind.get(responseKind) ?? [];
177
- queue.push(entry);
178
- this.pendingByKind.set(responseKind, queue);
179
- return `[request #${entry.id}]`;
180
- }
181
- return '';
182
- }
183
- formatResponse(entry) {
184
- const elapsed = Math.round(performance.now() - entry.start);
185
- return `[response #${entry.id}, ${elapsed}ms]`;
186
- }
187
- summarize(action) {
188
- if (client_1.SetModelAction.is(action) || client_1.UpdateModelAction.is(action)) {
189
- const root = action.newRoot;
190
- return `rootType=${root?.type ?? 'none'} children=${root?.children?.length ?? 0}`;
191
- }
192
- if (client_1.RequestBoundsAction.is(action)) {
193
- return `rootType=${action.newRoot.type} children=${action.newRoot.children?.length ?? 0}`;
194
- }
195
- if (client_1.ComputedBoundsAction.is(action)) {
196
- return `bounds=${action.bounds.length}`;
197
- }
198
- if (client_1.SetDirtyStateAction.is(action)) {
199
- return `isDirty=${action.isDirty} reason=${action.reason ?? 'n/a'}`;
200
- }
201
- if (client_1.SetEditModeAction.is(action)) {
202
- return `editMode=${action.editMode}`;
203
- }
204
- if (client_1.SetMarkersAction.is(action)) {
205
- return `markers=${action.markers.length}`;
206
- }
207
- if (client_1.StatusAction.is(action) || client_1.MessageAction.is(action)) {
208
- // severity=NONE with empty message is the conventional 'clear' signal.
209
- const clear = action.severity === 'NONE' && !action.message ? ' (clear)' : '';
210
- return `severity=${action.severity} message="${action.message.slice(0, 160)}"${clear}`;
211
- }
212
- if (client_1.RejectAction.is(action)) {
213
- return `reason="${action.message.slice(0, 160)}"`;
214
- }
215
- if (client_1.SetTypeHintsAction.is(action)) {
216
- return `shapes=${action.shapeHints.length} edges=${action.edgeHints.length}`;
217
- }
218
- if (client_1.RequestContextActions.is(action)) {
219
- return `contextId=${action.contextId}`;
220
- }
221
- return '';
222
- }
223
- };
224
- exports.HydraniumGlspActionDispatcher = HydraniumGlspActionDispatcher;
225
- __decorate([
226
- (0, inversify_1.inject)(browser_1.ChannelLogger),
227
- __metadata("design:type", browser_1.ChannelLogger)
228
- ], HydraniumGlspActionDispatcher.prototype, "channel", void 0);
229
- __decorate([
230
- (0, inversify_1.inject)(browser_1.ChannelTracer),
231
- __metadata("design:type", Object)
232
- ], HydraniumGlspActionDispatcher.prototype, "tracer", void 0);
233
- exports.HydraniumGlspActionDispatcher = HydraniumGlspActionDispatcher = __decorate([
234
- (0, inversify_1.injectable)(),
235
- __param(0, (0, inversify_1.unmanaged)()),
236
- __metadata("design:paramtypes", [Object])
237
- ], HydraniumGlspActionDispatcher);
238
- //# sourceMappingURL=action-dispatcher.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"action-dispatcher.js","sourceRoot":"","sources":["../../src/browser/action-dispatcher.ts"],"names":[],"mappings":"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"}