@interopio/workspaces-api 3.2.1 → 3.2.3

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 (40) hide show
  1. package/dist/workspaces.es.js +4295 -4648
  2. package/dist/workspaces.es.js.map +1 -1
  3. package/dist/workspaces.umd.js +5206 -5559
  4. package/dist/workspaces.umd.js.map +1 -1
  5. package/dist/workspaces.umd.min.js +1 -1
  6. package/package.json +36 -50
  7. package/workspaces.d.ts +8 -0
  8. package/rollup.config.js +0 -54
  9. package/src/builders/baseBuilder.ts +0 -50
  10. package/src/builders/parentBuilder.ts +0 -62
  11. package/src/builders/workspaceBuilder.ts +0 -102
  12. package/src/communication/bridge.ts +0 -263
  13. package/src/communication/constants.ts +0 -202
  14. package/src/communication/interop-transport.ts +0 -175
  15. package/src/controllers/base.ts +0 -487
  16. package/src/controllers/main.ts +0 -541
  17. package/src/controllers/shortcuts.ts +0 -28
  18. package/src/index.ts +0 -23
  19. package/src/main.ts +0 -415
  20. package/src/models/base/base.ts +0 -397
  21. package/src/models/column.ts +0 -187
  22. package/src/models/frame.ts +0 -368
  23. package/src/models/group.ts +0 -237
  24. package/src/models/row.ts +0 -188
  25. package/src/models/window.ts +0 -309
  26. package/src/models/workspace.ts +0 -717
  27. package/src/shared/decoders.ts +0 -939
  28. package/src/shared/ioc.ts +0 -227
  29. package/src/shared/privateDataManager.ts +0 -93
  30. package/src/shared/promisePlus.ts +0 -34
  31. package/src/shared/promiseWrapper.ts +0 -11
  32. package/src/types/builders.ts +0 -10
  33. package/src/types/controller.ts +0 -79
  34. package/src/types/glue.ts +0 -37
  35. package/src/types/ioc.ts +0 -33
  36. package/src/types/privateData.ts +0 -92
  37. package/src/types/protocol.ts +0 -453
  38. package/src/types/subscription.ts +0 -31
  39. package/temp.d.ts +0 -49
  40. package/tsconfig.json +0 -10
