@vuu-ui/vuu-data-remote 0.13.2 → 0.13.4
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.
- package/package.json +10 -13
- package/types/ConnectionManager.d.ts +0 -33
- package/types/DedicatedWorker.d.ts +0 -9
- package/types/VuuDataSource.d.ts +0 -53
- package/types/WebSocketConnection.d.ts +0 -68
- package/types/authenticate.d.ts +0 -1
- package/types/constants.d.ts +0 -41
- package/types/data-source.d.ts +0 -5
- package/types/index.d.ts +0 -9
- package/types/inlined-worker.d.ts +0 -1
- package/types/message-utils.d.ts +0 -11
- package/types/rest-data/RestDataSource.d.ts +0 -42
- package/types/rest-data/moving-window.d.ts +0 -14
- package/types/rest-data/rest-utils.d.ts +0 -14
- package/types/server-proxy/array-backed-moving-window.d.ts +0 -28
- package/types/server-proxy/messages.d.ts +0 -38
- package/types/server-proxy/rpc-services.d.ts +0 -2
- package/types/server-proxy/server-proxy.d.ts +0 -64
- package/types/server-proxy/viewport.d.ts +0 -117
- package/types/worker.d.ts +0 -1
package/package.json
CHANGED
|
@@ -1,33 +1,30 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.13.
|
|
2
|
+
"version": "0.13.4",
|
|
3
3
|
"author": "heswell",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"devDependencies": {
|
|
6
|
-
"@vuu-ui/vuu-data-types": "0.13.
|
|
7
|
-
"@vuu-ui/vuu-table-types": "0.13.
|
|
8
|
-
"@vuu-ui/vuu-filter-types": "0.13.
|
|
9
|
-
"@vuu-ui/vuu-protocol-types": "0.13.
|
|
6
|
+
"@vuu-ui/vuu-data-types": "0.13.4",
|
|
7
|
+
"@vuu-ui/vuu-table-types": "0.13.4",
|
|
8
|
+
"@vuu-ui/vuu-filter-types": "0.13.4",
|
|
9
|
+
"@vuu-ui/vuu-protocol-types": "0.13.4"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@vuu-ui/vuu-filter-parser": "0.13.
|
|
13
|
-
"@vuu-ui/vuu-utils": "0.13.
|
|
12
|
+
"@vuu-ui/vuu-filter-parser": "0.13.4",
|
|
13
|
+
"@vuu-ui/vuu-utils": "0.13.4"
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
16
|
"README.md",
|
|
17
17
|
"esm",
|
|
18
|
-
"cjs"
|
|
19
|
-
"/types"
|
|
18
|
+
"cjs"
|
|
20
19
|
],
|
|
21
20
|
"exports": {
|
|
22
21
|
".": {
|
|
23
22
|
"require": "./cjs/index.js",
|
|
24
|
-
"import": "./esm/index.js"
|
|
25
|
-
"types": "./types/index.d.ts"
|
|
23
|
+
"import": "./esm/index.js"
|
|
26
24
|
}
|
|
27
25
|
},
|
|
28
26
|
"main": "cjs/index.js",
|
|
29
27
|
"module": "esm/index.js",
|
|
30
28
|
"name": "@vuu-ui/vuu-data-remote",
|
|
31
|
-
"type": "module"
|
|
32
|
-
"types": "types/index.d.ts"
|
|
29
|
+
"type": "module"
|
|
33
30
|
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { ConnectOptions, DataSourceCallbackMessage, ServerAPI } from "@vuu-ui/vuu-data-types";
|
|
2
|
-
import { EventEmitter } from "@vuu-ui/vuu-utils";
|
|
3
|
-
import { WebSocketConnectionEvents } from "./WebSocketConnection";
|
|
4
|
-
import { ConnectionQualityMetrics } from "@vuu-ui/vuu-data-types";
|
|
5
|
-
export type PostMessageToClientCallback = (msg: DataSourceCallbackMessage) => void;
|
|
6
|
-
export type ConnectionEvents = WebSocketConnectionEvents & {
|
|
7
|
-
"connection-metrics": (message: ConnectionQualityMetrics) => void;
|
|
8
|
-
};
|
|
9
|
-
declare class ConnectionManager extends EventEmitter<ConnectionEvents> {
|
|
10
|
-
#private;
|
|
11
|
-
private constructor();
|
|
12
|
-
static get instance(): ConnectionManager;
|
|
13
|
-
/**
|
|
14
|
-
* Open a connection to the VuuServer. This method opens the websocket connection
|
|
15
|
-
* and logs in. It can be called from whichever client code has access to the auth
|
|
16
|
-
* token (eg. the login page, or just a hardcoded login script in a sample).
|
|
17
|
-
* This will unblock any DataSources which may have already tried to subscribe to data,
|
|
18
|
-
* but lacked access to the auth token.
|
|
19
|
-
*
|
|
20
|
-
* @param serverUrl
|
|
21
|
-
* @param token
|
|
22
|
-
*/
|
|
23
|
-
connect(options: ConnectOptions): Promise<"connected" | "reconnected" | "rejected">;
|
|
24
|
-
private handleMessageFromWorker;
|
|
25
|
-
get connectionStatus(): import("./WebSocketConnection").ConnectionStatus;
|
|
26
|
-
get serverAPI(): Promise<ServerAPI>;
|
|
27
|
-
private connectedServerAPI;
|
|
28
|
-
private asyncRequest;
|
|
29
|
-
disconnect(): Promise<"disconnected" | "rejected">;
|
|
30
|
-
destroy(): void;
|
|
31
|
-
}
|
|
32
|
-
declare const _default: ConnectionManager;
|
|
33
|
-
export default _default;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { ConnectOptions, VuuUIMessageIn, VuuUIMessageOut, WithRequestId } from "@vuu-ui/vuu-data-types";
|
|
2
|
-
import { VuuCreateVisualLink, VuuRemoveVisualLink, VuuRpcMenuRequest, VuuRpcServiceRequest, VuuRpcViewportRequest } from "@vuu-ui/vuu-protocol-types";
|
|
3
|
-
export declare class DedicatedWorker {
|
|
4
|
-
#private;
|
|
5
|
-
constructor(onMessage: (msg: VuuUIMessageIn) => void);
|
|
6
|
-
connect(options: ConnectOptions): Promise<"connected" | "reconnected" | "rejected">;
|
|
7
|
-
send(message: VuuUIMessageOut | WithRequestId<VuuRpcViewportRequest | VuuCreateVisualLink | VuuRemoveVisualLink | VuuRpcServiceRequest | VuuRpcMenuRequest>): Promise<void>;
|
|
8
|
-
terminate(): Promise<void>;
|
|
9
|
-
}
|
package/types/VuuDataSource.d.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { DataSource, DataSourceCallbackMessage, DataSourceConstructorProps, DataSourceStatus, OptimizeStrategy, Selection, DataSourceSubscribeCallback, DataSourceSubscribeProps, TableSchema, WithBaseFilter, WithFullConfig } from "@vuu-ui/vuu-data-types";
|
|
2
|
-
import { LinkDescriptorWithLabel, VuuDataRowDto, VuuGroupBy, VuuMenu, VuuRange, VuuRowDataItemType, VuuRpcRequest, VuuRpcResponse, VuuTable } from "@vuu-ui/vuu-protocol-types";
|
|
3
|
-
import { BaseDataSource } from "@vuu-ui/vuu-utils";
|
|
4
|
-
import { MenuRpcResponse } from "@vuu-ui/vuu-data-types";
|
|
5
|
-
type RangeRequest = (range: VuuRange) => void;
|
|
6
|
-
export declare class VuuDataSource extends BaseDataSource implements DataSource {
|
|
7
|
-
#private;
|
|
8
|
-
private bufferSize;
|
|
9
|
-
private server;
|
|
10
|
-
rangeRequest: RangeRequest;
|
|
11
|
-
table: VuuTable;
|
|
12
|
-
constructor(props: DataSourceConstructorProps);
|
|
13
|
-
subscribe(subscribeProps: DataSourceSubscribeProps, callback: DataSourceSubscribeCallback): Promise<void>;
|
|
14
|
-
handleMessageFromServer: (message: DataSourceCallbackMessage) => void;
|
|
15
|
-
unsubscribe(): void;
|
|
16
|
-
suspend(): void;
|
|
17
|
-
resume(callback?: DataSourceSubscribeCallback): void;
|
|
18
|
-
disable(): void;
|
|
19
|
-
enable(callback?: DataSourceSubscribeCallback): void;
|
|
20
|
-
select(selected: Selection): void;
|
|
21
|
-
openTreeNode(keyOrIndex: string | number): void;
|
|
22
|
-
closeTreeNode(keyOrIndex: string | number): void;
|
|
23
|
-
get tableSchema(): TableSchema | undefined;
|
|
24
|
-
set tableSchema(tableSchema: TableSchema | undefined);
|
|
25
|
-
get links(): LinkDescriptorWithLabel[] | undefined;
|
|
26
|
-
get menu(): VuuMenu | undefined;
|
|
27
|
-
get status(): DataSourceStatus;
|
|
28
|
-
get optimize(): OptimizeStrategy;
|
|
29
|
-
set optimize(optimize: OptimizeStrategy);
|
|
30
|
-
private revertDebounce;
|
|
31
|
-
get selectedRowsCount(): number;
|
|
32
|
-
private rawRangeRequest;
|
|
33
|
-
private debounceRangeRequest;
|
|
34
|
-
private throttleRangeRequest;
|
|
35
|
-
get config(): WithBaseFilter<WithFullConfig>;
|
|
36
|
-
set config(config: WithBaseFilter<WithFullConfig>);
|
|
37
|
-
set impendingConfig(config: WithBaseFilter<WithFullConfig>);
|
|
38
|
-
get groupBy(): VuuGroupBy;
|
|
39
|
-
set groupBy(groupBy: VuuGroupBy);
|
|
40
|
-
get title(): string;
|
|
41
|
-
set title(title: string);
|
|
42
|
-
get visualLink(): LinkDescriptorWithLabel | undefined;
|
|
43
|
-
set visualLink(visualLink: LinkDescriptorWithLabel | undefined);
|
|
44
|
-
remoteProcedureCall<T extends VuuRpcResponse = VuuRpcResponse>(): Promise<T>;
|
|
45
|
-
/** @deprecated */
|
|
46
|
-
rpcCall<T extends VuuRpcResponse = VuuRpcResponse>(rpcRequest: Omit<VuuRpcRequest, "vpId">): Promise<T>;
|
|
47
|
-
/** @deprecated */
|
|
48
|
-
menuRpcCall(rpcRequest: Omit<VuuRpcRequest, "vpId">): Promise<MenuRpcResponse<any> | undefined>;
|
|
49
|
-
applyEdit(rowKey: string, columnName: string, value: VuuRowDataItemType): Promise<string | true>;
|
|
50
|
-
insertRow(rowKey: string, data: VuuDataRowDto): Promise<string | true>;
|
|
51
|
-
deleteRow(rowKey: string): Promise<string | true>;
|
|
52
|
-
}
|
|
53
|
-
export {};
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { WebSocketProtocol } from "@vuu-ui/vuu-data-types";
|
|
2
|
-
import { VuuClientMessage, VuuServerMessage } from "@vuu-ui/vuu-protocol-types";
|
|
3
|
-
import { EventEmitter } from "@vuu-ui/vuu-utils";
|
|
4
|
-
export type ConnectingStatus = "connecting" | "reconnecting";
|
|
5
|
-
export type ConnectedStatus = "connected" | "reconnected";
|
|
6
|
-
export type ConnectionStatus = ConnectedStatus | "closed" | "connection-open-awaiting-session" | "disconnected" | "failed" | "inactive";
|
|
7
|
-
type InternalConnectionStatus = ConnectionStatus | ConnectingStatus;
|
|
8
|
-
type ReconnectAttempts = {
|
|
9
|
-
retryAttemptsTotal: number;
|
|
10
|
-
retryAttemptsRemaining: number;
|
|
11
|
-
secondsToNextRetry: number;
|
|
12
|
-
};
|
|
13
|
-
export interface WebSocketConnectionState<T extends InternalConnectionStatus = ConnectionStatus> extends ReconnectAttempts {
|
|
14
|
-
connectionPhase: ConnectingStatus;
|
|
15
|
-
connectionStatus: T;
|
|
16
|
-
}
|
|
17
|
-
export declare const isWebSocketConnectionMessage: (msg: object | WebSocketConnectionState) => msg is WebSocketConnectionState;
|
|
18
|
-
export type VuuServerMessageCallback = (msg: VuuServerMessage) => void;
|
|
19
|
-
export type RetryLimits = {
|
|
20
|
-
connect: number;
|
|
21
|
-
reconnect: number;
|
|
22
|
-
};
|
|
23
|
-
export type WebSocketConnectionConfig = {
|
|
24
|
-
url: string;
|
|
25
|
-
protocols: WebSocketProtocol;
|
|
26
|
-
callback: VuuServerMessageCallback;
|
|
27
|
-
connectionTimeout?: number;
|
|
28
|
-
retryLimits?: RetryLimits;
|
|
29
|
-
};
|
|
30
|
-
export type WebSocketConnectionCloseReason = "failure" | "shutdown";
|
|
31
|
-
export type WebSocketConnectionEvents = {
|
|
32
|
-
closed: (reason: WebSocketConnectionCloseReason) => void;
|
|
33
|
-
connected: () => void;
|
|
34
|
-
"connection-status": (message: WebSocketConnectionState) => void;
|
|
35
|
-
reconnected: () => void;
|
|
36
|
-
};
|
|
37
|
-
export declare class WebSocketConnection extends EventEmitter<WebSocketConnectionEvents> {
|
|
38
|
-
#private;
|
|
39
|
-
constructor({ callback, connectionTimeout, protocols, retryLimits, url, }: WebSocketConnectionConfig);
|
|
40
|
-
get connectionTimeout(): number;
|
|
41
|
-
get protocols(): WebSocketProtocol;
|
|
42
|
-
get requiresLogin(): boolean;
|
|
43
|
-
get isClosed(): boolean;
|
|
44
|
-
get isDisconnected(): boolean;
|
|
45
|
-
get isConnecting(): boolean;
|
|
46
|
-
get status(): InternalConnectionStatus;
|
|
47
|
-
private set status(value);
|
|
48
|
-
get connectionState(): WebSocketConnectionState<InternalConnectionStatus>;
|
|
49
|
-
private get hasConnectionAttemptsRemaining();
|
|
50
|
-
private get confirmedOpen();
|
|
51
|
-
/**
|
|
52
|
-
* We are 'confirmedOpen' when we see the first message transmitted
|
|
53
|
-
* from the server. This ensures that even if we have one or more
|
|
54
|
-
* proxies in our route to the endPoint, all connections have been
|
|
55
|
-
* opened successfully.
|
|
56
|
-
* First time in here (on our initial successful connection) we switch
|
|
57
|
-
* from 'connect' phase to 'reconnect' phase. We may have different
|
|
58
|
-
* retry configurations for these two phases.
|
|
59
|
-
*/
|
|
60
|
-
private set confirmedOpen(value);
|
|
61
|
-
get url(): string;
|
|
62
|
-
connect(clientCall?: boolean): Promise<unknown>;
|
|
63
|
-
private reconnect;
|
|
64
|
-
private receive;
|
|
65
|
-
send: (msg: VuuClientMessage) => void;
|
|
66
|
-
close(reason?: WebSocketConnectionCloseReason): void;
|
|
67
|
-
}
|
|
68
|
-
export {};
|
package/types/authenticate.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const authenticate: (username: string, password: string, authUrl?: string) => Promise<string | void>;
|
package/types/constants.d.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
export declare const connectionId: {
|
|
2
|
-
readonly nextValue: number;
|
|
3
|
-
};
|
|
4
|
-
export declare const msgType: {
|
|
5
|
-
connect: string;
|
|
6
|
-
connectionStatus: string;
|
|
7
|
-
getFilterData: string;
|
|
8
|
-
rowData: string;
|
|
9
|
-
rowSet: string;
|
|
10
|
-
select: string;
|
|
11
|
-
selectAll: string;
|
|
12
|
-
selectNone: string;
|
|
13
|
-
selected: string;
|
|
14
|
-
snapshot: string;
|
|
15
|
-
update: string;
|
|
16
|
-
createLink: string;
|
|
17
|
-
disable: string;
|
|
18
|
-
enable: string;
|
|
19
|
-
suspend: string;
|
|
20
|
-
resume: string;
|
|
21
|
-
addSubscription: string;
|
|
22
|
-
closeTreeNode: string;
|
|
23
|
-
columnList: string;
|
|
24
|
-
data: string;
|
|
25
|
-
openTreeNode: string;
|
|
26
|
-
aggregate: string;
|
|
27
|
-
filter: string;
|
|
28
|
-
filterQuery: string;
|
|
29
|
-
filterData: string;
|
|
30
|
-
getSearchData: string;
|
|
31
|
-
groupBy: string;
|
|
32
|
-
modifySubscription: string;
|
|
33
|
-
searchData: string;
|
|
34
|
-
setGroupState: string;
|
|
35
|
-
size: string;
|
|
36
|
-
sort: string;
|
|
37
|
-
subscribed: string;
|
|
38
|
-
tableList: string;
|
|
39
|
-
unsubscribe: string;
|
|
40
|
-
viewRangeChanged: string;
|
|
41
|
-
};
|
package/types/data-source.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { DataSourceCallbackMessage, DataSourceConfig, DataSourceConfigMessage, DataSourceDataSizeMessage } from "@vuu-ui/vuu-data-types";
|
|
2
|
-
export declare const isSizeOnly: (message: DataSourceCallbackMessage) => message is DataSourceDataSizeMessage;
|
|
3
|
-
export declare const toDataSourceConfig: (message: DataSourceConfigMessage) => DataSourceConfig;
|
|
4
|
-
export declare const shouldMessageBeRoutedToDataSource: (message: unknown) => message is DataSourceCallbackMessage;
|
|
5
|
-
export declare const isDataSourceConfigMessage: (message: DataSourceCallbackMessage) => message is DataSourceConfigMessage;
|
package/types/index.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export * from "./authenticate";
|
|
2
|
-
export * from "./ConnectionManager";
|
|
3
|
-
export { default as ConnectionManager } from "./ConnectionManager";
|
|
4
|
-
export * from "./constants";
|
|
5
|
-
export * from "./data-source";
|
|
6
|
-
export * from "./message-utils";
|
|
7
|
-
export * from "./rest-data/RestDataSource";
|
|
8
|
-
export * from "./VuuDataSource";
|
|
9
|
-
export type { WebSocketConnectionState } from "./WebSocketConnection";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const workerSourceCode: "\nvar __defProp = Object.defineProperty;\nvar __typeError = (msg) => {\n throw TypeError(msg);\n};\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nvar __accessCheck = (obj, member, msg) => member.has(obj) || __typeError(\"Cannot \" + msg);\nvar __privateGet = (obj, member, getter) => (__accessCheck(obj, member, \"read from private field\"), getter ? getter.call(obj) : member.get(obj));\nvar __privateAdd = (obj, member, value) => member.has(obj) ? __typeError(\"Cannot add the same private member more than once\") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);\nvar __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, \"write to private field\"), setter ? setter.call(obj, value) : member.set(obj, value), value);\n\n// ../vuu-utils/src/array-utils.ts\nfunction partition(array, test, pass = [], fail = []) {\n for (let i = 0, len = array.length; i < len; i++) {\n (test(array[i], i) ? pass : fail).push(array[i]);\n }\n return [pass, fail];\n}\n\n// ../vuu-utils/src/column-utils.ts\nvar KEY = 6;\nvar metadataKeys = {\n IDX: 0,\n RENDER_IDX: 1,\n IS_LEAF: 2,\n IS_EXPANDED: 3,\n DEPTH: 4,\n COUNT: 5,\n KEY,\n SELECTED: 7,\n count: 8,\n // TODO following only used in datamodel\n PARENT_IDX: \"parent_idx\",\n IDX_POINTER: \"idx_pointer\",\n FILTER_COUNT: \"filter_count\",\n NEXT_FILTER_IDX: \"next_filter_idx\"\n};\nvar { DEPTH, IS_LEAF } = metadataKeys;\n\n// ../vuu-utils/src/cookie-utils.ts\nvar getCookieValue = (name) => {\n var _a, _b;\n if (((_a = globalThis.document) == null ? void 0 : _a.cookie) !== void 0) {\n return (_b = globalThis.document.cookie.split(\"; \").find((row) => row.startsWith(`${name}=`))) == null ? void 0 : _b.split(\"=\")[1];\n }\n};\n\n// ../vuu-utils/src/range-utils.ts\nvar defaultRangeOptions = {\n renderBufferSize: 0,\n rowCount: -1\n};\nvar _baseFrom, _renderBufferSize, _rowCount, _baseTo;\nvar _RangeImpl = class _RangeImpl {\n constructor(from, to, rangeOptions = defaultRangeOptions) {\n __privateAdd(this, _baseFrom);\n __privateAdd(this, _renderBufferSize, 0);\n __privateAdd(this, _rowCount, -1);\n __privateAdd(this, _baseTo);\n // We have to keep these as simple public properties (not getters) so they survive structuredClone\n __publicField(this, \"from\", 0);\n __publicField(this, \"to\", 0);\n var _a, _b;\n __privateSet(this, _baseFrom, from);\n __privateSet(this, _baseTo, to);\n this.renderBufferSize = (_a = rangeOptions.renderBufferSize) != null ? _a : defaultRangeOptions.renderBufferSize;\n this.rowCount = (_b = rangeOptions.rowCount) != null ? _b : defaultRangeOptions.rowCount;\n console.log(\n `[Range] new (${__privateGet(this, _baseFrom)}:${__privateGet(this, _baseTo)}) renderBuffer: ${this.renderBufferSize}, rowCount: ${this.rowCount}`\n );\n }\n get firstRowInViewport() {\n return __privateGet(this, _baseFrom) + 1;\n }\n get lastRowInViewport() {\n if (__privateGet(this, _rowCount) > 0) {\n return Math.min(__privateGet(this, _baseTo), __privateGet(this, _rowCount));\n } else {\n return __privateGet(this, _baseTo);\n }\n }\n get renderBufferSize() {\n return __privateGet(this, _renderBufferSize);\n }\n set renderBufferSize(value) {\n __privateSet(this, _renderBufferSize, value);\n this.from = Math.max(0, __privateGet(this, _baseFrom) - value);\n if (__privateGet(this, _rowCount) > 0) {\n this.to = Math.max(__privateGet(this, _baseTo) + __privateGet(this, _renderBufferSize), __privateGet(this, _rowCount));\n } else {\n this.to = __privateGet(this, _baseTo) + __privateGet(this, _renderBufferSize);\n }\n }\n get rowCount() {\n return __privateGet(this, _rowCount);\n }\n set rowCount(value) {\n __privateSet(this, _rowCount, value);\n if (value > 0) {\n this.to = Math.min(__privateGet(this, _baseTo) + __privateGet(this, _renderBufferSize), value);\n } else {\n this.to = __privateGet(this, _baseTo) + __privateGet(this, _renderBufferSize);\n }\n }\n get reset() {\n return new _RangeImpl(0, __privateGet(this, _baseTo) - __privateGet(this, _baseFrom), {\n rowCount: __privateGet(this, _rowCount),\n renderBufferSize: __privateGet(this, _renderBufferSize)\n });\n }\n equals(range) {\n return range.from === __privateGet(this, _baseFrom) && range.to === __privateGet(this, _baseTo);\n }\n toJson() {\n return {\n from: this.from,\n to: this.to,\n baseFrom: __privateGet(this, _baseFrom),\n baseTo: __privateGet(this, _baseTo),\n renderBufferSize: __privateGet(this, _renderBufferSize),\n rowCount: __privateGet(this, _rowCount)\n };\n }\n};\n_baseFrom = new WeakMap();\n_renderBufferSize = new WeakMap();\n_rowCount = new WeakMap();\n_baseTo = new WeakMap();\nvar RangeImpl = _RangeImpl;\nvar Range = (from, to, rangeOptions) => new RangeImpl(from, to, rangeOptions);\nvar NULL_RANGE = Range(0, 0);\nfunction getFullRange({ from, to }, bufferSize = 0, totalRowCount = Number.MAX_SAFE_INTEGER) {\n if (from === 0 && to === 0) {\n return { from, to };\n } else if (bufferSize === 0) {\n if (totalRowCount < from) {\n return { from: 0, to: 0 };\n } else {\n return { from, to: Math.min(to, totalRowCount) };\n }\n } else if (from === 0) {\n return { from, to: Math.min(to + bufferSize, totalRowCount) };\n } else {\n const shortfallBefore = from - bufferSize < 0;\n const shortfallAfter = totalRowCount - (to + bufferSize) < 0;\n if (shortfallBefore && shortfallAfter) {\n return { from: 0, to: totalRowCount };\n } else if (shortfallBefore) {\n return { from: 0, to: to + bufferSize };\n } else if (shortfallAfter) {\n return {\n from: Math.max(0, from - bufferSize),\n to: totalRowCount\n };\n } else {\n return { from: from - bufferSize, to: to + bufferSize };\n }\n }\n}\nvar withinRange = (value, { from, to }) => value >= from && value < to;\nvar WindowRange = class _WindowRange {\n constructor(from, to) {\n __publicField(this, \"from\");\n __publicField(this, \"to\");\n this.from = from;\n this.to = to;\n }\n isWithin(index) {\n return withinRange(index, this);\n }\n //find the overlap of this range and a new one\n overlap(from, to) {\n return from >= this.to || to < this.from ? [0, 0] : [Math.max(from, this.from), Math.min(to, this.to)];\n }\n copy() {\n return new _WindowRange(this.from, this.to);\n }\n};\n\n// ../vuu-utils/src/event-emitter.ts\nfunction isArrayOfListeners(listeners) {\n return Array.isArray(listeners);\n}\nfunction isOnlyListener(listeners) {\n return !Array.isArray(listeners);\n}\nvar _events;\nvar EventEmitter = class {\n constructor() {\n __privateAdd(this, _events, /* @__PURE__ */ new Map());\n }\n addListener(event, listener) {\n const listeners = __privateGet(this, _events).get(event);\n if (!listeners) {\n __privateGet(this, _events).set(event, listener);\n } else if (isArrayOfListeners(listeners)) {\n listeners.push(listener);\n } else if (isOnlyListener(listeners)) {\n __privateGet(this, _events).set(event, [listeners, listener]);\n }\n }\n removeListener(event, listener) {\n if (!__privateGet(this, _events).has(event)) {\n return;\n }\n const listenerOrListeners = __privateGet(this, _events).get(event);\n let position = -1;\n if (listenerOrListeners === listener) {\n __privateGet(this, _events).delete(event);\n } else if (Array.isArray(listenerOrListeners)) {\n for (let i = listenerOrListeners.length; i-- > 0; ) {\n if (listenerOrListeners[i] === listener) {\n position = i;\n break;\n }\n }\n if (position < 0) {\n return;\n }\n if (listenerOrListeners.length === 1) {\n listenerOrListeners.length = 0;\n __privateGet(this, _events).delete(event);\n } else {\n listenerOrListeners.splice(position, 1);\n }\n }\n }\n removeAllListeners(event) {\n if (event && __privateGet(this, _events).has(event)) {\n __privateGet(this, _events).delete(event);\n } else if (event === void 0) {\n __privateGet(this, _events).clear();\n }\n }\n emit(event, ...args) {\n if (__privateGet(this, _events)) {\n const handler = __privateGet(this, _events).get(event);\n if (handler) {\n this.invokeHandler(handler, args);\n }\n }\n }\n once(event, listener) {\n const handler = (...args) => {\n this.removeListener(event, handler);\n listener(...args);\n };\n this.on(event, handler);\n }\n on(event, listener) {\n this.addListener(event, listener);\n }\n hasListener(event, listener) {\n const listeners = __privateGet(this, _events).get(event);\n if (Array.isArray(listeners)) {\n return listeners.includes(listener);\n } else {\n return listeners === listener;\n }\n }\n invokeHandler(handler, args) {\n if (isArrayOfListeners(handler)) {\n handler.slice().forEach((listener) => this.invokeHandler(listener, args));\n } else {\n switch (args.length) {\n case 0:\n handler();\n break;\n case 1:\n handler(args[0]);\n break;\n case 2:\n handler(args[0], args[1]);\n break;\n // slower\n default:\n handler.call(null, ...args);\n }\n }\n }\n};\n_events = new WeakMap();\n\n// ../vuu-utils/src/datasource/datasource-utils.ts\nvar isConnectionQualityMetrics = (msg) => msg.type === \"connection-metrics\";\nvar isVisualLinkMessage = (msg) => msg.type.endsWith(\"_VISUAL_LINK\");\nvar isViewportMessage = (msg) => \"viewport\" in msg;\n\n// ../vuu-utils/src/logging-utils.ts\nvar logLevels = [\"error\", \"warn\", \"info\", \"debug\"];\nvar isValidLogLevel = (value) => typeof value === \"string\" && logLevels.includes(value);\nvar DEFAULT_LOG_LEVEL = \"error\";\nvar NO_OP = () => void 0;\nvar DEFAULT_DEBUG_LEVEL = false ? \"error\" : \"info\";\nvar { loggingLevel = DEFAULT_DEBUG_LEVEL } = getLoggingSettings();\nvar logger = (category) => {\n const debugEnabled4 = loggingLevel === \"debug\";\n const infoEnabled4 = debugEnabled4 || loggingLevel === \"info\";\n const warnEnabled = infoEnabled4 || loggingLevel === \"warn\";\n const errorEnabled = warnEnabled || loggingLevel === \"error\";\n const info4 = infoEnabled4 ? (message) => console.info(`[${category}] ${message}`) : NO_OP;\n const warn3 = warnEnabled ? (message) => console.warn(`[${category}] ${message}`) : NO_OP;\n const debug4 = debugEnabled4 ? (message) => console.debug(`[${category}] ${message}`) : NO_OP;\n const error3 = errorEnabled ? (message) => console.error(`[${category}] ${message}`) : NO_OP;\n if (false) {\n return {\n errorEnabled,\n error: error3\n };\n } else {\n return {\n debugEnabled: debugEnabled4,\n infoEnabled: infoEnabled4,\n warnEnabled,\n errorEnabled,\n info: info4,\n warn: warn3,\n debug: debug4,\n error: error3\n };\n }\n};\nfunction getLoggingSettings() {\n if (typeof loggingSettings !== \"undefined\") {\n return loggingSettings;\n } else {\n return {\n loggingLevel: getLoggingLevelFromCookie()\n };\n }\n}\nfunction getLoggingLevelFromCookie() {\n const value = getCookieValue(\"vuu-logging-level\");\n if (isValidLogLevel(value)) {\n return value;\n } else {\n return DEFAULT_LOG_LEVEL;\n }\n}\n\n// ../vuu-utils/src/debug-utils.ts\nvar { debug, debugEnabled } = logger(\"range-monitor\");\nvar RangeMonitor = class {\n constructor(source) {\n this.source = source;\n __publicField(this, \"range\", { from: 0, to: 0 });\n __publicField(this, \"timestamp\", 0);\n }\n isSet() {\n return this.timestamp !== 0;\n }\n set({ from, to }) {\n const { timestamp } = this;\n this.range.from = from;\n this.range.to = to;\n this.timestamp = performance.now();\n if (timestamp) {\n debugEnabled && debug(\n `<${this.source}> [${from}-${to}], ${(this.timestamp - timestamp).toFixed(0)} ms elapsed`\n );\n } else {\n return 0;\n }\n }\n};\n\n// ../vuu-utils/src/keyset.ts\nvar EMPTY = [];\nvar KeySet = class {\n constructor(range) {\n __publicField(this, \"keys\", /* @__PURE__ */ new Map());\n __publicField(this, \"nextKeyValue\", 0);\n __publicField(this, \"range\");\n this.range = range;\n this.init(range);\n }\n next(free = EMPTY) {\n if (free.length > 0) {\n return free.shift();\n } else {\n return this.nextKeyValue++;\n }\n }\n init({ from, to }) {\n this.keys.clear();\n this.nextKeyValue = 0;\n for (let rowIndex = from; rowIndex < to; rowIndex++) {\n const nextKeyValue = this.next();\n this.keys.set(rowIndex, nextKeyValue);\n }\n return true;\n }\n reset(range) {\n const { from, to } = range;\n const newSize = to - from;\n const currentSize = this.range.to - this.range.from;\n this.range = range;\n if (currentSize > newSize) {\n return this.init(range);\n }\n const freeKeys = [];\n this.keys.forEach((keyValue, rowIndex) => {\n if (rowIndex < from || rowIndex >= to) {\n freeKeys.push(keyValue);\n this.keys.delete(rowIndex);\n }\n });\n for (let rowIndex = from; rowIndex < to; rowIndex++) {\n if (!this.keys.has(rowIndex)) {\n const nextKeyValue = this.next(freeKeys);\n this.keys.set(rowIndex, nextKeyValue);\n }\n }\n return false;\n }\n keyFor(rowIndex) {\n const key = this.keys.get(rowIndex);\n if (key === void 0) {\n console.log(`key not found\n keys: ${this.toDebugString()}\n `);\n throw Error(`KeySet, no key found for rowIndex ${rowIndex}`);\n }\n return key;\n }\n toDebugString() {\n return `${this.keys.size} keys\n${Array.from(this.keys.entries()).sort(([key1], [key2]) => key1 - key2).map(([k, v]) => `${k}=>${v}`).join(\",\")}]\n`;\n }\n};\n\n// ../vuu-utils/src/selection-utils.ts\nvar { SELECTED } = metadataKeys;\nvar RowSelected = {\n False: 0,\n True: 1,\n First: 2,\n Last: 4\n};\nvar rangeIncludes = (range, index) => index >= range[0] && index <= range[1];\nvar SINGLE_SELECTED_ROW = RowSelected.True + RowSelected.First + RowSelected.Last;\nvar FIRST_SELECTED_ROW_OF_BLOCK = RowSelected.True + RowSelected.First;\nvar LAST_SELECTED_ROW_OF_BLOCK = RowSelected.True + RowSelected.Last;\nvar getSelectionStatus = (selected, itemIndex) => {\n for (const item of selected) {\n if (typeof item === \"number\") {\n if (item === itemIndex) {\n return SINGLE_SELECTED_ROW;\n }\n } else if (rangeIncludes(item, itemIndex)) {\n if (itemIndex === item[0]) {\n return FIRST_SELECTED_ROW_OF_BLOCK;\n } else if (itemIndex === item[1]) {\n return LAST_SELECTED_ROW_OF_BLOCK;\n } else {\n return RowSelected.True;\n }\n }\n }\n return RowSelected.False;\n};\nvar expandSelection = (selected) => {\n if (selected.every((selectedItem) => typeof selectedItem === \"number\")) {\n return selected;\n }\n const expandedSelected = [];\n for (const selectedItem of selected) {\n if (typeof selectedItem === \"number\") {\n expandedSelected.push(selectedItem);\n } else {\n for (let i = selectedItem[0]; i <= selectedItem[1]; i++) {\n expandedSelected.push(i);\n }\n }\n }\n return expandedSelected;\n};\n\n// ../vuu-utils/src/promise-utils.ts\nvar _promise, _resolve, _reject, _resolved;\nvar DeferredPromise = class {\n constructor() {\n __privateAdd(this, _promise);\n __privateAdd(this, _resolve, () => console.log(\"resolve was not set\"));\n __privateAdd(this, _reject, () => console.log(\"reject was not set\"));\n __privateAdd(this, _resolved, false);\n __privateSet(this, _promise, new Promise((resolve, reject) => {\n __privateSet(this, _resolve, resolve);\n __privateSet(this, _reject, reject);\n }));\n }\n get promise() {\n return __privateGet(this, _promise);\n }\n get isResolved() {\n return __privateGet(this, _resolved);\n }\n resolve(value) {\n __privateSet(this, _resolved, true);\n return __privateGet(this, _resolve).call(this, value);\n }\n get reject() {\n return __privateGet(this, _reject);\n }\n};\n_promise = new WeakMap();\n_resolve = new WeakMap();\n_reject = new WeakMap();\n_resolved = new WeakMap();\n\n// ../vuu-utils/src/protocol-message-utils.ts\nvar MENU_RPC_TYPES = [\n \"VIEW_PORT_MENUS_SELECT_RPC\",\n \"VIEW_PORT_MENU_TABLE_RPC\",\n \"VIEW_PORT_MENU_ROW_RPC\",\n \"VIEW_PORT_MENU_CELL_RPC\",\n \"VP_EDIT_CELL_RPC\",\n \"VP_EDIT_ROW_RPC\",\n \"VP_EDIT_ADD_ROW_RPC\",\n \"VP_EDIT_DELETE_CELL_RPC\",\n \"VP_EDIT_DELETE_ROW_RPC\",\n \"VP_EDIT_SUBMIT_FORM_RPC\"\n];\nvar isVuuMenuRpcRequest = (message) => MENU_RPC_TYPES.includes(message[\"type\"]);\nvar isOpenDialogAction = (action) => action !== void 0 && action.type === \"OPEN_DIALOG_ACTION\";\nvar isSessionTable = (table) => {\n if (table !== null && typeof table === \"object\" && \"table\" in table && \"module\" in table) {\n return table.table.startsWith(\"session\");\n }\n return false;\n};\nfunction isActionMessage(rpcResponse) {\n return rpcResponse.type === \"VIEW_PORT_MENU_RESP\" || rpcResponse.type === \"VIEW_PORT_RPC_REPONSE\";\n}\nfunction isSessionTableActionMessage(rpcResponse) {\n var _a;\n return isActionMessage(rpcResponse) && isOpenDialogAction(rpcResponse.action) && isSessionTable(rpcResponse.action.table) && ((_a = rpcResponse.action) == null ? void 0 : _a.renderComponent) === \"inline-form\";\n}\n\n// src/message-utils.ts\nvar isVuuRpcRequest = (message) => message[\"type\"] === \"VIEW_PORT_RPC_CALL\";\nvar stripRequestId = ({\n requestId,\n ...rest\n}) => [requestId, rest];\nvar getFirstAndLastRows = (rows) => {\n let firstRow = rows.at(0);\n if (firstRow.updateType === \"SIZE\") {\n if (rows.length === 1) {\n return rows;\n } else {\n firstRow = rows.at(1);\n }\n }\n const lastRow = rows.at(-1);\n return [firstRow, lastRow];\n};\nvar insertRow = (rows, row) => {\n const lastRow = rows.at(-1);\n if (lastRow === void 0 || row.rowIndex > lastRow.rowIndex) {\n rows.push(row);\n } else {\n for (let i = 0; i < rows.length; i++) {\n if (row.rowIndex < rows[i].rowIndex) {\n rows.splice(i, 0, row);\n return;\n } else if (row.rowIndex === rows[i].rowIndex) {\n if (row.ts < rows[i].ts) {\n } else {\n rows[i] = row;\n }\n return;\n }\n }\n throw Error(\"don't expect to get this far\");\n }\n};\nvar groupRowsByViewport = (rows) => {\n const result = {};\n for (const row of rows) {\n const rowsForViewport = result[row.viewPortId] || (result[row.viewPortId] = []);\n insertRow(rowsForViewport, row);\n }\n return result;\n};\nvar createSchemaFromTableMetadata = ({\n columns,\n dataTypes,\n key,\n table\n}) => {\n return {\n table,\n columns: columns.map((col, idx) => ({\n name: col,\n serverDataType: dataTypes[idx]\n })),\n key\n };\n};\nvar gapBetweenLastRowSentToClient = (lastRowsReturnedToClient, pendingUpdates, clientRange) => {\n const firstPendingUpdate = pendingUpdates.at(0);\n const lastPendingUpdate = pendingUpdates.at(-1);\n if (firstPendingUpdate && lastPendingUpdate) {\n const [firstRowIndex, lastRowIndex] = lastRowsReturnedToClient;\n if (lastRowIndex < firstPendingUpdate.rowIndex - 1 && clientRange.from < firstPendingUpdate.rowIndex) {\n return {\n from: Math.max(lastRowIndex + 1, clientRange.from),\n to: firstPendingUpdate.rowIndex\n };\n } else if (firstRowIndex > lastPendingUpdate.rowIndex + 1 && clientRange.to > lastPendingUpdate.rowIndex) {\n return {\n from: lastPendingUpdate.rowIndex + 1,\n to: Math.min(clientRange.to, firstRowIndex)\n };\n }\n }\n};\n\n// src/server-proxy/messages.ts\nvar CHANGE_VP_SUCCESS = \"CHANGE_VP_SUCCESS\";\nvar CLOSE_TREE_NODE = \"CLOSE_TREE_NODE\";\nvar CLOSE_TREE_SUCCESS = \"CLOSE_TREE_SUCCESS\";\nvar CREATE_VP = \"CREATE_VP\";\nvar DISABLE_VP = \"DISABLE_VP\";\nvar DISABLE_VP_SUCCESS = \"DISABLE_VP_SUCCESS\";\nvar ENABLE_VP = \"ENABLE_VP\";\nvar ENABLE_VP_SUCCESS = \"ENABLE_VP_SUCCESS\";\nvar GET_VP_VISUAL_LINKS = \"GET_VP_VISUAL_LINKS\";\nvar GET_VIEW_PORT_MENUS = \"GET_VIEW_PORT_MENUS\";\nvar HB = \"HB\";\nvar HB_RESP = \"HB_RESP\";\nvar LOGIN = \"LOGIN\";\nvar OPEN_TREE_NODE = \"OPEN_TREE_NODE\";\nvar OPEN_TREE_SUCCESS = \"OPEN_TREE_SUCCESS\";\nvar REMOVE_VP = \"REMOVE_VP\";\nvar SET_SELECTION_SUCCESS = \"SET_SELECTION_SUCCESS\";\n\n// src/server-proxy/rpc-services.ts\nvar getRpcServiceModule = (service) => {\n switch (service) {\n case \"TypeAheadRpcHandler\":\n return \"TYPEAHEAD\";\n default:\n return \"SIMUL\";\n }\n};\n\n// src/server-proxy/array-backed-moving-window.ts\nvar EMPTY_ARRAY = [];\nvar log = logger(\"array-backed-moving-window\");\nfunction dataIsUnchanged(newRow, existingRow) {\n if (!existingRow) {\n return false;\n }\n if (existingRow.data.length !== newRow.data.length) {\n return false;\n }\n if (existingRow.sel !== newRow.sel) {\n return false;\n }\n for (let i = 0; i < existingRow.data.length; i++) {\n if (existingRow.data[i] !== newRow.data[i]) {\n return false;\n }\n }\n return true;\n}\nvar _range;\nvar ArrayBackedMovingWindow = class {\n // Note, the buffer is already accounted for in the range passed in here\n constructor({ from: clientFrom, to: clientTo }, { from, to }, bufferSize) {\n __privateAdd(this, _range);\n __publicField(this, \"bufferSize\");\n __publicField(this, \"internalData\");\n __publicField(this, \"rowsWithinRange\");\n __publicField(this, \"clientRange\");\n __publicField(this, \"rowCount\");\n __publicField(this, \"setRowCount\", (rowCount) => {\n var _a;\n (_a = log.info) == null ? void 0 : _a.call(log, `setRowCount ${rowCount}`);\n if (rowCount < this.internalData.length) {\n this.internalData.length = rowCount;\n }\n if (rowCount < this.rowCount) {\n this.rowsWithinRange = 0;\n const end = Math.min(rowCount, this.clientRange.to);\n for (let i = this.clientRange.from; i < end; i++) {\n const rowIndex = i - __privateGet(this, _range).from;\n if (this.internalData[rowIndex] !== void 0) {\n this.rowsWithinRange += 1;\n }\n }\n }\n this.rowCount = rowCount;\n });\n __publicField(this, \"bufferBreakout\", (from, to) => {\n const bufferPerimeter = this.bufferSize * 0.25;\n if (__privateGet(this, _range).to - to < bufferPerimeter) {\n return true;\n } else if (__privateGet(this, _range).from > 0 && from - __privateGet(this, _range).from < bufferPerimeter) {\n return true;\n } else {\n return false;\n }\n });\n this.bufferSize = bufferSize;\n this.clientRange = new WindowRange(clientFrom, clientTo);\n __privateSet(this, _range, new WindowRange(from, to));\n this.internalData = new Array(bufferSize);\n this.rowsWithinRange = 0;\n this.rowCount = 0;\n }\n get range() {\n return __privateGet(this, _range);\n }\n // TODO we should probably have a hasAllClientRowsWithinRange\n get hasAllRowsWithinRange() {\n return this.rowsWithinRange === this.clientRange.to - this.clientRange.from || // this.rowsWithinRange === this.range.to - this.range.from ||\n this.rowCount > 0 && this.clientRange.from + this.rowsWithinRange === this.rowCount;\n }\n // Check to see if set of rows is outside the current viewport range, indicating\n // that veiwport is being scrolled quickly and server is not able to keep up.\n outOfRange(firstIndex, lastIndex) {\n const { from, to } = this.range;\n if (lastIndex < from) {\n return true;\n }\n if (firstIndex >= to) {\n return true;\n }\n }\n setAtIndex(row) {\n const { rowIndex: index } = row;\n const internalIndex = index - __privateGet(this, _range).from;\n if (dataIsUnchanged(row, this.internalData[internalIndex])) {\n return false;\n }\n const isWithinClientRange = this.isWithinClientRange(index);\n if (isWithinClientRange || this.isWithinRange(index)) {\n if (!this.internalData[internalIndex] && isWithinClientRange) {\n this.rowsWithinRange += 1;\n }\n this.internalData[internalIndex] = row;\n }\n return isWithinClientRange;\n }\n getAtIndex(index) {\n return __privateGet(this, _range).isWithin(index) && this.internalData[index - __privateGet(this, _range).from] != null ? this.internalData[index - __privateGet(this, _range).from] : void 0;\n }\n isWithinRange(index) {\n return __privateGet(this, _range).isWithin(index);\n }\n isWithinClientRange(index) {\n return this.clientRange.isWithin(index);\n }\n // Returns [false] or [serverDataRequired, clientRows, holdingRows]\n setClientRange(from, to) {\n var _a;\n (_a = log.debug) == null ? void 0 : _a.call(log, `setClientRange ${from} - ${to}`);\n const currentFrom = this.clientRange.from;\n const currentTo = Math.min(this.clientRange.to, this.rowCount);\n if (from === currentFrom && to === currentTo) {\n return [\n false,\n EMPTY_ARRAY\n /*, EMPTY_ARRAY*/\n ];\n }\n const originalRange = this.clientRange.copy();\n this.clientRange.from = from;\n this.clientRange.to = to;\n this.rowsWithinRange = 0;\n for (let i = from; i < to; i++) {\n const internalIndex = i - __privateGet(this, _range).from;\n if (this.internalData[internalIndex]) {\n this.rowsWithinRange += 1;\n }\n }\n let clientRows = EMPTY_ARRAY;\n const offset = __privateGet(this, _range).from;\n if (this.hasAllRowsWithinRange) {\n if (to > originalRange.to) {\n const start = Math.max(from, originalRange.to);\n clientRows = this.internalData.slice(start - offset, to - offset);\n } else {\n const end = Math.min(originalRange.from, to);\n clientRows = this.internalData.slice(from - offset, end - offset);\n }\n }\n const serverDataRequired = this.bufferBreakout(from, to);\n return [serverDataRequired, clientRows];\n }\n setRange(from, to) {\n var _a, _b;\n if (from !== __privateGet(this, _range).from || to !== __privateGet(this, _range).to) {\n (_a = log.debug) == null ? void 0 : _a.call(log, `setRange ${from} - ${to}`);\n const [overlapFrom, overlapTo] = __privateGet(this, _range).overlap(from, to);\n const newData = new Array(to - from);\n this.rowsWithinRange = 0;\n for (let i = overlapFrom; i < overlapTo; i++) {\n const row = this.getAtIndex(i);\n if (row) {\n const index = i - from;\n newData[index] = row;\n if (this.isWithinClientRange(i)) {\n this.rowsWithinRange += 1;\n }\n }\n }\n this.internalData = newData;\n __privateGet(this, _range).from = from;\n __privateGet(this, _range).to = to;\n } else {\n (_b = log.debug) == null ? void 0 : _b.call(log, `setRange ${from} - ${to} IGNORED because not changed`);\n }\n }\n //TODO temp\n get data() {\n return this.internalData;\n }\n getData() {\n var _a;\n const { from, to } = __privateGet(this, _range);\n const { from: clientFrom, to: clientTo } = this.clientRange;\n const startOffset = Math.max(0, clientFrom - from);\n const endOffset = Math.min(\n to - from,\n to,\n clientTo - from,\n (_a = this.rowCount) != null ? _a : to\n );\n return this.internalData.slice(startOffset, endOffset);\n }\n clear() {\n var _a;\n (_a = log.debug) == null ? void 0 : _a.call(log, \"clear\");\n this.internalData.length = 0;\n this.rowsWithinRange = 0;\n this.setRowCount(0);\n }\n // used only for debugging\n getCurrentDataRange() {\n const rows = this.internalData;\n const len = rows.length;\n let [firstRow] = this.internalData;\n let lastRow = this.internalData[len - 1];\n if (firstRow && lastRow) {\n return [firstRow.rowIndex, lastRow.rowIndex];\n } else {\n for (let i = 0; i < len; i++) {\n if (rows[i] !== void 0) {\n firstRow = rows[i];\n break;\n }\n }\n for (let i = len - 1; i >= 0; i--) {\n if (rows[i] !== void 0) {\n lastRow = rows[i];\n break;\n }\n }\n if (firstRow && lastRow) {\n return [firstRow.rowIndex, lastRow.rowIndex];\n } else {\n return [-1, -1];\n }\n }\n }\n};\n_range = new WeakMap();\n\n// src/server-proxy/viewport.ts\nvar { debug: debug2, debugEnabled: debugEnabled2, error, info, infoEnabled, warn } = logger(\"Viewport\");\nvar isLeafUpdate = ({ rowKey, updateType }) => updateType === \"U\" && !rowKey.startsWith(\"$root\");\nvar NO_DATA_UPDATE = [\n void 0,\n void 0\n];\nvar NO_UPDATE_STATUS = {\n count: 0,\n mode: void 0,\n size: 0,\n ts: 0\n};\nvar _status, _clientRange;\nvar Viewport = class {\n constructor({\n aggregations,\n bufferSize = 50,\n columns,\n filterSpec: filter,\n groupBy = [],\n table,\n range,\n sort,\n title,\n viewport,\n visualLink\n }, postMessageToClient) {\n __privateAdd(this, _status, \"\");\n __publicField(this, \"aggregations\");\n __publicField(this, \"batchMode\", false);\n __publicField(this, \"bufferSize\");\n /**\n * clientRange is always the range requested by the client. We should assume\n * these are the rows visible to the user\n * TODO what is clientRange needed for ?\n */\n __privateAdd(this, _clientRange);\n __publicField(this, \"columns\");\n __publicField(this, \"dataWindow\");\n __publicField(this, \"filter\");\n __publicField(this, \"groupBy\");\n __publicField(this, \"sort\");\n __publicField(this, \"hasUpdates\", false);\n __publicField(this, \"pendingUpdates\", []);\n __publicField(this, \"keys\");\n __publicField(this, \"pendingLinkedParent\");\n __publicField(this, \"pendingOperations\", /* @__PURE__ */ new Map());\n __publicField(this, \"pendingRangeRequests\", []);\n __publicField(this, \"postMessageToClient\");\n __publicField(this, \"rowCountChanged\", false);\n __publicField(this, \"selectedRows\", []);\n __publicField(this, \"lastUpdateStatus\", NO_UPDATE_STATUS);\n __publicField(this, \"updateThrottleTimer\");\n __publicField(this, \"lastRowsReturnedToClient\", [-1, -1]);\n __publicField(this, \"rangeMonitor\", new RangeMonitor(\"ViewPort\"));\n __publicField(this, \"clientViewportId\");\n __publicField(this, \"disabled\", false);\n __publicField(this, \"isTree\", false);\n __publicField(this, \"links\");\n __publicField(this, \"linkedParent\");\n __publicField(this, \"serverViewportId\");\n // TODO roll disabled/suspended into status\n __publicField(this, \"suspended\", false);\n __publicField(this, \"suspendTimer\", null);\n __publicField(this, \"table\");\n __publicField(this, \"title\");\n // Records SIZE only updates\n __publicField(this, \"setLastSizeOnlyUpdateSize\", (size) => {\n this.lastUpdateStatus.size = size;\n });\n __publicField(this, \"setLastUpdate\", (mode) => {\n const { ts: lastTS, mode: lastMode } = this.lastUpdateStatus;\n let elapsedTime = 0;\n if (lastMode === mode) {\n const ts = Date.now();\n this.lastUpdateStatus.count += 1;\n this.lastUpdateStatus.ts = ts;\n elapsedTime = lastTS === 0 ? 0 : ts - lastTS;\n } else {\n this.lastUpdateStatus.count = 1;\n this.lastUpdateStatus.ts = 0;\n elapsedTime = 0;\n }\n this.lastUpdateStatus.mode = mode;\n return elapsedTime;\n });\n __publicField(this, \"rangeRequestAlreadyPending\", (range) => {\n const { bufferSize } = this;\n const bufferThreshold = bufferSize * 0.25;\n let { from: stillPendingFrom } = range;\n for (const { from, to } of this.pendingRangeRequests) {\n if (stillPendingFrom >= from && stillPendingFrom < to) {\n if (range.to + bufferThreshold <= to) {\n return true;\n } else {\n stillPendingFrom = to;\n }\n }\n }\n return false;\n });\n __publicField(this, \"sendThrottledSizeMessage\", () => {\n this.updateThrottleTimer = void 0;\n this.lastUpdateStatus.count = 3;\n this.postMessageToClient({\n clientViewportId: this.clientViewportId,\n mode: \"size-only\",\n size: this.lastUpdateStatus.size,\n type: \"viewport-update\"\n });\n });\n // If we are receiving multiple SIZE updates but no data, table is loading rows\n // outside of our viewport. We can safely throttle these requests. Doing so will\n // alleviate pressure on UI DataTable.\n __publicField(this, \"shouldThrottleMessage\", (mode) => {\n const elapsedTime = this.setLastUpdate(mode);\n return mode === \"size-only\" && elapsedTime > 0 && elapsedTime < 500 && this.lastUpdateStatus.count > 3;\n });\n __publicField(this, \"throttleMessage\", (mode) => {\n if (this.shouldThrottleMessage(mode)) {\n info == null ? void 0 : info(\"throttling updates setTimeout to 2000\");\n if (this.updateThrottleTimer === void 0) {\n this.updateThrottleTimer = setTimeout(\n this.sendThrottledSizeMessage,\n 2e3\n );\n }\n return true;\n } else if (this.updateThrottleTimer !== void 0) {\n clearTimeout(this.updateThrottleTimer);\n this.updateThrottleTimer = void 0;\n }\n return false;\n });\n __publicField(this, \"getNewRowCount\", () => {\n if (this.rowCountChanged && this.dataWindow) {\n this.rowCountChanged = false;\n return this.dataWindow.rowCount;\n }\n });\n this.aggregations = aggregations;\n this.bufferSize = bufferSize;\n __privateSet(this, _clientRange, range);\n this.clientViewportId = viewport;\n this.columns = columns;\n this.filter = filter;\n this.groupBy = groupBy;\n this.keys = new KeySet(range);\n this.pendingLinkedParent = visualLink;\n this.table = table;\n this.sort = sort;\n this.title = title;\n infoEnabled && (info == null ? void 0 : info(\n `constructor #${viewport} ${table.table} bufferSize=${bufferSize}`\n ));\n this.dataWindow = new ArrayBackedMovingWindow(\n __privateGet(this, _clientRange),\n range,\n this.bufferSize\n );\n this.postMessageToClient = postMessageToClient;\n }\n get hasUpdatesToProcess() {\n if (this.suspended) {\n return false;\n }\n return this.rowCountChanged || this.hasUpdates;\n }\n get size() {\n var _a;\n return (_a = this.dataWindow.rowCount) != null ? _a : 0;\n }\n get clientRange() {\n return __privateGet(this, _clientRange);\n }\n get status() {\n return __privateGet(this, _status);\n }\n set status(status) {\n __privateSet(this, _status, status);\n }\n subscribe() {\n const { filter } = this.filter;\n this.status = __privateGet(this, _status) === \"subscribed\" ? \"resubscribing\" : \"subscribing\";\n return {\n type: CREATE_VP,\n table: this.table,\n range: getFullRange(__privateGet(this, _clientRange), this.bufferSize),\n aggregations: this.aggregations,\n columns: this.columns,\n sort: this.sort,\n groupBy: this.groupBy,\n filterSpec: { filter }\n };\n }\n handleSubscribed({\n viewPortId,\n aggregations,\n columns,\n filterSpec: filter,\n range,\n sort,\n groupBy,\n table\n }, baseTableSchema) {\n this.serverViewportId = viewPortId;\n this.status = \"subscribed\";\n this.aggregations = aggregations;\n this.columns = columns;\n this.groupBy = groupBy;\n this.isTree = groupBy && groupBy.length > 0;\n this.dataWindow.setRange(range.from, range.to);\n const tableSchema = table === baseTableSchema.table.table ? baseTableSchema : {\n ...baseTableSchema,\n table: {\n ...baseTableSchema.table,\n session: table\n }\n };\n return {\n aggregations,\n type: \"subscribed\",\n clientViewportId: this.clientViewportId,\n columns,\n filterSpec: filter,\n groupBy,\n range,\n sort,\n tableSchema\n };\n }\n awaitOperation(requestId, msg) {\n this.pendingOperations.set(requestId, msg);\n }\n // Return a message if we need to communicate this to client UI\n completeOperation(requestId, ...params) {\n var _a;\n const { clientViewportId, pendingOperations } = this;\n const pendingOperation = pendingOperations.get(requestId);\n if (!pendingOperation) {\n error(\n `no matching operation found to complete for requestId ${requestId}`\n );\n return;\n }\n const { type } = pendingOperation;\n info == null ? void 0 : info(`completeOperation ${type}`);\n pendingOperations.delete(requestId);\n if (type === \"CHANGE_VP_RANGE\") {\n const [from, to] = params;\n infoEnabled && info(\n `completeOperation CHANGE_VP_RANGE\n window setRange (${from}:${to}) ${this.pendingRangeRequests.length} range requests pending`\n );\n (_a = this.dataWindow) == null ? void 0 : _a.setRange(from, to);\n for (let i = this.pendingRangeRequests.length - 1; i >= 0; i--) {\n const pendingRangeRequest = this.pendingRangeRequests[i];\n if (pendingRangeRequest.requestId === requestId) {\n pendingRangeRequest.acked = true;\n break;\n } else {\n warn == null ? void 0 : warn(\"range requests sent faster than they are being ACKed\");\n }\n }\n } else if (type === \"config\") {\n const {\n aggregations,\n columns,\n filterSpec: filter,\n groupBy,\n sort\n } = pendingOperation.data;\n this.aggregations = aggregations;\n this.columns = columns;\n this.filter = filter;\n this.groupBy = groupBy;\n this.sort = sort;\n if (groupBy.length > 0) {\n this.isTree = true;\n } else if (this.isTree) {\n this.isTree = false;\n }\n debug2 == null ? void 0 : debug2(`config change confirmed, isTree : ${this.isTree}`);\n return {\n clientViewportId,\n type,\n config: pendingOperation.data\n };\n } else if (type === \"selection\") {\n } else if (type === \"disable\") {\n this.disabled = true;\n return {\n type: \"disabled\",\n clientViewportId\n };\n } else if (type === \"enable\") {\n this.disabled = false;\n return {\n type: \"enabled\",\n clientViewportId\n };\n } else if (type === \"CREATE_VISUAL_LINK\") {\n const [colName, parentViewportId, parentColName] = params;\n this.linkedParent = {\n colName,\n parentViewportId,\n parentColName\n };\n this.pendingLinkedParent = void 0;\n return {\n requestId,\n type: \"vuu-link-created\",\n clientViewportId,\n colName,\n parentViewportId,\n parentColName\n };\n } else if (type === \"REMOVE_VISUAL_LINK\") {\n this.linkedParent = void 0;\n return {\n requestId,\n type: \"vuu-link-removed\",\n clientViewportId\n };\n }\n }\n // TODO when a range request arrives, consider the viewport to be scrolling\n // until data arrives and we have the full range.\n // When not scrolling, any server data is an update\n // When scrolling, we are in batch mode\n rangeRequest(requestId, range) {\n var _a, _b;\n if (debugEnabled2) {\n this.rangeMonitor.set(range);\n }\n infoEnabled && info(\n `(bufferSize ${this.bufferSize}) rangeRequest (${range.from}:${range.to}) \n current: window client (${this.dataWindow.clientRange.from}:${this.dataWindow.clientRange.to}), full (${this.dataWindow.range.from}:${this.dataWindow.range.to}) `\n );\n const type = \"CHANGE_VP_RANGE\";\n if (this.dataWindow) {\n const [serverDataRequired, clientRows] = this.dataWindow.setClientRange(\n range.from,\n range.to\n );\n infoEnabled && info(\n `updated: window client (${this.dataWindow.clientRange.from}:${this.dataWindow.clientRange.to}), full (${this.dataWindow.range.from}:${this.dataWindow.range.to})\n serverDataRequired ${serverDataRequired ? \"Y\" : \"N\"}\n ${clientRows.length} rows returned from local buffer`\n );\n let debounceRequest;\n const maxRange = this.dataWindow.rowCount || void 0;\n const serverRequest = serverDataRequired && !this.rangeRequestAlreadyPending(range) ? {\n type,\n viewPortId: this.serverViewportId,\n ...getFullRange(range, this.bufferSize, maxRange)\n } : null;\n if (serverRequest) {\n infoEnabled && info(\n `create CHANGE_VP_RANGE: (${serverRequest.from} - ${serverRequest.to})`\n );\n debugEnabled2 && (debug2 == null ? void 0 : debug2(\n `create CHANGE_VP_RANGE: [${serverRequest.from} - ${serverRequest.to}]`\n ));\n this.awaitOperation(requestId, { type });\n const pendingRequest = this.pendingRangeRequests.at(-1);\n if (pendingRequest) {\n if (pendingRequest.acked) {\n console.warn(\"Range Request before previous request is filled\");\n } else {\n const { from, to } = pendingRequest;\n if (this.dataWindow.outOfRange(from, to)) {\n debounceRequest = {\n clientViewportId: this.clientViewportId,\n type: \"debounce-begin\"\n };\n } else {\n warn == null ? void 0 : warn(\"Range Request before previous request is acked\");\n }\n }\n }\n this.pendingRangeRequests.push({ ...serverRequest, requestId });\n } else if (clientRows.length > 0) {\n this.batchMode = false;\n }\n this.keys.reset(this.dataWindow.clientRange);\n const toClient = this.isTree ? toClientRowTree : toClientRow;\n if (clientRows.length) {\n this.lastRowsReturnedToClient[0] = clientRows[0].rowIndex;\n this.lastRowsReturnedToClient[1] = (_b = (_a = clientRows.at(-1)) == null ? void 0 : _a.rowIndex) != null ? _b : -1;\n return [\n serverRequest,\n clientRows.map((row) => {\n return toClient(row, this.keys, this.selectedRows);\n })\n ];\n } else if (debounceRequest) {\n return [serverRequest, void 0, debounceRequest];\n } else {\n return [serverRequest];\n }\n } else {\n return [null];\n }\n }\n setLinks(links) {\n this.links = links.filter(\n (link) => link.parentVpId !== this.serverViewportId\n );\n return [\n {\n type: \"vuu-links\",\n links: this.links,\n clientViewportId: this.clientViewportId\n },\n this.pendingLinkedParent\n ];\n }\n setMenu(menu) {\n return {\n type: \"vuu-menu\",\n menu,\n clientViewportId: this.clientViewportId\n };\n }\n openTreeNode(requestId, message) {\n const treeKey = message.index === void 0 ? message.key : this.getKeyForRowAtIndex(message.index);\n infoEnabled && info(`treeKey ${treeKey}`);\n return {\n type: OPEN_TREE_NODE,\n vpId: this.serverViewportId,\n treeKey\n };\n }\n closeTreeNode(requestId, message) {\n const treeKey = message.index === void 0 ? message.key : this.getKeyForRowAtIndex(message.index);\n return {\n type: CLOSE_TREE_NODE,\n vpId: this.serverViewportId,\n treeKey\n };\n }\n createLink(requestId, vuuCreateVisualLink) {\n const message = {\n ...vuuCreateVisualLink,\n childVpId: this.serverViewportId\n };\n this.awaitOperation(requestId, message);\n return message;\n }\n removeLink(requestId) {\n const message = {\n type: \"REMOVE_VISUAL_LINK\",\n childVpId: this.serverViewportId\n };\n this.awaitOperation(requestId, message);\n return message;\n }\n suspend() {\n this.suspended = true;\n info == null ? void 0 : info(\"suspend\");\n }\n resume() {\n this.suspended = false;\n if (debugEnabled2) {\n debug2 == null ? void 0 : debug2(`resume: ${this.currentData()}`);\n }\n return [this.size, this.currentData()];\n }\n currentData() {\n const out = [];\n if (this.dataWindow) {\n const records = this.dataWindow.getData();\n const { keys } = this;\n const toClient = this.isTree ? toClientRowTree : toClientRow;\n for (const row of records) {\n if (row) {\n out.push(toClient(row, keys, this.selectedRows));\n }\n }\n }\n return out;\n }\n enable(requestId) {\n this.awaitOperation(requestId, { type: \"enable\" });\n info == null ? void 0 : info(`enable: ${this.serverViewportId}`);\n return {\n type: ENABLE_VP,\n viewPortId: this.serverViewportId\n };\n }\n disable(requestId) {\n this.awaitOperation(requestId, { type: \"disable\" });\n info == null ? void 0 : info(`disable: ${this.serverViewportId}`);\n this.suspended = false;\n return {\n type: DISABLE_VP,\n viewPortId: this.serverViewportId\n };\n }\n setConfig(requestId, config) {\n var _a;\n this.awaitOperation(requestId, { type: \"config\", data: config });\n const { filterSpec: filter, ...remainingConfig } = config;\n debugEnabled2 ? debug2 == null ? void 0 : debug2(`setConfig ${JSON.stringify(config)}`) : info == null ? void 0 : info(`setConfig`);\n if (!this.isTree && config.groupBy.length > 0) {\n (_a = this.dataWindow) == null ? void 0 : _a.clear();\n this.lastRowsReturnedToClient[0] = -1;\n this.lastRowsReturnedToClient[1] = -1;\n }\n return this.createRequest(\n {\n ...remainingConfig,\n filterSpec: typeof (filter == null ? void 0 : filter.filter) === \"string\" ? {\n filter: filter.filter\n } : {\n filter: \"\"\n }\n },\n true\n );\n }\n selectRequest(requestId, selected) {\n this.selectedRows = selected;\n this.awaitOperation(requestId, { type: \"selection\", data: selected });\n info == null ? void 0 : info(`selectRequest: ${selected}`);\n return {\n type: \"SET_SELECTION\",\n vpId: this.serverViewportId,\n selection: expandSelection(selected)\n };\n }\n removePendingRangeRequest(firstIndex, lastIndex) {\n for (let i = this.pendingRangeRequests.length - 1; i >= 0; i--) {\n const { from, to } = this.pendingRangeRequests[i];\n let isLast = true;\n if (firstIndex >= from && firstIndex < to || lastIndex > from && lastIndex < to) {\n if (!isLast) {\n console.warn(\n \"removePendingRangeRequest TABLE_ROWS are not for latest request\"\n );\n }\n this.pendingRangeRequests.splice(i, 1);\n break;\n } else {\n isLast = false;\n }\n }\n }\n updateRows(rows) {\n var _a, _b, _c;\n const [firstRow, lastRow] = getFirstAndLastRows(rows);\n if (firstRow && lastRow) {\n this.removePendingRangeRequest(firstRow.rowIndex, lastRow.rowIndex);\n }\n if (rows.length === 1) {\n if (firstRow.vpSize === 0 && this.disabled) {\n debug2 == null ? void 0 : debug2(\n `ignore a SIZE=0 message on disabled viewport (${rows.length} rows)`\n );\n return;\n } else if (firstRow.updateType === \"SIZE\") {\n this.setLastSizeOnlyUpdateSize(firstRow.vpSize);\n }\n }\n for (const row of rows) {\n if (this.isTree && isLeafUpdate(row)) {\n continue;\n } else {\n if (row.updateType === \"SIZE\" || ((_a = this.dataWindow) == null ? void 0 : _a.rowCount) !== row.vpSize) {\n (_b = this.dataWindow) == null ? void 0 : _b.setRowCount(row.vpSize);\n this.rowCountChanged = true;\n }\n if (row.updateType === \"U\") {\n if ((_c = this.dataWindow) == null ? void 0 : _c.setAtIndex(row)) {\n this.hasUpdates = true;\n if (!this.batchMode) {\n this.pendingUpdates.push(row);\n }\n }\n }\n }\n }\n }\n getKeyForRowAtIndex(rowIndex) {\n const row = this.dataWindow.getAtIndex(rowIndex);\n return row == null ? void 0 : row.rowKey;\n }\n // This is called only after new data has been received from server - data\n // returned direcly from buffer does not use this.\n getClientRows() {\n var _a, _b, _c, _d;\n let out = void 0;\n let mode = \"size-only\";\n if (!this.hasUpdates && !this.rowCountChanged) {\n return NO_DATA_UPDATE;\n }\n if (this.hasUpdates) {\n const { keys, selectedRows } = this;\n const toClient = this.isTree ? toClientRowTree : toClientRow;\n if (this.updateThrottleTimer) {\n self.clearTimeout(this.updateThrottleTimer);\n this.updateThrottleTimer = void 0;\n }\n if (this.pendingUpdates.length > 0 && this.dataWindow.hasAllRowsWithinRange) {\n out = [];\n mode = \"update\";\n const missingRows = gapBetweenLastRowSentToClient(\n this.lastRowsReturnedToClient,\n this.pendingUpdates,\n this.dataWindow.clientRange\n );\n if (missingRows) {\n for (let i = missingRows.from; i < missingRows.to; i++) {\n const row = this.dataWindow.getAtIndex(i);\n if (row) {\n out.push(toClient(row, keys, selectedRows));\n } else {\n throw Error(\"[Viewport] missing row not in data cache\");\n }\n }\n for (const row of this.pendingUpdates) {\n out.push(toClient(row, keys, selectedRows));\n }\n out.sort(\n ([idx1], [idx2]) => idx1 - idx2\n );\n } else {\n for (const row of this.pendingUpdates) {\n out.push(toClient(row, keys, selectedRows));\n }\n }\n this.lastRowsReturnedToClient[0] = (_b = (_a = out.at(0)) == null ? void 0 : _a[0]) != null ? _b : -1;\n this.lastRowsReturnedToClient[1] = (_d = (_c = out.at(-1)) == null ? void 0 : _c[0]) != null ? _d : -1;\n }\n this.pendingUpdates.length = 0;\n this.hasUpdates = false;\n }\n if (this.throttleMessage(mode)) {\n return NO_DATA_UPDATE;\n } else {\n return [out, mode];\n }\n }\n createRequest(params, overWrite = false) {\n if (overWrite) {\n return {\n type: \"CHANGE_VP\",\n viewPortId: this.serverViewportId,\n ...params\n };\n } else {\n return {\n type: \"CHANGE_VP\",\n viewPortId: this.serverViewportId,\n aggregations: this.aggregations,\n columns: this.columns,\n sort: this.sort,\n groupBy: this.groupBy,\n filterSpec: {\n filter: this.filter.filter\n },\n ...params\n };\n }\n }\n};\n_status = new WeakMap();\n_clientRange = new WeakMap();\nvar toClientRow = ({ rowIndex, rowKey, sel: isSelected, data }, keys, selectedRows) => {\n return [\n rowIndex,\n keys.keyFor(rowIndex),\n true,\n false,\n 0,\n 0,\n rowKey,\n isSelected ? getSelectionStatus(selectedRows, rowIndex) : 0\n ].concat(data);\n};\nvar toClientRowTree = ({ rowIndex, rowKey, sel: isSelected, data }, keys, selectedRows) => {\n const [depth, isExpanded, , isLeaf, , count, ...rest] = data;\n return [\n rowIndex,\n keys.keyFor(rowIndex),\n isLeaf,\n isExpanded,\n depth,\n count,\n rowKey,\n isSelected ? getSelectionStatus(selectedRows, rowIndex) : 0\n ].concat(rest);\n};\n\n// src/server-proxy/server-proxy.ts\nvar _requestId = 1;\nvar { debug: debug3, debugEnabled: debugEnabled3, error: error2, info: info2, infoEnabled: infoEnabled2, warn: warn2 } = logger(\"ServerProxy\");\nvar nextRequestId = () => `${_requestId++}`;\nvar DEFAULT_OPTIONS = {};\nvar isActiveViewport = (viewPort) => viewPort.disabled !== true && viewPort.suspended !== true;\nvar addTitleToLinks = (links, serverViewportId, label) => links.map(\n (link) => link.parentVpId === serverViewportId ? { ...link, label } : link\n);\nfunction addLabelsToLinks(links, viewports) {\n return links.map((linkDescriptor) => {\n const { parentVpId } = linkDescriptor;\n const viewport = viewports.get(parentVpId);\n if (viewport) {\n return {\n ...linkDescriptor,\n parentClientVpId: viewport.clientViewportId,\n label: viewport.title\n };\n } else {\n throw Error(\"addLabelsToLinks viewport not found\");\n }\n });\n}\nvar ServerProxy = class {\n constructor(connection, callback) {\n __publicField(this, \"connection\");\n __publicField(this, \"postMessageToClient\");\n __publicField(this, \"viewports\");\n __publicField(this, \"mapClientToServerViewport\");\n __publicField(this, \"authToken\", \"\");\n __publicField(this, \"user\", \"user\");\n __publicField(this, \"pendingLogin\");\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n __publicField(this, \"pendingRequests\", /* @__PURE__ */ new Map());\n __publicField(this, \"sessionId\");\n __publicField(this, \"queuedRequests\", []);\n __publicField(this, \"cachedTableMetaRequests\", /* @__PURE__ */ new Map());\n __publicField(this, \"cachedTableSchemas\", /* @__PURE__ */ new Map());\n __publicField(this, \"tableList\");\n __publicField(this, \"reconnect\", async () => {\n await this.login(this.authToken);\n const [activeViewports, inactiveViewports] = partition(\n Array.from(this.viewports.values()),\n isActiveViewport\n );\n this.viewports.clear();\n this.mapClientToServerViewport.clear();\n const reconnectViewports = (viewports) => {\n viewports.forEach((viewport) => {\n const { clientViewportId } = viewport;\n this.awaitResponseToMessage(\n viewport.subscribe(),\n clientViewportId\n ).then((msg) => {\n if (msg.type === \"CREATE_VP_SUCCESS\") {\n this.mapClientToServerViewport.set(\n clientViewportId,\n msg.viewPortId\n );\n this.viewports.set(msg.viewPortId, viewport);\n viewport.status = \"subscribed\";\n viewport.serverViewportId = msg.viewPortId;\n }\n });\n });\n };\n reconnectViewports(activeViewports);\n setTimeout(() => {\n reconnectViewports(inactiveViewports);\n }, 2e3);\n });\n this.connection = connection;\n this.postMessageToClient = callback;\n this.viewports = /* @__PURE__ */ new Map();\n this.mapClientToServerViewport = /* @__PURE__ */ new Map();\n connection.on(\"reconnected\", this.reconnect);\n }\n async login(authToken, user = \"user\") {\n if (authToken) {\n this.authToken = authToken;\n this.user = user;\n return new Promise((resolve, reject) => {\n this.sendMessageToServer(\n { type: LOGIN, token: this.authToken, user },\n \"\"\n );\n this.pendingLogin = { resolve, reject };\n });\n } else if (this.authToken === \"\") {\n error2(\"login, cannot login until auth token has been obtained\");\n }\n }\n disconnect() {\n this.viewports.forEach((viewport) => {\n const { clientViewportId } = viewport;\n this.unsubscribe(clientViewportId);\n this.postMessageToClient({\n clientViewportId,\n type: \"viewport-clear\"\n });\n });\n }\n subscribe(message) {\n if (!this.mapClientToServerViewport.has(message.viewport)) {\n const pendingTableSchema = this.getTableMeta(message.table);\n const viewport = new Viewport(message, this.postMessageToClient);\n this.viewports.set(message.viewport, viewport);\n const pendingSubscription = this.awaitResponseToMessage(\n viewport.subscribe(),\n message.viewport\n );\n const pendingResponses = [pendingSubscription, pendingTableSchema];\n const awaitPendingReponses = Promise.all(pendingResponses);\n awaitPendingReponses.then(([subscribeResponse, tableSchema]) => {\n const { viewPortId: serverViewportId } = subscribeResponse;\n const { status: previousViewportStatus } = viewport;\n if (message.viewport !== serverViewportId) {\n this.viewports.delete(message.viewport);\n this.viewports.set(serverViewportId, viewport);\n }\n this.mapClientToServerViewport.set(message.viewport, serverViewportId);\n const clientResponse = viewport.handleSubscribed(\n subscribeResponse,\n tableSchema\n );\n if (clientResponse) {\n this.postMessageToClient(clientResponse);\n if (debugEnabled3) {\n debug3(\n `post DataSourceSubscribedMessage to client: ${JSON.stringify(\n clientResponse\n )}`\n );\n }\n }\n if (message.selectedIndexValues) {\n infoEnabled2 && info2(`selected = ${JSON.stringify(message.selectedIndexValues)}`);\n this.select(viewport, { selected: message.selectedIndexValues });\n }\n if (viewport.disabled) {\n this.disableViewport(viewport);\n }\n if (this.queuedRequests.length > 0) {\n this.processQueuedRequests();\n }\n if (previousViewportStatus === \"subscribing\" && // A session table will never have Visual Links, nor Context Menus\n !isSessionTable(viewport.table)) {\n this.sendMessageToServer({\n type: GET_VP_VISUAL_LINKS,\n vpId: serverViewportId\n });\n this.sendMessageToServer({\n type: GET_VIEW_PORT_MENUS,\n vpId: serverViewportId\n });\n Array.from(this.viewports.entries()).filter(\n ([id, { disabled, status }]) => id !== serverViewportId && !disabled && status === \"subscribed\"\n ).forEach(([vpId]) => {\n this.sendMessageToServer({\n type: GET_VP_VISUAL_LINKS,\n vpId\n });\n });\n }\n });\n } else {\n error2(`spurious subscribe call ${message.viewport}`);\n }\n }\n /**\n * Currently we only queue range requests, this may change\n */\n addRequestToQueue(queuedRequest) {\n const isDifferentTypeViewport = (qr) => qr.clientViewportId !== queuedRequest.clientViewportId || queuedRequest.message.type !== qr.message.type;\n if (!this.queuedRequests.every(isDifferentTypeViewport)) {\n this.queuedRequests = this.queuedRequests.filter(isDifferentTypeViewport);\n }\n this.queuedRequests.push(queuedRequest);\n }\n processQueuedRequests() {\n const newQueue = [];\n for (const queuedRequest of this.queuedRequests) {\n const { clientViewportId, message, requestId } = queuedRequest;\n const serverViewportId = this.mapClientToServerViewport.get(clientViewportId);\n if (serverViewportId) {\n this.sendMessageToServer(\n {\n ...message,\n viewPortId: serverViewportId\n },\n requestId\n );\n } else if (this.viewports.has(clientViewportId)) {\n newQueue.push(queuedRequest);\n } else {\n console.warn(\n `ServerProxy processQueuedRequests, ${message.type} request not found ${clientViewportId}`\n );\n }\n }\n this.queuedRequests = newQueue;\n }\n unsubscribe(clientViewportId) {\n const serverViewportId = this.mapClientToServerViewport.get(clientViewportId);\n if (serverViewportId) {\n info2 == null ? void 0 : info2(\n `Unsubscribe Message (Client to Server):\n ${serverViewportId}`\n );\n this.sendMessageToServer({\n type: REMOVE_VP,\n viewPortId: serverViewportId\n });\n } else {\n error2(\n `failed to unsubscribe client viewport ${clientViewportId}, viewport not found`\n );\n }\n }\n getViewportForClient(clientViewportId, throws = true) {\n const serverViewportId = this.mapClientToServerViewport.get(clientViewportId);\n if (serverViewportId) {\n const viewport = this.viewports.get(serverViewportId);\n if (viewport) {\n return viewport;\n } else if (throws) {\n throw Error(\n `Viewport not found for client viewport ${clientViewportId}`\n );\n } else {\n return null;\n }\n } else if (this.viewports.has(clientViewportId)) {\n return this.viewports.get(clientViewportId);\n } else if (throws) {\n throw Error(\n `Viewport server id not found for client viewport ${clientViewportId}`\n );\n } else {\n return null;\n }\n }\n /**********************************************************************/\n /* Handle messages from client */\n /**********************************************************************/\n setViewRange(viewport, message) {\n const requestId = nextRequestId();\n console.log(\n `[ServerProxy] setViewRange (${message.range.from}:${message.range.to})`\n );\n infoEnabled2 && info2(`setViewRange (${message.range.from}:${message.range.to})`);\n const [serverRequest, rows, debounceRequest] = viewport.rangeRequest(\n requestId,\n message.range\n );\n if (viewport.status === \"subscribed\") {\n info2 == null ? void 0 : info2(`setViewRange ${message.range.from} - ${message.range.to}`);\n if (serverRequest) {\n if (true) {\n info2 == null ? void 0 : info2(\n `CHANGE_VP_RANGE (${message.range.from}-${message.range.to}) => (${serverRequest.from}-${serverRequest.to})`\n );\n }\n infoEnabled2 && info2(\n `setViewRange send CHANGE_VP_RANGE<#${requestId}> (${serverRequest.from}-${serverRequest.to})`\n );\n this.sendMessageToServer(serverRequest, requestId);\n }\n if (rows) {\n info2 == null ? void 0 : info2(`setViewRange ${rows.length} rows returned from cache`);\n this.postMessageToClient({\n mode: \"update\",\n type: \"viewport-update\",\n clientViewportId: viewport.clientViewportId,\n range: message.range,\n rows\n });\n } else if (debounceRequest) {\n this.postMessageToClient(debounceRequest);\n }\n } else if (serverRequest) {\n this.addRequestToQueue({\n clientViewportId: message.viewport,\n message: serverRequest,\n requestId\n });\n }\n }\n // TODO check config has actually changed\n setConfig(viewport, message) {\n const requestId = nextRequestId();\n const request = viewport.setConfig(requestId, message.config);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n setTitle(viewport, message) {\n if (viewport) {\n viewport.title = message.title;\n this.updateTitleOnVisualLinks(viewport);\n }\n }\n select(viewport, message) {\n const requestId = nextRequestId();\n const { selected } = message;\n const request = viewport.selectRequest(requestId, selected);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n disableViewport(viewport) {\n const requestId = nextRequestId();\n const request = viewport.disable(requestId);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n enableViewport(viewport) {\n if (viewport.disabled) {\n const requestId = nextRequestId();\n const request = viewport.enable(requestId);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n }\n suspendViewport(viewport) {\n viewport.suspend();\n viewport.suspendTimer = setTimeout(() => {\n info2 == null ? void 0 : info2(\"suspendTimer expired, escalate suspend to disable\");\n this.disableViewport(viewport);\n }, 3e3);\n }\n resumeViewport(viewport) {\n if (viewport.suspendTimer) {\n debug3 == null ? void 0 : debug3(\"clear suspend timer\");\n clearTimeout(viewport.suspendTimer);\n viewport.suspendTimer = null;\n }\n const [size, rows] = viewport.resume();\n debug3 == null ? void 0 : debug3(`resumeViewport size ${size}, ${rows.length} rows sent to client`);\n this.postMessageToClient({\n clientViewportId: viewport.clientViewportId,\n mode: \"update\",\n rows,\n size,\n type: \"viewport-update\"\n });\n }\n openTreeNode(viewport, message) {\n if (viewport.serverViewportId) {\n const requestId = nextRequestId();\n this.sendIfReady(\n viewport.openTreeNode(requestId, message),\n requestId,\n viewport.status === \"subscribed\"\n );\n }\n }\n closeTreeNode(viewport, message) {\n if (viewport.serverViewportId) {\n const requestId = nextRequestId();\n this.sendIfReady(\n viewport.closeTreeNode(requestId, message),\n requestId,\n viewport.status === \"subscribed\"\n );\n }\n }\n createLink(viewport, message) {\n const [requestId, visualLinkRequest] = stripRequestId(message);\n const parentVpId = this.mapClientToServerViewport.get(message.parentVpId);\n if (parentVpId) {\n const request = viewport.createLink(requestId, {\n ...visualLinkRequest,\n parentVpId\n });\n this.sendMessageToServer(request, requestId);\n } else {\n throw Error(`createLink parent viewport not found ${message.parentVpId}`);\n }\n }\n removeLink(viewport, message) {\n const { requestId } = message;\n const request = viewport.removeLink(requestId);\n this.sendMessageToServer(request, requestId);\n }\n updateTitleOnVisualLinks(viewport) {\n var _a;\n const { serverViewportId, title } = viewport;\n for (const vp of this.viewports.values()) {\n if (vp !== viewport && vp.links && serverViewportId && title) {\n if ((_a = vp.links) == null ? void 0 : _a.some((link) => link.parentVpId === serverViewportId)) {\n const [messageToClient] = vp.setLinks(\n addTitleToLinks(vp.links, serverViewportId, title)\n );\n this.postMessageToClient(messageToClient);\n }\n }\n }\n }\n removeViewportFromVisualLinks(serverViewportId) {\n var _a;\n for (const vp of this.viewports.values()) {\n if ((_a = vp.links) == null ? void 0 : _a.some(({ parentVpId }) => parentVpId === serverViewportId)) {\n const [messageToClient] = vp.setLinks(\n vp.links.filter(({ parentVpId }) => parentVpId !== serverViewportId)\n );\n this.postMessageToClient(messageToClient);\n }\n }\n }\n menuRpcCall(message) {\n const viewport = this.getViewportForClient(message.vpId, false);\n if (viewport == null ? void 0 : viewport.serverViewportId) {\n const [requestId, rpcRequest] = stripRequestId(message);\n this.sendMessageToServer(\n {\n ...rpcRequest,\n vpId: viewport.serverViewportId\n },\n requestId\n );\n }\n }\n viewportRpcCall(message) {\n const viewport = this.getViewportForClient(message.vpId, false);\n if (viewport == null ? void 0 : viewport.serverViewportId) {\n const [requestId, { namedParams = {}, ...rpcRequest }] = stripRequestId(message);\n this.sendMessageToServer(\n {\n ...rpcRequest,\n namedParams,\n vpId: viewport.serverViewportId\n },\n requestId\n );\n }\n }\n rpcCall(message) {\n const [requestId, rpcRequest] = stripRequestId(message);\n const module = getRpcServiceModule(rpcRequest.service);\n this.sendMessageToServer(rpcRequest, requestId, { module });\n }\n handleMessageFromClient(message) {\n var _a;\n if (isViewportMessage(message) || isVisualLinkMessage(message)) {\n if (message.type === \"disable\") {\n const viewport = this.getViewportForClient(message.viewport, false);\n if (viewport !== null) {\n return this.disableViewport(viewport);\n } else {\n return;\n }\n } else {\n const viewport = isVisualLinkMessage(message) ? this.getViewportForClient(message.childVpId) : this.getViewportForClient(message.viewport);\n switch (message.type) {\n case \"setViewRange\":\n return this.setViewRange(viewport, message);\n case \"config\":\n return this.setConfig(viewport, message);\n case \"select\":\n return this.select(viewport, message);\n case \"suspend\":\n return this.suspendViewport(viewport);\n case \"resume\":\n return this.resumeViewport(viewport);\n case \"enable\":\n return this.enableViewport(viewport);\n case \"openTreeNode\":\n return this.openTreeNode(viewport, message);\n case \"closeTreeNode\":\n return this.closeTreeNode(viewport, message);\n case \"CREATE_VISUAL_LINK\":\n return this.createLink(viewport, message);\n case \"REMOVE_VISUAL_LINK\":\n return this.removeLink(viewport, message);\n case \"setTitle\":\n return this.setTitle(viewport, message);\n default:\n }\n }\n } else if (isVuuRpcRequest(message)) {\n return this.viewportRpcCall(\n message\n );\n } else if (isVuuMenuRpcRequest(message)) {\n return this.menuRpcCall(message);\n } else if (message.type === \"disconnect\") {\n return this.disconnect();\n } else {\n const { type, requestId } = message;\n switch (type) {\n case \"GET_TABLE_LIST\": {\n (_a = this.tableList) != null ? _a : this.tableList = this.awaitResponseToMessage(\n { type },\n requestId\n );\n this.tableList.then((response) => {\n this.postMessageToClient({\n type: \"TABLE_LIST_RESP\",\n tables: response.tables,\n requestId\n });\n });\n return;\n }\n case \"GET_TABLE_META\": {\n this.getTableMeta(message.table, requestId).then((tableSchema) => {\n if (tableSchema) {\n this.postMessageToClient({\n type: \"TABLE_META_RESP\",\n tableSchema,\n requestId\n });\n }\n });\n return;\n }\n case \"RPC_CALL\":\n return this.rpcCall(message);\n default:\n }\n }\n error2(\n `Vuu ServerProxy Unexpected message from client ${JSON.stringify(\n message\n )}`\n );\n }\n getTableMeta(table, requestId = nextRequestId()) {\n if (isSessionTable(table)) {\n return this.awaitResponseToMessage(\n { type: \"GET_TABLE_META\", table },\n requestId\n ).then(createSchemaFromTableMetadata);\n }\n const key = `${table.module}:${table.table}`;\n let tableMetaRequest = this.cachedTableMetaRequests.get(key);\n if (!tableMetaRequest) {\n tableMetaRequest = this.awaitResponseToMessage(\n { type: \"GET_TABLE_META\", table },\n requestId\n );\n this.cachedTableMetaRequests.set(key, tableMetaRequest);\n }\n return tableMetaRequest == null ? void 0 : tableMetaRequest.then((response) => this.cacheTableMeta(response));\n }\n awaitResponseToMessage(message, requestId = nextRequestId()) {\n return new Promise((resolve, reject) => {\n this.sendMessageToServer(message, requestId);\n this.pendingRequests.set(requestId, { reject, resolve });\n });\n }\n sendIfReady(message, requestId, isReady = true) {\n if (isReady) {\n this.sendMessageToServer(message, requestId);\n }\n return isReady;\n }\n sendMessageToServer(body, requestId = `${_requestId++}`, options = DEFAULT_OPTIONS) {\n const { module = \"CORE\" } = options;\n if (this.authToken) {\n this.connection.send({\n requestId,\n sessionId: this.sessionId,\n token: this.authToken,\n user: this.user,\n module,\n body\n });\n }\n }\n handleMessageFromServer(message) {\n var _a, _b, _c;\n const { body, requestId, sessionId } = message;\n const pendingRequest = this.pendingRequests.get(requestId);\n if (pendingRequest) {\n const { resolve } = pendingRequest;\n this.pendingRequests.delete(requestId);\n resolve(body);\n return;\n }\n const { viewports } = this;\n switch (body.type) {\n case HB:\n this.sendMessageToServer(\n { type: HB_RESP, ts: +/* @__PURE__ */ new Date() },\n \"NA\"\n );\n break;\n case \"LOGIN_SUCCESS\":\n if (sessionId) {\n this.sessionId = sessionId;\n (_a = this.pendingLogin) == null ? void 0 : _a.resolve(sessionId);\n this.pendingLogin = void 0;\n } else {\n throw Error(\"LOGIN_SUCCESS did not provide sessionId\");\n }\n break;\n // TODO login rejected\n case \"REMOVE_VP_SUCCESS\":\n {\n const viewport = viewports.get(body.viewPortId);\n if (viewport) {\n this.mapClientToServerViewport.delete(viewport.clientViewportId);\n viewports.delete(body.viewPortId);\n this.removeViewportFromVisualLinks(body.viewPortId);\n }\n }\n break;\n case SET_SELECTION_SUCCESS:\n {\n const viewport = this.viewports.get(body.vpId);\n if (viewport) {\n viewport.completeOperation(requestId);\n }\n }\n break;\n case CHANGE_VP_SUCCESS:\n case DISABLE_VP_SUCCESS:\n if (viewports.has(body.viewPortId)) {\n const viewport = this.viewports.get(body.viewPortId);\n if (viewport) {\n const response = viewport.completeOperation(requestId);\n if (response !== void 0) {\n this.postMessageToClient(response);\n if (debugEnabled3) {\n debug3(`postMessageToClient ${JSON.stringify(response)}`);\n }\n }\n }\n }\n break;\n case ENABLE_VP_SUCCESS:\n {\n const viewport = this.viewports.get(body.viewPortId);\n if (viewport) {\n const response = viewport.completeOperation(requestId);\n if (response) {\n this.postMessageToClient(response);\n const [size, rows] = viewport.resume();\n this.postMessageToClient({\n clientViewportId: viewport.clientViewportId,\n mode: \"update\",\n rows,\n size,\n type: \"viewport-update\"\n });\n }\n }\n }\n break;\n case \"TABLE_ROW\":\n {\n const viewportRowMap = groupRowsByViewport(body.rows);\n const [firstRow, secondRow] = body.rows;\n if (body.rows.length === 0) {\n infoEnabled2 && info2(\"handleMessageFromServer TABLE_ROW 0 rows\");\n } else if ((firstRow == null ? void 0 : firstRow.rowIndex) === -1) {\n if (body.rows.length === 1) {\n if (firstRow.updateType === \"SIZE\") {\n infoEnabled2 && info2(\n `handleMessageFromServer [${firstRow.viewPortId}] TABLE_ROW SIZE ONLY ${firstRow.vpSize}`\n );\n infoEnabled2 && info2(\n `handleMessageFromServer [${firstRow.viewPortId}] TABLE_ROW SIZE ONLY ${firstRow.vpSize}`\n );\n } else {\n infoEnabled2 && info2(\n `handleMessageFromServer [${firstRow.viewPortId}] TABLE_ROW SIZE ${firstRow.vpSize} rowIdx ${firstRow.rowIndex}`\n );\n }\n } else {\n infoEnabled2 && info2(\n `handleMessageFromServer TABLE_ROW ${body.rows.length} rows, SIZE ${firstRow.vpSize}, [${secondRow == null ? void 0 : secondRow.rowIndex}] - [${(_b = body.rows[body.rows.length - 1]) == null ? void 0 : _b.rowIndex}]`\n );\n }\n } else {\n infoEnabled2 && info2(\n `handleMessageFromServer TABLE_ROW ${body.rows.length} rows [${firstRow == null ? void 0 : firstRow.rowIndex}] - [${(_c = body.rows[body.rows.length - 1]) == null ? void 0 : _c.rowIndex}]`\n );\n }\n for (const [viewportId, rows] of Object.entries(viewportRowMap)) {\n const viewport = viewports.get(viewportId);\n if (viewport) {\n viewport.updateRows(rows);\n } else {\n warn2 == null ? void 0 : warn2(\n `TABLE_ROW message received for non registered viewport ${viewportId}`\n );\n }\n }\n this.processUpdates();\n }\n break;\n case \"CHANGE_VP_RANGE_SUCCESS\":\n {\n const viewport = this.viewports.get(body.viewPortId);\n if (viewport) {\n const { from, to } = body;\n infoEnabled2 && info2(`CHANGE_VP_RANGE_SUCCESS<#${requestId}> ${from} - ${to}`);\n viewport.completeOperation(requestId, from, to);\n }\n }\n break;\n case OPEN_TREE_SUCCESS:\n case CLOSE_TREE_SUCCESS:\n break;\n case \"CREATE_VISUAL_LINK_SUCCESS\":\n {\n const viewport = this.viewports.get(body.childVpId);\n const parentViewport = this.viewports.get(body.parentVpId);\n if (viewport && parentViewport) {\n const { childColumnName, parentColumnName } = body;\n const response = viewport.completeOperation(\n requestId,\n childColumnName,\n parentViewport.clientViewportId,\n parentColumnName\n );\n if (response) {\n this.postMessageToClient(response);\n }\n }\n }\n break;\n case \"REMOVE_VISUAL_LINK_SUCCESS\":\n {\n const viewport = this.viewports.get(body.childVpId);\n if (viewport) {\n const response = viewport.completeOperation(\n requestId\n );\n if (response) {\n this.postMessageToClient(response);\n }\n }\n }\n break;\n case \"VP_VISUAL_LINKS_RESP\":\n {\n const activeLinkDescriptors = this.getActiveLinks(body.links);\n const viewport = this.viewports.get(body.vpId);\n if (activeLinkDescriptors.length && viewport) {\n const linkDescriptorsWithLabels = addLabelsToLinks(\n activeLinkDescriptors,\n this.viewports\n );\n const [clientMessage, pendingLink] = viewport.setLinks(\n linkDescriptorsWithLabels\n );\n this.postMessageToClient(clientMessage);\n if (pendingLink) {\n const { link, parentClientVpId } = pendingLink;\n const requestId2 = nextRequestId();\n const parentVpId = this.mapClientToServerViewport.get(parentClientVpId);\n if (parentVpId) {\n const message2 = viewport.createLink(requestId2, {\n childVpId: body.vpId,\n childColumnName: link.fromColumn,\n parentColumnName: link.toColumn,\n parentVpId,\n type: \"CREATE_VISUAL_LINK\"\n });\n this.sendMessageToServer(message2, requestId2);\n }\n }\n }\n }\n break;\n case \"VIEW_PORT_MENUS_RESP\":\n if (body.menu.name) {\n const viewport = this.viewports.get(body.vpId);\n if (viewport) {\n const clientMessage = viewport.setMenu(body.menu);\n this.postMessageToClient(clientMessage);\n }\n }\n break;\n case \"VP_EDIT_RPC_RESPONSE\":\n {\n this.postMessageToClient({\n action: body.action,\n requestId,\n rpcName: body.rpcName,\n type: \"VP_EDIT_RPC_RESPONSE\"\n });\n }\n break;\n case \"VP_EDIT_RPC_REJECT\":\n {\n const viewport = this.viewports.get(body.vpId);\n if (viewport) {\n this.postMessageToClient({\n requestId,\n type: \"VP_EDIT_RPC_REJECT\",\n error: body.error\n });\n }\n }\n break;\n case \"VIEW_PORT_MENU_REJ\": {\n const { error: error3, rpcName, vpId } = body;\n const viewport = this.viewports.get(vpId);\n if (viewport) {\n this.postMessageToClient({\n clientViewportId: viewport.clientViewportId,\n error: error3,\n rpcName,\n type: \"VIEW_PORT_MENU_REJ\",\n requestId\n });\n }\n break;\n }\n case \"VIEW_PORT_MENU_RESP\":\n {\n if (isSessionTableActionMessage(body)) {\n const { action, rpcName } = body;\n this.awaitResponseToMessage({\n type: \"GET_TABLE_META\",\n table: action.table\n }).then((response) => {\n const tableSchema = createSchemaFromTableMetadata(\n response\n );\n this.postMessageToClient({\n /* MenuRpcResponse */\n rpcName,\n type: \"VIEW_PORT_MENU_RESP\",\n action: {\n ...action,\n tableSchema\n },\n tableAlreadyOpen: this.isTableOpen(action.table),\n requestId\n });\n });\n } else {\n const { action, rpcName } = body;\n this.postMessageToClient({\n /* MenuRpcResponse */\n action,\n rpcName,\n requestId,\n tableAlreadyOpen: isOpenDialogAction(action) && this.isTableOpen(action.table),\n type: \"VIEW_PORT_MENU_RESP\"\n });\n }\n }\n break;\n case \"RPC_RESP\":\n {\n const { method, result } = body;\n this.postMessageToClient({\n type: \"RPC_RESP\",\n method,\n result,\n requestId\n });\n }\n break;\n case \"VIEW_PORT_RPC_REPONSE\":\n {\n const { method, action } = body;\n this.postMessageToClient({\n type: \"VIEW_PORT_RPC_RESPONSE\",\n rpcName: method,\n action,\n requestId\n });\n }\n break;\n case \"ERROR\":\n error2(body.msg);\n break;\n default:\n infoEnabled2 && info2(`handleMessageFromServer ${body[\"type\"]}.`);\n }\n }\n cacheTableMeta(messageBody) {\n const { module, table } = messageBody.table;\n const key = `${module}:${table}`;\n let tableSchema = this.cachedTableSchemas.get(key);\n if (!tableSchema) {\n tableSchema = createSchemaFromTableMetadata(messageBody);\n this.cachedTableSchemas.set(key, tableSchema);\n }\n return tableSchema;\n }\n isTableOpen(table) {\n if (table) {\n const tableName = table.table;\n for (const viewport of this.viewports.values()) {\n if (!viewport.suspended && viewport.table.table === tableName) {\n return true;\n }\n }\n }\n }\n // Eliminate links to suspended viewports\n getActiveLinks(linkDescriptors) {\n return linkDescriptors.filter((linkDescriptor) => {\n const viewport = this.viewports.get(linkDescriptor.parentVpId);\n return viewport && !viewport.suspended;\n });\n }\n processUpdates() {\n this.viewports.forEach((viewport) => {\n var _a;\n if (viewport.hasUpdatesToProcess) {\n const result = viewport.getClientRows();\n if (result !== NO_DATA_UPDATE) {\n const [rows, mode] = result;\n const size = viewport.getNewRowCount();\n if (size !== void 0 || rows && rows.length > 0) {\n debugEnabled3 && debug3(\n `postMessageToClient #${viewport.clientViewportId} viewport-update ${mode}, ${(_a = rows == null ? void 0 : rows.length) != null ? _a : \"no\"} rows, size ${size}`\n );\n if (mode) {\n this.postMessageToClient({\n clientViewportId: viewport.clientViewportId,\n mode,\n rows,\n size,\n type: \"viewport-update\"\n });\n }\n }\n }\n }\n });\n }\n};\n\n// src/WebSocketConnection.ts\nvar isNotConnecting = (connectionState) => connectionState.connectionStatus !== \"connecting\" && connectionState.connectionStatus !== \"reconnecting\";\nvar isWebSocketConnectionMessage = (msg) => {\n if (\"connectionStatus\" in msg) {\n return [\n \"connecting\",\n \"connected\",\n \"connection-open-awaiting-session\",\n \"reconnecting\",\n \"reconnected\",\n \"disconnected\",\n \"closed\",\n \"failed\"\n ].includes(msg.connectionStatus);\n } else {\n return false;\n }\n};\nvar DEFAULT_RETRY_LIMITS = {\n connect: 5,\n reconnect: 8\n};\nvar DEFAULT_CONNECTION_TIMEOUT = 1e4;\nvar ConnectingEndState = {\n connecting: \"connected\",\n reconnecting: \"reconnected\"\n};\nvar parseWebSocketMessage = (message) => {\n try {\n return JSON.parse(message);\n } catch (e) {\n throw Error(`Error parsing JSON response from server ${message}`);\n }\n};\nvar _callback, _confirmedOpen, _connectionState, _connectionTimeout, _deferredConnection, _protocols, _reconnectAttempts, _requiresLogin, _url, _ws;\nvar WebSocketConnection = class extends EventEmitter {\n constructor({\n callback,\n connectionTimeout = DEFAULT_CONNECTION_TIMEOUT,\n protocols,\n retryLimits = DEFAULT_RETRY_LIMITS,\n url\n }) {\n super();\n __privateAdd(this, _callback);\n /**\n We are not confirmedOpen until we receive the first message from the\n server. If we get an unexpected close event before that, we consider\n the reconnect attempts as still within the connection phase, not true\n reconnection. This can happen e.g. when connecting to remote host via\n a proxy.\n */\n __privateAdd(this, _confirmedOpen, false);\n __privateAdd(this, _connectionState);\n __privateAdd(this, _connectionTimeout);\n __privateAdd(this, _deferredConnection);\n __privateAdd(this, _protocols);\n __privateAdd(this, _reconnectAttempts);\n __privateAdd(this, _requiresLogin, true);\n __privateAdd(this, _url);\n __privateAdd(this, _ws);\n __publicField(this, \"receive\", (evt) => {\n const vuuMessageFromServer = parseWebSocketMessage(evt.data);\n __privateGet(this, _callback).call(this, vuuMessageFromServer);\n });\n __publicField(this, \"send\", (msg) => {\n var _a;\n (_a = __privateGet(this, _ws)) == null ? void 0 : _a.send(JSON.stringify(msg));\n });\n __privateSet(this, _callback, callback);\n __privateSet(this, _connectionTimeout, connectionTimeout);\n __privateSet(this, _url, url);\n __privateSet(this, _protocols, protocols);\n __privateSet(this, _reconnectAttempts, {\n retryAttemptsTotal: retryLimits.reconnect,\n retryAttemptsRemaining: retryLimits.reconnect,\n secondsToNextRetry: 1\n });\n __privateSet(this, _connectionState, {\n connectionPhase: \"connecting\",\n connectionStatus: \"closed\",\n retryAttemptsTotal: retryLimits.connect,\n retryAttemptsRemaining: retryLimits.connect,\n secondsToNextRetry: 1\n });\n }\n get connectionTimeout() {\n return __privateGet(this, _connectionTimeout);\n }\n get protocols() {\n return __privateGet(this, _protocols);\n }\n get requiresLogin() {\n return __privateGet(this, _requiresLogin);\n }\n get isClosed() {\n return this.status === \"closed\";\n }\n get isDisconnected() {\n return this.status === \"disconnected\";\n }\n get isConnecting() {\n return __privateGet(this, _connectionState).connectionPhase === \"connecting\";\n }\n get status() {\n return __privateGet(this, _connectionState).connectionStatus;\n }\n set status(connectionStatus) {\n __privateSet(this, _connectionState, {\n ...__privateGet(this, _connectionState),\n connectionStatus\n });\n if (isNotConnecting(__privateGet(this, _connectionState))) {\n this.emit(\"connection-status\", __privateGet(this, _connectionState));\n }\n }\n get connectionState() {\n return __privateGet(this, _connectionState);\n }\n get hasConnectionAttemptsRemaining() {\n return __privateGet(this, _connectionState).retryAttemptsRemaining > 0;\n }\n get confirmedOpen() {\n return __privateGet(this, _confirmedOpen);\n }\n /**\n * We are 'confirmedOpen' when we see the first message transmitted\n * from the server. This ensures that even if we have one or more\n * proxies in our route to the endPoint, all connections have been\n * opened successfully.\n * First time in here (on our initial successful connection) we switch\n * from 'connect' phase to 'reconnect' phase. We may have different\n * retry configurations for these two phases.\n */\n set confirmedOpen(confirmedOpen) {\n __privateSet(this, _confirmedOpen, confirmedOpen);\n if (confirmedOpen && this.isConnecting) {\n __privateSet(this, _connectionState, {\n ...__privateGet(this, _connectionState),\n connectionPhase: \"reconnecting\",\n ...__privateGet(this, _reconnectAttempts)\n });\n } else if (confirmedOpen) {\n __privateSet(this, _connectionState, {\n ...__privateGet(this, _connectionState),\n ...__privateGet(this, _reconnectAttempts)\n });\n }\n }\n get url() {\n return __privateGet(this, _url);\n }\n async connect(clientCall = true) {\n var _a;\n const state = __privateGet(this, _connectionState);\n if (this.isConnecting && __privateGet(this, _deferredConnection) === void 0) {\n __privateSet(this, _deferredConnection, new DeferredPromise());\n }\n const { connectionTimeout, protocols, url } = this;\n this.status = state.connectionPhase;\n const timer = setTimeout(() => {\n throw Error(\n `Failed to open WebSocket connection to ${url}, timed out after ${connectionTimeout}ms`\n );\n }, connectionTimeout);\n const ws2 = __privateSet(this, _ws, new WebSocket(url, protocols));\n ws2.onopen = () => {\n const connectedStatus = ConnectingEndState[state.connectionPhase];\n this.status = connectedStatus;\n clearTimeout(timer);\n if (__privateGet(this, _deferredConnection)) {\n __privateGet(this, _deferredConnection).resolve(void 0);\n __privateSet(this, _deferredConnection, void 0);\n }\n if (this.isConnecting) {\n this.emit(\"connected\");\n } else {\n this.emit(\"reconnected\");\n }\n };\n ws2.onerror = () => {\n clearTimeout(timer);\n };\n ws2.onclose = () => {\n if (!this.isClosed) {\n this.confirmedOpen = false;\n this.status = \"disconnected\";\n if (this.hasConnectionAttemptsRemaining) {\n this.reconnect();\n } else {\n this.close(\"failure\");\n }\n }\n };\n ws2.onmessage = (evt) => {\n if (!this.confirmedOpen) {\n this.confirmedOpen = true;\n }\n this.receive(evt);\n };\n if (clientCall) {\n return (_a = __privateGet(this, _deferredConnection)) == null ? void 0 : _a.promise;\n }\n }\n reconnect() {\n const { retryAttemptsRemaining, secondsToNextRetry } = __privateGet(this, _connectionState);\n setTimeout(() => {\n __privateSet(this, _connectionState, {\n ...__privateGet(this, _connectionState),\n retryAttemptsRemaining: retryAttemptsRemaining - 1,\n secondsToNextRetry: secondsToNextRetry * 2\n });\n this.connect(false);\n }, secondsToNextRetry * 1e3);\n }\n close(reason = \"shutdown\") {\n var _a;\n this.status = \"closed\";\n if (reason === \"failure\") {\n if (__privateGet(this, _deferredConnection)) {\n __privateGet(this, _deferredConnection).reject(Error(\"connection failed\"));\n __privateSet(this, _deferredConnection, void 0);\n }\n } else {\n (_a = __privateGet(this, _ws)) == null ? void 0 : _a.close();\n }\n this.emit(\"closed\", reason);\n __privateSet(this, _ws, void 0);\n }\n};\n_callback = new WeakMap();\n_confirmedOpen = new WeakMap();\n_connectionState = new WeakMap();\n_connectionTimeout = new WeakMap();\n_deferredConnection = new WeakMap();\n_protocols = new WeakMap();\n_reconnectAttempts = new WeakMap();\n_requiresLogin = new WeakMap();\n_url = new WeakMap();\n_ws = new WeakMap();\n\n// src/worker.ts\nvar server;\nvar { info: info3, infoEnabled: infoEnabled3 } = logger(\"worker\");\nvar getRetryLimits = (retryLimitDisconnect, retryLimitStartup) => {\n if (retryLimitDisconnect !== void 0 && retryLimitStartup !== void 0) {\n return {\n connect: retryLimitStartup,\n reconnect: retryLimitDisconnect\n };\n } else if (retryLimitDisconnect !== void 0) {\n return {\n connect: retryLimitDisconnect,\n reconnect: retryLimitDisconnect\n };\n } else if (retryLimitStartup !== void 0) {\n return {\n connect: retryLimitStartup,\n reconnect: retryLimitStartup\n };\n }\n};\nvar ws;\nvar sendMessageToClient = (message) => {\n postMessage(message);\n};\nasync function connectToServer(url, protocols, token, username, retryLimitDisconnect, retryLimitStartup) {\n const websocketConnection = ws = new WebSocketConnection({\n callback: (msg) => {\n if (isConnectionQualityMetrics(msg)) {\n postMessage({ type: \"connection-metrics\", messages: msg });\n } else if (isWebSocketConnectionMessage(msg)) {\n postMessage(msg);\n } else {\n server.handleMessageFromServer(msg);\n }\n },\n protocols,\n retryLimits: getRetryLimits(retryLimitStartup, retryLimitDisconnect),\n url\n });\n websocketConnection.on(\"connection-status\", postMessage);\n await websocketConnection.connect();\n server = new ServerProxy(websocketConnection, sendMessageToClient);\n if (websocketConnection.requiresLogin) {\n await server.login(token, username);\n }\n}\nvar handleMessageFromClient = async ({\n data: message\n}) => {\n switch (message.type) {\n case \"connect\":\n try {\n await connectToServer(\n message.url,\n message.protocol,\n message.token,\n message.username,\n message.retryLimitDisconnect,\n message.retryLimitStartup\n );\n postMessage({ type: \"connected\" });\n } catch (err) {\n postMessage({ type: \"connection-failed\", reason: String(err) });\n }\n break;\n // If any of the messages below are received BEFORE we have connected and created\n // the server - handle accordingly\n case \"disconnect\":\n server.disconnect();\n ws == null ? void 0 : ws.close();\n break;\n case \"subscribe\":\n infoEnabled3 && info3(`client subscribe: ${JSON.stringify(message)}`);\n server.subscribe(message);\n break;\n case \"unsubscribe\":\n infoEnabled3 && info3(`client unsubscribe: ${JSON.stringify(message)}`);\n server.unsubscribe(message.viewport);\n break;\n default:\n infoEnabled3 && info3(`client message: ${JSON.stringify(message)}`);\n server.handleMessageFromClient(message);\n }\n};\nself.addEventListener(\"message\", handleMessageFromClient);\npostMessage({ type: \"ready\" });\n\n";
|
package/types/message-utils.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { TableSchema, VuuUIMessageOut, WithRequestId } from "@vuu-ui/vuu-data-types";
|
|
2
|
-
import { VuuRpcMenuRequest, VuuRpcViewportRequest, VuuTableMetaResponse, VuuRow, VuuRpcServiceRequest, VuuRange } from "@vuu-ui/vuu-protocol-types";
|
|
3
|
-
export declare const isVuuRpcRequest: (message: VuuUIMessageOut | VuuRpcServiceRequest | VuuRpcMenuRequest | VuuRpcViewportRequest) => message is VuuRpcViewportRequest;
|
|
4
|
-
export declare const stripRequestId: <T>({ requestId, ...rest }: WithRequestId<T>) => [string, T];
|
|
5
|
-
export declare const getFirstAndLastRows: (rows: VuuRow[]) => [VuuRow, VuuRow] | [VuuRow];
|
|
6
|
-
export type ViewportRowMap = {
|
|
7
|
-
[key: string]: VuuRow[];
|
|
8
|
-
};
|
|
9
|
-
export declare const groupRowsByViewport: (rows: VuuRow[]) => ViewportRowMap;
|
|
10
|
-
export declare const createSchemaFromTableMetadata: ({ columns, dataTypes, key, table, }: Omit<VuuTableMetaResponse, "type">) => Readonly<TableSchema>;
|
|
11
|
-
export declare const gapBetweenLastRowSentToClient: (lastRowsReturnedToClient: [number, number], pendingUpdates: VuuRow[], clientRange: VuuRange) => VuuRange | undefined;
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { DataSource, DataSourceConstructorProps, DataSourceEditHandler, DataSourceStatus, DataSourceSubscribeCallback, DataSourceSubscribeProps, WithBaseFilter, WithFullConfig } from "@vuu-ui/vuu-data-types";
|
|
2
|
-
import { VuuTable, VuuGroupBy, VuuRange } from "@vuu-ui/vuu-protocol-types";
|
|
3
|
-
import { BaseDataSource } from "@vuu-ui/vuu-utils";
|
|
4
|
-
export type RestMetaData = {
|
|
5
|
-
recordCount: number;
|
|
6
|
-
};
|
|
7
|
-
export declare class RestDataSource extends BaseDataSource implements DataSource {
|
|
8
|
-
#private;
|
|
9
|
-
private static _api;
|
|
10
|
-
groupBy: VuuGroupBy;
|
|
11
|
-
selectedRowsCount: number;
|
|
12
|
-
status: DataSourceStatus;
|
|
13
|
-
table: VuuTable;
|
|
14
|
-
constructor(props: DataSourceConstructorProps & {
|
|
15
|
-
url?: string;
|
|
16
|
-
});
|
|
17
|
-
subscribe(subscribeProps: DataSourceSubscribeProps, callback: DataSourceSubscribeCallback): Promise<void>;
|
|
18
|
-
unsubscribe(): void;
|
|
19
|
-
private get pageSize();
|
|
20
|
-
static get api(): string;
|
|
21
|
-
static set api(url: string);
|
|
22
|
-
get url(): string;
|
|
23
|
-
get dataUrl(): string;
|
|
24
|
-
get httpHeaders(): Headers | undefined;
|
|
25
|
-
get metaDataUrl(): string;
|
|
26
|
-
private get queryStringParameters();
|
|
27
|
-
get title(): string;
|
|
28
|
-
set title(title: string);
|
|
29
|
-
rangeRequest(range: VuuRange): void;
|
|
30
|
-
get config(): WithBaseFilter<WithFullConfig>;
|
|
31
|
-
set config(config: WithBaseFilter<WithFullConfig>);
|
|
32
|
-
private fetchData;
|
|
33
|
-
private fetchMetaData;
|
|
34
|
-
private sendRowsToClient;
|
|
35
|
-
applyEdit: DataSourceEditHandler;
|
|
36
|
-
openTreeNode: () => never;
|
|
37
|
-
closeTreeNode: () => never;
|
|
38
|
-
remoteProcedureCall: <T>() => Promise<T>;
|
|
39
|
-
menuRpcCall: () => Promise<string>;
|
|
40
|
-
rpcCall: <T>() => Promise<T>;
|
|
41
|
-
select: () => never;
|
|
42
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { DataSourceRow } from "@vuu-ui/vuu-data-types";
|
|
2
|
-
import { VuuRange } from "@vuu-ui/vuu-protocol-types";
|
|
3
|
-
export declare class MovingWindow {
|
|
4
|
-
data: DataSourceRow[];
|
|
5
|
-
rowCount: number;
|
|
6
|
-
private range;
|
|
7
|
-
constructor({ from, to }: VuuRange);
|
|
8
|
-
setRowCount: (rowCount: number) => void;
|
|
9
|
-
add(data: DataSourceRow): void;
|
|
10
|
-
getAtIndex(index: number): DataSourceRow | undefined;
|
|
11
|
-
isWithinRange(index: number): boolean;
|
|
12
|
-
setRange({ from, to }: VuuRange): void;
|
|
13
|
-
getSelectedRows(): DataSourceRow[];
|
|
14
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { DataSourceRow } from "@vuu-ui/vuu-data-types";
|
|
2
|
-
import { VuuFilter, VuuSort } from "@vuu-ui/vuu-protocol-types";
|
|
3
|
-
import { ColumnMap } from "@vuu-ui/vuu-utils";
|
|
4
|
-
export type JsonPrimitive = string | number | boolean | null;
|
|
5
|
-
export type JsonArray = Json[];
|
|
6
|
-
export type JsonObject = {
|
|
7
|
-
[key: string]: Json;
|
|
8
|
-
};
|
|
9
|
-
export type Json = JsonPrimitive | JsonArray | JsonObject;
|
|
10
|
-
export type JsonHandler = (rowIndex: number, json: JsonObject) => void;
|
|
11
|
-
export declare const NDJsonReader: (startIndex: number, jsonHandler: JsonHandler, onEnd: () => void) => (response: Response) => void;
|
|
12
|
-
export declare const jsonToDataSourceRow: (rowIndex: number, json: JsonObject, columnMap: ColumnMap) => DataSourceRow;
|
|
13
|
-
export declare const sortToQueryString: (sort: VuuSort) => string;
|
|
14
|
-
export declare const filterToQueryString: (vuuFilter: VuuFilter) => string;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { VuuRange, VuuRow } from "@vuu-ui/vuu-protocol-types";
|
|
2
|
-
import { WindowRange } from "@vuu-ui/vuu-utils";
|
|
3
|
-
type RangeTuple = [boolean, readonly VuuRow[]];
|
|
4
|
-
export declare class ArrayBackedMovingWindow {
|
|
5
|
-
#private;
|
|
6
|
-
private bufferSize;
|
|
7
|
-
private internalData;
|
|
8
|
-
private rowsWithinRange;
|
|
9
|
-
clientRange: WindowRange;
|
|
10
|
-
rowCount: number;
|
|
11
|
-
constructor({ from: clientFrom, to: clientTo }: VuuRange, { from, to }: VuuRange, bufferSize: number);
|
|
12
|
-
get range(): WindowRange;
|
|
13
|
-
get hasAllRowsWithinRange(): boolean;
|
|
14
|
-
outOfRange(firstIndex: number, lastIndex: number): true | undefined;
|
|
15
|
-
setRowCount: (rowCount: number) => void;
|
|
16
|
-
setAtIndex(row: VuuRow): boolean;
|
|
17
|
-
getAtIndex(index: number): VuuRow | undefined;
|
|
18
|
-
isWithinRange(index: number): boolean;
|
|
19
|
-
isWithinClientRange(index: number): boolean;
|
|
20
|
-
setClientRange(from: number, to: number): RangeTuple;
|
|
21
|
-
setRange(from: number, to: number): void;
|
|
22
|
-
get data(): VuuRow[];
|
|
23
|
-
private bufferBreakout;
|
|
24
|
-
getData(): VuuRow[];
|
|
25
|
-
clear(): void;
|
|
26
|
-
getCurrentDataRange(): number[];
|
|
27
|
-
}
|
|
28
|
-
export {};
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
export declare const CHANGE_VP_SUCCESS = "CHANGE_VP_SUCCESS";
|
|
2
|
-
export declare const CHANGE_VP_RANGE_SUCCESS = "CHANGE_VP_RANGE_SUCCESS";
|
|
3
|
-
export declare const CLOSE_TREE_NODE = "CLOSE_TREE_NODE";
|
|
4
|
-
export declare const CLOSE_TREE_SUCCESS = "CLOSE_TREE_SUCCESS";
|
|
5
|
-
export declare const CLOSE_TREE_REJECT = "CLOSE_TREE_REJECT";
|
|
6
|
-
export declare const CREATE_VISUAL_LINK = "CREATE_VISUAL_LINK";
|
|
7
|
-
export declare const CREATE_VP = "CREATE_VP";
|
|
8
|
-
export declare const DISABLE_VP = "DISABLE_VP";
|
|
9
|
-
export declare const DISABLE_VP_SUCCESS = "DISABLE_VP_SUCCESS";
|
|
10
|
-
export declare const DISABLE_VP_REJECT = "DISABLE_VP_REJECT";
|
|
11
|
-
export declare const ENABLE_VP = "ENABLE_VP";
|
|
12
|
-
export declare const ENABLE_VP_SUCCESS = "ENABLE_VP_SUCCESS";
|
|
13
|
-
export declare const ENABLE_VP_REJECT = "ENABLE_VP_REJECT";
|
|
14
|
-
export declare const GET_TABLE_META = "GET_TABLE_META";
|
|
15
|
-
export declare const GET_VP_VISUAL_LINKS = "GET_VP_VISUAL_LINKS";
|
|
16
|
-
export declare const GET_VIEW_PORT_MENUS = "GET_VIEW_PORT_MENUS";
|
|
17
|
-
export declare const VIEW_PORT_MENUS_SELECT_RPC = "VIEW_PORT_MENUS_SELECT_RPC";
|
|
18
|
-
export declare const VIEW_PORT_MENU_CELL_RPC = "VIEW_PORT_MENU_CELL_RPC";
|
|
19
|
-
export declare const VIEW_PORT_MENU_TABLE_RPC = "VIEW_PORT_MENU_TABLE_RPC";
|
|
20
|
-
export declare const VIEW_PORT_MENU_ROW_RPC = "VIEW_PORT_MENU_ROW_RPC";
|
|
21
|
-
export declare const VIEW_PORT_MENU_RESP = "VIEW_PORT_MENU_RESP";
|
|
22
|
-
export declare const VIEW_PORT_MENU_REJ = "VIEW_PORT_MENU_REJ";
|
|
23
|
-
export declare const HB = "HB";
|
|
24
|
-
export declare const HB_RESP = "HB_RESP";
|
|
25
|
-
export declare const LOGIN = "LOGIN";
|
|
26
|
-
export declare const OPEN_TREE_NODE = "OPEN_TREE_NODE";
|
|
27
|
-
export declare const OPEN_TREE_SUCCESS = "OPEN_TREE_SUCCESS";
|
|
28
|
-
export declare const OPEN_TREE_REJECT = "OPEN_TREE_REJECT";
|
|
29
|
-
export declare const REMOVE_VP = "REMOVE_VP";
|
|
30
|
-
export declare const REMOVE_VP_REJECT = "REMOVE_VP_REJECT";
|
|
31
|
-
export declare const RPC_CALL = "RPC_CALL";
|
|
32
|
-
export declare const RPC_RESP = "RPC_RESP";
|
|
33
|
-
export declare const MENU_RPC_RESP = "MENU_RPC_RESP";
|
|
34
|
-
export declare const SET_SELECTION = "SET_SELECTION";
|
|
35
|
-
export declare const SET_SELECTION_SUCCESS = "SET_SELECTION_SUCCESS";
|
|
36
|
-
export declare const TABLE_ROW = "TABLE_ROW";
|
|
37
|
-
export declare const SIZE = "SIZE";
|
|
38
|
-
export declare const UPDATE = "U";
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import type { DataSourceCallbackMessage, ServerProxySubscribeMessage, VuuUIMessageIn, VuuUIMessageOut, VuuUIMessageOutConnect, VuuUIMessageOutSubscribe, VuuUIMessageOutUnsubscribe, WithRequestId } from "@vuu-ui/vuu-data-types";
|
|
2
|
-
import type { VuuRpcMenuRequest, VuuClientMessage, VuuServerMessage, VuuLinkDescriptor, VuuRpcServiceRequest, VuuTable, VuuCreateVisualLink, VuuRemoveVisualLink } from "@vuu-ui/vuu-protocol-types";
|
|
3
|
-
import { WebSocketConnection } from "../WebSocketConnection";
|
|
4
|
-
export type PostMessageToClientCallback = (message: VuuUIMessageIn | DataSourceCallbackMessage) => void;
|
|
5
|
-
export type MessageOptions = {
|
|
6
|
-
module?: string;
|
|
7
|
-
};
|
|
8
|
-
export declare const TEST_setRequestId: (id: number) => number;
|
|
9
|
-
export declare class ServerProxy {
|
|
10
|
-
private connection;
|
|
11
|
-
private postMessageToClient;
|
|
12
|
-
private viewports;
|
|
13
|
-
private mapClientToServerViewport;
|
|
14
|
-
private authToken;
|
|
15
|
-
private user;
|
|
16
|
-
private pendingLogin?;
|
|
17
|
-
private pendingRequests;
|
|
18
|
-
private sessionId?;
|
|
19
|
-
private queuedRequests;
|
|
20
|
-
private cachedTableMetaRequests;
|
|
21
|
-
private cachedTableSchemas;
|
|
22
|
-
private tableList;
|
|
23
|
-
constructor(connection: WebSocketConnection, callback: PostMessageToClientCallback);
|
|
24
|
-
private reconnect;
|
|
25
|
-
login(authToken?: string, user?: string): Promise<string | void>;
|
|
26
|
-
disconnect(): void;
|
|
27
|
-
subscribe(message: ServerProxySubscribeMessage): void;
|
|
28
|
-
/**
|
|
29
|
-
* Currently we only queue range requests, this may change
|
|
30
|
-
*/
|
|
31
|
-
private addRequestToQueue;
|
|
32
|
-
private processQueuedRequests;
|
|
33
|
-
unsubscribe(clientViewportId: string): void;
|
|
34
|
-
private getViewportForClient;
|
|
35
|
-
/**********************************************************************/
|
|
36
|
-
/**********************************************************************/
|
|
37
|
-
private setViewRange;
|
|
38
|
-
private setConfig;
|
|
39
|
-
private setTitle;
|
|
40
|
-
private select;
|
|
41
|
-
private disableViewport;
|
|
42
|
-
private enableViewport;
|
|
43
|
-
private suspendViewport;
|
|
44
|
-
private resumeViewport;
|
|
45
|
-
private openTreeNode;
|
|
46
|
-
private closeTreeNode;
|
|
47
|
-
private createLink;
|
|
48
|
-
private removeLink;
|
|
49
|
-
private updateTitleOnVisualLinks;
|
|
50
|
-
private removeViewportFromVisualLinks;
|
|
51
|
-
private menuRpcCall;
|
|
52
|
-
private viewportRpcCall;
|
|
53
|
-
private rpcCall;
|
|
54
|
-
handleMessageFromClient(message: Exclude<VuuUIMessageOut, VuuUIMessageOutConnect | VuuUIMessageOutSubscribe | VuuUIMessageOutUnsubscribe> | WithRequestId<VuuRpcServiceRequest> | WithRequestId<VuuRpcMenuRequest> | WithRequestId<VuuCreateVisualLink> | WithRequestId<VuuRemoveVisualLink>): void;
|
|
55
|
-
private getTableMeta;
|
|
56
|
-
private awaitResponseToMessage;
|
|
57
|
-
sendIfReady(message: VuuClientMessage["body"], requestId: string, isReady?: boolean): boolean;
|
|
58
|
-
sendMessageToServer(body: VuuClientMessage["body"], requestId?: string, options?: MessageOptions): void;
|
|
59
|
-
handleMessageFromServer(message: VuuServerMessage): void;
|
|
60
|
-
private cacheTableMeta;
|
|
61
|
-
isTableOpen(table?: VuuTable): true | undefined;
|
|
62
|
-
getActiveLinks(linkDescriptors: VuuLinkDescriptor[]): VuuLinkDescriptor[];
|
|
63
|
-
processUpdates(): void;
|
|
64
|
-
}
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import { DataSourceFilter, DataSourceRow, DataSourceCallbackMessage, DataSourceDebounceRequest, DataSourceDisabledMessage, DataSourceEnabledMessage, DataSourceMenusMessage, DataSourceSetConfigMessage, 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, VuuViewportRangeRequest, LinkDescriptorWithLabel, VuuViewportCreateResponse, VuuMenu, VuuRange, VuuRow, VuuTable } from "@vuu-ui/vuu-protocol-types";
|
|
3
|
-
export type ViewportStatus = "" | "subscribing" | "resubscribing" | "subscribed";
|
|
4
|
-
interface Disable {
|
|
5
|
-
type: "disable";
|
|
6
|
-
}
|
|
7
|
-
interface Enable {
|
|
8
|
-
type: "enable";
|
|
9
|
-
}
|
|
10
|
-
interface ChangeViewportRange {
|
|
11
|
-
type: "CHANGE_VP_RANGE";
|
|
12
|
-
}
|
|
13
|
-
interface ViewportFilter {
|
|
14
|
-
data: DataSourceFilter;
|
|
15
|
-
type: "filter";
|
|
16
|
-
}
|
|
17
|
-
interface ConfigOperation {
|
|
18
|
-
data: WithFullConfig;
|
|
19
|
-
type: "config";
|
|
20
|
-
}
|
|
21
|
-
interface SelectionOperation {
|
|
22
|
-
data: Selection;
|
|
23
|
-
type: "selection";
|
|
24
|
-
}
|
|
25
|
-
type AsyncOperationWithData = ConfigOperation | ViewportFilter | SelectionOperation;
|
|
26
|
-
type AsyncOperation = AsyncOperationWithData | ChangeViewportRange | Disable | Enable | VuuCreateVisualLink | VuuRemoveVisualLink;
|
|
27
|
-
type RangeRequestTuple = [
|
|
28
|
-
VuuViewportRangeRequest | null,
|
|
29
|
-
DataSourceRow[]?,
|
|
30
|
-
DataSourceDebounceRequest?
|
|
31
|
-
];
|
|
32
|
-
type LinkedParent = {
|
|
33
|
-
colName: string;
|
|
34
|
-
parentViewportId: string;
|
|
35
|
-
parentColName: string;
|
|
36
|
-
};
|
|
37
|
-
export declare const NO_DATA_UPDATE: Readonly<[undefined, undefined]>;
|
|
38
|
-
export declare class Viewport {
|
|
39
|
-
#private;
|
|
40
|
-
private aggregations;
|
|
41
|
-
private batchMode;
|
|
42
|
-
private bufferSize;
|
|
43
|
-
private columns;
|
|
44
|
-
private dataWindow;
|
|
45
|
-
private filter;
|
|
46
|
-
private groupBy;
|
|
47
|
-
private sort;
|
|
48
|
-
private hasUpdates;
|
|
49
|
-
private pendingUpdates;
|
|
50
|
-
private keys;
|
|
51
|
-
private pendingLinkedParent?;
|
|
52
|
-
private pendingOperations;
|
|
53
|
-
private pendingRangeRequests;
|
|
54
|
-
private postMessageToClient;
|
|
55
|
-
private rowCountChanged;
|
|
56
|
-
private selectedRows;
|
|
57
|
-
private lastUpdateStatus;
|
|
58
|
-
private updateThrottleTimer;
|
|
59
|
-
private lastRowsReturnedToClient;
|
|
60
|
-
private rangeMonitor;
|
|
61
|
-
clientViewportId: string;
|
|
62
|
-
disabled: boolean;
|
|
63
|
-
isTree: boolean;
|
|
64
|
-
links?: LinkDescriptorWithLabel[];
|
|
65
|
-
linkedParent?: LinkedParent;
|
|
66
|
-
serverViewportId?: string;
|
|
67
|
-
suspended: boolean;
|
|
68
|
-
suspendTimer: number | null;
|
|
69
|
-
table: VuuTable;
|
|
70
|
-
title: string | undefined;
|
|
71
|
-
constructor({ aggregations, bufferSize, columns, filterSpec: filter, groupBy, table, range, sort, title, viewport, visualLink, }: ServerProxySubscribeMessage,
|
|
72
|
-
/**
|
|
73
|
-
* Viewport is given access to postMessageToClient in the event that it needs
|
|
74
|
-
* to send 'out of band' messageg, e.g cached SIZE messages when a timer
|
|
75
|
-
* expires
|
|
76
|
-
*/
|
|
77
|
-
postMessageToClient: (message: DataSourceCallbackMessage) => void);
|
|
78
|
-
private setLastSizeOnlyUpdateSize;
|
|
79
|
-
private setLastUpdate;
|
|
80
|
-
get hasUpdatesToProcess(): boolean;
|
|
81
|
-
get size(): number;
|
|
82
|
-
get clientRange(): VuuRange;
|
|
83
|
-
get status(): ViewportStatus;
|
|
84
|
-
set status(status: ViewportStatus);
|
|
85
|
-
subscribe(): VuuViewportCreateRequest;
|
|
86
|
-
handleSubscribed({ viewPortId, aggregations, columns, filterSpec: filter, range, sort, groupBy, table, }: VuuViewportCreateResponse, baseTableSchema: TableSchema): DataSourceSubscribedMessage;
|
|
87
|
-
awaitOperation(requestId: string, msg: AsyncOperation): void;
|
|
88
|
-
completeOperation(requestId: string, ...params: unknown[]): DataSourceSetConfigMessage | DataSourceDisabledMessage | DataSourceEnabledMessage | WithRequestId<DataSourceVisualLinkCreatedMessage> | WithRequestId<DataSourceVisualLinkRemovedMessage> | undefined;
|
|
89
|
-
rangeRequest(requestId: string, range: VuuRange): RangeRequestTuple;
|
|
90
|
-
setLinks(links: LinkDescriptorWithLabel[]): [DataSourceVisualLinksMessage, LinkDescriptorWithLabel | undefined];
|
|
91
|
-
setMenu(menu: VuuMenu): DataSourceMenusMessage;
|
|
92
|
-
openTreeNode(requestId: string, message: VuuUIMessageOutOpenTreeNode): ClientToServerOpenTreeNode;
|
|
93
|
-
closeTreeNode(requestId: string, message: VuuUIMessageOutCloseTreeNode): ClientToServerCloseTreeNode;
|
|
94
|
-
createLink(requestId: string, vuuCreateVisualLink: VuuCreateVisualLink): VuuCreateVisualLink;
|
|
95
|
-
removeLink(requestId: string): VuuRemoveVisualLink;
|
|
96
|
-
suspend(): void;
|
|
97
|
-
resume(): [number, DataSourceRow[]];
|
|
98
|
-
currentData(): DataSourceRow[];
|
|
99
|
-
enable(requestId: string): ClientToServerEnable;
|
|
100
|
-
disable(requestId: string): ClientToServerDisable;
|
|
101
|
-
setConfig(requestId: string, config: WithFullConfig): VuuViewportChangeRequest;
|
|
102
|
-
selectRequest(requestId: string, selected: Selection): ClientToServerSelection;
|
|
103
|
-
private removePendingRangeRequest;
|
|
104
|
-
private rangeRequestAlreadyPending;
|
|
105
|
-
updateRows(rows: VuuRow[]): void;
|
|
106
|
-
private getKeyForRowAtIndex;
|
|
107
|
-
getClientRows(): Readonly<[
|
|
108
|
-
DataSourceRow[] | undefined,
|
|
109
|
-
DataUpdateMode | undefined
|
|
110
|
-
]>;
|
|
111
|
-
private sendThrottledSizeMessage;
|
|
112
|
-
private shouldThrottleMessage;
|
|
113
|
-
private throttleMessage;
|
|
114
|
-
getNewRowCount: () => number | undefined;
|
|
115
|
-
createRequest(params: Partial<Omit<VuuViewportChangeRequest, "type" | "viewPortId">>, overWrite?: boolean): VuuViewportChangeRequest;
|
|
116
|
-
}
|
|
117
|
-
export {};
|
package/types/worker.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|