@hydranium/glsp-client-theia 1.0.0-next.10

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 (94) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +134 -0
  3. package/lib/browser/action-dispatcher.d.ts +85 -0
  4. package/lib/browser/action-dispatcher.d.ts.map +1 -0
  5. package/lib/browser/action-dispatcher.js +238 -0
  6. package/lib/browser/action-dispatcher.js.map +1 -0
  7. package/lib/browser/client-contribution.d.ts +53 -0
  8. package/lib/browser/client-contribution.d.ts.map +1 -0
  9. package/lib/browser/client-contribution.js +111 -0
  10. package/lib/browser/client-contribution.js.map +1 -0
  11. package/lib/browser/diagram-loader.d.ts +123 -0
  12. package/lib/browser/diagram-loader.d.ts.map +1 -0
  13. package/lib/browser/diagram-loader.js +153 -0
  14. package/lib/browser/diagram-loader.js.map +1 -0
  15. package/lib/browser/diagram-only-marker-manager.d.ts +28 -0
  16. package/lib/browser/diagram-only-marker-manager.d.ts.map +1 -0
  17. package/lib/browser/diagram-only-marker-manager.js +44 -0
  18. package/lib/browser/diagram-only-marker-manager.js.map +1 -0
  19. package/lib/browser/diagram-widget.d.ts +97 -0
  20. package/lib/browser/diagram-widget.d.ts.map +1 -0
  21. package/lib/browser/diagram-widget.js +172 -0
  22. package/lib/browser/diagram-widget.js.map +1 -0
  23. package/lib/browser/glsp-client-theia-module.d.ts +40 -0
  24. package/lib/browser/glsp-client-theia-module.d.ts.map +1 -0
  25. package/lib/browser/glsp-client-theia-module.js +46 -0
  26. package/lib/browser/glsp-client-theia-module.js.map +1 -0
  27. package/lib/browser/glsp-diagram-manager.d.ts +46 -0
  28. package/lib/browser/glsp-diagram-manager.d.ts.map +1 -0
  29. package/lib/browser/glsp-diagram-manager.js +66 -0
  30. package/lib/browser/glsp-diagram-manager.js.map +1 -0
  31. package/lib/browser/glsp-message-service.d.ts +59 -0
  32. package/lib/browser/glsp-message-service.d.ts.map +1 -0
  33. package/lib/browser/glsp-message-service.js +97 -0
  34. package/lib/browser/glsp-message-service.js.map +1 -0
  35. package/lib/browser/glsp-theia-frontend-module.d.ts +110 -0
  36. package/lib/browser/glsp-theia-frontend-module.d.ts.map +1 -0
  37. package/lib/browser/glsp-theia-frontend-module.js +133 -0
  38. package/lib/browser/glsp-theia-frontend-module.js.map +1 -0
  39. package/lib/browser/hidden-bounds-updater.d.ts +122 -0
  40. package/lib/browser/hidden-bounds-updater.d.ts.map +1 -0
  41. package/lib/browser/hidden-bounds-updater.js +207 -0
  42. package/lib/browser/hidden-bounds-updater.js.map +1 -0
  43. package/lib/browser/hydranium-glsp-diagram-configuration.d.ts +52 -0
  44. package/lib/browser/hydranium-glsp-diagram-configuration.d.ts.map +1 -0
  45. package/lib/browser/hydranium-glsp-diagram-configuration.js +72 -0
  46. package/lib/browser/hydranium-glsp-diagram-configuration.js.map +1 -0
  47. package/lib/browser/index.d.ts +20 -0
  48. package/lib/browser/index.d.ts.map +1 -0
  49. package/lib/browser/index.js +38 -0
  50. package/lib/browser/index.js.map +1 -0
  51. package/lib/index.d.ts +10 -0
  52. package/lib/index.d.ts.map +1 -0
  53. package/lib/index.js +39 -0
  54. package/lib/index.js.map +1 -0
  55. package/lib/node/connection-container-module.d.ts +22 -0
  56. package/lib/node/connection-container-module.d.ts.map +1 -0
  57. package/lib/node/connection-container-module.js +36 -0
  58. package/lib/node/connection-container-module.js.map +1 -0
  59. package/lib/node/glsp-server-connection-handler.d.ts +49 -0
  60. package/lib/node/glsp-server-connection-handler.d.ts.map +1 -0
  61. package/lib/node/glsp-server-connection-handler.js +64 -0
  62. package/lib/node/glsp-server-connection-handler.js.map +1 -0
  63. package/lib/node/index.d.ts +11 -0
  64. package/lib/node/index.d.ts.map +1 -0
  65. package/lib/node/index.js +28 -0
  66. package/lib/node/index.js.map +1 -0
  67. package/lib/testing/bind-recorder.d.ts +67 -0
  68. package/lib/testing/bind-recorder.d.ts.map +1 -0
  69. package/lib/testing/bind-recorder.js +72 -0
  70. package/lib/testing/bind-recorder.js.map +1 -0
  71. package/lib/testing/index.d.ts +10 -0
  72. package/lib/testing/index.d.ts.map +1 -0
  73. package/lib/testing/index.js +30 -0
  74. package/lib/testing/index.js.map +1 -0
  75. package/package.json +114 -0
  76. package/src/browser/action-dispatcher.ts +257 -0
  77. package/src/browser/client-contribution.ts +100 -0
  78. package/src/browser/diagram-loader.ts +173 -0
  79. package/src/browser/diagram-only-marker-manager.ts +33 -0
  80. package/src/browser/diagram-widget.ts +178 -0
  81. package/src/browser/glsp-client-theia-module.ts +54 -0
  82. package/src/browser/glsp-diagram-manager.ts +67 -0
  83. package/src/browser/glsp-message-service.ts +90 -0
  84. package/src/browser/glsp-theia-frontend-module.ts +157 -0
  85. package/src/browser/hidden-bounds-updater.ts +212 -0
  86. package/src/browser/hydranium-glsp-diagram-configuration.ts +63 -0
  87. package/src/browser/index.ts +22 -0
  88. package/src/index.ts +23 -0
  89. package/src/node/connection-container-module.ts +34 -0
  90. package/src/node/glsp-server-connection-handler.ts +69 -0
  91. package/src/node/index.ts +12 -0
  92. package/src/testing/bind-recorder.ts +126 -0
  93. package/src/testing/index.ts +15 -0
  94. package/style/diagram-loading.css +67 -0