package/rollup.config.js DELETED
@@ -1,54 +0,0 @@
1
- const typescript = require('rollup-plugin-typescript2');
2
- const terser = require('@rollup/plugin-terser');
3
- const commonjs = require('@rollup/plugin-commonjs');
4
- const resolve = require('@rollup/plugin-node-resolve');
5
- const json = require('@rollup/plugin-json');
6
- const pkg = require('./package.json');
7
- const del = require('rollup-plugin-delete');
8
-
9
- module.exports = {
10
- input: 'src/index.ts',
11
- output: [
12
- {
13
- file: pkg.main,
14
- name: 'workspaces',
15
- format: 'umd',
16
- sourcemap: true
17
- },
18
- {
19
- file: './dist/workspaces.umd.min.js',
20
- name: 'workspaces.min',
21
- format: 'umd',
22
- plugins: [terser()]
23
- },
24
- {
25
- file: pkg.module,
26
- format: 'es',
27
- sourcemap: true
28
- },
29
- ],
30
- external: [
31
- //...Object.keys(pkg.dependencies || {}),
32
- ...Object.keys(pkg.peerDependencies || {}),
33
- ],
34
-
35
- plugins: [
36
- del({ targets: 'dist/*' }),
37
- typescript({
38
- typescript: require('typescript')
39
- }),
40
- // Allow json resolution
41
- json(),
42
- // // Allow bundling cjs modules (unlike webpack, rollup doesn't understand cjs)
43
- commonjs(),
44
- // // Allow node_modules resolution, so you can use 'external' to control
45
- // // which external modules to include in the bundle
46
- // // https://github.com/rollup/rollup-plugin-node-resolve#usage
47
- resolve({
48
- mainFields: ['module', 'main', 'browser']
49
- }),
50
-
51
- // // Resolve source maps to the original source
52
- // sourceMaps(),
53
- ],
54
- };
@@ -1,50 +0,0 @@
1
- import { ParentBuilder } from "./parentBuilder";
2
- import { ChildDefinition, ChildBuilder } from "../types/builders";
3
- import { parentDefinitionDecoder, swimlaneWindowDefinitionDecoder } from "../shared/decoders";
4
- import { IOConnectWorkspaces } from "../../workspaces";
5
- import { WorkspaceBuilder } from "./workspaceBuilder";
6
-
7
- export class BaseBuilder {
8
-
9
- constructor(
10
- private readonly getBuilder: (config: IOConnectWorkspaces.BuilderConfig) => ParentBuilder | WorkspaceBuilder,
11
- ) { }
12
-
13
- public wrapChildren(children: ChildDefinition[]): ChildBuilder[] {
14
- return children.map((child) => {
15
- if (child.type === "window") {
16
- return child;
17
- }
18
-
19
- return this.getBuilder({ type: child.type, definition: child }) as ParentBuilder;
20
- });
21
- }
22
-
23
- public add(type: "row" | "column" | "group", children: ChildBuilder[], definition?: IOConnectWorkspaces.BoxDefinition): ParentBuilder {
24
- const validatedDefinition = parentDefinitionDecoder.runWithException(definition);
25
-
26
- const childBuilder = this.getBuilder({ type, definition: validatedDefinition }) as ParentBuilder;
27
-
28
- children.push(childBuilder);
29
-
30
- return childBuilder;
31
- }
32
-
33
- public addWindow(children: ChildBuilder[], definition: IOConnectWorkspaces.WorkspaceWindowDefinition): void {
34
- const validatedDefinition = swimlaneWindowDefinitionDecoder.runWithException(definition);
35
-
36
- validatedDefinition.type = "window";
37
-
38
- children.push(validatedDefinition);
39
- }
40
-
41
- public serializeChildren(children: ChildBuilder[]): ChildDefinition[] {
42
- return children.map((child) => {
43
- if (child instanceof ParentBuilder) {
44
- return child.serialize();
45
- } else {
46
- return child as IOConnectWorkspaces.WorkspaceWindowDefinition;
47
- }
48
- });
49
- }
50
- }
@@ -1,62 +0,0 @@
1
- import { BaseBuilder } from "./baseBuilder";
2
- import { ChildBuilder } from "../types/builders";
3
- import { IOConnectWorkspaces } from "../../workspaces";
4
-
5
- interface PrivateData {
6
- definition: IOConnectWorkspaces.BoxDefinition;
7
- base: BaseBuilder;
8
- children: ChildBuilder[];
9
- }
10
-
11
- const privateData = new WeakMap<ParentBuilder, PrivateData>();
12
-
13
- export class ParentBuilder implements ParentBuilder {
14
-
15
- constructor(
16
- definition: IOConnectWorkspaces.BoxDefinition,
17
- base: BaseBuilder
18
- ) {
19
- const children = base.wrapChildren(definition.children);
20
-
21
- delete definition.children;
22
-
23
- privateData.set(this, { base, children, definition });
24
- }
25
-
26
- public get type(): "column" | "row" | "group" {
27
- return privateData.get(this).definition.type;
28
- }
29
-
30
- public addColumn(definition?: IOConnectWorkspaces.BoxDefinition): ParentBuilder {
31
- const base = privateData.get(this).base;
32
-
33
- return base.add("column", privateData.get(this).children, definition);
34
- }
35
-
36
- public addRow(definition?: IOConnectWorkspaces.BoxDefinition): ParentBuilder {
37
- const base = privateData.get(this).base;
38
-
39
- return base.add("row", privateData.get(this).children, definition);
40
- }
41
-
42
- public addGroup(definition?: IOConnectWorkspaces.BoxDefinition): ParentBuilder {
43
- const base = privateData.get(this).base;
44
-
45
- return base.add("group", privateData.get(this).children, definition);
46
- }
47
-
48
- public addWindow(definition: IOConnectWorkspaces.WorkspaceWindowDefinition): ParentBuilder {
49
- const base = privateData.get(this).base;
50
-
51
- base.addWindow(privateData.get(this).children, definition);
52
-
53
- return this;
54
- }
55
-
56
- public serialize(): IOConnectWorkspaces.BoxDefinition {
57
- const definition = privateData.get(this).definition;
58
- definition.children = privateData.get(this).base.serializeChildren(privateData.get(this).children);
59
- return definition;
60
- }
61
-
62
- }
@@ -1,102 +0,0 @@
1
- import { BaseBuilder } from "./baseBuilder";
2
- import { ChildBuilder } from "../types/builders";
3
- import { ParentBuilder } from "./parentBuilder";
4
- import { workspaceBuilderCreateConfigDecoder, nonNegativeNumberDecoder } from "../shared/decoders";
5
- import { IOConnectWorkspaces } from "../../workspaces";
6
- import { WorkspacesController } from "../types/controller";
7
-
8
- interface PrivateData {
9
- definition: IOConnectWorkspaces.WorkspaceDefinition;
10
- children: ChildBuilder[];
11
- base: BaseBuilder;
12
- controller: WorkspacesController;
13
- }
14
-
15
- const privateData = new WeakMap<WorkspaceBuilder, PrivateData>();
16
-
17
- export class WorkspaceBuilder implements WorkspaceBuilder {
18
-
19
- constructor(
20
- definition: IOConnectWorkspaces.WorkspaceDefinition,
21
- base: BaseBuilder,
22
- controller: WorkspacesController
23
- ) {
24
- const children = base.wrapChildren(definition.children);
25
-
26
- delete definition.children;
27
-
28
- privateData.set(this, { base, children, definition, controller });
29
- }
30
-
31
- public addColumn(definition?: IOConnectWorkspaces.BoxDefinition): ParentBuilder {
32
- const children = privateData.get(this).children;
33
-
34
- const areAllColumns = children.every((child) => child instanceof ParentBuilder && child.type === "column");
35
-
36
- if (!areAllColumns) {
37
- throw new Error("Cannot add a column to this workspace, because there are already children of another type");
38
- }
39
-
40
- const base = privateData.get(this).base;
41
-
42
- return base.add("column", children, definition);
43
- }
44
-
45
- public addRow(definition?: IOConnectWorkspaces.BoxDefinition): ParentBuilder {
46
- const children = privateData.get(this).children;
47
-
48
- const areAllRows = children.every((child) => child instanceof ParentBuilder && child.type === "row");
49
-
50
- if (!areAllRows) {
51
- throw new Error("Cannot add a row to this workspace, because there are already children of another type");
52
- }
53
-
54
- const base = privateData.get(this).base;
55
-
56
- return base.add("row", children, definition);
57
- }
58
-
59
- public addGroup(definition?: IOConnectWorkspaces.BoxDefinition): ParentBuilder {
60
- const children = privateData.get(this).children;
61
-
62
- if (children.length !== 0) {
63
- throw new Error("Cannot add a group to this workspace, because there are already defined children.");
64
- }
65
-
66
- const base = privateData.get(this).base;
67
-
68
- return base.add("group", children, definition);
69
- }
70
-
71
- public addWindow(definition: IOConnectWorkspaces.WorkspaceWindowDefinition): WorkspaceBuilder {
72
- const children = privateData.get(this).children;
73
-
74
- if (children.length !== 0) {
75
- throw new Error("Cannot add a window to this workspace, because there are already defined children.");
76
- }
77
-
78
- const base = privateData.get(this).base;
79
-
80
- base.addWindow(children, definition);
81
-
82
- return this;
83
- }
84
-
85
- public getChildAt(index: number): ChildBuilder {
86
- nonNegativeNumberDecoder.runWithException(index);
87
- const data = privateData.get(this).children;
88
-
89
- return data[index];
90
- }
91
-
92
- public async create(config?: IOConnectWorkspaces.WorkspaceCreateConfig): Promise<IOConnectWorkspaces.Workspace> {
93
- const saveConfig = workspaceBuilderCreateConfigDecoder.runWithException(config);
94
-
95
- const definition = privateData.get(this).definition;
96
- definition.children = privateData.get(this).base.serializeChildren(privateData.get(this).children);
97
-
98
- const controller = privateData.get(this).controller;
99
-
100
- return controller.createWorkspace(definition, saveConfig);
101
- }
102
- }
@@ -1,263 +0,0 @@
1
- import { CallbackRegistry, UnsubscribeFunction } from "callback-registry";
2
- import { SubscriptionConfig, ActiveSubscription, WorkspaceEventType, WorkspaceEventAction, WorkspacePayload, WorkspaceEventScope, PendingSubscription } from "../types/subscription";
3
- import { ClientOperations, CLIENT_OPERATIONS, STREAMS } from "./constants";
4
- import { OPERATIONS } from "./constants";
5
- import { eventTypeDecoder, streamRequestArgumentsDecoder, workspaceEventActionDecoder } from "../shared/decoders";
6
- import { IOConnectWorkspaces } from "../../workspaces";
7
- import { InteropTransport } from "./interop-transport";
8
- import { PromiseWrapper } from "../shared/promiseWrapper";
9
- import { Instance } from "../types/glue";
10
-
11
- export class Bridge {
12
-
13
- private readonly activeSubscriptions: ActiveSubscription[] = [];
14
- private readonly pendingSubScriptions: PendingSubscription[] = [];
15
-
16
- constructor(
17
- private readonly transport: InteropTransport,
18
- private readonly registry: CallbackRegistry
19
- ) { }
20
-
21
- public async createCoreEventSubscription(): Promise<void> {
22
- await this.transport.coreSubscriptionReady(this.handleCoreEvent.bind(this));
23
- }
24
-
25
- public handleCoreSubscription(config: SubscriptionConfig): UnsubscribeFunction {
26
- const registryKey = `${config.eventType}-${config.action}`;
27
- const scope = config.scope;
28
- const scopeId = config.scopeId;
29
-
30
- return this.registry.add(registryKey, (args) => {
31
- const scopeConfig = {
32
- type: scope,
33
- id: scopeId
34
- };
35
-
36
- const receivedIds = {
37
- frame: args.frameSummary?.id || args.windowSummary?.config.frameId,
38
- workspace: args.workspaceSummary?.id || args.windowSummary?.config.workspaceId,
39
- container: args.containerSummary?.itemId,
40
- window: args.windowSummary?.itemId
41
- };
42
-
43
- const shouldInvokeCallback = this.checkScopeMatch(scopeConfig, receivedIds);
44
-
45
- if (!shouldInvokeCallback) {
46
- return;
47
- }
48
-
49
- config.callback(args);
50
- });
51
- }
52
-
53
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
- public async send<T>(operationName: string, operationArgs?: any): Promise<T> {
55
-
56
- const operationDefinition = Object.values(OPERATIONS).find((operation) => operation.name === operationName);
57
-
58
- if (!operationDefinition) {
59
- throw new Error(`Cannot find definition for operation name: ${operationName}`);
60
- }
61
-
62
- if (operationDefinition.argsDecoder) {
63
- try {
64
- operationDefinition.argsDecoder.runWithException(operationArgs);
65
- } catch (error) {
66
- throw new Error(`Unexpected internal outgoing validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`);
67
- }
68
- }
69
-
70
- try {
71
- const operationResult = await this.transport.transmitControl(operationDefinition.name, operationArgs);
72
-
73
- operationDefinition.resultDecoder.runWithException(operationResult);
74
-
75
- return operationResult;
76
- } catch (error) {
77
- if (error.kind) {
78
- throw new Error(`Unexpected internal incoming validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`);
79
- }
80
- throw new Error(error.message);
81
- }
82
- }
83
-
84
- public async subscribe(config: SubscriptionConfig): Promise<IOConnectWorkspaces.Unsubscribe> {
85
- const pendingSub = this.getPendingSubscription(config);
86
- if (pendingSub) {
87
- await pendingSub.promise;
88
- }
89
-
90
- let activeSub = this.getActiveSubscription(config);
91
- const registryKey = this.getRegistryKey(config);
92
-
93
- if (!activeSub) {
94
- const pendingPromise = new PromiseWrapper<void>();
95
- const pendingSubscription = {
96
- streamType: config.eventType,
97
- level: config.scope,
98
- levelId: config.scopeId,
99
- promise: pendingPromise.promise
100
- };
101
- this.pendingSubScriptions.push(pendingSubscription);
102
- try {
103
- const stream = STREAMS[config.eventType];
104
- const gdSub = await this.transport.subscribe(stream.name, this.getBranchKey(config), config.eventType);
105
-
106
- gdSub.onData((streamData) => {
107
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
108
- const data = streamData.data as { action: string; payload: any };
109
-
110
- // important to decode without exception, because we do not want to throw an exception here
111
- const requestedArgumentsResult = streamRequestArgumentsDecoder.run(streamData.requestArguments);
112
- const actionResult = workspaceEventActionDecoder.run(data.action);
113
-
114
- if (!requestedArgumentsResult.ok || !actionResult.ok) {
115
- return;
116
- }
117
-
118
- const streamType = requestedArgumentsResult.result.type;
119
- const branch = requestedArgumentsResult.result.branch;
120
-
121
- const keyToExecute = `${streamType}-${branch}-${actionResult.result}`;
122
- const validatedPayload = STREAMS[streamType].payloadDecoder.run(data.payload);
123
- if (!validatedPayload.ok) {
124
- return;
125
- }
126
-
127
- this.registry.execute(keyToExecute, validatedPayload.result);
128
- });
129
-
130
- activeSub = {
131
- streamType: config.eventType,
132
- level: config.scope,
133
- levelId: config.scopeId,
134
- callbacksCount: 0,
135
- gdSub
136
- };
137
-
138
- this.activeSubscriptions.push(activeSub);
139
-
140
- pendingPromise.resolve();
141
- } catch (error) {
142
- pendingPromise.reject(error);
143
-
144
- throw error;
145
- } finally {
146
- this.removePendingSubscription(pendingSubscription);
147
- }
148
-
149
- }
150
-
151
- const unsubscribe = this.registry.add(registryKey, config.callback);
152
-
153
- ++activeSub.callbacksCount;
154
-
155
- return (): void => {
156
- unsubscribe();
157
- --activeSub.callbacksCount;
158
-
159
- if (activeSub.callbacksCount === 0) {
160
- activeSub.gdSub.close();
161
- this.activeSubscriptions.splice(this.activeSubscriptions.indexOf(activeSub), 1);
162
- }
163
- };
164
- }
165
-
166
- public onOperation(callback: (operation: ClientOperations, caller: Instance) => void) {
167
-
168
- const wrappedCallback = (payload: ClientOperations, caller: Instance) => {
169
- const operationName = payload.operation;
170
- const operationArgs = payload.data;
171
- const operationDefinition = Object.values(CLIENT_OPERATIONS).find((operation) => operation.name === operationName);
172
-
173
- if (!operationDefinition) {
174
- throw new Error(`Cannot find definition for operation name: ${operationName}`);
175
- }
176
-
177
- if (operationDefinition.argsDecoder) {
178
- try {
179
- operationDefinition.argsDecoder.runWithException(operationArgs);
180
- } catch (error) {
181
- throw new Error(`Unexpected internal outgoing validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`);
182
- }
183
- }
184
-
185
- callback(payload, caller);
186
- };
187
-
188
- return this.transport.onInternalMethodInvoked("control", wrappedCallback);
189
- }
190
-
191
- private checkScopeMatch(scope: { type: WorkspaceEventScope; id?: string }, receivedIds: { frame: string; workspace: string; container: string; window: string }): boolean {
192
-
193
- if (scope.type === "global") {
194
- return true;
195
- }
196
-
197
- if (scope.type === "frame" && scope.id === receivedIds.frame) {
198
- return true;
199
- }
200
-
201
- if (scope.type === "workspace" && scope.id === receivedIds.workspace) {
202
- return true;
203
- }
204
-
205
- if (scope.type === "container" && scope.id === receivedIds.container) {
206
- return true;
207
- }
208
-
209
- if (scope.type === "window" && scope.id === receivedIds.window) {
210
- return true;
211
- }
212
-
213
- return false;
214
- }
215
-
216
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
217
- private handleCoreEvent(args: any): void {
218
- const data = args.data;
219
- try {
220
- const verifiedAction: WorkspaceEventAction = workspaceEventActionDecoder.runWithException(data.action);
221
- const verifiedType: WorkspaceEventType = eventTypeDecoder.runWithException(data.type);
222
- const verifiedPayload: WorkspacePayload = STREAMS[verifiedType].payloadDecoder.runWithException(data.payload);
223
-
224
- const registryKey = `${verifiedType}-${verifiedAction}`;
225
-
226
- this.registry.execute(registryKey, verifiedPayload);
227
- } catch (error) {
228
- console.warn(`Cannot handle event with data ${JSON.stringify(data)}, because of validation error: ${error.message}`);
229
- }
230
- }
231
-
232
- private getBranchKey(config: SubscriptionConfig): string {
233
- return config.scope === "global" ? config.scope : `${config.scope}_${config.scopeId}`;
234
- }
235
-
236
- private getRegistryKey(config: SubscriptionConfig): string {
237
- return `${config.eventType}-${this.getBranchKey(config)}-${config.action}`;
238
- }
239
-
240
- private getActiveSubscription(config: SubscriptionConfig): ActiveSubscription {
241
- return this.activeSubscriptions
242
- .find((activeSub) => activeSub.streamType === config.eventType &&
243
- activeSub.level === config.scope &&
244
- activeSub.levelId === config.scopeId
245
- );
246
- }
247
-
248
- private getPendingSubscription(config: SubscriptionConfig): PendingSubscription {
249
- return this.pendingSubScriptions
250
- .find((activeSub) => activeSub.streamType === config.eventType &&
251
- activeSub.level === config.scope &&
252
- activeSub.levelId === config.scopeId
253
- );
254
- }
255
-
256
- private removePendingSubscription(pendingSubscription: PendingSubscription): void {
257
- const index = this.pendingSubScriptions.indexOf(pendingSubscription);
258
-
259
- if (index >= 0) {
260
- this.pendingSubScriptions.splice(index, 1);
261
- }
262
- }
263
- }