@vuu-ui/vuu-data-remote 0.8.93 → 0.8.95

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 (63) hide show
  1. package/cjs/ConnectionManager.js +168 -0
  2. package/cjs/ConnectionManager.js.map +1 -0
  3. package/cjs/DedicatedWorker.js +61 -0
  4. package/cjs/DedicatedWorker.js.map +1 -0
  5. package/cjs/WebSocketConnection.js +23 -0
  6. package/cjs/WebSocketConnection.js.map +1 -0
  7. package/cjs/data-source.js +1 -0
  8. package/cjs/data-source.js.map +1 -1
  9. package/cjs/index.js +4 -5
  10. package/cjs/index.js.map +1 -1
  11. package/cjs/inlined-worker.js +610 -330
  12. package/cjs/inlined-worker.js.map +1 -1
  13. package/cjs/rest-data/moving-window.js +66 -0
  14. package/cjs/rest-data/moving-window.js.map +1 -0
  15. package/cjs/rest-data/rest-data-source.js +195 -0
  16. package/cjs/rest-data/rest-data-source.js.map +1 -0
  17. package/cjs/rest-data/rest-utils.js +52 -0
  18. package/cjs/rest-data/rest-utils.js.map +1 -0
  19. package/cjs/vuu-data-source.js +42 -17
  20. package/cjs/vuu-data-source.js.map +1 -1
  21. package/esm/ConnectionManager.js +166 -0
  22. package/esm/ConnectionManager.js.map +1 -0
  23. package/esm/DedicatedWorker.js +59 -0
  24. package/esm/DedicatedWorker.js.map +1 -0
  25. package/esm/WebSocketConnection.js +21 -0
  26. package/esm/WebSocketConnection.js.map +1 -0
  27. package/esm/data-source.js +1 -0
  28. package/esm/data-source.js.map +1 -1
  29. package/esm/index.js +2 -1
  30. package/esm/index.js.map +1 -1
  31. package/esm/inlined-worker.js +610 -330
  32. package/esm/inlined-worker.js.map +1 -1
  33. package/esm/rest-data/moving-window.js +64 -0
  34. package/esm/rest-data/moving-window.js.map +1 -0
  35. package/esm/rest-data/rest-data-source.js +193 -0
  36. package/esm/rest-data/rest-data-source.js.map +1 -0
  37. package/esm/rest-data/rest-utils.js +49 -0
  38. package/esm/rest-data/rest-utils.js.map +1 -0
  39. package/esm/vuu-data-source.js +43 -18
  40. package/esm/vuu-data-source.js.map +1 -1
  41. package/package.json +7 -7
  42. package/types/ConnectionManager.d.ts +33 -0
  43. package/types/DedicatedWorker.d.ts +9 -0
  44. package/types/WebSocketConnection.d.ts +68 -0
  45. package/types/index.d.ts +4 -2
  46. package/types/inlined-worker.d.ts +1 -1
  47. package/types/rest-data/moving-window.d.ts +14 -0
  48. package/types/rest-data/rest-data-source.d.ts +48 -0
  49. package/types/rest-data/rest-utils.d.ts +11 -0
  50. package/types/server-proxy/server-proxy.d.ts +8 -3
  51. package/types/server-proxy/viewport.d.ts +7 -8
  52. package/types/vuu-data-source.d.ts +7 -5
  53. package/cjs/connection-manager.js +0 -224
  54. package/cjs/connection-manager.js.map +0 -1
  55. package/cjs/server-proxy/messages.js +0 -6
  56. package/cjs/server-proxy/messages.js.map +0 -1
  57. package/esm/connection-manager.js +0 -219
  58. package/esm/connection-manager.js.map +0 -1
  59. package/esm/server-proxy/messages.js +0 -4
  60. package/esm/server-proxy/messages.js.map +0 -1
  61. package/types/connection-manager.d.ts +0 -52
  62. package/types/connectionTypes.d.ts +0 -5
  63. package/types/websocket-connection.d.ts +0 -24
@@ -0,0 +1,48 @@
1
+ import { DataSource, DataSourceConstructorProps, DataSourceEditHandler, DataSourceEvents, DataSourceFilter, DataSourceStatus, SubscribeCallback, SubscribeProps, WithFullConfig } from "@vuu-ui/vuu-data-types";
2
+ import { VuuAggregation, VuuTable, VuuGroupBy, VuuRange, VuuSort } from "@vuu-ui/vuu-protocol-types";
3
+ import { EventEmitter } from "@vuu-ui/vuu-utils";
4
+ export type RestMetaData = {
5
+ recordCount: number;
6
+ };
7
+ export declare class RestDataSource extends EventEmitter<DataSourceEvents> implements DataSource {
8
+ #private;
9
+ private static _api;
10
+ private clientCallback;
11
+ aggregations: VuuAggregation[];
12
+ filter: DataSourceFilter;
13
+ groupBy: VuuGroupBy;
14
+ selectedRowsCount: number;
15
+ size: number;
16
+ sort: VuuSort;
17
+ status: DataSourceStatus;
18
+ table: VuuTable;
19
+ viewport: string;
20
+ constructor({ table, title, viewport, }: DataSourceConstructorProps & {
21
+ url?: string;
22
+ });
23
+ private get pageSize();
24
+ static get api(): string;
25
+ static set api(url: string);
26
+ get url(): string;
27
+ get dataUrl(): string;
28
+ get metaDataUrl(): string;
29
+ get title(): string;
30
+ set title(title: string);
31
+ subscribe({ range, ...props }: SubscribeProps, callback: SubscribeCallback): Promise<void>;
32
+ unsubscribe(): void;
33
+ get columns(): import("@vuu-ui/vuu-protocol-types").VuuColumns;
34
+ get config(): WithFullConfig;
35
+ get range(): VuuRange;
36
+ set range(range: VuuRange);
37
+ private fetchData;
38
+ private fetchMetaData;
39
+ private sendRowsToClient;
40
+ applyEdit: DataSourceEditHandler;
41
+ applyConfig: () => import("@vuu-ui/vuu-utils").MaybeDataSourceConfigChanges;
42
+ openTreeNode: () => never;
43
+ closeTreeNode: () => never;
44
+ remoteProcedureCall: <T>() => Promise<T>;
45
+ menuRpcCall: () => Promise<string>;
46
+ rpcCall: <T>() => Promise<T>;
47
+ select: () => never;
48
+ }
@@ -0,0 +1,11 @@
1
+ import { DataSourceRow } from "@vuu-ui/vuu-data-types";
2
+ import { ColumnMap } from "@vuu-ui/vuu-utils";
3
+ export type JsonPrimitive = string | number | boolean | null;
4
+ export type JsonArray = Json[];
5
+ export type JsonObject = {
6
+ [key: string]: Json;
7
+ };
8
+ export type Json = JsonPrimitive | JsonArray | JsonObject;
9
+ export type JsonHandler = (rowIndex: number, json: JsonObject) => void;
10
+ export declare const NDJsonReader: (startIndex: number, jsonHandler: JsonHandler, onEnd: () => void) => (response: Response) => void;
11
+ export declare const jsonToDataSourceRow: (rowIndex: number, json: JsonObject, columnMap: ColumnMap) => DataSourceRow;
@@ -1,6 +1,6 @@
1
1
  import type { DataSourceCallbackMessage, ServerProxySubscribeMessage, VuuUIMessageIn, VuuUIMessageOut, VuuUIMessageOutConnect, VuuUIMessageOutSubscribe, VuuUIMessageOutUnsubscribe, WithRequestId } from "@vuu-ui/vuu-data-types";