@@ -0,0 +1,126 @@
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 type { interfaces } from 'inversify';
11
+
12
+ /**
13
+ * One captured `bind(...)` or `rebind(...)` call on a {@link BindRecorder}.
14
+ *
15
+ * `chain` holds the follow-up methods in invocation order, one string per call,
16
+ * rendered as `name(arg, …)`. Arguments are stringified inline so assertions
17
+ * can compare structure without re-resolving service identifiers.
18
+ */
19
+ export interface BindRecorderEntry {
20
+ readonly kind: 'bind' | 'rebind';
21
+ readonly token: unknown;
22
+ readonly chain: string[];
23
+ }
24
+
25
+ /**
26
+ * A spy set of Inversify binding hooks that records every call and its chain.
27
+ * Hand them to a module-factory under test — they satisfy Inversify's
28
+ * `interfaces.Bind` / `interfaces.Rebind` / `interfaces.Unbind` /
29
+ * `interfaces.IsBound` shapes at the call site but never resolve real services.
30
+ *
31
+ * Together they match GLSP's `BindingContext`, so a factory taking the whole
32
+ * context is called as `factory(recorder, options)` — the recorder *is*
33
+ * structurally a context.
34
+ *
35
+ * Use {@link captured} to assert which tokens were touched and with what
36
+ * fluent chain. {@link find} is a small ergonomic helper for the common
37
+ * lookup pattern.
38
+ */
39
+ export interface BindRecorder {
40
+ readonly bind: interfaces.Bind;
41
+ readonly rebind: interfaces.Rebind;
42
+ readonly unbind: interfaces.Unbind;
43
+ readonly isBound: interfaces.IsBound;
44
+ readonly captured: readonly BindRecorderEntry[];
45
+ /** Convenience lookup — returns the first entry matching both `kind` and `token`, or `undefined`. */
46
+ find(kind: 'bind' | 'rebind', token: unknown): BindRecorderEntry | undefined;
47
+ }
48
+
49
+ /** Options for {@link makeBindRecorder}. */
50
+ export interface BindRecorderOptions {
51
+ /**
52
+ * What `isBound` answers. Defaults to `true` for every token, matching
53
+ * production: a head registers its own module *after* the GLSP default
54
+ * modules, so the tokens a framework module rebinds are already bound. Pass a
55
+ * list to model a container where only those tokens are bound — e.g. to
56
+ * exercise a factory's bind-instead-of-rebind fallback.
57
+ */
58
+ readonly boundTokens?: readonly unknown[];
59
+ }
60
+
61
+ /** Methods on Inversify's binding builder that the recorder traps verbatim. */
62
+ const RECORDED_CHAIN_METHODS = [
63
+ 'toSelf',
64
+ 'to',
65
+ 'toService',
66
+ 'toConstantValue',
67
+ 'toDynamicValue',
68
+ 'toFactory',
69
+ 'toFunction',
70
+ 'toAutoFactory',
71
+ 'toProvider',
72
+ 'inSingletonScope',
73
+ 'inTransientScope',
74
+ 'inRequestScope',
75
+ 'whenTargetNamed',
76
+ 'whenTargetTagged',
77
+ 'whenInjectedInto',
78
+ 'onActivation',
79
+ 'onDeactivation'
80
+ ] as const;
81
+
82
+ /**
83
+ * Build a {@link BindRecorder} for testing Inversify module factories without a
84
+ * real container: hand it to the factory, then assert over {@link BindRecorder.find}.
85
+ *
86
+ * The `bind` / `rebind` functions return a chained proxy that ignores its
87
+ * arguments structurally but records every method invocation as a string.
88
+ * Stringification: functions → `<className>`, symbols → `Symbol(desc).toString()`,
89
+ * everything else → `String(value)`. This is enough to assert which tokens are
90
+ * involved without dragging real service resolution into the test.
91
+ */
92
+ export function makeBindRecorder(options: BindRecorderOptions = {}): BindRecorder {
93
+ const captured: BindRecorderEntry[] = [];
94
+
95
+ const stringifyArg = (value: unknown): string => {
96
+ if (typeof value === 'function') {
97
+ return `<${value.name || 'fn'}>`;
98
+ }
99
+ if (typeof value === 'symbol') {
100
+ return value.toString();
101
+ }
102
+ return String(value);
103
+ };
104
+
105
+ const beginEntry = (kind: 'bind' | 'rebind', token: unknown): unknown => {
106
+ const entry: BindRecorderEntry = { kind, token, chain: [] };
107
+ captured.push(entry);
108
+ const proxy: Record<string, (...args: unknown[]) => unknown> = {};
109
+ for (const method of RECORDED_CHAIN_METHODS) {
110
+ proxy[method] = (...args: unknown[]): unknown => {
111
+ entry.chain.push(`${method}(${args.map(stringifyArg).join(', ')})`);
112
+ return proxy;
113
+ };
114
+ }
115
+ return proxy;
116
+ };
117
+
118
+ const bind = ((token: unknown) => beginEntry('bind', token)) as interfaces.Bind;
119
+ const rebind = ((token: unknown) => beginEntry('rebind', token)) as interfaces.Rebind;
120
+ const unbind = (() => undefined) as unknown as interfaces.Unbind;
121
+ const isBound = ((token: unknown) => options.boundTokens?.includes(token) ?? true) as interfaces.IsBound;
122
+ const find = (kind: 'bind' | 'rebind', token: unknown): BindRecorderEntry | undefined =>
123
+ captured.find(entry => entry.kind === kind && entry.token === token);
124
+
125
+ return { bind, rebind, unbind, isBound, captured, find };
126
+ }
@@ -0,0 +1,15 @@
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
+ // Subpath barrel for `@hydranium/glsp-client-theia/testing` — the
11
+ // GLSP-module-specific Inversify test double. The cross-head doubles
12
+ // (`makeStubOutputChannelManager`, `makeStubInversifyContext`) live in
13
+ // `@hydranium/client-theia/testing`, alongside the logger they double for.
14
+
15
+ export * from './bind-recorder';
@@ -0,0 +1,67 @@
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
+ /* Loading overlay shown by HydraniumGlspDiagramWidget until the diagram load
11
+ settles. Imported by the widget module itself, so an adopter cannot forget it;
12
+ every rule is overridable from an adopter stylesheet loaded afterwards.
13
+ Colours come from Theia theme variables, so light/dark follow the workbench. */
14
+
15
+ .hydranium-diagram-loading {
16
+ position: absolute;
17
+ inset: 0;
18
+ z-index: 10;
19
+ display: flex;
20
+ flex-direction: column;
21
+ align-items: center;
22
+ justify-content: center;
23
+ gap: 12px;
24
+ background: var(--theia-editor-background);
25
+ color: var(--theia-descriptionForeground);
26
+ font-size: var(--theia-ui-font-size1);
27
+ }
28
+
29
+ .hydranium-diagram-loading-spinner {
30
+ width: 40px;
31
+ height: 40px;
32
+ border: 4px solid var(--theia-editorWidget-border);
33
+ border-top-color: var(--theia-button-background);
34
+ border-radius: 50%;
35
+ /* transform-only, so the animation runs on the compositor and keeps turning
36
+ through a synchronous phase that blocks the main thread — which is exactly
37
+ when the user most needs to see that something is still happening. */
38
+ animation: hydranium-diagram-loading-spin 0.9s linear infinite;
39
+ will-change: transform;
40
+ }
41
+
42
+ @keyframes hydranium-diagram-loading-spin {
43
+ from {
44
+ transform: rotate(0deg);
45
+ }
46
+
47
+ to {
48
+ transform: rotate(360deg);
49
+ }
50
+ }
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. */
57
+ .hydranium-diagram-loading-failed .hydranium-diagram-loading-spinner {
58
+ display: none;
59
+ }
60
+
61
+ .hydranium-diagram-loading-failed .hydranium-diagram-loading-label {
62
+ /* Wrap rather than clip: a load failure message can be long (a connection
63
+ error carries a URI), and it is the only copy the user gets here. */
64
+ max-width: 80%;
65
+ text-align: center;
66
+ color: var(--theia-errorForeground);
67
+ }