@eclipse-glsp/layout-elk 2.8.0-next.0 → 2.8.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.
@@ -15,6 +15,7 @@
15
15
  ********************************************************************************/
16
16
  import { BindingTarget, GLSPModule } from '@eclipse-glsp/server';
17
17
  import { LayoutOptions } from 'elkjs/lib/elk.bundled';
18
+ import { ELK } from 'elkjs/lib/elk-api';
18
19
  import { ContainerModule, interfaces } from 'inversify';
19
20
  import { ElementFilter } from './element-filter';
20
21
  import { ElkFactory, GlspElkLayoutEngine } from './glsp-elk-layout-engine';
@@ -70,6 +71,21 @@ export declare class ElkLayoutModule extends GLSPModule {
70
71
  protected bindElementFilter(): BindingTarget<ElementFilter>;
71
72
  protected bindLayoutConfigurator(): BindingTarget<LayoutConfigurator>;
72
73
  protected bindElkFactory(): BindingTarget<ElkFactory>;
74
+ /** Creates the underlying elkjs {@link ELK} instance, see {@link createWebWorkerElk} for the web-worker case. */
75
+ protected createElk(options: {
76
+ algorithms: string[];
77
+ defaultLayoutOptions?: LayoutOptions;
78
+ }, isWebWorker?: boolean): ELK;
79
+ /**
80
+ * Creates an {@link ELK} instance for a web-worker server. elkjs only exposes its in-process fake worker when it
81
+ * doesn't detect a dedicated-worker scope (`self` present, `document` absent) — otherwise it hijacks
82
+ * `self.onmessage` and layout never runs. Briefly presenting a `document` during construction flips elkjs back to
83
+ * the in-process worker without touching the server's own `self.onmessage` handler.
84
+ */
85
+ protected createWebWorkerElk(options: {
86
+ algorithms: string[];
87
+ defaultLayoutOptions?: LayoutOptions;
88
+ }): ELK;
73
89
  protected bindGlspElkLayoutEngine(): BindingTarget<GlspElkLayoutEngine>;
74
90
  /** Provide fallbacks so the module works standalone in tests/specs that don't preconfigure logging. */
75
91
  protected bindLoggerFallbacks(bind: interfaces.Bind, isBound: interfaces.IsBound): void;
@@ -1 +1 @@
1
- {"version":3,"file":"di.config.d.ts","sourceRoot":"","sources":["../src/di.config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;kFAckF;AAClF,OAAO,EACH,aAAa,EACb,UAAU,EAOb,MAAM,sBAAsB,CAAC;AAC9B,OAAuB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,eAAe,EAAc,UAAU,EAAE,MAAM,WAAW,CAAC;AACpE,OAAO,EAAwB,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAA8B,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEvF,KAAK,WAAW,CAAC,CAAC,IAAI,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B;;OAEG;IACH,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB;;;OAGG;IACH,oBAAoB,CAAC,EAAE,aAAa,CAAC;IACrC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,CAAC;IACrD;;;OAGG;IACH,aAAa,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;IAC3C;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;;;GAaG;AACH,qBACa,eAAgB,SAAQ,UAAU;IAC/B,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,gBAAgB;gBAAzB,OAAO,EAAE,gBAAgB;IAIxD,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,GAAG,IAAI;IAUnI,SAAS,CAAC,iBAAiB,IAAI,aAAa,CAAC,aAAa,CAAC;IAI3D,SAAS,CAAC,sBAAsB,IAAI,aAAa,CAAC,kBAAkB,CAAC;IAOrE,SAAS,CAAC,cAAc,IAAI,aAAa,CAAC,UAAU,CAAC;IAarD,SAAS,CAAC,uBAAuB,IAAI,aAAa,CAAC,mBAAmB,CAAC;IAYvE,uGAAuG;IACvG,SAAS,CAAC,mBAAmB,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,OAAO,GAAG,IAAI;CAY1F;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,gBAAgB,GAAG,eAAe,CAEnF"}
1
+ {"version":3,"file":"di.config.d.ts","sourceRoot":"","sources":["../src/di.config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;kFAckF;AAClF,OAAO,EACH,aAAa,EACb,UAAU,EAOb,MAAM,sBAAsB,CAAC;AAC9B,OAAuB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAc,UAAU,EAAE,MAAM,WAAW,CAAC;AACpE,OAAO,EAAwB,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAA8B,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEvF,KAAK,WAAW,CAAC,CAAC,IAAI,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B;;OAEG;IACH,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB;;;OAGG;IACH,oBAAoB,CAAC,EAAE,aAAa,CAAC;IACrC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,CAAC;IACrD;;;OAGG;IACH,aAAa,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;IAC3C;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;;;GAaG;AACH,qBACa,eAAgB,SAAQ,UAAU;IAC/B,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,gBAAgB;gBAAzB,OAAO,EAAE,gBAAgB;IAIxD,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,GAAG,IAAI;IAUnI,SAAS,CAAC,iBAAiB,IAAI,aAAa,CAAC,aAAa,CAAC;IAI3D,SAAS,CAAC,sBAAsB,IAAI,aAAa,CAAC,kBAAkB,CAAC;IAOrE,SAAS,CAAC,cAAc,IAAI,aAAa,CAAC,UAAU,CAAC;IAMrD,iHAAiH;IACjH,SAAS,CAAC,SAAS,CAAC,OAAO,EAAE;QAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QAAC,oBAAoB,CAAC,EAAE,aAAa,CAAA;KAAE,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,GAAG;IAIxH;;;;;OAKG;IACH,SAAS,CAAC,kBAAkB,CAAC,OAAO,EAAE;QAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QAAC,oBAAoB,CAAC,EAAE,aAAa,CAAA;KAAE,GAAG,GAAG;IAgB1G,SAAS,CAAC,uBAAuB,IAAI,aAAa,CAAC,mBAAmB,CAAC;IAYvE,uGAAuG;IACvG,SAAS,CAAC,mBAAmB,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,OAAO,GAAG,IAAI;CAY1F;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,gBAAgB,GAAG,eAAe,CAEnF"}
package/lib/di.config.js CHANGED
@@ -61,8 +61,7 @@ let ElkLayoutModule = class ElkLayoutModule extends server_1.GLSPModule {
61
61
  this.bindLoggerFallbacks(bind, isBound);
62
62
  }
63
63
  bindElementFilter() {
64
- var _a;
65
- return (_a = this.options.elementFilter) !== null && _a !== void 0 ? _a : element_filter_1.DefaultElementFilter;
64
+ return this.options.elementFilter ?? element_filter_1.DefaultElementFilter;
66
65
  }
67
66
  bindLayoutConfigurator() {
68
67
  if (this.options.layoutConfigurator) {
@@ -72,15 +71,36 @@ let ElkLayoutModule = class ElkLayoutModule extends server_1.GLSPModule {
72
71
  }
73
72
  bindElkFactory() {
74
73
  const { algorithms, defaultLayoutOptions, isWebWorker } = this.options;
75
- const factory = () => new elk_bundled_1.default({
76
- algorithms,
77
- defaultLayoutOptions,
78
- // The node implementation relies on elkjs' `FakeWorker` to set the `workerFactory`. The required file is
79
- // dynamically loaded and not available in a web-worker context, so it has to be mocked manually there.
80
- workerFactory: isWebWorker ? () => ({ postMessage: () => { } }) : undefined
81
- });
74
+ const factory = () => this.createElk({ algorithms, defaultLayoutOptions }, isWebWorker);
82
75
  return { constantValue: factory };
83
76
  }
77
+ /** Creates the underlying elkjs {@link ELK} instance, see {@link createWebWorkerElk} for the web-worker case. */
78
+ createElk(options, isWebWorker) {
79
+ return isWebWorker ? this.createWebWorkerElk(options) : new elk_bundled_1.default(options);
80
+ }
81
+ /**
82
+ * Creates an {@link ELK} instance for a web-worker server. elkjs only exposes its in-process fake worker when it
83
+ * doesn't detect a dedicated-worker scope (`self` present, `document` absent) — otherwise it hijacks
84
+ * `self.onmessage` and layout never runs. Briefly presenting a `document` during construction flips elkjs back to
85
+ * the in-process worker without touching the server's own `self.onmessage` handler.
86
+ */
87
+ createWebWorkerElk(options) {
88
+ const globalScope = globalThis;
89
+ const hadDocument = 'document' in globalScope;
90
+ const previousDocument = globalScope.document;
91
+ globalScope.document = previousDocument ?? {};
92
+ try {
93
+ return new elk_bundled_1.default(options);
94
+ }
95
+ finally {
96
+ if (hadDocument) {
97
+ globalScope.document = previousDocument;
98
+ }
99
+ else {
100
+ delete globalScope.document;
101
+ }
102
+ }
103
+ }
84
104
  bindGlspElkLayoutEngine() {
85
105
  return {
86
106
  dynamicValue: ctx => {
@@ -1 +1 @@
1
- {"version":3,"file":"di.config.js","sourceRoot":"","sources":["../src/di.config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"di.config.js","sourceRoot":"","sources":["../src/di.config.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eclipse-glsp/layout-elk",
3
- "version": "2.8.0-next.0+bb0b4e8",
3
+ "version": "2.8.0-next.10",
4
4
  "description": "Integration of ELK graph layout algorithms in GLSP Node Server",
5
5
  "keywords": [
6
6
  "eclipse",
@@ -36,27 +36,25 @@
36
36
  "types": "lib/index",
37
37
  "files": [
38
38
  "lib",
39
- "src"
39
+ "src",
40
+ "!**/*.spec.ts",
41
+ "!**/*.spec.tsx"
40
42
  ],
41
- "scripts": {
42
- "build": "tsc -b",
43
- "clean": "rimraf lib *.tsbuildinfo coverage .nyc_output",
44
- "generate:index": "glsp generateIndex src -f -s",
45
- "lint": "eslint ./src",
46
- "test": "mocha --config ../../.mocharc \"./src/**/*.spec.?(ts|tsx)\"",
47
- "test:ci": "yarn test --reporter mocha-ctrf-json-reporter",
48
- "test:coverage": "nyc yarn test",
49
- "watch": "tsc -w"
50
- },
51
43
  "dependencies": {
52
- "@eclipse-glsp/server": "2.8.0-next.0+bb0b4e8",
53
- "elkjs": "^0.10.1"
44
+ "elkjs": "^0.11.1",
45
+ "@eclipse-glsp/server": "2.8.0-next.10"
54
46
  },
55
47
  "peerDependencies": {
56
- "inversify": "^6.1.3"
48
+ "inversify": "^6.1.3",
49
+ "reflect-metadata": "^0.2.2"
57
50
  },
58
51
  "publishConfig": {
59
52
  "access": "public"
60
53
  },
61
- "gitHead": "bb0b4e86909b0c6ea8ba805a9aba68e4afd2decb"
62
- }
54
+ "scripts": {
55
+ "build": "tsc -b",
56
+ "clean": "rimraf lib *.tsbuildinfo coverage",
57
+ "generate:index": "glsp generateIndex src -f -s",
58
+ "lint": "eslint ./src"
59
+ }
60
+ }
package/src/di.config.ts CHANGED
@@ -24,6 +24,7 @@ import {
24
24
  applyBindingTarget
25
25
  } from '@eclipse-glsp/server';
26
26
  import ElkConstructor, { LayoutOptions } from 'elkjs/lib/elk.bundled';
27
+ import { ELK } from 'elkjs/lib/elk-api';
27
28
  import { ContainerModule, injectable, interfaces } from 'inversify';
28
29
  import { DefaultElementFilter, ElementFilter } from './element-filter';
29
30
  import { ElkFactory, GlspElkLayoutEngine } from './glsp-elk-layout-engine';
@@ -104,17 +105,37 @@ export class ElkLayoutModule extends GLSPModule {
104
105
 
105
106
  protected bindElkFactory(): BindingTarget<ElkFactory> {
106
107
  const { algorithms, defaultLayoutOptions, isWebWorker } = this.options;
107
- const factory: ElkFactory = () =>
108
- new ElkConstructor({
109
- algorithms,
110
- defaultLayoutOptions,
111
- // The node implementation relies on elkjs' `FakeWorker` to set the `workerFactory`. The required file is
112
- // dynamically loaded and not available in a web-worker context, so it has to be mocked manually there.
113
- workerFactory: isWebWorker ? () => ({ postMessage: () => {} }) as unknown as Worker : undefined
114
- });
108
+ const factory: ElkFactory = () => this.createElk({ algorithms, defaultLayoutOptions }, isWebWorker);
115
109
  return { constantValue: factory };
116
110
  }
117
111
 
112
+ /** Creates the underlying elkjs {@link ELK} instance, see {@link createWebWorkerElk} for the web-worker case. */
113
+ protected createElk(options: { algorithms: string[]; defaultLayoutOptions?: LayoutOptions }, isWebWorker?: boolean): ELK {
114
+ return isWebWorker ? this.createWebWorkerElk(options) : new ElkConstructor(options);
115
+ }
116
+
117
+ /**
118
+ * Creates an {@link ELK} instance for a web-worker server. elkjs only exposes its in-process fake worker when it
119
+ * doesn't detect a dedicated-worker scope (`self` present, `document` absent) — otherwise it hijacks
120
+ * `self.onmessage` and layout never runs. Briefly presenting a `document` during construction flips elkjs back to
121
+ * the in-process worker without touching the server's own `self.onmessage` handler.
122
+ */
123
+ protected createWebWorkerElk(options: { algorithms: string[]; defaultLayoutOptions?: LayoutOptions }): ELK {
124
+ const globalScope = globalThis as { document?: unknown };
125
+ const hadDocument = 'document' in globalScope;
126
+ const previousDocument = globalScope.document;
127
+ globalScope.document = previousDocument ?? {};
128
+ try {
129
+ return new ElkConstructor(options);
130
+ } finally {
131
+ if (hadDocument) {
132
+ globalScope.document = previousDocument;
133
+ } else {
134
+ delete globalScope.document;
135
+ }
136
+ }
137
+ }
138
+
118
139
  protected bindGlspElkLayoutEngine(): BindingTarget<GlspElkLayoutEngine> {
119
140
  return {
120
141
  dynamicValue: ctx => {
@@ -1,110 +0,0 @@
1
- /********************************************************************************
2
- * Copyright (c) 2022-2023 STMicroelectronics and others.
3
- *
4
- * This program and the accompanying materials are made available under the
5
- * terms of the Eclipse Public License v. 2.0 which is available at
6
- * http://www.eclipse.org/legal/epl-2.0.
7
- *
8
- * This Source Code may also be made available under the following Secondary
9
- * Licenses when the conditions for such availability set forth in the Eclipse
10
- * Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- * with the GNU Classpath Exception which is available at
12
- * https://www.gnu.org/software/classpath/license.html.
13
- *
14
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
- ********************************************************************************/
16
- import {
17
- DefaultModelState,
18
- DiagramConfiguration,
19
- EdgeTypeHint,
20
- GGraph,
21
- GModelElementConstructor,
22
- ModelState,
23
- ServerLayoutKind,
24
- ShapeTypeHint
25
- } from '@eclipse-glsp/server';
26
- import { expect } from 'chai';
27
- import { Container, ContainerModule, injectable } from 'inversify';
28
- import * as sinon from 'sinon';
29
- import { configureELKLayoutModule } from './di.config';
30
- import { DefaultElementFilter, ElementFilter } from './element-filter';
31
- import { AbstractLayoutConfigurator, FallbackLayoutConfigurator, LayoutConfigurator } from './layout-configurator';
32
-
33
- @injectable()
34
- class CustomLayoutConfigurator extends AbstractLayoutConfigurator {}
35
-
36
- @injectable()
37
- class CustomElementFilter extends DefaultElementFilter {}
38
-
39
- class StubDiagramConfiguration implements DiagramConfiguration {
40
- typeMapping = new Map<string, GModelElementConstructor>();
41
-
42
- shapeTypeHints: ShapeTypeHint[] = [];
43
-
44
- edgeTypeHints: EdgeTypeHint[] = [];
45
-
46
- layoutKind = ServerLayoutKind.NONE;
47
-
48
- needsClientLayout = true;
49
-
50
- animatedUpdate = true;
51
- }
52
-
53
- describe('test configureELKLayoutModule', () => {
54
- const sandbox = sinon.createSandbox();
55
- const mockDiagramConfiguration = new StubDiagramConfiguration();
56
- const typeMappings = new Map<string, GModelElementConstructor>();
57
-
58
- typeMappings.set('graph', GGraph);
59
- sandbox.stub(mockDiagramConfiguration, 'typeMapping').value(typeMappings);
60
- const modelState = new DefaultModelState();
61
- const baseModule = new ContainerModule(bind => {
62
- bind(ModelState).toConstantValue(modelState);
63
- });
64
- it('configure with minimal options', () => {
65
- const algorithm = 'layered';
66
- const elkModule = configureELKLayoutModule({ algorithms: [algorithm] });
67
- const container = new Container();
68
- container.load(baseModule, elkModule);
69
- const filter = container.get<ElementFilter>(ElementFilter);
70
- expect(filter).to.be.an.instanceOf(DefaultElementFilter);
71
- const configurator = container.get<LayoutConfigurator>(LayoutConfigurator);
72
- expect(configurator).to.be.an.instanceOf(FallbackLayoutConfigurator);
73
- const graphOptions = configurator.apply(new GGraph());
74
- expect(graphOptions).not.to.be.undefined;
75
- expect(graphOptions!['elk.algorithm']).to.equal(algorithm);
76
- });
77
-
78
- it('configure with additional default layout options', () => {
79
- const algorithm = 'layered';
80
- const defaultLayoutOptions = {
81
- 'elk.direction': 'LEFT',
82
- 'elk.edgeRouting': 'POLYLINE'
83
- };
84
- const elkModule = configureELKLayoutModule({ algorithms: [algorithm], defaultLayoutOptions });
85
- const container = new Container();
86
- container.load(baseModule, elkModule);
87
- const configurator = container.get<LayoutConfigurator>(LayoutConfigurator);
88
- const graphOptions = configurator.apply(new GGraph());
89
- expect(graphOptions).not.to.be.undefined;
90
- expect(graphOptions).to.include(defaultLayoutOptions);
91
- });
92
-
93
- it('configure with custom layout configurator', () => {
94
- const algorithm = 'layered';
95
- const elkModule = configureELKLayoutModule({ algorithms: [algorithm], layoutConfigurator: CustomLayoutConfigurator });
96
- const container = new Container();
97
- container.load(baseModule, elkModule);
98
- const configurator = container.get<LayoutConfigurator>(LayoutConfigurator);
99
- expect(configurator).to.be.an.instanceOf(CustomLayoutConfigurator);
100
- });
101
-
102
- it('configure with custom element filter', () => {
103
- const algorithm = 'layered';
104
- const elkModule = configureELKLayoutModule({ algorithms: [algorithm], elementFilter: CustomElementFilter });
105
- const container = new Container();
106
- container.load(baseModule, elkModule);
107
- const filter = container.get<ElementFilter>(ElementFilter);
108
- expect(filter).to.be.an.instanceOf(CustomElementFilter);
109
- });
110
- });