2
2
  import type { VuuRpcMenuRequest, VuuClientMessage, VuuServerMessage, VuuLinkDescriptor, VuuRpcServiceRequest, VuuTable, VuuCreateVisualLink, VuuRemoveVisualLink } from "@vuu-ui/vuu-protocol-types";
3
- import type { Connection } from "../connectionTypes";
3
+ import { WebSocketConnection } from "../WebSocketConnection";
4
4
  export type PostMessageToClientCallback = (message: VuuUIMessageIn | DataSourceCallbackMessage) => void;
5
5
  export type MessageOptions = {
6
6
  module?: string;
@@ -20,10 +20,15 @@ export declare class ServerProxy {
20
20
  private cachedTableMetaRequests;
21
21
  private cachedTableSchemas;
22
22
  private tableList;
23
- constructor(connection: Connection, callback: PostMessageToClientCallback);
24
- reconnect(): Promise<void>;
23
+ constructor(connection: WebSocketConnection, callback: PostMessageToClientCallback);
24
+ private reconnect;
25
25
  login(authToken?: string, user?: string): Promise<string | void>;
26
+ disconnect(): void;
26
27
  subscribe(message: ServerProxySubscribeMessage): void;
28
+ /**
29
+ * Currently we only queue range requests, this may change
30
+ */
31
+ private addRequestToQueue;
27
32
  private processQueuedRequests;
28
33
  unsubscribe(clientViewportId: string): void;
29
34
  private getViewportForClient;
@@ -1,5 +1,6 @@
1
1
  import { DataSourceFilter, DataSourceRow, DataSourceAggregateMessage, DataSourceCallbackMessage, DataSourceColumnsMessage, DataSourceDebounceRequest, DataSourceDisabledMessage, DataSourceEnabledMessage, DataSourceFilterMessage, DataSourceGroupByMessage, DataSourceMenusMessage, DataSourceSetConfigMessage, DataSourceSortMessage, DataSourceSubscribedMessage, DataSourceVisualLinkCreatedMessage, DataSourceVisualLinkRemovedMessage, DataSourceVisualLinksMessage, DataUpdateMode, Selection, TableSchema, WithFullConfig, ServerProxySubscribeMessage, VuuUIMessageOutOpenTreeNode, VuuUIMessageOutCloseTreeNode, WithRequestId } from "@vuu-ui/vuu-data-types";
2
- import { VuuViewportChangeRequest, ClientToServerCloseTreeNode, VuuCreateVisualLink, VuuViewportCreateRequest, ClientToServerDisable, ClientToServerEnable, ClientToServerOpenTreeNode, VuuRemoveVisualLink, ClientToServerSelection, ClientToServerViewPortRange, LinkDescriptorWithLabel, VuuViewportCreateResponse, VuuAggregation, VuuGroupBy, VuuMenu, VuuRange, VuuRow, VuuSort, VuuTable } from "@vuu-ui/vuu-protocol-types";
2
+ import { VuuViewportChangeRequest, ClientToServerCloseTreeNode, VuuCreateVisualLink, VuuViewportCreateRequest, ClientToServerDisable, ClientToServerEnable, ClientToServerOpenTreeNode, VuuRemoveVisualLink, ClientToServerSelection, VuuViewportRangeRequest, LinkDescriptorWithLabel, VuuViewportCreateResponse, VuuAggregation, VuuGroupBy, VuuMenu, VuuRange, VuuRow, VuuSort, VuuTable } from "@vuu-ui/vuu-protocol-types";
3
+ export type ViewportStatus = "" | "subscribing" | "resubscribing" | "subscribed";
3
4
  interface Disable {
4
5
  type: "disable";
5
6
  }
@@ -44,7 +45,7 @@ interface GroupByClear {
44
45
  type AsyncOperationWithData = Aggregate | Columns | ConfigOperation | ViewportFilter | GroupBy | GroupByClear | SelectionOperation | Sort;
45
46
  type AsyncOperation = AsyncOperationWithData | ChangeViewportRange | Disable | Enable | VuuCreateVisualLink | VuuRemoveVisualLink;
46
47
  type RangeRequestTuple = [
47
- ClientToServerViewPortRange | null,
48
+ VuuViewportRangeRequest | null,
48
49
  DataSourceRow[]?,
49
50
  DataSourceDebounceRequest?
50
51
  ];
@@ -55,15 +56,11 @@ type LinkedParent = {
55
56
  };
56
57
  export declare const NO_DATA_UPDATE: Readonly<[undefined, undefined]>;
57
58
  export declare class Viewport {
59
+ #private;
58
60
  private aggregations;
59
61
  /** batchMode is irrelevant for Vuu Table, it was introduced to try and improve rendering performance of AgGrid */
60
62
  private batchMode;
61
63
  private bufferSize;
62
- /**
63
- * clientRange is always the range requested by the client. We should assume
64
- * these are the rows visible to the user
65
- */
66
- private clientRange;
67
64
  private columns;
68
65
  private dataWindow;
69
66
  private filter;
@@ -88,7 +85,6 @@ export declare class Viewport {
88
85
  links?: LinkDescriptorWithLabel[];
89
86
  linkedParent?: LinkedParent;
90
87
  serverViewportId?: string;
91
- status: "" | "subscribing" | "resubscribing" | "subscribed";
92
88
  suspended: boolean;
93
89
  suspendTimer: number | null;
94
90
  table: VuuTable;
@@ -104,6 +100,9 @@ export declare class Viewport {
104
100
  private setLastUpdate;
105
101
  get hasUpdatesToProcess(): boolean;
106
102
  get size(): number;
103
+ get clientRange(): VuuRange;
104
+ get status(): ViewportStatus;
105
+ set status(status: ViewportStatus);
107
106
  subscribe(): VuuViewportCreateRequest;
108
107
  handleSubscribed({ viewPortId, aggregations, columns, filterSpec: filter, range, sort, groupBy, table, }: VuuViewportCreateResponse, baseTableSchema: TableSchema): DataSourceSubscribedMessage;
109
108
  awaitOperation(requestId: string, msg: AsyncOperation): void;
@@ -1,6 +1,6 @@
1
- import { DataSource, DataSourceCallbackMessage, DataSourceConfig, DataSourceConstructorProps, DataSourceEvents, DataSourceFilter, DataSourceStatus, OptimizeStrategy, Selection, SubscribeCallback, SubscribeProps, TableSchema } from "@vuu-ui/vuu-data-types";
2
- import { LinkDescriptorWithLabel, VuuAggregation, VuuDataRowDto, VuuGroupBy, VuuMenu, VuuRange, VuuRowDataItemType, VuuSort, VuuTable, VuuRpcResponse, VuuRpcRequest } from "@vuu-ui/vuu-protocol-types";
3
- import { EventEmitter, DataSourceConfigChanges } from "@vuu-ui/vuu-utils";
1
+ import { DataSource, DataSourceCallbackMessage, DataSourceConfig, DataSourceConstructorProps, DataSourceEvents, DataSourceFilter, DataSourceStatus, OptimizeStrategy, Selection, SubscribeCallback, SubscribeProps, TableSchema, WithBaseFilter } from "@vuu-ui/vuu-data-types";
2
+ import { LinkDescriptorWithLabel, VuuAggregation, VuuDataRowDto, VuuGroupBy, VuuMenu, VuuRange, VuuRowDataItemType, VuuRpcRequest, VuuRpcResponse, VuuSort, VuuTable } from "@vuu-ui/vuu-protocol-types";
3
+ import { DataSourceConfigChanges, EventEmitter } from "@vuu-ui/vuu-utils";
4
4
  import { MenuRpcResponse } from "@vuu-ui/vuu-data-types";
5
5
  export declare class VuuDataSource extends EventEmitter<DataSourceEvents> implements DataSource {
6
6
  #private;
@@ -16,7 +16,7 @@ export declare class VuuDataSource extends EventEmitter<DataSourceEvents> implem
16
16
  handleMessageFromServer: (message: DataSourceCallbackMessage) => void;
17
17
  unsubscribe(): void;
18
18
  suspend(): void;
19
- resume(): void;
19
+ resume(callback?: SubscribeCallback): void;
20
20
  disable(): void;
21
21
  enable(callback?: SubscribeCallback): void;
22
22
  select(selected: Selection): void;
@@ -39,13 +39,15 @@ export declare class VuuDataSource extends EventEmitter<DataSourceEvents> implem
39
39
  private throttleRangeRequest;
40
40
  get config(): DataSourceConfig;
41
41
  set config(config: DataSourceConfig);
42
- applyConfig(config: DataSourceConfig, preserveExistingConfigAttributes?: boolean): DataSourceConfigChanges | undefined;
42
+ applyConfig(config: WithBaseFilter<DataSourceConfig>, preserveExistingConfigAttributes?: boolean): DataSourceConfigChanges | undefined;
43
43
  get columns(): string[];
44
44
  set columns(columns: string[]);
45
45
  get aggregations(): VuuAggregation[];
46
46
  set aggregations(aggregations: VuuAggregation[]);
47
47
  get sort(): VuuSort;
48
48
  set sort(sort: VuuSort);
49
+ get baseFilter(): DataSourceFilter;
50
+ set baseFilter(baseFilter: DataSourceFilter);
49
51
  get filter(): DataSourceFilter;
50
52
  set filter(filter: DataSourceFilter);
51
53
  get groupBy(): VuuGroupBy;
@@ -1,224 +0,0 @@
1
- 'use strict';
2
-
3
- var vuuUtils = require('@vuu-ui/vuu-utils');
4
- var dataSource = require('./data-source.js');
5
- var messages = require('./server-proxy/messages.js');
6
- var inlinedWorker = require('./inlined-worker.js');
7
-
8
- const workerBlob = new Blob([vuuUtils.getLoggingConfigForWorker() + inlinedWorker.workerSourceCode], {
9
- type: "text/javascript"
10
- });
11
- const workerBlobUrl = URL.createObjectURL(workerBlob);
12
- let worker;
13
- let pendingWorker;
14
- const pendingWorkerNoToken = [];
15
- let resolveServer;
16
- let rejectServer;
17
- const serverAPI = new Promise((resolve, reject) => {
18
- resolveServer = resolve;
19
- rejectServer = reject;
20
- });
21
- const getServerAPI = () => serverAPI;
22
- const viewports = /* @__PURE__ */ new Map();
23
- const pendingRequests = /* @__PURE__ */ new Map();
24
- const getWorker = async ({
25
- handleConnectionStatusChange,
26
- protocol,
27
- retryLimitDisconnect,
28
- retryLimitStartup,
29
- token = "",
30
- username,
31
- url
32
- }) => {
33
- if (token === "" && pendingWorker === void 0) {
34
- return new Promise((resolve, reject) => {
35
- pendingWorkerNoToken.push({ resolve, reject });
36
- });
37
- }
38
- return pendingWorker || // we get this far when we receive the first request with auth token
39
- (pendingWorker = new Promise((resolve, reject) => {
40
- const worker2 = new Worker(workerBlobUrl);
41
- const timer = window.setTimeout(() => {
42
- reject(Error("timed out waiting for worker to load"));
43
- }, 1e3);
44
- worker2.onmessage = (msg) => {
45
- const { data: message } = msg;
46
- if (message.type === "ready") {
47
- window.clearTimeout(timer);
48
- worker2.postMessage({
49
- protocol,
50
- retryLimitDisconnect,
51
- retryLimitStartup,
52
- token,
53
- type: "connect",
54
- url,
55
- username
56
- });
57
- } else if (message.type === "connected") {
58
- worker2.onmessage = handleMessageFromWorker;
59
- resolve(worker2);
60
- for (const pendingWorkerRequest of pendingWorkerNoToken) {
61
- pendingWorkerRequest.resolve(worker2);
62
- }
63
- pendingWorkerNoToken.length = 0;
64
- } else if (vuuUtils.isConnectionStatusMessage(message)) {
65
- handleConnectionStatusChange({ data: message });
66
- } else if (message.type === "connection-failed") {
67
- reject(message.reason);
68
- for (const pendingWorkerRequest of pendingWorkerNoToken) {
69
- pendingWorkerRequest.reject(message.reason);
70
- }
71
- pendingWorkerNoToken.length = 0;
72
- } else {
73
- console.warn("ConnectionManager: Unexpected message from the worker");
74
- }
75
- };
76
- }));
77
- };
78
- function handleMessageFromWorker({
79
- data: message
80
- }) {
81
- if (dataSource.shouldMessageBeRoutedToDataSource(message)) {
82
- const viewport = viewports.get(message.clientViewportId);
83
- if (viewport) {
84
- viewport.postMessageToClientDataSource(message);
85
- } else {
86
- console.error(
87
- `[ConnectionManager] ${message.type} message received, viewport not found`
88
- );
89
- }
90
- } else if (vuuUtils.isConnectionStatusMessage(message)) {
91
- ConnectionManager.emit("connection-status", message);
92
- } else if (vuuUtils.isConnectionQualityMetrics(message)) {
93
- ConnectionManager.emit("connection-metrics", message);
94
- } else if (vuuUtils.isRequestResponse(message)) {
95
- const { requestId } = message;
96
- if (pendingRequests.has(requestId)) {
97
- const { resolve } = pendingRequests.get(requestId);
98
- pendingRequests.delete(requestId);
99
- const { requestId: _, ...messageWithoutRequestId } = message;
100
- if (vuuUtils.messageHasResult(message)) {
101
- resolve(message.result);
102
- } else if (message.type === "VP_EDIT_RPC_RESPONSE" || message.type === "VP_EDIT_RPC_REJECT") {
103
- resolve(message);
104
- } else if (vuuUtils.isTableSchemaMessage(message)) {
105
- resolve(message.tableSchema);
106
- } else {
107
- resolve(messageWithoutRequestId);
108
- }
109
- } else {
110
- console.warn(
111
- "%cConnectionManager Unexpected message from the worker",
112
- "color:red;font-weight:bold;"
113
- );
114
- }
115
- }
116
- }
117
- const asyncRequest = (msg) => {
118
- const requestId = vuuUtils.uuid();
119
- worker.postMessage({
120
- requestId,
121
- ...msg
122
- });
123
- return new Promise((resolve, reject) => {
124
- pendingRequests.set(requestId, { resolve, reject });
125
- });
126
- };
127
- const connectedServerAPI = {
128
- subscribe: (message, callback) => {
129
- if (viewports.get(message.viewport)) {
130
- throw Error(
131
- `ConnectionManager attempting to subscribe with an existing viewport id`
132
- );
133
- }
134
- viewports.set(message.viewport, {
135
- status: "subscribing",
136
- request: message,
137
- postMessageToClientDataSource: callback
138
- });
139
- worker.postMessage({ type: "subscribe", ...message });
140
- },
141
- unsubscribe: (viewport) => {
142
- worker.postMessage({ type: "unsubscribe", viewport });
143
- },
144
- send: (message) => {
145
- worker.postMessage(message);
146
- },
147
- destroy: (viewportId) => {
148
- if (viewportId && viewports.has(viewportId)) {
149
- viewports.delete(viewportId);
150
- }
151
- },
152
- rpcCall: async (message) => asyncRequest(message),
153
- getTableList: async () => asyncRequest({ type: "GET_TABLE_LIST" }),
154
- getTableSchema: async (table) => asyncRequest({
155
- type: messages.GET_TABLE_META,
156
- table
157
- })
158
- };
159
- class _ConnectionManager extends vuuUtils.EventEmitter {
160
- // The first request must have the token. We can change this to block others until
161
- // the request with token is received.
162
- async connect({
163
- url,
164
- authToken,
165
- username,
166
- protocol,
167
- retryLimitDisconnect,
168
- retryLimitStartup
169
- }) {
170
- worker = await getWorker({
171
- protocol,
172
- url,
173
- token: authToken,
174
- username,
175
- retryLimitDisconnect,
176
- retryLimitStartup,
177
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
178
- // @ts-ignore
179
- handleConnectionStatusChange: handleMessageFromWorker
180
- });
181
- return connectedServerAPI;
182
- }
183
- destroy() {
184
- worker.terminate();
185
- }
186
- }
187
- const ConnectionManager = new _ConnectionManager();
188
- const connectToServer = async ({
189
- url,
190
- protocol = void 0,
191
- authToken,
192
- username,
193
- retryLimitDisconnect,
194
- retryLimitStartup
195
- }) => {
196
- try {
197
- const serverAPI2 = await ConnectionManager.connect({
198
- protocol,
199
- url,
200
- authToken,
201
- username,
202
- retryLimitDisconnect,
203
- retryLimitStartup
204
- });
205
- resolveServer(serverAPI2);
206
- return "connected";
207
- } catch (err) {
208
- rejectServer(err);
209
- return "rejected";
210
- }
211
- };
212
- const makeRpcCall = async (rpcRequest) => {
213
- try {
214
- return (await serverAPI).rpcCall(rpcRequest);
215
- } catch (err) {
216
- throw Error("Error accessing server api");
217
- }
218
- };
219
-
220
- exports.ConnectionManager = ConnectionManager;
221
- exports.connectToServer = connectToServer;
222
- exports.getServerAPI = getServerAPI;
223
- exports.makeRpcCall = makeRpcCall;
224
- //# sourceMappingURL=connection-manager.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"connection-manager.js","sources":["../src/connection-manager.ts"],"sourcesContent":["import {\n ConnectionStatusMessage,\n DataSourceCallbackMessage,\n ServerProxySubscribeMessage,\n TableSchema,\n VuuUIMessageIn,\n VuuUIMessageOut,\n WebSocketProtocol,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n VuuRpcMenuRequest,\n VuuTableListRequest,\n VuuTableMetaRequest,\n VuuRpcViewportRequest,\n VuuRpcServiceRequest,\n VuuTable,\n VuuTableList,\n VuuCreateVisualLink,\n VuuRemoveVisualLink,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport {\n EventEmitter,\n getLoggingConfigForWorker,\n isConnectionQualityMetrics,\n isConnectionStatusMessage,\n isRequestResponse,\n isTableSchemaMessage,\n messageHasResult,\n uuid,\n} from \"@vuu-ui/vuu-utils\";\nimport { shouldMessageBeRoutedToDataSource as messageShouldBeRoutedToDataSource } from \"./data-source\";\nimport * as Message from \"./server-proxy/messages\";\n\n// Note: inlined-worker is a generated file, it must be built\nimport { ConnectionQualityMetrics } from \"@vuu-ui/vuu-data-types\";\nimport { workerSourceCode } from \"./inlined-worker\";\n\nconst workerBlob = new Blob([getLoggingConfigForWorker() + workerSourceCode], {\n type: \"text/javascript\",\n});\nconst workerBlobUrl = URL.createObjectURL(workerBlob);\n\ntype WorkerResolver = {\n reject: (message: string | PromiseLike<string>) => void;\n resolve: (value: Worker | PromiseLike<Worker>) => void;\n};\n\nlet worker: Worker;\nlet pendingWorker: Promise<Worker>;\nconst pendingWorkerNoToken: WorkerResolver[] = [];\n\nlet resolveServer: (server: ServerAPI) => void;\nlet rejectServer: (err: unknown) => void;\n\nconst serverAPI = new Promise<ServerAPI>((resolve, reject) => {\n resolveServer = resolve;\n rejectServer = reject;\n});\n\n/**\n * returns a promise for serverApi. This will be resolved when the\n * connectToServer call succeeds. If client never calls connectToServer\n * serverAPI will never be resolved.\n */\nexport const getServerAPI = () => serverAPI;\n\nexport type PostMessageToClientCallback = (\n msg: DataSourceCallbackMessage,\n) => void;\n\nconst viewports = new Map<\n string,\n {\n postMessageToClientDataSource: PostMessageToClientCallback;\n request: ServerProxySubscribeMessage;\n status: \"subscribing\";\n }\n>();\nconst pendingRequests = new Map();\n\ntype WorkerOptions = {\n protocol: WebSocketProtocol;\n retryLimitDisconnect?: number;\n retryLimitStartup?: number;\n url: string;\n token?: string;\n username: string | undefined;\n handleConnectionStatusChange: (msg: {\n data: ConnectionStatusMessage;\n }) => void;\n};\n\n// We do not resolve the worker until we have a connection, but we will get\n// connection status messages before that, so we forward them to caller\n// while they wait for worker.\nconst getWorker = async ({\n handleConnectionStatusChange,\n protocol,\n retryLimitDisconnect,\n retryLimitStartup,\n token = \"\",\n username,\n url,\n}: WorkerOptions) => {\n if (token === \"\" && pendingWorker === undefined) {\n return new Promise<Worker>((resolve, reject) => {\n pendingWorkerNoToken.push({ resolve, reject });\n });\n }\n //FIXME If we have a pending request already and a new request arrives with a DIFFERENT\n // token, this would cause us to ignore the new request and ultimately resolve it with\n // the original request.\n return (\n pendingWorker ||\n // we get this far when we receive the first request with auth token\n (pendingWorker = new Promise((resolve, reject) => {\n const worker = new Worker(workerBlobUrl);\n\n const timer: number | null = window.setTimeout(() => {\n reject(Error(\"timed out waiting for worker to load\"));\n }, 1000);\n\n // This is the inial message handler only, it processes messages whilst we are\n // establishing a connection. When we resolve the worker, a runtime message\n // handler will replace this (see below)\n worker.onmessage = (msg: MessageEvent<VuuUIMessageIn>) => {\n const { data: message } = msg;\n if (message.type === \"ready\") {\n window.clearTimeout(timer);\n worker.postMessage({\n protocol,\n retryLimitDisconnect,\n retryLimitStartup,\n token,\n type: \"connect\",\n url,\n username,\n });\n } else if (message.type === \"connected\") {\n worker.onmessage = handleMessageFromWorker;\n resolve(worker);\n for (const pendingWorkerRequest of pendingWorkerNoToken) {\n pendingWorkerRequest.resolve(worker);\n }\n pendingWorkerNoToken.length = 0;\n } else if (isConnectionStatusMessage(message)) {\n handleConnectionStatusChange({ data: message });\n } else if (message.type === \"connection-failed\") {\n reject(message.reason);\n for (const pendingWorkerRequest of pendingWorkerNoToken) {\n pendingWorkerRequest.reject(message.reason);\n }\n pendingWorkerNoToken.length = 0;\n } else {\n console.warn(\"ConnectionManager: Unexpected message from the worker\");\n }\n };\n // TODO handle error\n }))\n );\n};\n\nfunction handleMessageFromWorker({\n data: message,\n}: MessageEvent<VuuUIMessageIn | DataSourceCallbackMessage>) {\n if (messageShouldBeRoutedToDataSource(message)) {\n const viewport = viewports.get(message.clientViewportId);\n if (viewport) {\n viewport.postMessageToClientDataSource(message);\n } else {\n console.error(\n `[ConnectionManager] ${message.type} message received, viewport not found`,\n );\n }\n } else if (isConnectionStatusMessage(message)) {\n ConnectionManager.emit(\"connection-status\", message);\n } else if (isConnectionQualityMetrics(message)) {\n ConnectionManager.emit(\"connection-metrics\", message);\n } else if (isRequestResponse(message)) {\n const { requestId } = message;\n if (pendingRequests.has(requestId)) {\n const { resolve } = pendingRequests.get(requestId);\n pendingRequests.delete(requestId);\n const { requestId: _, ...messageWithoutRequestId } = message;\n\n if (messageHasResult(message)) {\n resolve(message.result);\n } else if (\n message.type === \"VP_EDIT_RPC_RESPONSE\" ||\n message.type === \"VP_EDIT_RPC_REJECT\"\n ) {\n resolve(message);\n } else if (isTableSchemaMessage(message)) {\n resolve(message.tableSchema);\n } else {\n resolve(messageWithoutRequestId);\n }\n } else {\n console.warn(\n \"%cConnectionManager Unexpected message from the worker\",\n \"color:red;font-weight:bold;\",\n );\n }\n }\n}\n\nconst asyncRequest = <T = unknown>(\n msg:\n | VuuRpcServiceRequest\n | VuuRpcMenuRequest\n | VuuTableListRequest\n | VuuTableMetaRequest\n | VuuRpcViewportRequest\n | VuuCreateVisualLink\n | VuuRemoveVisualLink,\n): Promise<T> => {\n const requestId = uuid();\n worker.postMessage({\n requestId,\n ...msg,\n });\n return new Promise((resolve, reject) => {\n pendingRequests.set(requestId, { resolve, reject });\n });\n};\n\nexport interface ServerAPI {\n destroy: (viewportId?: string) => void;\n getTableSchema: (table: VuuTable) => Promise<TableSchema>;\n getTableList: (module?: string) => Promise<VuuTableList>;\n // TODO its not really unknown\n rpcCall: <T = unknown>(\n msg:\n | VuuRpcServiceRequest\n | VuuRpcMenuRequest\n | VuuRpcViewportRequest\n | VuuCreateVisualLink\n | VuuRemoveVisualLink,\n ) => Promise<T>;\n send: (message: VuuUIMessageOut) => void;\n subscribe: (\n message: ServerProxySubscribeMessage,\n callback: PostMessageToClientCallback,\n ) => void;\n unsubscribe: (viewport: string) => void;\n}\n\nconst connectedServerAPI: ServerAPI = {\n subscribe: (message, callback) => {\n if (viewports.get(message.viewport)) {\n throw Error(\n `ConnectionManager attempting to subscribe with an existing viewport id`,\n );\n }\n // TODO we never use this status\n viewports.set(message.viewport, {\n status: \"subscribing\",\n request: message,\n postMessageToClientDataSource: callback,\n });\n worker.postMessage({ type: \"subscribe\", ...message });\n },\n\n unsubscribe: (viewport) => {\n worker.postMessage({ type: \"unsubscribe\", viewport });\n },\n\n send: (message) => {\n worker.postMessage(message);\n },\n\n destroy: (viewportId?: string) => {\n if (viewportId && viewports.has(viewportId)) {\n viewports.delete(viewportId);\n }\n },\n\n rpcCall: async <T = unknown>(\n message:\n | VuuRpcServiceRequest\n | VuuRpcMenuRequest\n | VuuRpcViewportRequest\n | VuuCreateVisualLink\n | VuuRemoveVisualLink,\n ) => asyncRequest<T>(message),\n\n getTableList: async () =>\n asyncRequest<VuuTableList>({ type: \"GET_TABLE_LIST\" }),\n\n getTableSchema: async (table) =>\n asyncRequest<TableSchema>({\n type: Message.GET_TABLE_META,\n table,\n }),\n};\n\nexport type ConnectionEvents = {\n \"connection-status\": (message: ConnectionStatusMessage) => void;\n \"connection-metrics\": (message: ConnectionQualityMetrics) => void;\n};\n\nexport type ConnectOptions = {\n url: string;\n authToken?: string;\n username?: string;\n protocol?: WebSocketProtocol;\n /** Max number of reconnect attempts in the event of unsuccessful websocket connection at startup */\n retryLimitStartup?: number;\n /** Max number of reconnect attempts in the event of a disconnected websocket connection */\n retryLimitDisconnect?: number;\n};\n\nclass _ConnectionManager extends EventEmitter<ConnectionEvents> {\n // The first request must have the token. We can change this to block others until\n // the request with token is received.\n async connect({\n url,\n authToken,\n username,\n protocol,\n retryLimitDisconnect,\n retryLimitStartup,\n }: ConnectOptions): Promise<ServerAPI> {\n // By passing handleMessageFromWorker here, we can get connection status\n //messages while we wait for worker to resolve.\n worker = await getWorker({\n protocol,\n url,\n token: authToken,\n username,\n retryLimitDisconnect,\n retryLimitStartup,\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n handleConnectionStatusChange: handleMessageFromWorker,\n });\n return connectedServerAPI;\n }\n\n destroy() {\n worker.terminate();\n }\n}\n\nexport const ConnectionManager = new _ConnectionManager();\n\n/**\n * Open a connection to the VuuServer. This method opens the websocket connection\n * and logs in. It can be called from whichever client code has access to the auth\n * token (eg. the login page, or just a hardcoded login script in a sample).\n * This will unblock any DataSources which may have already tried to subscribe to data,\n * but lacked access to the auth token.\n *\n * @param serverUrl\n * @param token\n */\nexport const connectToServer = async ({\n url,\n protocol = undefined,\n authToken,\n username,\n retryLimitDisconnect,\n retryLimitStartup,\n}: ConnectOptions): Promise<\"connected\" | \"rejected\"> => {\n try {\n const serverAPI = await ConnectionManager.connect({\n protocol,\n url,\n authToken,\n username,\n retryLimitDisconnect,\n retryLimitStartup,\n });\n resolveServer(serverAPI);\n return \"connected\";\n } catch (err: unknown) {\n rejectServer(err);\n return \"rejected\";\n }\n};\n\nexport const makeRpcCall = async <T = unknown>(\n rpcRequest: VuuRpcServiceRequest,\n) => {\n try {\n return (await serverAPI).rpcCall<T>(rpcRequest);\n } catch (err) {\n throw Error(\"Error accessing server api\");\n }\n};\n"],"names":["getLoggingConfigForWorker","workerSourceCode","worker","isConnectionStatusMessage","messageShouldBeRoutedToDataSource","isConnectionQualityMetrics","isRequestResponse","messageHasResult","isTableSchemaMessage","uuid","Message.GET_TABLE_META","EventEmitter","serverAPI"],"mappings":"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"}
@@ -1,6 +0,0 @@
1
- 'use strict';
2
-
3
- const GET_TABLE_META = "GET_TABLE_META";
4
-
5
- exports.GET_TABLE_META = GET_TABLE_META;
6
- //# sourceMappingURL=messages.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"messages.js","sources":["../../src/server-proxy/messages.ts"],"sourcesContent":["export const CHANGE_VP_SUCCESS = \"CHANGE_VP_SUCCESS\";\nexport const CHANGE_VP_RANGE_SUCCESS = \"CHANGE_VP_RANGE_SUCCESS\";\nexport const CLOSE_TREE_NODE = \"CLOSE_TREE_NODE\";\nexport const CLOSE_TREE_SUCCESS = \"CLOSE_TREE_SUCCESS\";\nexport const CLOSE_TREE_REJECT = \"CLOSE_TREE_REJECT\";\nexport const CREATE_VISUAL_LINK = \"CREATE_VISUAL_LINK\";\nexport const CREATE_VP = \"CREATE_VP\";\nexport const DISABLE_VP = \"DISABLE_VP\";\nexport const DISABLE_VP_SUCCESS = \"DISABLE_VP_SUCCESS\";\nexport const DISABLE_VP_REJECT = \"DISABLE_VP_REJECT\";\nexport const ENABLE_VP = \"ENABLE_VP\";\nexport const ENABLE_VP_SUCCESS = \"ENABLE_VP_SUCCESS\";\nexport const ENABLE_VP_REJECT = \"ENABLE_VP_REJECT\";\nexport const GET_TABLE_META = \"GET_TABLE_META\";\nexport const GET_VP_VISUAL_LINKS = \"GET_VP_VISUAL_LINKS\";\nexport const GET_VIEW_PORT_MENUS = \"GET_VIEW_PORT_MENUS\";\nexport const VIEW_PORT_MENUS_SELECT_RPC = \"VIEW_PORT_MENUS_SELECT_RPC\";\nexport const VIEW_PORT_MENU_CELL_RPC = \"VIEW_PORT_MENU_CELL_RPC\";\nexport const VIEW_PORT_MENU_TABLE_RPC = \"VIEW_PORT_MENU_TABLE_RPC\";\nexport const VIEW_PORT_MENU_ROW_RPC = \"VIEW_PORT_MENU_ROW_RPC\";\nexport const VIEW_PORT_MENU_RESP = \"VIEW_PORT_MENU_RESP\";\nexport const VIEW_PORT_MENU_REJ = \"VIEW_PORT_MENU_REJ\";\nexport const HB = \"HB\";\nexport const HB_RESP = \"HB_RESP\";\nexport const LOGIN = \"LOGIN\";\nexport const OPEN_TREE_NODE = \"OPEN_TREE_NODE\";\nexport const OPEN_TREE_SUCCESS = \"OPEN_TREE_SUCCESS\";\nexport const OPEN_TREE_REJECT = \"OPEN_TREE_REJECT\";\nexport const REMOVE_VP = \"REMOVE_VP\";\nexport const REMOVE_VP_REJECT = \"REMOVE_VP_REJECT\";\nexport const RPC_CALL = \"RPC_CALL\";\nexport const RPC_RESP = \"RPC_RESP\";\nexport const MENU_RPC_RESP = \"MENU_RPC_RESP\";\nexport const SET_SELECTION = \"SET_SELECTION\";\nexport const SET_SELECTION_SUCCESS = \"SET_SELECTION_SUCCESS\";\n\nexport const TABLE_ROW = \"TABLE_ROW\";\nexport const SIZE = \"SIZE\";\nexport const UPDATE = \"U\";\n"],"names":[],"mappings":";;AAaO,MAAM,cAAiB,GAAA;;;;"}
@@ -1,219 +0,0 @@
1
- import { getLoggingConfigForWorker, EventEmitter, isConnectionStatusMessage, isConnectionQualityMetrics, isRequestResponse, messageHasResult, isTableSchemaMessage, uuid } from '@vuu-ui/vuu-utils';
2
- import { shouldMessageBeRoutedToDataSource } from './data-source.js';
3
- import { GET_TABLE_META } from './server-proxy/messages.js';
4
- import { workerSourceCode } from './inlined-worker.js';
5
-
6
- const workerBlob = new Blob([getLoggingConfigForWorker() + workerSourceCode], {
7
- type: "text/javascript"
8
- });
9
- const workerBlobUrl = URL.createObjectURL(workerBlob);
10
- let worker;
11
- let pendingWorker;
12
- const pendingWorkerNoToken = [];
13
- let resolveServer;
14
- let rejectServer;
15
- const serverAPI = new Promise((resolve, reject) => {
16
- resolveServer = resolve;
17
- rejectServer = reject;
18
- });
19
- const getServerAPI = () => serverAPI;
20
- const viewports = /* @__PURE__ */ new Map();
21
- const pendingRequests = /* @__PURE__ */ new Map();
22
- const getWorker = async ({
23
- handleConnectionStatusChange,
24
- protocol,
25
- retryLimitDisconnect,
26
- retryLimitStartup,
27
- token = "",
28
- username,
29
- url
30
- }) => {
31
- if (token === "" && pendingWorker === void 0) {
32
- return new Promise((resolve, reject) => {
33
- pendingWorkerNoToken.push({ resolve, reject });
34
- });
35
- }
36
- return pendingWorker || // we get this far when we receive the first request with auth token
37
- (pendingWorker = new Promise((resolve, reject) => {
38
- const worker2 = new Worker(workerBlobUrl);
39
- const timer = window.setTimeout(() => {
40
- reject(Error("timed out waiting for worker to load"));
41
- }, 1e3);
42
- worker2.onmessage = (msg) => {
43
- const { data: message } = msg;
44
- if (message.type === "ready") {
45
- window.clearTimeout(timer);
46
- worker2.postMessage({
47
- protocol,
48
- retryLimitDisconnect,
49
- retryLimitStartup,
50
- token,
51
- type: "connect",
52
- url,
53
- username
54
- });
55
- } else if (message.type === "connected") {
56
- worker2.onmessage = handleMessageFromWorker;
57
- resolve(worker2);
58
- for (const pendingWorkerRequest of pendingWorkerNoToken) {
59
- pendingWorkerRequest.resolve(worker2);
60
- }
61
- pendingWorkerNoToken.length = 0;
62
- } else if (isConnectionStatusMessage(message)) {
63
- handleConnectionStatusChange({ data: message });
64
- } else if (message.type === "connection-failed") {
65
- reject(message.reason);
66
- for (const pendingWorkerRequest of pendingWorkerNoToken) {
67
- pendingWorkerRequest.reject(message.reason);
68
- }
69
- pendingWorkerNoToken.length = 0;
70
- } else {
71
- console.warn("ConnectionManager: Unexpected message from the worker");
72
- }
73
- };
74
- }));
75
- };
76
- function handleMessageFromWorker({
77
- data: message
78
- }) {
79
- if (shouldMessageBeRoutedToDataSource(message)) {
80
- const viewport = viewports.get(message.clientViewportId);
81
- if (viewport) {
82
- viewport.postMessageToClientDataSource(message);
83
- } else {
84
- console.error(
85
- `[ConnectionManager] ${message.type} message received, viewport not found`
86
- );
87
- }
88
- } else if (isConnectionStatusMessage(message)) {
89
- ConnectionManager.emit("connection-status", message);
90
- } else if (isConnectionQualityMetrics(message)) {
91
- ConnectionManager.emit("connection-metrics", message);
92
- } else if (isRequestResponse(message)) {
93
- const { requestId } = message;
94
- if (pendingRequests.has(requestId)) {
95
- const { resolve } = pendingRequests.get(requestId);
96
- pendingRequests.delete(requestId);
97
- const { requestId: _, ...messageWithoutRequestId } = message;
98
- if (messageHasResult(message)) {
99
- resolve(message.result);
100
- } else if (message.type === "VP_EDIT_RPC_RESPONSE" || message.type === "VP_EDIT_RPC_REJECT") {
101
- resolve(message);
102
- } else if (isTableSchemaMessage(message)) {
103
- resolve(message.tableSchema);
104
- } else {
105
- resolve(messageWithoutRequestId);
106
- }
107
- } else {
108
- console.warn(
109
- "%cConnectionManager Unexpected message from the worker",
110
- "color:red;font-weight:bold;"
111
- );
112
- }
113
- }
114
- }
115
- const asyncRequest = (msg) => {
116
- const requestId = uuid();
117
- worker.postMessage({
118
- requestId,
119
- ...msg
120
- });
121
- return new Promise((resolve, reject) => {
122
- pendingRequests.set(requestId, { resolve, reject });
123
- });
124
- };
125
- const connectedServerAPI = {
126
- subscribe: (message, callback) => {
127
- if (viewports.get(message.viewport)) {
128
- throw Error(
129
- `ConnectionManager attempting to subscribe with an existing viewport id`
130
- );
131
- }
132
- viewports.set(message.viewport, {
133
- status: "subscribing",
134
- request: message,
135
- postMessageToClientDataSource: callback
136
- });
137
- worker.postMessage({ type: "subscribe", ...message });
138
- },
139
- unsubscribe: (viewport) => {
140
- worker.postMessage({ type: "unsubscribe", viewport });
141
- },
142
- send: (message) => {
143
- worker.postMessage(message);
144
- },
145
- destroy: (viewportId) => {
146
- if (viewportId && viewports.has(viewportId)) {
147
- viewports.delete(viewportId);
148
- }
149
- },
150
- rpcCall: async (message) => asyncRequest(message),
151
- getTableList: async () => asyncRequest({ type: "GET_TABLE_LIST" }),
152
- getTableSchema: async (table) => asyncRequest({
153
- type: GET_TABLE_META,
154
- table
155
- })
156
- };
157
- class _ConnectionManager extends EventEmitter {
158
- // The first request must have the token. We can change this to block others until
159
- // the request with token is received.
160
- async connect({
161
- url,
162
- authToken,
163
- username,
164
- protocol,
165
- retryLimitDisconnect,
166
- retryLimitStartup
167
- }) {
168
- worker = await getWorker({
169
- protocol,
170
- url,
171
- token: authToken,
172
- username,
173
- retryLimitDisconnect,
174
- retryLimitStartup,
175
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
176
- // @ts-ignore
177
- handleConnectionStatusChange: handleMessageFromWorker
178
- });
179
- return connectedServerAPI;
180
- }
181
- destroy() {
182
- worker.terminate();
183
- }
184
- }
185
- const ConnectionManager = new _ConnectionManager();
186
- const connectToServer = async ({
187
- url,
188
- protocol = void 0,
189
- authToken,
190
- username,
191
- retryLimitDisconnect,
192
- retryLimitStartup
193
- }) => {
194
- try {
195
- const serverAPI2 = await ConnectionManager.connect({
196
- protocol,
197
- url,
198
- authToken,
199
- username,
200
- retryLimitDisconnect,
201
- retryLimitStartup
202
- });
203
- resolveServer(serverAPI2);
204
- return "connected";
205
- } catch (err) {
206
- rejectServer(err);
207
- return "rejected";
208
- }
209
- };
210
- const makeRpcCall = async (rpcRequest) => {
211
- try {
212
- return (await serverAPI).rpcCall(rpcRequest);
213
- } catch (err) {
214
- throw Error("Error accessing server api");
215
- }
216
- };
217
-
218
- export { ConnectionManager, connectToServer, getServerAPI, makeRpcCall };
219
- //# sourceMappingURL=connection-manager.js.map