@qlik/api 1.30.0 → 1.32.0
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/api-keys.d.ts +2 -2
- package/api-keys.js +2 -2
- package/apps.d.ts +4 -2
- package/apps.js +2 -2
- package/assistants.d.ts +1301 -0
- package/assistants.js +273 -0
- package/audits.d.ts +2 -2
- package/audits.js +2 -2
- package/{auth-types-PkN9CAF_.d.ts → auth-types-DqfMuSRX.d.ts} +1 -0
- package/auth.d.ts +27 -3
- package/auth.js +8 -4
- package/automation-connections.d.ts +366 -0
- package/automation-connections.js +91 -0
- package/automations.d.ts +2 -2
- package/automations.js +2 -2
- package/automl-deployments.d.ts +97 -0
- package/automl-deployments.js +27 -0
- package/automl-predictions.d.ts +214 -0
- package/automl-predictions.js +72 -0
- package/brands.d.ts +2 -2
- package/brands.js +2 -2
- package/chunks/{JIX6RMFP.js → 6ZONDHRN.js} +1 -1
- package/chunks/ETNHFALU.js +61 -0
- package/chunks/{G6QUM5WQ.js → FKDGGR2O.js} +137 -45
- package/chunks/{TXC5XORK.js → LTNGXTXG.js} +3 -3
- package/chunks/{OTTC4QSX.js → LY7RP2HA.js} +7 -3
- package/chunks/{FKCZFVJL.js → M64RLKVG.js} +2074 -12
- package/chunks/{F5UDCCRD.js → PLVPW5IR.js} +1 -1
- package/chunks/{QK4TMJ64.js → RCLKKVYB.js} +11 -1
- package/chunks/{QWQLGDMI.js → UZTIZ4H5.js} +392 -372
- package/chunks/{PTDXR7AY.js → VVD2DPKQ.js} +2 -2
- package/chunks/{IQBP2PKS.js → YTT2FEVE.js} +1 -1
- package/collections.d.ts +3 -3
- package/collections.js +2 -2
- package/conditions.d.ts +662 -0
- package/conditions.js +113 -0
- package/consumption.d.ts +182 -0
- package/consumption.js +24 -0
- package/csp-origins.d.ts +2 -2
- package/csp-origins.js +2 -2
- package/csrf-token.d.ts +62 -0
- package/csrf-token.js +23 -0
- package/data-alerts.d.ts +1004 -0
- package/data-alerts.js +155 -0
- package/data-assets.d.ts +2 -2
- package/data-assets.js +2 -2
- package/data-connections.d.ts +7 -7
- package/data-connections.js +2 -2
- package/data-credentials.d.ts +2 -2
- package/data-credentials.js +2 -2
- package/data-files.d.ts +2 -2
- package/data-files.js +2 -2
- package/data-qualities.d.ts +175 -0
- package/data-qualities.js +44 -0
- package/data-sets.d.ts +424 -0
- package/data-sets.js +75 -0
- package/data-sources.d.ts +268 -0
- package/data-sources.js +39 -0
- package/data-stores.d.ts +537 -0
- package/data-stores.js +108 -0
- package/dcaas.d.ts +192 -0
- package/dcaas.js +39 -0
- package/di-projects.d.ts +673 -0
- package/di-projects.js +164 -0
- package/docs/authentication.md +47 -0
- package/encryption.d.ts +370 -0
- package/encryption.js +98 -0
- package/extensions.d.ts +2 -2
- package/extensions.js +2 -2
- package/glossaries.d.ts +2 -2
- package/glossaries.js +2 -2
- package/groups.d.ts +5 -4
- package/groups.js +2 -2
- package/identity-providers.d.ts +2 -2
- package/identity-providers.js +2 -2
- package/index.d.ts +110 -4
- package/index.js +556 -4
- package/interceptors.d.ts +2 -2
- package/{invoke-fetch-types-BXn-uSF5.d.ts → invoke-fetch-types-Cq7bjkqn.d.ts} +10 -2
- package/items.d.ts +3 -3
- package/items.js +2 -2
- package/knowledgebases.d.ts +890 -0
- package/knowledgebases.js +169 -0
- package/licenses.d.ts +6 -3
- package/licenses.js +2 -2
- package/lineage-graphs.d.ts +712 -0
- package/lineage-graphs.js +92 -0
- package/ml.d.ts +2628 -0
- package/ml.js +384 -0
- package/notes.d.ts +110 -0
- package/notes.js +31 -0
- package/notifications.d.ts +98 -0
- package/notifications.js +24 -0
- package/oauth-clients.d.ts +7 -2
- package/oauth-clients.js +2 -2
- package/oauth-tokens.d.ts +126 -0
- package/oauth-tokens.js +31 -0
- package/package.json +29 -2
- package/qix.d.ts +421 -26
- package/qix.js +2 -2
- package/questions.d.ts +364 -0
- package/questions.js +34 -0
- package/quotas.d.ts +2 -2
- package/quotas.js +2 -2
- package/reload-tasks.d.ts +4 -2
- package/reload-tasks.js +2 -2
- package/reloads.d.ts +4 -2
- package/reloads.js +2 -2
- package/report-templates.d.ts +287 -0
- package/report-templates.js +80 -0
- package/reports.d.ts +2 -2
- package/reports.js +2 -2
- package/roles.d.ts +2 -2
- package/roles.js +2 -2
- package/sharing-tasks.d.ts +952 -0
- package/sharing-tasks.js +105 -0
- package/spaces.d.ts +3 -7
- package/spaces.js +2 -2
- package/tasks.d.ts +564 -0
- package/tasks.js +106 -0
- package/temp-contents.d.ts +2 -2
- package/temp-contents.js +2 -2
- package/tenants.d.ts +2 -2
- package/tenants.js +2 -2
- package/themes.d.ts +2 -2
- package/themes.js +2 -2
- package/transports.d.ts +2 -2
- package/transports.js +2 -2
- package/ui-config.d.ts +274 -0
- package/ui-config.js +77 -0
- package/users.d.ts +2 -2
- package/users.js +2 -2
- package/web-integrations.d.ts +2 -2
- package/web-integrations.js +2 -2
- package/web-notifications.d.ts +2 -2
- package/web-notifications.js +2 -2
- package/webhooks.d.ts +2 -2
- package/webhooks.js +2 -2
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
|
+
getHumanReadableSocketClosedErrorMessage
|
|
3
|
+
} from "./ETNHFALU.js";
|
|
4
|
+
import {
|
|
5
|
+
exposeInternalApiOnWindow,
|
|
2
6
|
generateRandomString,
|
|
3
7
|
getRestCallAuthParams,
|
|
4
8
|
getWebSocketAuthParams,
|
|
9
|
+
handleAuthenticationError,
|
|
10
|
+
isWindows,
|
|
5
11
|
toValidWebsocketLocationUrl
|
|
6
|
-
} from "./
|
|
12
|
+
} from "./FKDGGR2O.js";
|
|
7
13
|
import "./3RGGGGAR.js";
|
|
8
14
|
import {
|
|
9
15
|
isNode
|
|
10
16
|
} from "./2ZQ3ZX7F.js";
|
|
11
17
|
|
|
12
|
-
// src/qix/session/enigma-session.ts
|
|
13
|
-
import enigma from "enigma.js";
|
|
14
|
-
|
|
15
18
|
// src/qix/session/schema/engine-api.js
|
|
16
19
|
var engine_api_default = {
|
|
17
20
|
structs: {
|
|
@@ -8575,6 +8578,9 @@ var base_default = {
|
|
|
8575
8578
|
types: ["Doc", "GenericObject", "GenericDimension", "GenericMeasure", "GenericBookmark", "GenericVariable", "Field"],
|
|
8576
8579
|
init(args) {
|
|
8577
8580
|
const { api } = args;
|
|
8581
|
+
if (api.Promise) {
|
|
8582
|
+
return;
|
|
8583
|
+
}
|
|
8578
8584
|
if (api.getAppLayout) {
|
|
8579
8585
|
api.session.app = api;
|
|
8580
8586
|
}
|
|
@@ -8602,9 +8608,13 @@ function createGetMethod(cacheKey) {
|
|
|
8602
8608
|
return api.migrate.object(api).then(() => api);
|
|
8603
8609
|
}
|
|
8604
8610
|
return api;
|
|
8605
|
-
}).catch(() => {
|
|
8611
|
+
}).catch((err) => {
|
|
8606
8612
|
delete apiCache[id];
|
|
8607
|
-
return Promise.reject({
|
|
8613
|
+
return Promise.reject({
|
|
8614
|
+
code: engine_enums_default.NxLocalizedErrorCode.LOCERR_GENERIC_NOT_FOUND,
|
|
8615
|
+
message: "Object not found",
|
|
8616
|
+
error: { code: engine_enums_default.NxLocalizedErrorCode.LOCERR_GENERIC_NOT_FOUND }
|
|
8617
|
+
});
|
|
8608
8618
|
});
|
|
8609
8619
|
apiCache[id] = promise;
|
|
8610
8620
|
return promise;
|
|
@@ -9209,16 +9219,16 @@ var state_default = {
|
|
|
9209
9219
|
self.setState(RPCStates.VALIDATING);
|
|
9210
9220
|
}
|
|
9211
9221
|
if (self.ongoingRequests[CACHE_KEY]) {
|
|
9212
|
-
const
|
|
9222
|
+
const ongoingRequests2 = self.ongoingRequests[CACHE_KEY];
|
|
9213
9223
|
if (pure) {
|
|
9214
|
-
return
|
|
9224
|
+
return ongoingRequests2.then(() => {
|
|
9215
9225
|
if (!self.pureLayout.permissions) {
|
|
9216
9226
|
self.pureLayout.permissions = self.layout.permissions;
|
|
9217
9227
|
}
|
|
9218
9228
|
return self.pureLayout;
|
|
9219
9229
|
});
|
|
9220
9230
|
}
|
|
9221
|
-
return
|
|
9231
|
+
return ongoingRequests2;
|
|
9222
9232
|
}
|
|
9223
9233
|
const request = _getLayout().then((layout) => {
|
|
9224
9234
|
if (!self.isValid) {
|
|
@@ -10380,8 +10390,9 @@ async function createEnigmaSession({
|
|
|
10380
10390
|
/^http/,
|
|
10381
10391
|
"ws"
|
|
10382
10392
|
);
|
|
10393
|
+
const unitTestCreateWebSocket = hostConfig?.createWebSocket;
|
|
10383
10394
|
let createSocketBuilder;
|
|
10384
|
-
if (isNodeEnvironment) {
|
|
10395
|
+
if (isNodeEnvironment && !unitTestCreateWebSocket) {
|
|
10385
10396
|
const WS = (await import("ws")).default;
|
|
10386
10397
|
createSocketBuilder = async () => {
|
|
10387
10398
|
let url = baseUrl;
|
|
@@ -10400,9 +10411,17 @@ async function createEnigmaSession({
|
|
|
10400
10411
|
Object.entries(queryParams).forEach(([key, value]) => {
|
|
10401
10412
|
url = `${url}&${key}=${value}`;
|
|
10402
10413
|
});
|
|
10403
|
-
return (socketUrl) =>
|
|
10414
|
+
return (socketUrl) => {
|
|
10415
|
+
const socket = unitTestCreateWebSocket ? unitTestCreateWebSocket(url) : new WebSocket(url);
|
|
10416
|
+
exposeInternalApiOnWindow("closeLastWebSocket", (code) => {
|
|
10417
|
+
console.log("Closing websocket with code", code, socket);
|
|
10418
|
+
socket.close(code);
|
|
10419
|
+
});
|
|
10420
|
+
return socket;
|
|
10421
|
+
};
|
|
10404
10422
|
};
|
|
10405
10423
|
}
|
|
10424
|
+
const { default: enigma } = await import("enigma.js");
|
|
10406
10425
|
const session = enigma.create({
|
|
10407
10426
|
schema: engine_api_default,
|
|
10408
10427
|
mixins: mixins5,
|
|
@@ -10424,6 +10443,2049 @@ async function createEnigmaSession({
|
|
|
10424
10443
|
session.resume = resume;
|
|
10425
10444
|
return session;
|
|
10426
10445
|
}
|
|
10446
|
+
|
|
10447
|
+
// src/qix/session/phoenix/logger.ts
|
|
10448
|
+
var ongoingRequests = /* @__PURE__ */ new Set();
|
|
10449
|
+
var requestDepths = /* @__PURE__ */ new Map();
|
|
10450
|
+
var startIntent = 0;
|
|
10451
|
+
var baseIndent = " ";
|
|
10452
|
+
var logEnabled = false;
|
|
10453
|
+
try {
|
|
10454
|
+
logEnabled = globalThis.qlikQixWebSocketLogEnabled || localStorage?.getItem("qlik-qix-websocket-log") === "true";
|
|
10455
|
+
} catch {
|
|
10456
|
+
}
|
|
10457
|
+
function logRequest(handleOrObject, websocketRequest, request) {
|
|
10458
|
+
if (logEnabled) {
|
|
10459
|
+
const indent = startIndent(websocketRequest);
|
|
10460
|
+
const preThing = `${indent} ===> ${websocketRequest.id} call `;
|
|
10461
|
+
console.log(`${preThing}${toLogName(handleOrObject)}.${request.method}`, ...formatParams(request.params));
|
|
10462
|
+
}
|
|
10463
|
+
}
|
|
10464
|
+
function logResponse(handleOrObject, websocketRequest, sendResponse) {
|
|
10465
|
+
if (logEnabled) {
|
|
10466
|
+
const indent = endIndent(websocketRequest);
|
|
10467
|
+
if (sendResponse?.change) {
|
|
10468
|
+
console.log(`${indent} <--- ${websocketRequest.id} Changed: ${sendResponse.change.join(", ")}`);
|
|
10469
|
+
}
|
|
10470
|
+
if (sendResponse?.close) {
|
|
10471
|
+
console.log(`${indent} <--- ${websocketRequest.id} Closed: ${sendResponse.close.join(", ")}`);
|
|
10472
|
+
}
|
|
10473
|
+
const preThing = `${indent} <=== ${websocketRequest.id} return`;
|
|
10474
|
+
if (sendResponse.error) {
|
|
10475
|
+
console.log(preThing, JSON.stringify(sendResponse.error));
|
|
10476
|
+
} else {
|
|
10477
|
+
console.log(preThing, sendResponse.result);
|
|
10478
|
+
}
|
|
10479
|
+
}
|
|
10480
|
+
}
|
|
10481
|
+
function logJsonRpcChannelError(handleOrObject, websocketRequest, error) {
|
|
10482
|
+
if (logEnabled) {
|
|
10483
|
+
const indent = endIndent(websocketRequest);
|
|
10484
|
+
const preThing = `${indent} <=== ${websocketRequest.id} throw`;
|
|
10485
|
+
console.log(preThing, JSON.stringify(error));
|
|
10486
|
+
}
|
|
10487
|
+
}
|
|
10488
|
+
function logEvent(message, ...optionalParams) {
|
|
10489
|
+
if (logEnabled) {
|
|
10490
|
+
console.log("QIX", message, ...optionalParams);
|
|
10491
|
+
}
|
|
10492
|
+
}
|
|
10493
|
+
function startIndent(websocketRequest) {
|
|
10494
|
+
ongoingRequests.add(websocketRequest.id);
|
|
10495
|
+
requestDepths.set(websocketRequest.id, ongoingRequests.size);
|
|
10496
|
+
const indent = baseIndent.repeat(startIntent + ongoingRequests.size);
|
|
10497
|
+
return indent;
|
|
10498
|
+
}
|
|
10499
|
+
function endIndent(websocketRequest) {
|
|
10500
|
+
const indent = baseIndent.repeat(startIntent + (requestDepths.get(websocketRequest.id) || 0));
|
|
10501
|
+
ongoingRequests.delete(websocketRequest.id);
|
|
10502
|
+
requestDepths.delete(websocketRequest.id);
|
|
10503
|
+
return indent;
|
|
10504
|
+
}
|
|
10505
|
+
function toLogName(handleOrObject) {
|
|
10506
|
+
if (handleOrObject === 1) {
|
|
10507
|
+
return "Doc";
|
|
10508
|
+
} else if (handleOrObject === -1) {
|
|
10509
|
+
return "Global";
|
|
10510
|
+
} else if (typeof handleOrObject === "undefined") {
|
|
10511
|
+
return "(undefined handle)";
|
|
10512
|
+
} else if (typeof handleOrObject === "object") {
|
|
10513
|
+
const obj = handleOrObject;
|
|
10514
|
+
if (!obj.id) {
|
|
10515
|
+
const params = obj.respawnInfo.creatingRequest?.params;
|
|
10516
|
+
if (Array.isArray(params)) {
|
|
10517
|
+
return params?.filter((arg) => typeof arg === "string").join("/");
|
|
10518
|
+
}
|
|
10519
|
+
}
|
|
10520
|
+
return `${obj.id}/${obj.getHandle()}`;
|
|
10521
|
+
} else {
|
|
10522
|
+
return handleOrObject;
|
|
10523
|
+
}
|
|
10524
|
+
}
|
|
10525
|
+
function formatParams(params) {
|
|
10526
|
+
if (Array.isArray(params)) {
|
|
10527
|
+
const result = ["("];
|
|
10528
|
+
for (let i = 0; i < params.length; i++) {
|
|
10529
|
+
result.push(params[i]);
|
|
10530
|
+
if (i < params.length - 1) {
|
|
10531
|
+
result.push(",");
|
|
10532
|
+
}
|
|
10533
|
+
}
|
|
10534
|
+
result.push(")");
|
|
10535
|
+
return result;
|
|
10536
|
+
} else {
|
|
10537
|
+
return [params];
|
|
10538
|
+
}
|
|
10539
|
+
}
|
|
10540
|
+
|
|
10541
|
+
// src/qix/session/phoenix/interest-monitor.ts
|
|
10542
|
+
function createInterestMonitor() {
|
|
10543
|
+
let activity = createPromiseAndResolveFunc();
|
|
10544
|
+
let listening = false;
|
|
10545
|
+
let onUserActivityDetectedCallback;
|
|
10546
|
+
function signalInterest() {
|
|
10547
|
+
stopListeningForActivity();
|
|
10548
|
+
logEvent("Someone is interested in this");
|
|
10549
|
+
onUserActivityDetectedCallback?.();
|
|
10550
|
+
activity.resolve();
|
|
10551
|
+
}
|
|
10552
|
+
function waitUntilSomeoneIsInterestedInThis() {
|
|
10553
|
+
logEvent("Waiting for someone to be interested in this");
|
|
10554
|
+
startListeningForActivity();
|
|
10555
|
+
const result = activity.promise;
|
|
10556
|
+
activity = createPromiseAndResolveFunc();
|
|
10557
|
+
return result;
|
|
10558
|
+
}
|
|
10559
|
+
function resetAnyInterestSignalledBeforeNow() {
|
|
10560
|
+
logEvent("stop waiting for someone to be interested in this");
|
|
10561
|
+
stopListeningForActivity();
|
|
10562
|
+
activity = createPromiseAndResolveFunc();
|
|
10563
|
+
}
|
|
10564
|
+
function onUserActivityDetected(activityCallback) {
|
|
10565
|
+
onUserActivityDetectedCallback = activityCallback;
|
|
10566
|
+
}
|
|
10567
|
+
function mouseListener() {
|
|
10568
|
+
signalInterest();
|
|
10569
|
+
}
|
|
10570
|
+
function visibilityChangeListener() {
|
|
10571
|
+
if (globalThis.document?.visibilityState === "visible") {
|
|
10572
|
+
logEvent("Document is visible");
|
|
10573
|
+
signalInterest();
|
|
10574
|
+
}
|
|
10575
|
+
}
|
|
10576
|
+
function focusListener() {
|
|
10577
|
+
logEvent("Document has focus");
|
|
10578
|
+
signalInterest();
|
|
10579
|
+
}
|
|
10580
|
+
function startListeningForActivity() {
|
|
10581
|
+
if (!listening) {
|
|
10582
|
+
listening = true;
|
|
10583
|
+
globalThis.window?.document.addEventListener("visibilitychange", visibilityChangeListener);
|
|
10584
|
+
globalThis.window?.addEventListener("focus", focusListener);
|
|
10585
|
+
globalThis.window?.addEventListener("mousemove", mouseListener);
|
|
10586
|
+
}
|
|
10587
|
+
}
|
|
10588
|
+
function stopListeningForActivity() {
|
|
10589
|
+
if (listening) {
|
|
10590
|
+
listening = false;
|
|
10591
|
+
globalThis.window?.document.removeEventListener("visibilitychange", visibilityChangeListener);
|
|
10592
|
+
globalThis.window?.removeEventListener("focus", focusListener);
|
|
10593
|
+
globalThis.window?.removeEventListener("mousemove", mouseListener);
|
|
10594
|
+
}
|
|
10595
|
+
}
|
|
10596
|
+
const api = {
|
|
10597
|
+
startListeningForActivity,
|
|
10598
|
+
stopListeningForActivity,
|
|
10599
|
+
waitUntilSomeoneIsInterestedInThis,
|
|
10600
|
+
resetAnyInterestSignalledBeforeNow,
|
|
10601
|
+
onUserActivityDetected,
|
|
10602
|
+
signalInterest
|
|
10603
|
+
};
|
|
10604
|
+
return api;
|
|
10605
|
+
}
|
|
10606
|
+
function createPromiseAndResolveFunc() {
|
|
10607
|
+
let resolve = () => {
|
|
10608
|
+
};
|
|
10609
|
+
const promise = new Promise((res) => {
|
|
10610
|
+
resolve = res;
|
|
10611
|
+
});
|
|
10612
|
+
return { promise, resolve };
|
|
10613
|
+
}
|
|
10614
|
+
|
|
10615
|
+
// src/qix/session/phoenix/rpc-object-ref.ts
|
|
10616
|
+
function normalizeObjectRef(response) {
|
|
10617
|
+
if (response.qHandle) {
|
|
10618
|
+
return {
|
|
10619
|
+
handle: response.qHandle,
|
|
10620
|
+
type: response.qType,
|
|
10621
|
+
id: response.qGenericId,
|
|
10622
|
+
genericType: response.qGenericType
|
|
10623
|
+
};
|
|
10624
|
+
} else {
|
|
10625
|
+
return {
|
|
10626
|
+
handle: response.handle,
|
|
10627
|
+
type: response.type,
|
|
10628
|
+
id: response.id,
|
|
10629
|
+
genericType: response.genericType
|
|
10630
|
+
};
|
|
10631
|
+
}
|
|
10632
|
+
}
|
|
10633
|
+
function isQixObjectRef(ref) {
|
|
10634
|
+
return typeof ref === "object" && ref.qHandle && ref.qType;
|
|
10635
|
+
}
|
|
10636
|
+
function getHandleOfRef(response) {
|
|
10637
|
+
return response.qHandle ?? response.handle;
|
|
10638
|
+
}
|
|
10639
|
+
|
|
10640
|
+
// src/qix/session/phoenix/phoenix-session-state.ts
|
|
10641
|
+
function createPhoenixSessionState({
|
|
10642
|
+
doc,
|
|
10643
|
+
global,
|
|
10644
|
+
executedAppActions
|
|
10645
|
+
}) {
|
|
10646
|
+
const objects = {};
|
|
10647
|
+
return {
|
|
10648
|
+
getObjects() {
|
|
10649
|
+
return objects;
|
|
10650
|
+
},
|
|
10651
|
+
getObject(ref) {
|
|
10652
|
+
if (typeof ref === "object") {
|
|
10653
|
+
const handle = getHandleOfRef(ref);
|
|
10654
|
+
if (handle === global.getHandle()) {
|
|
10655
|
+
return global;
|
|
10656
|
+
}
|
|
10657
|
+
if (handle === doc.getHandle()) {
|
|
10658
|
+
return doc;
|
|
10659
|
+
}
|
|
10660
|
+
if (handle) {
|
|
10661
|
+
return objects[handle];
|
|
10662
|
+
}
|
|
10663
|
+
return void 0;
|
|
10664
|
+
}
|
|
10665
|
+
return objects[ref];
|
|
10666
|
+
},
|
|
10667
|
+
removeObject(handle) {
|
|
10668
|
+
delete objects[handle];
|
|
10669
|
+
},
|
|
10670
|
+
setObject(handle, object) {
|
|
10671
|
+
objects[handle] = object;
|
|
10672
|
+
},
|
|
10673
|
+
getDoc() {
|
|
10674
|
+
return doc;
|
|
10675
|
+
},
|
|
10676
|
+
getGlobal() {
|
|
10677
|
+
return global;
|
|
10678
|
+
},
|
|
10679
|
+
addExecutedInitialAppAction(initialAppAction) {
|
|
10680
|
+
executedAppActions.push(initialAppAction);
|
|
10681
|
+
},
|
|
10682
|
+
isAppActionExecuted(initialAppAction) {
|
|
10683
|
+
return executedAppActions.indexOf(initialAppAction) >= 0;
|
|
10684
|
+
},
|
|
10685
|
+
getExecutedAppActions() {
|
|
10686
|
+
return executedAppActions;
|
|
10687
|
+
}
|
|
10688
|
+
};
|
|
10689
|
+
}
|
|
10690
|
+
|
|
10691
|
+
// src/qix/session/phoenix/json-patch.js
|
|
10692
|
+
import originalExtend from "extend";
|
|
10693
|
+
var extend2 = originalExtend.bind(null, true);
|
|
10694
|
+
var JSONPatch2 = {};
|
|
10695
|
+
var { isArray: isArray2 } = Array;
|
|
10696
|
+
function isObject2(v) {
|
|
10697
|
+
return v != null && !Array.isArray(v) && typeof v === "object";
|
|
10698
|
+
}
|
|
10699
|
+
function isUndef2(v) {
|
|
10700
|
+
return typeof v === "undefined";
|
|
10701
|
+
}
|
|
10702
|
+
function isFunction2(v) {
|
|
10703
|
+
return typeof v === "function";
|
|
10704
|
+
}
|
|
10705
|
+
function generateValue2(val) {
|
|
10706
|
+
if (val) {
|
|
10707
|
+
return extend2({}, { val }).val;
|
|
10708
|
+
}
|
|
10709
|
+
return val;
|
|
10710
|
+
}
|
|
10711
|
+
function isSpecialProperty2(obj, key) {
|
|
10712
|
+
return isFunction2(obj[key]) || key.substring(0, 2) === "$$" || key.substring(0, 1) === "_";
|
|
10713
|
+
}
|
|
10714
|
+
function getParent2(data, str) {
|
|
10715
|
+
const seperator = "/";
|
|
10716
|
+
const parts = str.substring(1).split(seperator).slice(0, -1);
|
|
10717
|
+
let numPart;
|
|
10718
|
+
parts.forEach((part, i) => {
|
|
10719
|
+
if (i === parts.length) {
|
|
10720
|
+
return;
|
|
10721
|
+
}
|
|
10722
|
+
numPart = +part;
|
|
10723
|
+
const newPart = !isNaN(numPart) ? [] : {};
|
|
10724
|
+
data[numPart || part] = isUndef2(data[numPart || part]) ? newPart : data[part];
|
|
10725
|
+
data = data[numPart || part];
|
|
10726
|
+
});
|
|
10727
|
+
return data;
|
|
10728
|
+
}
|
|
10729
|
+
function emptyObject2(obj) {
|
|
10730
|
+
Object.keys(obj).forEach((key) => {
|
|
10731
|
+
const config = Object.getOwnPropertyDescriptor(obj, key);
|
|
10732
|
+
if (config.configurable && !isSpecialProperty2(obj, key)) {
|
|
10733
|
+
delete obj[key];
|
|
10734
|
+
}
|
|
10735
|
+
});
|
|
10736
|
+
}
|
|
10737
|
+
function compare2(a, b) {
|
|
10738
|
+
let isIdentical = true;
|
|
10739
|
+
if (isObject2(a) && isObject2(b)) {
|
|
10740
|
+
if (Object.keys(a).length !== Object.keys(b).length) {
|
|
10741
|
+
return false;
|
|
10742
|
+
}
|
|
10743
|
+
Object.keys(a).forEach((key) => {
|
|
10744
|
+
if (!compare2(a[key], b[key])) {
|
|
10745
|
+
isIdentical = false;
|
|
10746
|
+
}
|
|
10747
|
+
});
|
|
10748
|
+
return isIdentical;
|
|
10749
|
+
}
|
|
10750
|
+
if (isArray2(a) && isArray2(b)) {
|
|
10751
|
+
if (a.length !== b.length) {
|
|
10752
|
+
return false;
|
|
10753
|
+
}
|
|
10754
|
+
for (let i = 0, l = a.length; i < l; i += 1) {
|
|
10755
|
+
if (!compare2(a[i], b[i])) {
|
|
10756
|
+
return false;
|
|
10757
|
+
}
|
|
10758
|
+
}
|
|
10759
|
+
return true;
|
|
10760
|
+
}
|
|
10761
|
+
return a === b;
|
|
10762
|
+
}
|
|
10763
|
+
function patchArray2(original, newA, basePath) {
|
|
10764
|
+
let patches = [];
|
|
10765
|
+
const oldA = original.slice();
|
|
10766
|
+
let tmpIdx = -1;
|
|
10767
|
+
function findIndex(a, id, idx) {
|
|
10768
|
+
if (a[idx] && isUndef2(a[idx].qInfo)) {
|
|
10769
|
+
return null;
|
|
10770
|
+
}
|
|
10771
|
+
if (a[idx] && a[idx].qInfo.qId === id) {
|
|
10772
|
+
return idx;
|
|
10773
|
+
}
|
|
10774
|
+
for (let ii = 0, ll = a.length; ii < ll; ii += 1) {
|
|
10775
|
+
if (a[ii] && a[ii].qInfo.qId === id) {
|
|
10776
|
+
return ii;
|
|
10777
|
+
}
|
|
10778
|
+
}
|
|
10779
|
+
return -1;
|
|
10780
|
+
}
|
|
10781
|
+
if (compare2(newA, oldA)) {
|
|
10782
|
+
return patches;
|
|
10783
|
+
}
|
|
10784
|
+
if (!isUndef2(newA[0]) && isUndef2(newA[0].qInfo)) {
|
|
10785
|
+
patches.push({
|
|
10786
|
+
op: "replace",
|
|
10787
|
+
path: basePath,
|
|
10788
|
+
value: newA
|
|
10789
|
+
});
|
|
10790
|
+
return patches;
|
|
10791
|
+
}
|
|
10792
|
+
for (let i = oldA.length - 1; i >= 0; i -= 1) {
|
|
10793
|
+
tmpIdx = findIndex(newA, oldA[i].qInfo && oldA[i].qInfo.qId, i);
|
|
10794
|
+
if (tmpIdx === -1) {
|
|
10795
|
+
patches.push({
|
|
10796
|
+
op: "remove",
|
|
10797
|
+
path: `${basePath}/${i}`
|
|
10798
|
+
});
|
|
10799
|
+
oldA.splice(i, 1);
|
|
10800
|
+
} else {
|
|
10801
|
+
patches = patches.concat(JSONPatch2.generate(oldA[i], newA[tmpIdx], `${basePath}/${i}`));
|
|
10802
|
+
}
|
|
10803
|
+
}
|
|
10804
|
+
for (let i = 0, l = newA.length; i < l; i += 1) {
|
|
10805
|
+
tmpIdx = findIndex(oldA, newA[i].qInfo && newA[i].qInfo.qId);
|
|
10806
|
+
if (tmpIdx === -1) {
|
|
10807
|
+
patches.push({
|
|
10808
|
+
op: "add",
|
|
10809
|
+
path: `${basePath}/${i}`,
|
|
10810
|
+
value: newA[i]
|
|
10811
|
+
});
|
|
10812
|
+
oldA.splice(i, 0, newA[i]);
|
|
10813
|
+
} else if (tmpIdx !== i) {
|
|
10814
|
+
patches.push({
|
|
10815
|
+
op: "move",
|
|
10816
|
+
path: `${basePath}/${i}`,
|
|
10817
|
+
from: `${basePath}/${tmpIdx}`
|
|
10818
|
+
});
|
|
10819
|
+
oldA.splice(i, 0, oldA.splice(tmpIdx, 1)[0]);
|
|
10820
|
+
}
|
|
10821
|
+
}
|
|
10822
|
+
return patches;
|
|
10823
|
+
}
|
|
10824
|
+
JSONPatch2.generate = function generate(original, newData, basePath) {
|
|
10825
|
+
basePath = basePath || "";
|
|
10826
|
+
let patches = [];
|
|
10827
|
+
Object.keys(newData).forEach((key) => {
|
|
10828
|
+
const val = generateValue2(newData[key]);
|
|
10829
|
+
const oldVal = original[key];
|
|
10830
|
+
const tmpPath = `${basePath}/${key}`;
|
|
10831
|
+
if (compare2(val, oldVal) || isSpecialProperty2(newData, key)) {
|
|
10832
|
+
return;
|
|
10833
|
+
}
|
|
10834
|
+
if (isUndef2(oldVal)) {
|
|
10835
|
+
patches.push({
|
|
10836
|
+
op: "add",
|
|
10837
|
+
path: tmpPath,
|
|
10838
|
+
value: val
|
|
10839
|
+
});
|
|
10840
|
+
} else if (isObject2(val) && isObject2(oldVal)) {
|
|
10841
|
+
patches = patches.concat(JSONPatch2.generate(oldVal, val, tmpPath));
|
|
10842
|
+
} else if (isArray2(val) && isArray2(oldVal)) {
|
|
10843
|
+
patches = patches.concat(patchArray2(oldVal, val, tmpPath));
|
|
10844
|
+
} else {
|
|
10845
|
+
patches.push({
|
|
10846
|
+
op: "replace",
|
|
10847
|
+
path: `${basePath}/${key}`,
|
|
10848
|
+
value: val
|
|
10849
|
+
});
|
|
10850
|
+
}
|
|
10851
|
+
});
|
|
10852
|
+
Object.keys(original).forEach((key) => {
|
|
10853
|
+
if (isUndef2(newData[key]) && !isSpecialProperty2(original, key)) {
|
|
10854
|
+
patches.push({
|
|
10855
|
+
op: "remove",
|
|
10856
|
+
path: `${basePath}/${key}`
|
|
10857
|
+
});
|
|
10858
|
+
}
|
|
10859
|
+
});
|
|
10860
|
+
return patches;
|
|
10861
|
+
};
|
|
10862
|
+
JSONPatch2.apply = function apply(original, patches) {
|
|
10863
|
+
patches.forEach((patch) => {
|
|
10864
|
+
let parent = getParent2(original, patch.path);
|
|
10865
|
+
let key = patch.path.split("/").splice(-1)[0];
|
|
10866
|
+
let target = key && isNaN(+key) ? parent[key] : parent[+key] || parent;
|
|
10867
|
+
const from = patch.from ? patch.from.split("/").splice(-1)[0] : null;
|
|
10868
|
+
if (patch.path === "/") {
|
|
10869
|
+
parent = null;
|
|
10870
|
+
target = original;
|
|
10871
|
+
}
|
|
10872
|
+
if (patch.op === "add" || patch.op === "replace") {
|
|
10873
|
+
if (isArray2(parent)) {
|
|
10874
|
+
if (key === "-") {
|
|
10875
|
+
key = parent.length;
|
|
10876
|
+
}
|
|
10877
|
+
parent.splice(+key, patch.op === "add" ? 0 : 1, patch.value);
|
|
10878
|
+
} else if (isArray2(target) && isArray2(patch.value)) {
|
|
10879
|
+
target.length = 0;
|
|
10880
|
+
const chunkSize = 1e3;
|
|
10881
|
+
for (let i = 0; i < patch.value.length; i += chunkSize) {
|
|
10882
|
+
const chunk = patch.value.slice(i, i + chunkSize);
|
|
10883
|
+
target.push(...chunk);
|
|
10884
|
+
}
|
|
10885
|
+
} else if (isObject2(target) && isObject2(patch.value)) {
|
|
10886
|
+
emptyObject2(target);
|
|
10887
|
+
extend2(target, patch.value);
|
|
10888
|
+
} else if (!parent) {
|
|
10889
|
+
throw new Error("Patchee is not an object we can patch");
|
|
10890
|
+
} else {
|
|
10891
|
+
parent[key] = patch.value;
|
|
10892
|
+
}
|
|
10893
|
+
} else if (patch.op === "move") {
|
|
10894
|
+
const oldParent = getParent2(original, patch.from);
|
|
10895
|
+
if (isArray2(parent)) {
|
|
10896
|
+
parent.splice(+key, 0, oldParent.splice(+from, 1)[0]);
|
|
10897
|
+
} else {
|
|
10898
|
+
parent[key] = oldParent[from];
|
|
10899
|
+
delete oldParent[from];
|
|
10900
|
+
}
|
|
10901
|
+
} else if (patch.op === "remove") {
|
|
10902
|
+
if (isArray2(parent)) {
|
|
10903
|
+
parent.splice(+key, 1);
|
|
10904
|
+
} else {
|
|
10905
|
+
delete parent[key];
|
|
10906
|
+
}
|
|
10907
|
+
}
|
|
10908
|
+
});
|
|
10909
|
+
};
|
|
10910
|
+
JSONPatch2.clone = function clone(obj) {
|
|
10911
|
+
return extend2({}, obj);
|
|
10912
|
+
};
|
|
10913
|
+
JSONPatch2.createPatch = function createPatch(op, val, path) {
|
|
10914
|
+
const patch = {
|
|
10915
|
+
op: op.toLowerCase(),
|
|
10916
|
+
path
|
|
10917
|
+
};
|
|
10918
|
+
if (patch.op === "move") {
|
|
10919
|
+
patch.from = val;
|
|
10920
|
+
} else if (typeof val !== "undefined") {
|
|
10921
|
+
patch.value = val;
|
|
10922
|
+
}
|
|
10923
|
+
return patch;
|
|
10924
|
+
};
|
|
10925
|
+
JSONPatch2.updateObject = function updateObject(original, newData) {
|
|
10926
|
+
if (!Object.keys(original).length) {
|
|
10927
|
+
extend2(original, newData);
|
|
10928
|
+
return;
|
|
10929
|
+
}
|
|
10930
|
+
JSONPatch2.apply(original, JSONPatch2.generate(original, newData));
|
|
10931
|
+
};
|
|
10932
|
+
var json_patch_default2 = JSONPatch2;
|
|
10933
|
+
|
|
10934
|
+
// src/qix/session/phoenix/delta-compression.ts
|
|
10935
|
+
function unwrapDeltas(result, state, handle, method) {
|
|
10936
|
+
const newResult = {};
|
|
10937
|
+
Object.entries(result).forEach(([outKey, patches]) => {
|
|
10938
|
+
if (!Array.isArray(patches)) {
|
|
10939
|
+
throw new Error("Unexpected RPC response, expected array of patches");
|
|
10940
|
+
}
|
|
10941
|
+
let entry = state[handle]?.[method]?.[outKey];
|
|
10942
|
+
if (typeof entry === "undefined") {
|
|
10943
|
+
entry = patches[0] && Array.isArray(patches[0].value) ? [] : {};
|
|
10944
|
+
}
|
|
10945
|
+
if (patches.length) {
|
|
10946
|
+
if (patches[0].path === "/" && typeof patches[0].value !== "object") {
|
|
10947
|
+
entry = patches[0].value;
|
|
10948
|
+
} else {
|
|
10949
|
+
json_patch_default2.apply(entry, patches);
|
|
10950
|
+
}
|
|
10951
|
+
if (!state[handle]) {
|
|
10952
|
+
state[handle] = {};
|
|
10953
|
+
}
|
|
10954
|
+
if (!state[handle][method]) {
|
|
10955
|
+
state[handle][method] = {};
|
|
10956
|
+
}
|
|
10957
|
+
state[handle][method][outKey] = entry;
|
|
10958
|
+
}
|
|
10959
|
+
newResult[outKey] = entry;
|
|
10960
|
+
});
|
|
10961
|
+
return JSON.parse(JSON.stringify(newResult));
|
|
10962
|
+
}
|
|
10963
|
+
|
|
10964
|
+
// src/qix/session/phoenix/protocol-helpers.ts
|
|
10965
|
+
function getDeltaAndReturnEmptyProps(request) {
|
|
10966
|
+
if (request.method === "GetProperties" || request.method === "GetFullPropertyTree") {
|
|
10967
|
+
return {
|
|
10968
|
+
return_empty: true,
|
|
10969
|
+
delta: false
|
|
10970
|
+
// return_empty require delta to be false to work
|
|
10971
|
+
};
|
|
10972
|
+
} else {
|
|
10973
|
+
return {
|
|
10974
|
+
delta: request.outKey !== -1 && request.outKey !== "qSuccess"
|
|
10975
|
+
};
|
|
10976
|
+
}
|
|
10977
|
+
}
|
|
10978
|
+
function extractResult(request, resultObject) {
|
|
10979
|
+
if (typeof resultObject !== "object") {
|
|
10980
|
+
return resultObject;
|
|
10981
|
+
}
|
|
10982
|
+
if (request.method === "CreateSessionApp" || request.method === "CreateSessionAppFromApp") {
|
|
10983
|
+
resultObject.qReturn.qGenericId = resultObject.qSessionAppId || resultObject.qReturn.qGenericId;
|
|
10984
|
+
} else if (request.method === "GetInteract" || request.method === "StoreTempSelectionState" || request.method === "CreateTemporaryBookmark") {
|
|
10985
|
+
delete resultObject.qReturn;
|
|
10986
|
+
}
|
|
10987
|
+
if (typeof resultObject.qReturn !== "undefined") {
|
|
10988
|
+
return resultObject.qReturn;
|
|
10989
|
+
}
|
|
10990
|
+
if (request.outKey !== -1) {
|
|
10991
|
+
return resultObject[request.outKey || "qReturn"];
|
|
10992
|
+
}
|
|
10993
|
+
return resultObject;
|
|
10994
|
+
}
|
|
10995
|
+
function createResolvablePromise() {
|
|
10996
|
+
let resolve;
|
|
10997
|
+
let reject;
|
|
10998
|
+
const promise = new Promise((res, rej) => {
|
|
10999
|
+
resolve = res;
|
|
11000
|
+
reject = rej;
|
|
11001
|
+
});
|
|
11002
|
+
return [promise, resolve, reject];
|
|
11003
|
+
}
|
|
11004
|
+
|
|
11005
|
+
// src/qix/session/phoenix/websocket.ts
|
|
11006
|
+
var forceUniqueSessionForTestPurposes = false;
|
|
11007
|
+
exposeInternalApiOnWindow("makeNextWebsocketGetNewEngineSession", () => {
|
|
11008
|
+
forceUniqueSessionForTestPurposes = true;
|
|
11009
|
+
});
|
|
11010
|
+
var WebSocketError = class extends Error {
|
|
11011
|
+
code;
|
|
11012
|
+
reason;
|
|
11013
|
+
constructor({ code = 0, reason = "" }, { appId, hostConfig }) {
|
|
11014
|
+
super(getHumanReadableSocketClosedErrorMessage({ code, reason }, { appId, hostConfig }));
|
|
11015
|
+
this.code = code;
|
|
11016
|
+
this.reason = reason;
|
|
11017
|
+
}
|
|
11018
|
+
};
|
|
11019
|
+
async function createWebSocket(props, listeners) {
|
|
11020
|
+
try {
|
|
11021
|
+
return await createWebsocketSingleAttempt(props, listeners);
|
|
11022
|
+
} catch (err) {
|
|
11023
|
+
logEvent("Retrying to create websocket", err);
|
|
11024
|
+
const action = await handleAuthenticationError({
|
|
11025
|
+
headers: new Headers(),
|
|
11026
|
+
status: 101,
|
|
11027
|
+
canRetry: true,
|
|
11028
|
+
hostConfig: props.hostConfig
|
|
11029
|
+
});
|
|
11030
|
+
if (action.retry) {
|
|
11031
|
+
return createWebsocketSingleAttempt(props, listeners);
|
|
11032
|
+
}
|
|
11033
|
+
if (action.preventDefault) {
|
|
11034
|
+
return new Promise(() => {
|
|
11035
|
+
});
|
|
11036
|
+
}
|
|
11037
|
+
throw err;
|
|
11038
|
+
}
|
|
11039
|
+
}
|
|
11040
|
+
async function createWebsocketSingleAttempt({ appId, identity, hostConfig, useReloadEngine = false, workloadType, ttlSeconds }, listeners) {
|
|
11041
|
+
const locationUrl = toValidWebsocketLocationUrl(hostConfig);
|
|
11042
|
+
const reloadUri = encodeURIComponent(`${locationUrl}/sense/app/${appId}`);
|
|
11043
|
+
const ttlPart = ttlSeconds !== void 0 && ttlSeconds >= 0 ? `/ttl/${ttlSeconds}` : "";
|
|
11044
|
+
const identityToUse = forceUniqueSessionForTestPurposes ? generateRandomString(16) : identity;
|
|
11045
|
+
if (forceUniqueSessionForTestPurposes) {
|
|
11046
|
+
logEvent("Forcing a new session for testing purposes");
|
|
11047
|
+
forceUniqueSessionForTestPurposes = false;
|
|
11048
|
+
}
|
|
11049
|
+
const identityPart = identityToUse ? `/identity/${identityToUse}` : "";
|
|
11050
|
+
const workloadTypePart = useReloadEngine ? "&workloadType=interactive-reload" : workloadType ? `&workloadType=${workloadType}` : "";
|
|
11051
|
+
let url = `${locationUrl}/app/${appId}${identityPart}${ttlPart}?reloadUri=${reloadUri}${workloadTypePart}`.replace(
|
|
11052
|
+
/^http/,
|
|
11053
|
+
"ws"
|
|
11054
|
+
);
|
|
11055
|
+
const isNodeEnvironment = isNode();
|
|
11056
|
+
const unitTestCreateWebSocket = hostConfig?.createWebSocket;
|
|
11057
|
+
logEvent("Creating websocket", url);
|
|
11058
|
+
let socket;
|
|
11059
|
+
if (isNodeEnvironment && !unitTestCreateWebSocket) {
|
|
11060
|
+
const { headers, queryParams } = await getRestCallAuthParams({ hostConfig, method: "POST" });
|
|
11061
|
+
const WS = (await import("ws")).default;
|
|
11062
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
11063
|
+
url = `${url}&${key}=${value}`;
|
|
11064
|
+
});
|
|
11065
|
+
socket = new WS(url, void 0, {
|
|
11066
|
+
headers
|
|
11067
|
+
});
|
|
11068
|
+
} else {
|
|
11069
|
+
const { queryParams } = await getWebSocketAuthParams({ hostConfig });
|
|
11070
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
11071
|
+
url = `${url}&${key}=${value}`;
|
|
11072
|
+
});
|
|
11073
|
+
socket = unitTestCreateWebSocket ? unitTestCreateWebSocket(url) : new WebSocket(url);
|
|
11074
|
+
exposeInternalApiOnWindow("closeLastWebSocket", (code) => {
|
|
11075
|
+
console.log("Closing websocket with code", code, socket);
|
|
11076
|
+
socket.close(code);
|
|
11077
|
+
});
|
|
11078
|
+
}
|
|
11079
|
+
logEvent("Created websocket", url);
|
|
11080
|
+
const [socketOpenPromise, resolveSocketOpenPromise, rejectSocketOpenPromise] = createResolvablePromise();
|
|
11081
|
+
let opened = false;
|
|
11082
|
+
socket.onopen = () => {
|
|
11083
|
+
socket.onopen = null;
|
|
11084
|
+
socket.onerror = null;
|
|
11085
|
+
logEvent("Websocket opened");
|
|
11086
|
+
opened = true;
|
|
11087
|
+
resolveSocketOpenPromise(socket);
|
|
11088
|
+
};
|
|
11089
|
+
socket.onerror = () => {
|
|
11090
|
+
socket.onopen = null;
|
|
11091
|
+
socket.onerror = null;
|
|
11092
|
+
};
|
|
11093
|
+
socket.onmessage = (message) => {
|
|
11094
|
+
listeners.onMessage(message);
|
|
11095
|
+
};
|
|
11096
|
+
socket.onclose = ({ code, reason }) => {
|
|
11097
|
+
if (!opened) {
|
|
11098
|
+
rejectSocketOpenPromise(new WebSocketError({ code, reason }, { appId, hostConfig }));
|
|
11099
|
+
} else {
|
|
11100
|
+
listeners.onClose({ code, reason });
|
|
11101
|
+
}
|
|
11102
|
+
};
|
|
11103
|
+
return socketOpenPromise;
|
|
11104
|
+
}
|
|
11105
|
+
|
|
11106
|
+
// src/qix/session/phoenix/json-rpc-channel.ts
|
|
11107
|
+
var RPC_CLOSE_NORMAL = 1e3;
|
|
11108
|
+
var RPC_CLOSE_MANUAL_SUSPEND = 4e3;
|
|
11109
|
+
var WebsocketClosedError = class extends Error {
|
|
11110
|
+
};
|
|
11111
|
+
async function createJsonRpcChannel(props, listener) {
|
|
11112
|
+
const { hostConfig } = props;
|
|
11113
|
+
const [connectionInfoPromise, resolveConnectionInfo] = createResolvablePromise();
|
|
11114
|
+
const [authenticationInfoPromise, resolveAuthenticationInfo] = createResolvablePromise();
|
|
11115
|
+
let pendingInvocations = {};
|
|
11116
|
+
let initiator = "network";
|
|
11117
|
+
let closed = false;
|
|
11118
|
+
const socket = await createWebSocket(props, {
|
|
11119
|
+
onMessage: (event) => {
|
|
11120
|
+
const data = JSON.parse(event.data);
|
|
11121
|
+
if (isInvocationResponse(data)) {
|
|
11122
|
+
const pendingInvocation = pendingInvocations[data.id];
|
|
11123
|
+
listener.onMessage(data, pendingInvocation?.handle);
|
|
11124
|
+
pendingInvocation?.resolve(data);
|
|
11125
|
+
} else {
|
|
11126
|
+
listener.onMessage(data, void 0);
|
|
11127
|
+
if (data.method === "OnConnected") {
|
|
11128
|
+
resolveConnectionInfo(data.params?.qSessionState);
|
|
11129
|
+
} else if (data.method === "OnAuthenticationInformation") {
|
|
11130
|
+
if (data.mustAuthenticate) {
|
|
11131
|
+
void handleAuthenticationError({
|
|
11132
|
+
headers: new Headers(),
|
|
11133
|
+
status: 101,
|
|
11134
|
+
canRetry: true,
|
|
11135
|
+
hostConfig
|
|
11136
|
+
}).then(() => {
|
|
11137
|
+
socket.close();
|
|
11138
|
+
});
|
|
11139
|
+
} else {
|
|
11140
|
+
resolveAuthenticationInfo(data);
|
|
11141
|
+
}
|
|
11142
|
+
}
|
|
11143
|
+
}
|
|
11144
|
+
},
|
|
11145
|
+
onClose: ({ code, reason }) => {
|
|
11146
|
+
logEvent("Websocket closed", code, reason);
|
|
11147
|
+
closed = true;
|
|
11148
|
+
listener.onConnectionClosed({ code, reason, initiator });
|
|
11149
|
+
const pendingInvocationsAtCloseTime = Object.values(pendingInvocations);
|
|
11150
|
+
pendingInvocations = {};
|
|
11151
|
+
pendingInvocationsAtCloseTime.forEach(
|
|
11152
|
+
(pendingInvocation) => pendingInvocation.reject(new WebsocketClosedError())
|
|
11153
|
+
);
|
|
11154
|
+
}
|
|
11155
|
+
});
|
|
11156
|
+
const sessionState = await connectionInfoPromise;
|
|
11157
|
+
const reattached = sessionState === "SESSION_ATTACHED";
|
|
11158
|
+
if (await isWindows(hostConfig)) {
|
|
11159
|
+
const authInfo = await authenticationInfoPromise;
|
|
11160
|
+
if (authInfo.mustAuthenticate) {
|
|
11161
|
+
throw new Error("Windows authentication needed");
|
|
11162
|
+
}
|
|
11163
|
+
}
|
|
11164
|
+
function send(request) {
|
|
11165
|
+
if (closed) {
|
|
11166
|
+
throw new WebsocketClosedError();
|
|
11167
|
+
}
|
|
11168
|
+
const promise = new Promise((resolve, reject) => {
|
|
11169
|
+
pendingInvocations[request.id] = {
|
|
11170
|
+
handle: request.handle,
|
|
11171
|
+
resolve,
|
|
11172
|
+
reject
|
|
11173
|
+
};
|
|
11174
|
+
socket.send(JSON.stringify(request));
|
|
11175
|
+
});
|
|
11176
|
+
return promise;
|
|
11177
|
+
}
|
|
11178
|
+
return {
|
|
11179
|
+
send,
|
|
11180
|
+
isClosed: () => !!closed,
|
|
11181
|
+
isReattached: () => !!reattached,
|
|
11182
|
+
getSessionState: () => sessionState,
|
|
11183
|
+
closeNormal: () => {
|
|
11184
|
+
logEvent("Closing websocket!");
|
|
11185
|
+
initiator = "manual";
|
|
11186
|
+
closed = true;
|
|
11187
|
+
socket.close(RPC_CLOSE_NORMAL, "Websocket closed from client side");
|
|
11188
|
+
},
|
|
11189
|
+
closeSuspend: () => {
|
|
11190
|
+
logEvent("Suspending websocket!");
|
|
11191
|
+
initiator = "manual";
|
|
11192
|
+
closed = true;
|
|
11193
|
+
socket.close(RPC_CLOSE_MANUAL_SUSPEND, "Websocket suspended from client side");
|
|
11194
|
+
}
|
|
11195
|
+
};
|
|
11196
|
+
}
|
|
11197
|
+
function isInvocationResponse(data) {
|
|
11198
|
+
return data.id;
|
|
11199
|
+
}
|
|
11200
|
+
|
|
11201
|
+
// src/qix/session/phoenix/qix-connection.ts
|
|
11202
|
+
var QixError = class extends Error {
|
|
11203
|
+
code;
|
|
11204
|
+
parameter;
|
|
11205
|
+
enigmaError = true;
|
|
11206
|
+
isCancelled;
|
|
11207
|
+
constructor({
|
|
11208
|
+
message,
|
|
11209
|
+
code,
|
|
11210
|
+
parameter
|
|
11211
|
+
}, isCancelled) {
|
|
11212
|
+
super(message);
|
|
11213
|
+
this.code = code;
|
|
11214
|
+
this.parameter = parameter;
|
|
11215
|
+
this.isCancelled = isCancelled || false;
|
|
11216
|
+
}
|
|
11217
|
+
};
|
|
11218
|
+
function isCancelRequest(handleOrObject, method) {
|
|
11219
|
+
const handle = typeof handleOrObject === "object" ? handleOrObject.getHandle() : handleOrObject;
|
|
11220
|
+
return handle === 1 && method === "CancelRequest";
|
|
11221
|
+
}
|
|
11222
|
+
async function createQixConnection(props, listener) {
|
|
11223
|
+
let requestCounter = 1;
|
|
11224
|
+
const canceledRequests = {};
|
|
11225
|
+
function storeCanceledRequestId(request) {
|
|
11226
|
+
if (Array.isArray(request.params) && request.params.length > 0) {
|
|
11227
|
+
const cancelledRequestId = request.params[0];
|
|
11228
|
+
canceledRequests[cancelledRequestId] = true;
|
|
11229
|
+
}
|
|
11230
|
+
}
|
|
11231
|
+
function requestWasCanceled(requestId) {
|
|
11232
|
+
if (canceledRequests[requestId]) {
|
|
11233
|
+
delete canceledRequests[requestId];
|
|
11234
|
+
return true;
|
|
11235
|
+
}
|
|
11236
|
+
return false;
|
|
11237
|
+
}
|
|
11238
|
+
function onMessage(message, handle) {
|
|
11239
|
+
listener.onMessageReceived(message, handle);
|
|
11240
|
+
if (message.change) {
|
|
11241
|
+
message.change.forEach((changedHandle) => listener.onObjectChanged(changedHandle));
|
|
11242
|
+
}
|
|
11243
|
+
if (message.close) {
|
|
11244
|
+
message.close.forEach((closedHandle) => listener.onObjectClosed(closedHandle));
|
|
11245
|
+
}
|
|
11246
|
+
if (message.params) {
|
|
11247
|
+
listener.onNotification(message);
|
|
11248
|
+
}
|
|
11249
|
+
}
|
|
11250
|
+
function onConnectionClosed(closeEvent) {
|
|
11251
|
+
listener.onConnectionClosed(closeEvent);
|
|
11252
|
+
}
|
|
11253
|
+
const lowLevelConnection = await createJsonRpcChannel(props, { onMessage, onConnectionClosed });
|
|
11254
|
+
const deltaState = {};
|
|
11255
|
+
async function invoke(handleOrObject, request, reportRequestId) {
|
|
11256
|
+
const { outKey, ...requestWithoutOutKey } = request;
|
|
11257
|
+
const handle = typeof handleOrObject === "object" ? handleOrObject.getHandle() : handleOrObject;
|
|
11258
|
+
const websocketRequest = {
|
|
11259
|
+
jsonrpc: "2.0",
|
|
11260
|
+
handle,
|
|
11261
|
+
id: requestCounter++,
|
|
11262
|
+
...getDeltaAndReturnEmptyProps({ method: request.method, outKey: outKey || -1 }),
|
|
11263
|
+
...requestWithoutOutKey
|
|
11264
|
+
};
|
|
11265
|
+
reportRequestId?.(websocketRequest.id);
|
|
11266
|
+
if (isCancelRequest(handleOrObject, request.method)) {
|
|
11267
|
+
storeCanceledRequestId(request);
|
|
11268
|
+
}
|
|
11269
|
+
logRequest(handleOrObject, websocketRequest, request);
|
|
11270
|
+
listener.onMessageSent(websocketRequest, websocketRequest.handle);
|
|
11271
|
+
let response;
|
|
11272
|
+
try {
|
|
11273
|
+
response = await lowLevelConnection.send(websocketRequest);
|
|
11274
|
+
} catch (error) {
|
|
11275
|
+
logJsonRpcChannelError(handleOrObject, websocketRequest, error);
|
|
11276
|
+
throw error;
|
|
11277
|
+
}
|
|
11278
|
+
if (response.error) {
|
|
11279
|
+
const isCancelled = requestWasCanceled(websocketRequest.id);
|
|
11280
|
+
const { jsonrpc: jsonrpc2, delta: delta2, id: id2, ...errorResponse } = response;
|
|
11281
|
+
logResponse(handleOrObject, websocketRequest, errorResponse);
|
|
11282
|
+
throw new QixError(response.error, isCancelled);
|
|
11283
|
+
}
|
|
11284
|
+
let resultObject = response.result || {};
|
|
11285
|
+
if (response.delta) {
|
|
11286
|
+
resultObject = unwrapDeltas(resultObject, deltaState, handle, request.method);
|
|
11287
|
+
}
|
|
11288
|
+
const result = extractResult({ method: request.method, outKey: outKey || -1 }, resultObject);
|
|
11289
|
+
const { jsonrpc, delta, id, ...sendResponse } = { ...response, result };
|
|
11290
|
+
logResponse(handleOrObject, websocketRequest, sendResponse);
|
|
11291
|
+
return result;
|
|
11292
|
+
}
|
|
11293
|
+
return {
|
|
11294
|
+
invoke,
|
|
11295
|
+
isReattached: lowLevelConnection.isReattached,
|
|
11296
|
+
getSessionState: lowLevelConnection.getSessionState,
|
|
11297
|
+
isClosed: lowLevelConnection.isClosed,
|
|
11298
|
+
closeNormal: lowLevelConnection.closeNormal,
|
|
11299
|
+
closeSuspend: lowLevelConnection.closeSuspend
|
|
11300
|
+
};
|
|
11301
|
+
}
|
|
11302
|
+
|
|
11303
|
+
// src/qix/session/phoenix/retry-logic.ts
|
|
11304
|
+
var retryRegexpFilter2 = /(?!^GetHyperCube|^GetListObject)(^Get|^Create|^OpenDoc$)/i;
|
|
11305
|
+
function shouldRetryRequest(request, error) {
|
|
11306
|
+
if (error instanceof QixError) {
|
|
11307
|
+
if (error.isCancelled) {
|
|
11308
|
+
return { retry: false };
|
|
11309
|
+
}
|
|
11310
|
+
if (!retryRegexpFilter2.test(request.method)) {
|
|
11311
|
+
return { retry: false };
|
|
11312
|
+
}
|
|
11313
|
+
if (error.code === engine_api_default.enums.LocalizedErrorCode.LOCERR_GENERIC_ABORTED) {
|
|
11314
|
+
return {
|
|
11315
|
+
retry: true
|
|
11316
|
+
};
|
|
11317
|
+
}
|
|
11318
|
+
if (error.code === engine_api_default.enums.LocalizedErrorCode.LOCERR_HC_MODAL_OBJECT_ERROR) {
|
|
11319
|
+
return {
|
|
11320
|
+
retry: true,
|
|
11321
|
+
retryPrepAction: async ({ connection, appHandle }) => {
|
|
11322
|
+
return connection.invoke(appHandle, { method: "abortModalSelection", params: [] });
|
|
11323
|
+
}
|
|
11324
|
+
};
|
|
11325
|
+
}
|
|
11326
|
+
return { retry: false };
|
|
11327
|
+
}
|
|
11328
|
+
return { retry: true };
|
|
11329
|
+
}
|
|
11330
|
+
|
|
11331
|
+
// src/qix/session/phoenix/event-emitter.js
|
|
11332
|
+
var util = {};
|
|
11333
|
+
util.isObject = function isObject3(arg) {
|
|
11334
|
+
return typeof arg === "object" && arg !== null;
|
|
11335
|
+
};
|
|
11336
|
+
util.isNumber = function isNumber(arg) {
|
|
11337
|
+
return typeof arg === "number";
|
|
11338
|
+
};
|
|
11339
|
+
util.isUndefined = function isUndefined(arg) {
|
|
11340
|
+
return arg === void 0;
|
|
11341
|
+
};
|
|
11342
|
+
util.isFunction = function isFunction3(arg) {
|
|
11343
|
+
return typeof arg === "function";
|
|
11344
|
+
};
|
|
11345
|
+
function EventEmitter() {
|
|
11346
|
+
EventEmitter.init.call(this);
|
|
11347
|
+
}
|
|
11348
|
+
EventEmitter.EventEmitter = EventEmitter;
|
|
11349
|
+
EventEmitter.prototype._events = void 0;
|
|
11350
|
+
EventEmitter.prototype._maxListeners = void 0;
|
|
11351
|
+
EventEmitter.defaultMaxListeners = 10;
|
|
11352
|
+
EventEmitter.init = function() {
|
|
11353
|
+
this._events = this._events || {};
|
|
11354
|
+
this._maxListeners = this._maxListeners || void 0;
|
|
11355
|
+
};
|
|
11356
|
+
EventEmitter.prototype.setMaxListeners = function(n) {
|
|
11357
|
+
if (!util.isNumber(n) || n < 0 || isNaN(n)) throw TypeError("n must be a positive number");
|
|
11358
|
+
this._maxListeners = n;
|
|
11359
|
+
return this;
|
|
11360
|
+
};
|
|
11361
|
+
EventEmitter.prototype.emit = function(type) {
|
|
11362
|
+
var er, handler, len, args, i, listeners;
|
|
11363
|
+
if (!this._events) this._events = {};
|
|
11364
|
+
if (type === "error" && !this._events.error) {
|
|
11365
|
+
er = arguments[1];
|
|
11366
|
+
if (er instanceof Error) {
|
|
11367
|
+
throw er;
|
|
11368
|
+
} else {
|
|
11369
|
+
throw Error('Uncaught, unspecified "error" event.');
|
|
11370
|
+
}
|
|
11371
|
+
return false;
|
|
11372
|
+
}
|
|
11373
|
+
handler = this._events[type];
|
|
11374
|
+
if (util.isUndefined(handler)) return false;
|
|
11375
|
+
if (util.isFunction(handler)) {
|
|
11376
|
+
switch (arguments.length) {
|
|
11377
|
+
// fast cases
|
|
11378
|
+
case 1:
|
|
11379
|
+
handler.call(this);
|
|
11380
|
+
break;
|
|
11381
|
+
case 2:
|
|
11382
|
+
handler.call(this, arguments[1]);
|
|
11383
|
+
break;
|
|
11384
|
+
case 3:
|
|
11385
|
+
handler.call(this, arguments[1], arguments[2]);
|
|
11386
|
+
break;
|
|
11387
|
+
// slower
|
|
11388
|
+
default:
|
|
11389
|
+
len = arguments.length;
|
|
11390
|
+
args = new Array(len - 1);
|
|
11391
|
+
for (i = 1; i < len; i++) args[i - 1] = arguments[i];
|
|
11392
|
+
handler.apply(this, args);
|
|
11393
|
+
}
|
|
11394
|
+
} else if (util.isObject(handler)) {
|
|
11395
|
+
len = arguments.length;
|
|
11396
|
+
args = new Array(len - 1);
|
|
11397
|
+
for (i = 1; i < len; i++) args[i - 1] = arguments[i];
|
|
11398
|
+
listeners = handler.slice();
|
|
11399
|
+
len = listeners.length;
|
|
11400
|
+
for (i = 0; i < len; i++) listeners[i].apply(this, args);
|
|
11401
|
+
}
|
|
11402
|
+
return true;
|
|
11403
|
+
};
|
|
11404
|
+
EventEmitter.prototype.addListener = function(type, listener) {
|
|
11405
|
+
var m;
|
|
11406
|
+
if (!util.isFunction(listener)) throw TypeError("listener must be a function");
|
|
11407
|
+
if (!this._events) this._events = {};
|
|
11408
|
+
if (this._events.newListener)
|
|
11409
|
+
this.emit("newListener", type, util.isFunction(listener.listener) ? listener.listener : listener);
|
|
11410
|
+
if (!this._events[type])
|
|
11411
|
+
this._events[type] = listener;
|
|
11412
|
+
else if (util.isObject(this._events[type]))
|
|
11413
|
+
this._events[type].push(listener);
|
|
11414
|
+
else this._events[type] = [this._events[type], listener];
|
|
11415
|
+
if (util.isObject(this._events[type]) && !this._events[type].warned) {
|
|
11416
|
+
var m;
|
|
11417
|
+
if (!util.isUndefined(this._maxListeners)) {
|
|
11418
|
+
m = this._maxListeners;
|
|
11419
|
+
} else {
|
|
11420
|
+
m = EventEmitter.defaultMaxListeners;
|
|
11421
|
+
}
|
|
11422
|
+
if (m && m > 0 && this._events[type].length > m) {
|
|
11423
|
+
this._events[type].warned = true;
|
|
11424
|
+
if (util.isFunction(console.error)) {
|
|
11425
|
+
console.error(
|
|
11426
|
+
"(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",
|
|
11427
|
+
this._events[type].length
|
|
11428
|
+
);
|
|
11429
|
+
}
|
|
11430
|
+
if (util.isFunction(console.trace)) console.trace();
|
|
11431
|
+
}
|
|
11432
|
+
}
|
|
11433
|
+
return this;
|
|
11434
|
+
};
|
|
11435
|
+
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
|
|
11436
|
+
EventEmitter.prototype.once = function(type, listener) {
|
|
11437
|
+
if (!util.isFunction(listener)) throw TypeError("listener must be a function");
|
|
11438
|
+
var fired = false;
|
|
11439
|
+
function g() {
|
|
11440
|
+
this.removeListener(type, g);
|
|
11441
|
+
if (!fired) {
|
|
11442
|
+
fired = true;
|
|
11443
|
+
listener.apply(this, arguments);
|
|
11444
|
+
}
|
|
11445
|
+
}
|
|
11446
|
+
g.listener = listener;
|
|
11447
|
+
this.on(type, g);
|
|
11448
|
+
return this;
|
|
11449
|
+
};
|
|
11450
|
+
EventEmitter.prototype.removeListener = function(type, listener) {
|
|
11451
|
+
var list, position, length, i;
|
|
11452
|
+
if (!util.isFunction(listener)) throw TypeError("listener must be a function");
|
|
11453
|
+
if (!this._events || !this._events[type]) return this;
|
|
11454
|
+
list = this._events[type];
|
|
11455
|
+
length = list.length;
|
|
11456
|
+
position = -1;
|
|
11457
|
+
if (list === listener || util.isFunction(list.listener) && list.listener === listener) {
|
|
11458
|
+
delete this._events[type];
|
|
11459
|
+
if (this._events.removeListener) this.emit("removeListener", type, listener);
|
|
11460
|
+
} else if (util.isObject(list)) {
|
|
11461
|
+
for (i = length; i-- > 0; ) {
|
|
11462
|
+
if (list[i] === listener || list[i].listener && list[i].listener === listener) {
|
|
11463
|
+
position = i;
|
|
11464
|
+
break;
|
|
11465
|
+
}
|
|
11466
|
+
}
|
|
11467
|
+
if (position < 0) return this;
|
|
11468
|
+
if (list.length === 1) {
|
|
11469
|
+
list.length = 0;
|
|
11470
|
+
delete this._events[type];
|
|
11471
|
+
} else {
|
|
11472
|
+
list.splice(position, 1);
|
|
11473
|
+
}
|
|
11474
|
+
if (this._events.removeListener) this.emit("removeListener", type, listener);
|
|
11475
|
+
}
|
|
11476
|
+
return this;
|
|
11477
|
+
};
|
|
11478
|
+
EventEmitter.prototype.removeAllListeners = function(type) {
|
|
11479
|
+
var key, listeners;
|
|
11480
|
+
if (!this._events) return this;
|
|
11481
|
+
if (!this._events.removeListener) {
|
|
11482
|
+
if (arguments.length === 0) this._events = {};
|
|
11483
|
+
else if (this._events[type]) delete this._events[type];
|
|
11484
|
+
return this;
|
|
11485
|
+
}
|
|
11486
|
+
if (arguments.length === 0) {
|
|
11487
|
+
for (key in this._events) {
|
|
11488
|
+
if (key === "removeListener") continue;
|
|
11489
|
+
this.removeAllListeners(key);
|
|
11490
|
+
}
|
|
11491
|
+
this.removeAllListeners("removeListener");
|
|
11492
|
+
this._events = {};
|
|
11493
|
+
return this;
|
|
11494
|
+
}
|
|
11495
|
+
listeners = this._events[type];
|
|
11496
|
+
if (util.isFunction(listeners)) {
|
|
11497
|
+
this.removeListener(type, listeners);
|
|
11498
|
+
} else if (Array.isArray(listeners)) {
|
|
11499
|
+
while (listeners.length) this.removeListener(type, listeners[listeners.length - 1]);
|
|
11500
|
+
}
|
|
11501
|
+
delete this._events[type];
|
|
11502
|
+
return this;
|
|
11503
|
+
};
|
|
11504
|
+
EventEmitter.prototype.listeners = function(type) {
|
|
11505
|
+
var ret;
|
|
11506
|
+
if (!this._events || !this._events[type]) ret = [];
|
|
11507
|
+
else if (util.isFunction(this._events[type])) ret = [this._events[type]];
|
|
11508
|
+
else ret = this._events[type].slice();
|
|
11509
|
+
return ret;
|
|
11510
|
+
};
|
|
11511
|
+
EventEmitter.listenerCount = function(emitter, type) {
|
|
11512
|
+
var ret;
|
|
11513
|
+
if (!emitter._events || !emitter._events[type]) ret = 0;
|
|
11514
|
+
else if (util.isFunction(emitter._events[type])) ret = 1;
|
|
11515
|
+
else ret = emitter._events[type].length;
|
|
11516
|
+
return ret;
|
|
11517
|
+
};
|
|
11518
|
+
|
|
11519
|
+
// src/qix/session/phoenix/rpc-object-session.ts
|
|
11520
|
+
var counter = 0;
|
|
11521
|
+
var SuspendResumeImpl = class {
|
|
11522
|
+
Promise;
|
|
11523
|
+
#connection;
|
|
11524
|
+
constructor(connection) {
|
|
11525
|
+
this.Promise = Promise;
|
|
11526
|
+
this.#connection = connection;
|
|
11527
|
+
}
|
|
11528
|
+
resume() {
|
|
11529
|
+
return this.#connection.resume();
|
|
11530
|
+
}
|
|
11531
|
+
suspend() {
|
|
11532
|
+
return this.#connection.suspend();
|
|
11533
|
+
}
|
|
11534
|
+
get isSuspended() {
|
|
11535
|
+
return this.#connection.isSuspended;
|
|
11536
|
+
}
|
|
11537
|
+
};
|
|
11538
|
+
var ConfigImpl = class {
|
|
11539
|
+
Promise;
|
|
11540
|
+
constructor() {
|
|
11541
|
+
this.Promise = Promise;
|
|
11542
|
+
}
|
|
11543
|
+
};
|
|
11544
|
+
var RpcImpl = class extends EventEmitter {
|
|
11545
|
+
Promise;
|
|
11546
|
+
#connection;
|
|
11547
|
+
constructor(connection) {
|
|
11548
|
+
super();
|
|
11549
|
+
this.#connection = connection;
|
|
11550
|
+
this.Promise = Promise;
|
|
11551
|
+
}
|
|
11552
|
+
/**
|
|
11553
|
+
* @deprecated
|
|
11554
|
+
* For backwards compatibility, this function is deprecated.
|
|
11555
|
+
*/
|
|
11556
|
+
send(requestWithHandle) {
|
|
11557
|
+
const object = { getHandle: () => requestWithHandle.handle };
|
|
11558
|
+
const { handle, ...request } = requestWithHandle;
|
|
11559
|
+
return this.#connection.invoke(object, request, () => {
|
|
11560
|
+
});
|
|
11561
|
+
}
|
|
11562
|
+
// Backwards compatibility placeholder functions that does nothing
|
|
11563
|
+
close() {
|
|
11564
|
+
}
|
|
11565
|
+
};
|
|
11566
|
+
var RpcObjectSessionImpl = class extends EventEmitter {
|
|
11567
|
+
rpc;
|
|
11568
|
+
suspendResume;
|
|
11569
|
+
config;
|
|
11570
|
+
id = counter++;
|
|
11571
|
+
#connection;
|
|
11572
|
+
/**
|
|
11573
|
+
*
|
|
11574
|
+
* @internal
|
|
11575
|
+
*/
|
|
11576
|
+
constructor(connection) {
|
|
11577
|
+
super();
|
|
11578
|
+
this.#connection = connection;
|
|
11579
|
+
this.rpc = new RpcImpl(connection);
|
|
11580
|
+
this.suspendResume = new SuspendResumeImpl(connection);
|
|
11581
|
+
this.config = new ConfigImpl();
|
|
11582
|
+
}
|
|
11583
|
+
/**
|
|
11584
|
+
* @deprecated
|
|
11585
|
+
* For backwards compatibility, this function is deprecated.
|
|
11586
|
+
*/
|
|
11587
|
+
send(requestWithHandle) {
|
|
11588
|
+
return this.rpc.send(requestWithHandle);
|
|
11589
|
+
}
|
|
11590
|
+
getObjectApi(ref) {
|
|
11591
|
+
return this.#connection.getObjectApi(ref);
|
|
11592
|
+
}
|
|
11593
|
+
/**
|
|
11594
|
+
* Returns the app object for the session.
|
|
11595
|
+
*/
|
|
11596
|
+
get global() {
|
|
11597
|
+
return this.#connection.global;
|
|
11598
|
+
}
|
|
11599
|
+
/**
|
|
11600
|
+
* Returns the app object for the session.
|
|
11601
|
+
*/
|
|
11602
|
+
get app() {
|
|
11603
|
+
return this.#connection.doc;
|
|
11604
|
+
}
|
|
11605
|
+
get sessionState() {
|
|
11606
|
+
return this.#connection.sessionState;
|
|
11607
|
+
}
|
|
11608
|
+
get Promise() {
|
|
11609
|
+
return Promise;
|
|
11610
|
+
}
|
|
11611
|
+
resume() {
|
|
11612
|
+
return this.#connection.resume();
|
|
11613
|
+
}
|
|
11614
|
+
suspend() {
|
|
11615
|
+
return this.#connection.suspend();
|
|
11616
|
+
}
|
|
11617
|
+
get createdAt() {
|
|
11618
|
+
return this.#connection.createdAt;
|
|
11619
|
+
}
|
|
11620
|
+
get lastTrafficAt() {
|
|
11621
|
+
return this.#connection.lastTrafficAt;
|
|
11622
|
+
}
|
|
11623
|
+
get globalPromise() {
|
|
11624
|
+
return Promise.resolve(this.#connection.global);
|
|
11625
|
+
}
|
|
11626
|
+
get openDocPromise() {
|
|
11627
|
+
return Promise.resolve(this.#connection.doc);
|
|
11628
|
+
}
|
|
11629
|
+
// TODO IMPLEMENT FOR BACKWARDS COMPATIBLIITY
|
|
11630
|
+
open() {
|
|
11631
|
+
return this.globalPromise;
|
|
11632
|
+
}
|
|
11633
|
+
close() {
|
|
11634
|
+
return Promise.resolve();
|
|
11635
|
+
}
|
|
11636
|
+
};
|
|
11637
|
+
|
|
11638
|
+
// src/qix/session/phoenix/phoenix-connection.ts
|
|
11639
|
+
async function createPhoenixConnection(openProps, objectFactory2, { onWebSocketEvent, getInitialAppActions }) {
|
|
11640
|
+
const phoenixConnection = new PhoenixConnectionImpl(openProps, objectFactory2, {
|
|
11641
|
+
onWebSocketEvent,
|
|
11642
|
+
getInitialAppActions
|
|
11643
|
+
});
|
|
11644
|
+
await phoenixConnection.waitForConnection();
|
|
11645
|
+
return phoenixConnection;
|
|
11646
|
+
}
|
|
11647
|
+
var PhoenixConnectionImpl = class {
|
|
11648
|
+
#interestMonitor = createInterestMonitor();
|
|
11649
|
+
#sessionIsNotInUseAnymore = false;
|
|
11650
|
+
#openProps;
|
|
11651
|
+
#objectFactory;
|
|
11652
|
+
#rpcObjectSession;
|
|
11653
|
+
#owner;
|
|
11654
|
+
#globalRpcObject;
|
|
11655
|
+
#docRpcObject;
|
|
11656
|
+
#state = "opening";
|
|
11657
|
+
#currentReincarnationPromise = Promise.resolve(void 0);
|
|
11658
|
+
#currentReincarnation;
|
|
11659
|
+
#lastTrafficAt = Date.now();
|
|
11660
|
+
#createdAt = Date.now();
|
|
11661
|
+
/** @internal */
|
|
11662
|
+
constructor(openProps, objectFactory2, owner) {
|
|
11663
|
+
this.#openProps = openProps;
|
|
11664
|
+
this.#objectFactory = objectFactory2;
|
|
11665
|
+
this.#owner = owner;
|
|
11666
|
+
this.#rpcObjectSession = new RpcObjectSessionImpl(this);
|
|
11667
|
+
logEvent("Creating phoenix session", openProps);
|
|
11668
|
+
this.#globalRpcObject = objectFactory2.createObject(
|
|
11669
|
+
{ qHandle: -1, qType: "Global", qGenericId: "Global" },
|
|
11670
|
+
this,
|
|
11671
|
+
void 0
|
|
11672
|
+
);
|
|
11673
|
+
this.#docRpcObject = objectFactory2.createObject(
|
|
11674
|
+
{ qHandle: 1, qGenericId: openProps.appId, qType: "Doc" },
|
|
11675
|
+
this,
|
|
11676
|
+
void 0
|
|
11677
|
+
);
|
|
11678
|
+
this.#interestMonitor.onUserActivityDetected(() => {
|
|
11679
|
+
void this.#getCurrentOrAcquireNewReincarnation();
|
|
11680
|
+
});
|
|
11681
|
+
}
|
|
11682
|
+
get classicEnigmaSessionApi() {
|
|
11683
|
+
return this.#rpcObjectSession;
|
|
11684
|
+
}
|
|
11685
|
+
get createdAt() {
|
|
11686
|
+
return this.#createdAt;
|
|
11687
|
+
}
|
|
11688
|
+
get lastTrafficAt() {
|
|
11689
|
+
return this.#lastTrafficAt;
|
|
11690
|
+
}
|
|
11691
|
+
async waitForConnection() {
|
|
11692
|
+
await this.#getCurrentOrAcquireNewReincarnation();
|
|
11693
|
+
}
|
|
11694
|
+
/**
|
|
11695
|
+
* Invokes a method on the engine and returns the result.
|
|
11696
|
+
* If the result is an object reference, it will be resolved to a PhoenixRpcObject.
|
|
11697
|
+
* If the request fails, it will be retried if the error is retryable.
|
|
11698
|
+
* If the websocket is down or goes down during the request a new connection will be opened and reestablished and the request retried.
|
|
11699
|
+
*
|
|
11700
|
+
*
|
|
11701
|
+
* @param object An rpc object (or at least something that can provide a handle)
|
|
11702
|
+
* @param request a high level qix request (method, params and outKey)
|
|
11703
|
+
* @param reportRequestId
|
|
11704
|
+
* @returns Either the Json response or a PhoenixRpcObject
|
|
11705
|
+
* @throws QixError if the request fails and is not retryable
|
|
11706
|
+
*/
|
|
11707
|
+
async invoke(object, request, reportRequestId) {
|
|
11708
|
+
try {
|
|
11709
|
+
return await this.#sendAndResolveRpcObjects(object, request, reportRequestId);
|
|
11710
|
+
} catch (err) {
|
|
11711
|
+
const { retry, retryPrepAction } = shouldRetryRequest(request, err);
|
|
11712
|
+
if (retry) {
|
|
11713
|
+
if (retryPrepAction) {
|
|
11714
|
+
await retryPrepAction({
|
|
11715
|
+
connection: this.#currentReincarnation.connection,
|
|
11716
|
+
appHandle: this.#currentReincarnation.state.getDoc().getHandle()
|
|
11717
|
+
});
|
|
11718
|
+
}
|
|
11719
|
+
return this.#sendAndResolveRpcObjects(object, request, reportRequestId);
|
|
11720
|
+
}
|
|
11721
|
+
throw err;
|
|
11722
|
+
}
|
|
11723
|
+
}
|
|
11724
|
+
/**
|
|
11725
|
+
* Returns an RPC object for the given reference. If the object already exists, it will be returned.
|
|
11726
|
+
*/
|
|
11727
|
+
getObjectApi(ref) {
|
|
11728
|
+
if (!this.#currentReincarnation) {
|
|
11729
|
+
throw new Error("Not yet connected!");
|
|
11730
|
+
}
|
|
11731
|
+
const existingObject = this.#currentReincarnation.state.getObject(ref);
|
|
11732
|
+
if (existingObject) {
|
|
11733
|
+
return existingObject;
|
|
11734
|
+
}
|
|
11735
|
+
const newObject = this.#objectFactory.createObject(ref, this, void 0);
|
|
11736
|
+
this.#currentReincarnation.state.setObject(newObject.getHandle(), newObject);
|
|
11737
|
+
return newObject;
|
|
11738
|
+
}
|
|
11739
|
+
/**
|
|
11740
|
+
* The main Doc/App rpc object
|
|
11741
|
+
*/
|
|
11742
|
+
get doc() {
|
|
11743
|
+
return this.#docRpcObject;
|
|
11744
|
+
}
|
|
11745
|
+
/**
|
|
11746
|
+
* The Global rpc object
|
|
11747
|
+
*/
|
|
11748
|
+
get global() {
|
|
11749
|
+
return this.#globalRpcObject;
|
|
11750
|
+
}
|
|
11751
|
+
/**
|
|
11752
|
+
* A string representing if the session was newly established or reonnected
|
|
11753
|
+
*/
|
|
11754
|
+
get sessionState() {
|
|
11755
|
+
return this.#currentReincarnation?.connection.getSessionState() ?? "";
|
|
11756
|
+
}
|
|
11757
|
+
/**
|
|
11758
|
+
* Signals from outside that the session is not in use (maybe will be in a few seconds!)
|
|
11759
|
+
*/
|
|
11760
|
+
stopActivityMonitoring() {
|
|
11761
|
+
this.#interestMonitor.stopListeningForActivity();
|
|
11762
|
+
}
|
|
11763
|
+
close() {
|
|
11764
|
+
this.#interestMonitor.stopListeningForActivity();
|
|
11765
|
+
this.#sessionIsNotInUseAnymore = true;
|
|
11766
|
+
if (this.#currentReincarnation && !this.#currentReincarnation.connection.isClosed()) {
|
|
11767
|
+
this.#currentReincarnation.connection.closeNormal();
|
|
11768
|
+
}
|
|
11769
|
+
}
|
|
11770
|
+
async resume() {
|
|
11771
|
+
this.#interestMonitor.signalInterest();
|
|
11772
|
+
await this.#getCurrentOrAcquireNewReincarnation();
|
|
11773
|
+
}
|
|
11774
|
+
async suspend() {
|
|
11775
|
+
if (this.#currentReincarnation && !this.#currentReincarnation.connection.isClosed()) {
|
|
11776
|
+
this.#currentReincarnation.connection.closeSuspend();
|
|
11777
|
+
}
|
|
11778
|
+
}
|
|
11779
|
+
get isSuspended() {
|
|
11780
|
+
return this.#currentReincarnation && this.#currentReincarnation.connection.isClosed() || false;
|
|
11781
|
+
}
|
|
11782
|
+
initialAppActionsUpdated() {
|
|
11783
|
+
void (async () => {
|
|
11784
|
+
await this.#runPendingInitialAppActions(await this.#getCurrentOrAcquireNewReincarnation());
|
|
11785
|
+
})();
|
|
11786
|
+
}
|
|
11787
|
+
/**
|
|
11788
|
+
* Makes a single attempt at calling the backend
|
|
11789
|
+
* * Acquires a working connection
|
|
11790
|
+
* * Invokes the backend using thta connection
|
|
11791
|
+
* * If the result is an object reference, it will be resolved to a PhoenixRpcObject
|
|
11792
|
+
*/
|
|
11793
|
+
async #sendAndResolveRpcObjects(object, request, reportRequestId) {
|
|
11794
|
+
const { connection, state } = await this.#getCurrentOrAcquireNewReincarnation();
|
|
11795
|
+
const result = await connection.invoke(object, request, reportRequestId);
|
|
11796
|
+
if (isQixObjectRef(result)) {
|
|
11797
|
+
const objectRef = result;
|
|
11798
|
+
let objectResult = state.getObject(objectRef.qHandle);
|
|
11799
|
+
if (!objectResult) {
|
|
11800
|
+
objectResult = this.#objectFactory.createObject(objectRef, this, request);
|
|
11801
|
+
state.setObject(objectRef.qHandle, objectResult);
|
|
11802
|
+
}
|
|
11803
|
+
return objectResult;
|
|
11804
|
+
}
|
|
11805
|
+
return result;
|
|
11806
|
+
}
|
|
11807
|
+
/**
|
|
11808
|
+
* This function will acquire a new reincarnation (connection + session state) if the current one is closed
|
|
11809
|
+
* It will also update the traffic timestamp
|
|
11810
|
+
*/
|
|
11811
|
+
async #getCurrentOrAcquireNewReincarnation() {
|
|
11812
|
+
this.#lastTrafficAt = Date.now();
|
|
11813
|
+
const result = this.#currentReincarnationPromise.then(async (lastReincarnation) => {
|
|
11814
|
+
while (lastReincarnation?.next !== void 0) {
|
|
11815
|
+
lastReincarnation = await lastReincarnation.next;
|
|
11816
|
+
}
|
|
11817
|
+
if (lastReincarnation && !lastReincarnation.connection.isClosed()) {
|
|
11818
|
+
return lastReincarnation;
|
|
11819
|
+
}
|
|
11820
|
+
const isResume = !!lastReincarnation;
|
|
11821
|
+
if (isResume) {
|
|
11822
|
+
this.#state = "resuming";
|
|
11823
|
+
this.#onResuming();
|
|
11824
|
+
}
|
|
11825
|
+
const newReincarnation = await this.#openNewQixConnectionAndPrepareSessionStateWithRetry(
|
|
11826
|
+
lastReincarnation,
|
|
11827
|
+
isResume
|
|
11828
|
+
);
|
|
11829
|
+
this.#state = "open";
|
|
11830
|
+
if (isResume) {
|
|
11831
|
+
this.#onResume();
|
|
11832
|
+
} else {
|
|
11833
|
+
this.#onOpen();
|
|
11834
|
+
}
|
|
11835
|
+
this.#currentReincarnation = newReincarnation;
|
|
11836
|
+
await this.#runPendingInitialAppActions(newReincarnation);
|
|
11837
|
+
return newReincarnation;
|
|
11838
|
+
});
|
|
11839
|
+
this.#currentReincarnationPromise = result;
|
|
11840
|
+
return result;
|
|
11841
|
+
}
|
|
11842
|
+
/**
|
|
11843
|
+
* Really tries and retries to successfully open a new Qix connection and prepares the session state for the new connection.
|
|
11844
|
+
* If a few attempts of reopening fails, it will wait for activity on the session before trying again.
|
|
11845
|
+
* This means that this function will not return until a new reincarnation is acquired.
|
|
11846
|
+
*
|
|
11847
|
+
*/
|
|
11848
|
+
async #openNewQixConnectionAndPrepareSessionStateWithRetry(lastReincarnation, isResume) {
|
|
11849
|
+
return new Promise((resolve, reject) => {
|
|
11850
|
+
let retryCount = 0;
|
|
11851
|
+
const INITIAL_RETRY_TIME = 2e3;
|
|
11852
|
+
let retryWaitTime = INITIAL_RETRY_TIME;
|
|
11853
|
+
const oneTry = async () => {
|
|
11854
|
+
logEvent("Trying to acquire new reincarnation", this.#openProps);
|
|
11855
|
+
try {
|
|
11856
|
+
resolve(await this.#openNewQixConnectionAndPrepareSessionState(lastReincarnation?.state));
|
|
11857
|
+
} catch (err) {
|
|
11858
|
+
if (isResume) {
|
|
11859
|
+
this.#interestMonitor.resetAnyInterestSignalledBeforeNow();
|
|
11860
|
+
if (retryCount < 5) {
|
|
11861
|
+
retryCount++;
|
|
11862
|
+
retryWaitTime *= 1.5;
|
|
11863
|
+
logEvent("Failed to acquire new reincarnation, retrying in ", retryWaitTime, err);
|
|
11864
|
+
setTimeout(() => {
|
|
11865
|
+
void oneTry();
|
|
11866
|
+
}, retryWaitTime);
|
|
11867
|
+
} else {
|
|
11868
|
+
await this.#interestMonitor.waitUntilSomeoneIsInterestedInThis();
|
|
11869
|
+
logEvent("Activity detected, retrying to acquire new reincarnation", this.#openProps);
|
|
11870
|
+
retryCount = 0;
|
|
11871
|
+
retryWaitTime = INITIAL_RETRY_TIME;
|
|
11872
|
+
setTimeout(() => {
|
|
11873
|
+
void oneTry();
|
|
11874
|
+
}, retryWaitTime);
|
|
11875
|
+
}
|
|
11876
|
+
} else {
|
|
11877
|
+
logEvent("Failed to open app", err);
|
|
11878
|
+
reject(err);
|
|
11879
|
+
}
|
|
11880
|
+
}
|
|
11881
|
+
};
|
|
11882
|
+
void oneTry();
|
|
11883
|
+
});
|
|
11884
|
+
}
|
|
11885
|
+
async #openNewQixConnectionAndPrepareSessionState(lastState) {
|
|
11886
|
+
let stateForNewConnection;
|
|
11887
|
+
stateForNewConnection = void 0;
|
|
11888
|
+
logEvent("-------- Opening new Qix Connection ---------");
|
|
11889
|
+
const newConnection = await createQixConnection(this.#openProps, {
|
|
11890
|
+
onMessageSent: (message, handle) => {
|
|
11891
|
+
this.#onMessageSent(message, stateForNewConnection?.getObject(handle));
|
|
11892
|
+
},
|
|
11893
|
+
onMessageReceived: (message, handle) => {
|
|
11894
|
+
const object = handle ? stateForNewConnection?.getObject(handle) : void 0;
|
|
11895
|
+
this.#onMessageReceived(message, object);
|
|
11896
|
+
},
|
|
11897
|
+
onNotification: (message) => {
|
|
11898
|
+
this.#onNotification(message);
|
|
11899
|
+
},
|
|
11900
|
+
onObjectChanged: (handle) => {
|
|
11901
|
+
stateForNewConnection?.getObject(handle)?.emit("changed");
|
|
11902
|
+
},
|
|
11903
|
+
onObjectClosed: (handle) => {
|
|
11904
|
+
stateForNewConnection?.getObject(handle)?.emit("closed");
|
|
11905
|
+
stateForNewConnection?.removeObject(handle);
|
|
11906
|
+
},
|
|
11907
|
+
onConnectionClosed: (error) => {
|
|
11908
|
+
this.#onConnectionClosed(error);
|
|
11909
|
+
}
|
|
11910
|
+
});
|
|
11911
|
+
const appRef = await newConnection.invoke(-1, {
|
|
11912
|
+
method: "OpenDoc",
|
|
11913
|
+
params: [this.#openProps.appId, "", "", "", !!this.#openProps.withoutData],
|
|
11914
|
+
outKey: -1
|
|
11915
|
+
});
|
|
11916
|
+
this.#docRpcObject.setHandle(appRef.qHandle);
|
|
11917
|
+
const newState = createPhoenixSessionState({
|
|
11918
|
+
global: this.#globalRpcObject,
|
|
11919
|
+
doc: this.#docRpcObject,
|
|
11920
|
+
executedAppActions: lastState?.getExecutedAppActions() ?? []
|
|
11921
|
+
});
|
|
11922
|
+
if (lastState) {
|
|
11923
|
+
await Promise.all(
|
|
11924
|
+
Object.values(lastState.getObjects()).map(async (object) => {
|
|
11925
|
+
await object.respawn(newConnection);
|
|
11926
|
+
newState.setObject(object.getHandle(), object);
|
|
11927
|
+
})
|
|
11928
|
+
);
|
|
11929
|
+
logEvent("-------- Respawned objects ---------");
|
|
11930
|
+
logEvent(
|
|
11931
|
+
Object.entries(lastState.getObjects()).map(([key, value]) => `${value.id}: ${key} => ${value.getHandle()}`)
|
|
11932
|
+
);
|
|
11933
|
+
}
|
|
11934
|
+
stateForNewConnection = newState;
|
|
11935
|
+
if (lastState) {
|
|
11936
|
+
Object.values(lastState.getObjects()).forEach((object) => {
|
|
11937
|
+
object.emit("changed");
|
|
11938
|
+
});
|
|
11939
|
+
}
|
|
11940
|
+
logEvent("-------- Opening done ---------");
|
|
11941
|
+
return { connection: newConnection, state: newState };
|
|
11942
|
+
}
|
|
11943
|
+
/* -------------------------------------------------------------------------- */
|
|
11944
|
+
/* Event handlers for various Qix Connection events */
|
|
11945
|
+
/* -------------------------------------------------------------------------- */
|
|
11946
|
+
#onOpen() {
|
|
11947
|
+
this.#owner.onWebSocketEvent({ eventType: "opened", ...this.#openProps });
|
|
11948
|
+
this.#rpcObjectSession.emit("opened");
|
|
11949
|
+
}
|
|
11950
|
+
#onResuming() {
|
|
11951
|
+
this.#owner.onWebSocketEvent({ eventType: "resuming", ...this.#openProps });
|
|
11952
|
+
this.#rpcObjectSession.emit("resuming");
|
|
11953
|
+
}
|
|
11954
|
+
#onResume() {
|
|
11955
|
+
this.#createdAt = Date.now();
|
|
11956
|
+
this.#owner.onWebSocketEvent({ eventType: "resumed", ...this.#openProps });
|
|
11957
|
+
this.#rpcObjectSession.emit("resumed");
|
|
11958
|
+
}
|
|
11959
|
+
#onMessageSent(message, object) {
|
|
11960
|
+
this.#rpcObjectSession.rpc.emit("traffic", "sent", message, object?.handle);
|
|
11961
|
+
this.#rpcObjectSession.emit("traffic:*", "sent", message);
|
|
11962
|
+
this.#rpcObjectSession.emit(`traffic:sent`, message);
|
|
11963
|
+
object?.emit("traffic:*", "sent", message);
|
|
11964
|
+
object?.emit("traffic:sent", message);
|
|
11965
|
+
}
|
|
11966
|
+
#onMessageReceived(message, object) {
|
|
11967
|
+
this.#rpcObjectSession.rpc.emit("traffic", "received", message, object?.handle);
|
|
11968
|
+
this.#rpcObjectSession.emit("traffic:*", message);
|
|
11969
|
+
this.#rpcObjectSession.emit(`traffic:received`, message);
|
|
11970
|
+
object?.emit("traffic:*", "received", message);
|
|
11971
|
+
object?.emit("traffic:received", message);
|
|
11972
|
+
}
|
|
11973
|
+
#onNotification(message) {
|
|
11974
|
+
this.#rpcObjectSession.emit("notification:*", message.method, message.params);
|
|
11975
|
+
this.#rpcObjectSession.emit(`notification:${message.method}`, message.params);
|
|
11976
|
+
this.#rpcObjectSession.rpc.emit("notification", message);
|
|
11977
|
+
}
|
|
11978
|
+
#onConnectionClosed(closeEvent) {
|
|
11979
|
+
const { code, reason, initiator } = closeEvent || { code: 0, reason: "unknown", initiator: "network" };
|
|
11980
|
+
if (this.#sessionIsNotInUseAnymore) {
|
|
11981
|
+
logEvent("Connection closed, session is not in use anymore", this.#openProps);
|
|
11982
|
+
this.#owner.onWebSocketEvent({ eventType: "closed", code, reason, ...this.#openProps });
|
|
11983
|
+
this.#rpcObjectSession.emit("closed", { code, reason, initiator });
|
|
11984
|
+
} else if (this.#state === "open") {
|
|
11985
|
+
logEvent("Connection closed, session is still in use", this.#openProps, code, reason);
|
|
11986
|
+
this.#owner.onWebSocketEvent({ eventType: "suspended", code, reason, initiator, ...this.#openProps });
|
|
11987
|
+
this.#rpcObjectSession.emit("suspended", { code, reason, initiator });
|
|
11988
|
+
if (shouldResumeImmediately(code)) {
|
|
11989
|
+
void this.#getCurrentOrAcquireNewReincarnation();
|
|
11990
|
+
} else {
|
|
11991
|
+
this.#interestMonitor.startListeningForActivity();
|
|
11992
|
+
}
|
|
11993
|
+
}
|
|
11994
|
+
}
|
|
11995
|
+
async #runPendingInitialAppActions(newReincarnation) {
|
|
11996
|
+
for (const action of this.#owner.getInitialAppActions()) {
|
|
11997
|
+
if (!newReincarnation.state.isAppActionExecuted(action)) {
|
|
11998
|
+
await action(newReincarnation.state.getDoc());
|
|
11999
|
+
newReincarnation.state.addExecutedInitialAppAction(action);
|
|
12000
|
+
}
|
|
12001
|
+
}
|
|
12002
|
+
}
|
|
12003
|
+
};
|
|
12004
|
+
function shouldResumeImmediately(code) {
|
|
12005
|
+
const IMMEDIATE_RESUME_CDDES = {
|
|
12006
|
+
/** The engine hosting the session is shutting down,
|
|
12007
|
+
* auto-resume to get another session from another engine. */
|
|
12008
|
+
ENGINE_TERMINATING: 4003,
|
|
12009
|
+
/** App deleted from an engine, auto-resume to open it on another engine. */
|
|
12010
|
+
APP_DELETED: 4004,
|
|
12011
|
+
/** App-mode changed to Direct Query mode, let's auto-resume */
|
|
12012
|
+
APP_MODE_CHANGED: 4007
|
|
12013
|
+
};
|
|
12014
|
+
switch (code) {
|
|
12015
|
+
case IMMEDIATE_RESUME_CDDES.ENGINE_TERMINATING:
|
|
12016
|
+
case IMMEDIATE_RESUME_CDDES.APP_DELETED:
|
|
12017
|
+
case IMMEDIATE_RESUME_CDDES.APP_MODE_CHANGED:
|
|
12018
|
+
return true;
|
|
12019
|
+
default:
|
|
12020
|
+
return false;
|
|
12021
|
+
}
|
|
12022
|
+
}
|
|
12023
|
+
|
|
12024
|
+
// src/qix/session/phoenix/remote-object.ts
|
|
12025
|
+
var RemoteObjectImpl = class {
|
|
12026
|
+
#connection;
|
|
12027
|
+
#handle;
|
|
12028
|
+
#id;
|
|
12029
|
+
#type;
|
|
12030
|
+
#genericType;
|
|
12031
|
+
#respawnInfo;
|
|
12032
|
+
constructor({ connection, handle, id, type, genericType, respawnInfo }) {
|
|
12033
|
+
this.#connection = connection;
|
|
12034
|
+
this.#handle = handle;
|
|
12035
|
+
this.#id = id;
|
|
12036
|
+
this.#type = type;
|
|
12037
|
+
this.#genericType = genericType;
|
|
12038
|
+
this.#respawnInfo = respawnInfo;
|
|
12039
|
+
}
|
|
12040
|
+
invoke(req) {
|
|
12041
|
+
let lastRequestId = 0;
|
|
12042
|
+
const promise = this.#connection.invoke(this, req, (requestId) => {
|
|
12043
|
+
lastRequestId = requestId;
|
|
12044
|
+
});
|
|
12045
|
+
addToPromiseChain(promise, "requestId", () => lastRequestId);
|
|
12046
|
+
return promise;
|
|
12047
|
+
}
|
|
12048
|
+
getHandle() {
|
|
12049
|
+
return this.#handle;
|
|
12050
|
+
}
|
|
12051
|
+
get handle() {
|
|
12052
|
+
return this.#handle;
|
|
12053
|
+
}
|
|
12054
|
+
set handle(newHandle) {
|
|
12055
|
+
this.#handle = newHandle;
|
|
12056
|
+
}
|
|
12057
|
+
get id() {
|
|
12058
|
+
return this.#id;
|
|
12059
|
+
}
|
|
12060
|
+
get type() {
|
|
12061
|
+
return this.#type;
|
|
12062
|
+
}
|
|
12063
|
+
get genericType() {
|
|
12064
|
+
return this.#genericType;
|
|
12065
|
+
}
|
|
12066
|
+
get session() {
|
|
12067
|
+
return this.#connection.classicEnigmaSessionApi;
|
|
12068
|
+
}
|
|
12069
|
+
get respawnInfo() {
|
|
12070
|
+
return this.#respawnInfo;
|
|
12071
|
+
}
|
|
12072
|
+
};
|
|
12073
|
+
function addToPromiseChain(promise, name, getValue) {
|
|
12074
|
+
Object.defineProperty(promise, name, {
|
|
12075
|
+
get() {
|
|
12076
|
+
return getValue();
|
|
12077
|
+
},
|
|
12078
|
+
enumerable: true,
|
|
12079
|
+
configurable: true
|
|
12080
|
+
});
|
|
12081
|
+
const { then } = promise;
|
|
12082
|
+
promise.then = function patchedThen(...params) {
|
|
12083
|
+
const chain = then.apply(this, params);
|
|
12084
|
+
addToPromiseChain(chain, name, getValue);
|
|
12085
|
+
return chain;
|
|
12086
|
+
};
|
|
12087
|
+
}
|
|
12088
|
+
|
|
12089
|
+
// src/qix/session/phoenix/rpc-object.ts
|
|
12090
|
+
var PhoenixRpcObjectImpl = class extends EventEmitter {
|
|
12091
|
+
/** @internal */
|
|
12092
|
+
#remoteObject;
|
|
12093
|
+
/** @deprecated */
|
|
12094
|
+
Promise;
|
|
12095
|
+
/**
|
|
12096
|
+
* @internal
|
|
12097
|
+
*/
|
|
12098
|
+
constructor(rpcObjectCore) {
|
|
12099
|
+
super();
|
|
12100
|
+
this.#remoteObject = rpcObjectCore;
|
|
12101
|
+
this.Promise = Promise;
|
|
12102
|
+
}
|
|
12103
|
+
get __remote__() {
|
|
12104
|
+
return this.#remoteObject;
|
|
12105
|
+
}
|
|
12106
|
+
get handle() {
|
|
12107
|
+
return this.#remoteObject.handle;
|
|
12108
|
+
}
|
|
12109
|
+
set handle(handle) {
|
|
12110
|
+
this.#remoteObject.handle = handle;
|
|
12111
|
+
}
|
|
12112
|
+
get app() {
|
|
12113
|
+
return this.#remoteObject.session.app;
|
|
12114
|
+
}
|
|
12115
|
+
get global() {
|
|
12116
|
+
return this.#remoteObject.session.global;
|
|
12117
|
+
}
|
|
12118
|
+
set global(newGlobal) {
|
|
12119
|
+
if (newGlobal !== this.#remoteObject.session.global) {
|
|
12120
|
+
console.warn("Changing the global object on a qix object is not allowed");
|
|
12121
|
+
}
|
|
12122
|
+
}
|
|
12123
|
+
get id() {
|
|
12124
|
+
return this.#remoteObject.id;
|
|
12125
|
+
}
|
|
12126
|
+
get type() {
|
|
12127
|
+
return this.#remoteObject.type;
|
|
12128
|
+
}
|
|
12129
|
+
get genericType() {
|
|
12130
|
+
return this.#remoteObject.genericType;
|
|
12131
|
+
}
|
|
12132
|
+
get session() {
|
|
12133
|
+
return this.#remoteObject.session;
|
|
12134
|
+
}
|
|
12135
|
+
getHandle() {
|
|
12136
|
+
return this.#remoteObject.handle;
|
|
12137
|
+
}
|
|
12138
|
+
setHandle(handle) {
|
|
12139
|
+
const oldHandle = this.#remoteObject.handle;
|
|
12140
|
+
this.#remoteObject.handle = handle;
|
|
12141
|
+
if (oldHandle !== handle) {
|
|
12142
|
+
logEvent("Change handle for ", this.#remoteObject.id, "from", oldHandle, "to", handle);
|
|
12143
|
+
}
|
|
12144
|
+
}
|
|
12145
|
+
/** @deprecated */
|
|
12146
|
+
get enigmaModel() {
|
|
12147
|
+
return this;
|
|
12148
|
+
}
|
|
12149
|
+
/**
|
|
12150
|
+
* @internal
|
|
12151
|
+
*/
|
|
12152
|
+
// This is overriden in mixins but the signature needs to have a QixConnection as parameter
|
|
12153
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
12154
|
+
async respawn(newConnection) {
|
|
12155
|
+
if (this.#remoteObject.type !== "Doc" && this.#remoteObject.type !== "Global") {
|
|
12156
|
+
console.error("No respawn mixin found for object ", this.#remoteObject.type, this.#remoteObject.genericType);
|
|
12157
|
+
}
|
|
12158
|
+
}
|
|
12159
|
+
};
|
|
12160
|
+
|
|
12161
|
+
// src/qix/session/phoenix/rpc-object-respawn-mixins.ts
|
|
12162
|
+
var refetch1 = {
|
|
12163
|
+
types: ["GenericObject"],
|
|
12164
|
+
override: {
|
|
12165
|
+
async respawn(original, connection) {
|
|
12166
|
+
if (this.__remote__.respawnInfo.isSessionObject) {
|
|
12167
|
+
let objectFoundInEngine = false;
|
|
12168
|
+
if (connection.isReattached()) {
|
|
12169
|
+
try {
|
|
12170
|
+
this.setHandle(
|
|
12171
|
+
await connection.invoke(this.app.handle, { method: "GetObject", params: [this.id], outKey: -1 }).then((res) => res.qHandle)
|
|
12172
|
+
);
|
|
12173
|
+
objectFoundInEngine = true;
|
|
12174
|
+
} catch (err) {
|
|
12175
|
+
console.warn("Session object not found in reattached session", err);
|
|
12176
|
+
objectFoundInEngine = false;
|
|
12177
|
+
}
|
|
12178
|
+
}
|
|
12179
|
+
if (!objectFoundInEngine) {
|
|
12180
|
+
const props = JSON.parse(JSON.stringify(this.__remote__.respawnInfo.properties));
|
|
12181
|
+
props.qInfo = props.qInfo || {};
|
|
12182
|
+
props.qInfo.qId = this.id;
|
|
12183
|
+
logEvent("Respawning session object using", this.__remote__.respawnInfo.properties);
|
|
12184
|
+
this.setHandle(
|
|
12185
|
+
await connection.invoke(this.app.handle, {
|
|
12186
|
+
method: "CreateSessionObject",
|
|
12187
|
+
params: [props],
|
|
12188
|
+
outKey: -1
|
|
12189
|
+
}).then((res) => res.qHandle)
|
|
12190
|
+
);
|
|
12191
|
+
}
|
|
12192
|
+
} else {
|
|
12193
|
+
this.setHandle(
|
|
12194
|
+
await connection.invoke(this.app.handle, { method: "GetObject", params: [this.id], outKey: -1 }).then((res) => res.qHandle)
|
|
12195
|
+
);
|
|
12196
|
+
}
|
|
12197
|
+
if (this.__remote__.respawnInfo.activeModalSelectionPaths && !connection.isReattached()) {
|
|
12198
|
+
try {
|
|
12199
|
+
logEvent(
|
|
12200
|
+
"########### BeginSelections ###################################",
|
|
12201
|
+
this.__remote__.respawnInfo.activeModalSelectionPaths
|
|
12202
|
+
);
|
|
12203
|
+
await connection.invoke(this.handle, {
|
|
12204
|
+
method: "BeginSelections",
|
|
12205
|
+
params: [this.__remote__.respawnInfo.activeModalSelectionPaths],
|
|
12206
|
+
outKey: -1
|
|
12207
|
+
});
|
|
12208
|
+
} catch (err) {
|
|
12209
|
+
console.warn("Could not reapply modal selection state", err);
|
|
12210
|
+
}
|
|
12211
|
+
}
|
|
12212
|
+
},
|
|
12213
|
+
async beginSelections(original, paths) {
|
|
12214
|
+
logEvent("Storing modal selections", this.handle, this.__remote__.respawnInfo.activeModalSelectionPaths);
|
|
12215
|
+
this.__remote__.respawnInfo.activeModalSelectionPaths = paths;
|
|
12216
|
+
return original(paths);
|
|
12217
|
+
},
|
|
12218
|
+
async endSelections(original, accept) {
|
|
12219
|
+
this.__remote__.respawnInfo.activeModalSelectionPaths = void 0;
|
|
12220
|
+
logEvent("Removing modal selections", this.handle, this.__remote__.respawnInfo.activeModalSelectionPaths);
|
|
12221
|
+
return original(accept);
|
|
12222
|
+
},
|
|
12223
|
+
/**
|
|
12224
|
+
* TODO SUPPORT THESE ASWELL
|
|
12225
|
+
applyPatches: (patches: NxPatch[], softPatch?: boolean) => Promise<void>;
|
|
12226
|
+
clearSoftPatches: () => Promise<void>;
|
|
12227
|
+
copyFrom: (fromId: string) => Promise<void>;
|
|
12228
|
+
destroyAllChildren: (propForThis?: CustomProperties) => Promise<void>;
|
|
12229
|
+
destroyChild: (id: string, propForThis?: CustomProperties) => Promise<boolean>;
|
|
12230
|
+
lock: (path: string, colIndices?: number[]) => Promise<void>;
|
|
12231
|
+
resetMadeSelections: () => Promise<void>;
|
|
12232
|
+
setChildArrayOrder: (ids: string[]) => Promise<void>;
|
|
12233
|
+
setFullPropertyTree: (propEntry: GenericObjectEntry) => Promise<void>;
|
|
12234
|
+
setProperties: (prop: CustomProperties) => Promise<void>;
|
|
12235
|
+
unlock: (path: string, colIndices?: number[]) => Promise<void>;
|
|
12236
|
+
*/
|
|
12237
|
+
async setProperties(original, props) {
|
|
12238
|
+
this.__remote__.respawnInfo.properties = props;
|
|
12239
|
+
return original(props);
|
|
12240
|
+
}
|
|
12241
|
+
}
|
|
12242
|
+
};
|
|
12243
|
+
var variableRespawnMixin = {
|
|
12244
|
+
types: ["GenericVariable"],
|
|
12245
|
+
override: {
|
|
12246
|
+
async respawn(original, connection) {
|
|
12247
|
+
logEvent("Respawning variable ", this.id);
|
|
12248
|
+
if (this.__remote__.respawnInfo.isSessionObject) {
|
|
12249
|
+
let objectFoundInEngine = false;
|
|
12250
|
+
if (connection.isReattached()) {
|
|
12251
|
+
try {
|
|
12252
|
+
this.setHandle(
|
|
12253
|
+
await connection.invoke(this.app.handle, { method: "GetObject", params: [this.id], outKey: -1 }).then((res) => res.qHandle)
|
|
12254
|
+
);
|
|
12255
|
+
objectFoundInEngine = true;
|
|
12256
|
+
} catch (err) {
|
|
12257
|
+
console.warn("Session variable not found in reattached session", err);
|
|
12258
|
+
objectFoundInEngine = false;
|
|
12259
|
+
}
|
|
12260
|
+
}
|
|
12261
|
+
if (!objectFoundInEngine) {
|
|
12262
|
+
this.setHandle(
|
|
12263
|
+
await connection.invoke(this.app.handle, {
|
|
12264
|
+
method: "CreateSessionVariable",
|
|
12265
|
+
params: [this.__remote__.respawnInfo.properties],
|
|
12266
|
+
outKey: -1
|
|
12267
|
+
}).then((res) => res.qHandle)
|
|
12268
|
+
);
|
|
12269
|
+
}
|
|
12270
|
+
} else {
|
|
12271
|
+
this.setHandle(
|
|
12272
|
+
await connection.invoke(this.app.handle, { method: "GetObject", params: [this.id], outKey: -1 }).then((res) => res.qHandle)
|
|
12273
|
+
);
|
|
12274
|
+
}
|
|
12275
|
+
},
|
|
12276
|
+
// TODO suppor these functions as well
|
|
12277
|
+
//applyPatches: (patches: NxPatch[]) => Promise<void>;
|
|
12278
|
+
//setDualValue: (text: string, num: number) => Promise<void>;
|
|
12279
|
+
//setNumValue: (val: number) => Promise<void>;
|
|
12280
|
+
//setStringValue: (val: string) => Promise<void>;
|
|
12281
|
+
async setProperties(original, props) {
|
|
12282
|
+
this.__remote__.respawnInfo.properties = props;
|
|
12283
|
+
return original(props);
|
|
12284
|
+
}
|
|
12285
|
+
}
|
|
12286
|
+
};
|
|
12287
|
+
var variarbleMeasureAndBookmarkRespawnMixin = {
|
|
12288
|
+
types: ["GenericDimension", "GenericMeasure", "GenericBookmark"],
|
|
12289
|
+
override: {
|
|
12290
|
+
async respawn(original, connection) {
|
|
12291
|
+
logEvent("Respawning field dimension, measure or bookmark", this.id);
|
|
12292
|
+
this.setHandle(
|
|
12293
|
+
await connection.invoke(this.app.handle, { method: "GetObject", params: [this.id], outKey: -1 }).then((res) => res.qHandle)
|
|
12294
|
+
);
|
|
12295
|
+
}
|
|
12296
|
+
}
|
|
12297
|
+
};
|
|
12298
|
+
var fieldRespawningMixin = {
|
|
12299
|
+
types: ["Field"],
|
|
12300
|
+
override: {
|
|
12301
|
+
async respawn(original, connection) {
|
|
12302
|
+
logEvent("Respawning field object ", this.id);
|
|
12303
|
+
if (this.__remote__.respawnInfo.creatingRequest && this.__remote__.respawnInfo.creatingRequest.method.startsWith("Get")) {
|
|
12304
|
+
this.setHandle(
|
|
12305
|
+
await connection.invoke(1, this.__remote__.respawnInfo.creatingRequest).then((res) => res.qHandle)
|
|
12306
|
+
);
|
|
12307
|
+
logEvent("Respawned field object using creating request ", this.id, this.handle);
|
|
12308
|
+
} else {
|
|
12309
|
+
this.setHandle(0);
|
|
12310
|
+
logEvent("No idea how to respawn", this.id);
|
|
12311
|
+
}
|
|
12312
|
+
}
|
|
12313
|
+
}
|
|
12314
|
+
};
|
|
12315
|
+
var rememberCreatePropsMixin = {
|
|
12316
|
+
types: ["Doc"],
|
|
12317
|
+
override: {
|
|
12318
|
+
async createSessionObject(original, properties) {
|
|
12319
|
+
const object = await original(properties);
|
|
12320
|
+
const phoenixObject = object;
|
|
12321
|
+
phoenixObject.__remote__.respawnInfo.isSessionObject = true;
|
|
12322
|
+
phoenixObject.__remote__.respawnInfo.properties = properties;
|
|
12323
|
+
return phoenixObject;
|
|
12324
|
+
},
|
|
12325
|
+
async createSessionVariable(original, properties) {
|
|
12326
|
+
const object = await original(properties);
|
|
12327
|
+
const phoenixObject = object;
|
|
12328
|
+
phoenixObject.__remote__.respawnInfo.isSessionObject = true;
|
|
12329
|
+
phoenixObject.__remote__.respawnInfo.properties = properties;
|
|
12330
|
+
return object;
|
|
12331
|
+
}
|
|
12332
|
+
}
|
|
12333
|
+
};
|
|
12334
|
+
var rpc_object_respawn_mixins_default = [
|
|
12335
|
+
refetch1,
|
|
12336
|
+
variableRespawnMixin,
|
|
12337
|
+
variarbleMeasureAndBookmarkRespawnMixin,
|
|
12338
|
+
fieldRespawningMixin,
|
|
12339
|
+
rememberCreatePropsMixin
|
|
12340
|
+
];
|
|
12341
|
+
|
|
12342
|
+
// src/qix/session/phoenix/rpc-object-mixins.ts
|
|
12343
|
+
function toMixinMap(mixinsArray) {
|
|
12344
|
+
const mixins6 = {};
|
|
12345
|
+
rpc_object_respawn_mixins_default.concat(mixinsArray).forEach((mixin22) => {
|
|
12346
|
+
(Array.isArray(mixin22.types) ? mixin22.types : [mixin22.types]).forEach((type) => {
|
|
12347
|
+
mixins6[type] = mixins6[type] || [];
|
|
12348
|
+
mixins6[type].push(mixin22);
|
|
12349
|
+
});
|
|
12350
|
+
});
|
|
12351
|
+
return mixins6;
|
|
12352
|
+
}
|
|
12353
|
+
function applyMixins(classPrototype, mixinList) {
|
|
12354
|
+
mixinList.forEach(({ extend: extend3 = {}, override = {} }) => {
|
|
12355
|
+
Object.keys(override).forEach((key) => {
|
|
12356
|
+
if (typeof classPrototype[key] === "function" && typeof override[key] === "function") {
|
|
12357
|
+
const baseFn = classPrototype[key];
|
|
12358
|
+
classPrototype[key] = function wrappedFn(...args) {
|
|
12359
|
+
return override[key].apply(this, [baseFn.bind(this), ...args]);
|
|
12360
|
+
};
|
|
12361
|
+
} else {
|
|
12362
|
+
throw new Error(
|
|
12363
|
+
`Tring to override non-existing function in ${classPrototype.type}/${classPrototype.genericType}: ${key}`
|
|
12364
|
+
);
|
|
12365
|
+
}
|
|
12366
|
+
});
|
|
12367
|
+
Object.keys(extend3).forEach((key) => {
|
|
12368
|
+
if (typeof classPrototype[key] === "function" && typeof extend3[key] === "function") {
|
|
12369
|
+
throw new Error(
|
|
12370
|
+
`Extend is not allowed. Function already exists in ${classPrototype.type}/${classPrototype.genericType}: ${key}`
|
|
12371
|
+
);
|
|
12372
|
+
} else {
|
|
12373
|
+
classPrototype[key] = extend3[key];
|
|
12374
|
+
}
|
|
12375
|
+
});
|
|
12376
|
+
});
|
|
12377
|
+
}
|
|
12378
|
+
function initMixins(rpcObject, mixinList) {
|
|
12379
|
+
mixinList.forEach(({ init }) => {
|
|
12380
|
+
if (init) {
|
|
12381
|
+
init.bind(rpcObject)({ api: rpcObject, config: { Promise } });
|
|
12382
|
+
}
|
|
12383
|
+
});
|
|
12384
|
+
}
|
|
12385
|
+
|
|
12386
|
+
// src/qix/session/phoenix/rpc-object-schema.ts
|
|
12387
|
+
function schemaToStructureOfUnboundFunctions(schema) {
|
|
12388
|
+
const result = {};
|
|
12389
|
+
Object.entries(schema.structs).forEach(([type, objectSchema]) => {
|
|
12390
|
+
result[type] = schemaToFunctionsEntries(objectSchema);
|
|
12391
|
+
});
|
|
12392
|
+
function schemaToFunctionsEntries(objectSchema) {
|
|
12393
|
+
return Object.entries(objectSchema).map(([pascalName, methodSchema]) => {
|
|
12394
|
+
return { methodName: toCamelCase(pascalName), fn: generateUnboundMethod(pascalName, methodSchema) };
|
|
12395
|
+
});
|
|
12396
|
+
}
|
|
12397
|
+
return result;
|
|
12398
|
+
}
|
|
12399
|
+
function generateUnboundMethod(pascalMethodName, methodSchema) {
|
|
12400
|
+
const out = methodSchema.Out;
|
|
12401
|
+
const outKey = out.length === 1 ? out[0].Name : -1;
|
|
12402
|
+
return function generatedMethod(...params) {
|
|
12403
|
+
return this.__remote__.invoke({ method: pascalMethodName, params, outKey });
|
|
12404
|
+
};
|
|
12405
|
+
}
|
|
12406
|
+
function toCamelCase(symbol) {
|
|
12407
|
+
return symbol.substring(0, 1).toLowerCase() + symbol.substring(1);
|
|
12408
|
+
}
|
|
12409
|
+
|
|
12410
|
+
// src/qix/session/phoenix/rpc-object-factory.ts
|
|
12411
|
+
function createRpcObjectFactory(schema, mixinsArray) {
|
|
12412
|
+
return new RpcObjectFactoryImpl(schema, mixinsArray);
|
|
12413
|
+
}
|
|
12414
|
+
var RpcObjectFactoryImpl = class {
|
|
12415
|
+
/**
|
|
12416
|
+
* Map from type to mixin
|
|
12417
|
+
*/
|
|
12418
|
+
#mixinsByType;
|
|
12419
|
+
/**
|
|
12420
|
+
* Map from type to array of native qix functions
|
|
12421
|
+
*/
|
|
12422
|
+
#nativeFunctionsByType;
|
|
12423
|
+
/**
|
|
12424
|
+
* All generated rpc object classes with mixins and native functions
|
|
12425
|
+
*/
|
|
12426
|
+
#generatedClasses = {};
|
|
12427
|
+
constructor(schema, mixinsArray) {
|
|
12428
|
+
this.#mixinsByType = toMixinMap(mixinsArray);
|
|
12429
|
+
this.#nativeFunctionsByType = schemaToStructureOfUnboundFunctions(schema);
|
|
12430
|
+
}
|
|
12431
|
+
/**
|
|
12432
|
+
* Creates a new RPC Object with mixins et'al
|
|
12433
|
+
*/
|
|
12434
|
+
createObject(refMultipleFormats, connection, creatingRequest) {
|
|
12435
|
+
const { handle, id, type, genericType } = normalizeObjectRef(refMultipleFormats);
|
|
12436
|
+
if (!type) {
|
|
12437
|
+
throw new Error(`Trying to create object without type: ${type}`);
|
|
12438
|
+
}
|
|
12439
|
+
const coreRpcObject = new RemoteObjectImpl({
|
|
12440
|
+
connection,
|
|
12441
|
+
handle,
|
|
12442
|
+
respawnInfo: {
|
|
12443
|
+
creatingRequest
|
|
12444
|
+
},
|
|
12445
|
+
id,
|
|
12446
|
+
type,
|
|
12447
|
+
genericType
|
|
12448
|
+
});
|
|
12449
|
+
const TypeSpecificPhoenixRpcClass = this.#getClass(type, genericType);
|
|
12450
|
+
return new TypeSpecificPhoenixRpcClass(coreRpcObject);
|
|
12451
|
+
}
|
|
12452
|
+
#getClass(type, genericType) {
|
|
12453
|
+
const key = `${type}:${genericType}`;
|
|
12454
|
+
if (!this.#generatedClasses[key]) {
|
|
12455
|
+
const rpcFunctions = this.#getRpcFunctionsForType(type);
|
|
12456
|
+
const mixins6 = this.#getMixinsForType(type).concat(this.#getMixinsForType(genericType));
|
|
12457
|
+
this.#generatedClasses[type] = class GeneratedBaseQixRpxObject extends PhoenixRpcObjectImpl {
|
|
12458
|
+
constructor(createProps) {
|
|
12459
|
+
super(createProps);
|
|
12460
|
+
initMixins(this, mixins6);
|
|
12461
|
+
}
|
|
12462
|
+
};
|
|
12463
|
+
const classPrototype = this.#generatedClasses[type].prototype;
|
|
12464
|
+
rpcFunctions.forEach(({ methodName, fn }) => {
|
|
12465
|
+
classPrototype[methodName] = fn;
|
|
12466
|
+
});
|
|
12467
|
+
applyMixins(classPrototype, mixins6);
|
|
12468
|
+
}
|
|
12469
|
+
return this.#generatedClasses[type];
|
|
12470
|
+
}
|
|
12471
|
+
#getMixinsForType(type) {
|
|
12472
|
+
return (type ? this.#mixinsByType[type] : []) || [];
|
|
12473
|
+
}
|
|
12474
|
+
#getRpcFunctionsForType(type) {
|
|
12475
|
+
return this.#nativeFunctionsByType[type];
|
|
12476
|
+
}
|
|
12477
|
+
};
|
|
12478
|
+
|
|
12479
|
+
// src/qix/session/qix-chunk-entrypoint.ts
|
|
12480
|
+
var objectFactory;
|
|
12481
|
+
async function createPhoenixConnectionEntrypoint(openProps, connectionwOwner) {
|
|
12482
|
+
objectFactory = objectFactory || createRpcObjectFactory(engine_api_default, mixins5);
|
|
12483
|
+
return createPhoenixConnection(openProps, objectFactory, connectionwOwner);
|
|
12484
|
+
}
|
|
12485
|
+
async function createEnigmaSessionEntrypoint(openProps) {
|
|
12486
|
+
return createEnigmaSession(openProps);
|
|
12487
|
+
}
|
|
10427
12488
|
export {
|
|
10428
|
-
|
|
12489
|
+
createEnigmaSessionEntrypoint,
|
|
12490
|
+
createPhoenixConnectionEntrypoint
|
|
10429
12491
|
};
|