@qlik/api 1.29.0 → 1.31.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.
Files changed (86) hide show
  1. package/api-keys.d.ts +2 -2
  2. package/api-keys.js +2 -2
  3. package/apps.d.ts +5 -13
  4. package/apps.js +2 -2
  5. package/audits.d.ts +2 -2
  6. package/audits.js +2 -2
  7. package/{auth-types-PkN9CAF_.d.ts → auth-types-DqfMuSRX.d.ts} +1 -0
  8. package/auth.d.ts +27 -3
  9. package/auth.js +8 -4
  10. package/automations.d.ts +38 -38
  11. package/automations.js +2 -2
  12. package/brands.d.ts +2 -2
  13. package/brands.js +2 -2
  14. package/chunks/{2BRBIRM2.js → 6ZONDHRN.js} +1 -1
  15. package/chunks/{2B7YWDQC.js → DLKLPD7T.js} +3 -3
  16. package/chunks/ETNHFALU.js +61 -0
  17. package/chunks/{NBW6PHZU.js → FKDGGR2O.js} +158 -45
  18. package/chunks/{KYCIMQ4L.js → GUU3KZGK.js} +11 -1
  19. package/chunks/{5XNSGPGZ.js → KBSD75QL.js} +1 -1
  20. package/chunks/{4D5NADHK.js → LY7RP2HA.js} +7 -3
  21. package/chunks/{QOOCP2TS.js → M64RLKVG.js} +2074 -12
  22. package/chunks/{5MRIMVKS.js → PLVPW5IR.js} +17 -20
  23. package/chunks/{MGXEGSJC.js → UZTIZ4H5.js} +392 -372
  24. package/chunks/{WQYEWU54.js → YKZ2QYHN.js} +2 -2
  25. package/collections.d.ts +3 -3
  26. package/collections.js +2 -2
  27. package/csp-origins.d.ts +2 -2
  28. package/csp-origins.js +2 -2
  29. package/data-assets.d.ts +2 -2
  30. package/data-assets.js +2 -2
  31. package/data-connections.d.ts +8 -8
  32. package/data-connections.js +2 -2
  33. package/data-credentials.d.ts +2 -2
  34. package/data-credentials.js +2 -2
  35. package/data-files.d.ts +2 -2
  36. package/data-files.js +2 -2
  37. package/docs/authentication.md +47 -0
  38. package/extensions.d.ts +2 -2
  39. package/extensions.js +2 -2
  40. package/glossaries.d.ts +22 -15
  41. package/glossaries.js +2 -2
  42. package/groups.d.ts +5 -4
  43. package/groups.js +2 -2
  44. package/identity-providers.d.ts +2 -2
  45. package/identity-providers.js +2 -2
  46. package/index.d.ts +10 -4
  47. package/index.js +29 -4
  48. package/interceptors.d.ts +2 -2
  49. package/{invoke-fetch-types-BXn-uSF5.d.ts → invoke-fetch-types-Cq7bjkqn.d.ts} +10 -2
  50. package/items.d.ts +3 -3
  51. package/items.js +2 -2
  52. package/licenses.d.ts +5 -2
  53. package/licenses.js +2 -2
  54. package/oauth-clients.d.ts +521 -0
  55. package/oauth-clients.js +112 -0
  56. package/package.json +4 -2
  57. package/qix.d.ts +422 -27
  58. package/qix.js +2 -2
  59. package/quotas.d.ts +2 -2
  60. package/quotas.js +2 -2
  61. package/reload-tasks.d.ts +4 -2
  62. package/reload-tasks.js +2 -2
  63. package/reloads.d.ts +6 -2
  64. package/reloads.js +2 -2
  65. package/reports.d.ts +4 -2
  66. package/reports.js +2 -2
  67. package/roles.d.ts +14 -4
  68. package/roles.js +2 -2
  69. package/spaces.d.ts +3 -7
  70. package/spaces.js +2 -2
  71. package/temp-contents.d.ts +2 -2
  72. package/temp-contents.js +2 -2
  73. package/tenants.d.ts +2 -2
  74. package/tenants.js +2 -2
  75. package/themes.d.ts +2 -2
  76. package/themes.js +2 -2
  77. package/transports.d.ts +2 -2
  78. package/transports.js +2 -2
  79. package/users.d.ts +2 -2
  80. package/users.js +2 -2
  81. package/web-integrations.d.ts +2 -2
  82. package/web-integrations.js +2 -2
  83. package/web-notifications.d.ts +2 -2
  84. package/web-notifications.js +2 -2
  85. package/webhooks.d.ts +2 -2
  86. package/webhooks.js +2 -2
@@ -1,87 +1,138 @@
1
+ import {
2
+ getHumanReadableSocketClosedErrorMessage
3
+ } from "./ETNHFALU.js";
1
4
  import {
2
5
  getPlatform,
3
6
  handleAuthenticationError,
4
7
  invokeFetch,
5
8
  isWindows,
6
9
  toValidWebsocketLocationUrl
7
- } from "./NBW6PHZU.js";
10
+ } from "./FKDGGR2O.js";
8
11
  import "./3RGGGGAR.js";
9
12
  import {
10
13
  isBrowser
11
14
  } from "./2ZQ3ZX7F.js";
12
15
 
13
- // src/qix/session/websocket-errors.ts
14
- var closeCodeEngineTerminating = 4003;
15
- var closeCodeEngineAbnormalClosure = 1006;
16
- var closeCodeEngineProxyGeneric = 4200;
17
- var closeCodeClientTimeout = 4201;
18
- var closeCodeBadRequest = 4202;
19
- var closeCodePermissions = 4203;
20
- var closeCodeNotFound = 4204;
21
- var closeCodeTooManyRequests = 4205;
22
- var closeCodeNetwork = 4206;
23
- var closeCodeDependencyGeneric = 4210;
24
- var closeCodeDependencyUnavailable = 4211;
25
- var closeCodeEngineGeneric = 4220;
26
- var closeCodeEntitlement = 4230;
27
- var closeCodeNoEnginesAvailable = 4240;
28
- var CloseCodeSessionReservationMissing = 4222;
29
- var closeCodeMessages = {
30
- [closeCodeEngineTerminating]: "The engine is in terminating state",
31
- [closeCodeEngineAbnormalClosure]: "The engine is abnormally closed",
32
- [closeCodeEngineProxyGeneric]: "A problem occurred in engine-proxy",
33
- [closeCodeClientTimeout]: "The client has closed the connection",
34
- [closeCodeBadRequest]: "The provided request is invalid and/or malformed",
35
- [closeCodePermissions]: "No permission to open the app",
36
- [closeCodeNotFound]: "App not found",
37
- [closeCodeTooManyRequests]: "Too many requests have been sent in a given amount of time",
38
- [closeCodeNetwork]: "Networking issues",
39
- [closeCodeDependencyGeneric]: "A problem occurred in a dependency of engine-proxy",
40
- [closeCodeDependencyUnavailable]: "A dependency is unavailable and not serving any requests",
41
- [closeCodeEngineGeneric]: "A problem occurred in an engine",
42
- [closeCodeEntitlement]: "You are not entitled to perform that operation",
43
- [closeCodeNoEnginesAvailable]: "There are currently no engines available",
44
- [CloseCodeSessionReservationMissing]: "The reserved session is missing"
45
- };
46
- var uknownCloseErrorMessage = "websocket closed for unknown reason";
47
- function getHumanReadableSocketClosedErrorMessage(err, { appId, hostConfig }) {
48
- const closeCode = err?.original?.code;
49
- const closeMessage = closeCode ? closeCodeMessages[closeCode] || uknownCloseErrorMessage : err.message;
50
- if (hostConfig?.host) {
51
- return `Failed to open app ${appId} on ${hostConfig?.host}: ${closeMessage}`;
52
- } else {
53
- return `Failed to open app ${appId}: ${closeMessage}`;
54
- }
55
- }
56
-
57
- // src/qix/session/shared-sessions.ts
58
- var globalEventListeners = /* @__PURE__ */ new Set();
59
- function globalOnWebSocketEvent(listener) {
60
- globalEventListeners.add(listener);
61
- return () => {
62
- globalEventListeners.delete(listener);
16
+ // src/qix/app-session.ts
17
+ var isBrowserEnvironment = isBrowser();
18
+ function createAppSession(sharedSession) {
19
+ const listeners = /* @__PURE__ */ new Set();
20
+ let alreadyClosed = false;
21
+ const sharedSessionClient = {
22
+ onWebSocketEvent(event) {
23
+ listeners.forEach((listener) => {
24
+ listener(event);
25
+ });
26
+ }
63
27
  };
64
- }
65
- var globalStateListeners = /* @__PURE__ */ new Set();
66
- function globalOnStateChange(listener) {
67
- globalStateListeners.add(listener);
68
- return () => {
69
- globalStateListeners.delete(listener);
28
+ const appSession = {
29
+ getDoc: () => sharedSession.getDoc(),
30
+ onWebSocketEvent(fn) {
31
+ listeners.add(fn);
32
+ return () => {
33
+ listeners.delete(fn);
34
+ };
35
+ },
36
+ resume: async () => {
37
+ return sharedSession.resume();
38
+ },
39
+ close(props) {
40
+ if (!alreadyClosed) {
41
+ alreadyClosed = true;
42
+ const defaultDelay = isBrowserEnvironment ? 5e3 : -1;
43
+ return sharedSession.removeClient(sharedSessionClient, props?.websocketCloseDelay ?? defaultDelay);
44
+ }
45
+ return Promise.resolve();
46
+ },
47
+ /* Only for test cases */
48
+ // @ts-expect-error ts(2353)
49
+ _listeners: listeners
70
50
  };
51
+ sharedSession.addClient(sharedSessionClient);
52
+ return appSession;
71
53
  }
72
- async function resumeAll() {
73
- const promises = [];
74
- Object.keys(globalState.sessionStates).forEach((key) => {
75
- const state = globalState.sessionStates[key];
76
- if (state === "suspended") {
77
- promises.push(sharedSessions[key].resume());
54
+
55
+ // src/qix/external-app-session.ts
56
+ function createExternalSharedSession(externalApp, onWebSocketEvent2, appSessionProps) {
57
+ const clients = [];
58
+ const sharedSession = {
59
+ getDoc: () => externalApp,
60
+ addClient(client) {
61
+ const index = clients.indexOf(client, 0);
62
+ if (index === -1) {
63
+ clients.push(client);
64
+ }
65
+ },
66
+ removeClient(client) {
67
+ const index = clients.indexOf(client, 0);
68
+ if (index > -1) {
69
+ clients.splice(index, 1);
70
+ }
71
+ return Promise.resolve();
72
+ },
73
+ initialActionsUpdated: () => {
74
+ },
75
+ clientsCount: () => clients.length,
76
+ resume: async () => {
77
+ try {
78
+ await externalApp.then((doc) => doc.session?.resume());
79
+ } catch (err) {
80
+ console.warn(err);
81
+ }
82
+ }
83
+ };
84
+ const triggerEventListeners = (event) => {
85
+ onWebSocketEvent2(event);
86
+ for (const client of clients) {
87
+ client.onWebSocketEvent(event);
78
88
  }
89
+ };
90
+ void externalApp.then((app) => {
91
+ app.session.on("opened", (event) => {
92
+ const wsEvent = {
93
+ eventType: "opened",
94
+ ...appSessionProps,
95
+ ...event
96
+ };
97
+ triggerEventListeners(wsEvent);
98
+ });
99
+ app.session.on("closed", (event) => {
100
+ const wsEvent = {
101
+ eventType: "closed",
102
+ ...appSessionProps,
103
+ ...event
104
+ };
105
+ triggerEventListeners(wsEvent);
106
+ });
107
+ app.session.on("suspended", (event) => {
108
+ const wsEvent = {
109
+ eventType: "suspended",
110
+ ...appSessionProps,
111
+ ...event
112
+ };
113
+ triggerEventListeners(wsEvent);
114
+ });
115
+ app.session.on("resuming", (event) => {
116
+ const wsEvent = {
117
+ eventType: "resuming",
118
+ ...appSessionProps,
119
+ ...event
120
+ };
121
+ triggerEventListeners(wsEvent);
122
+ });
123
+ app.session.on("resumed", (event) => {
124
+ const wsEvent = {
125
+ eventType: "resumed",
126
+ ...appSessionProps,
127
+ ...event
128
+ };
129
+ triggerEventListeners(wsEvent);
130
+ });
79
131
  });
80
- await Promise.all(promises);
81
- return Promise.resolve();
132
+ return sharedSession;
82
133
  }
83
- var initialActions = {};
84
- var sharedSessions = {};
134
+
135
+ // src/qix/internal/global-app-session.id.ts
85
136
  function toGlobalAppSessionId({
86
137
  appId,
87
138
  identity,
@@ -89,7 +140,8 @@ function toGlobalAppSessionId({
89
140
  withoutData,
90
141
  useReloadEngine,
91
142
  ttlSeconds,
92
- workloadType
143
+ workloadType,
144
+ autoResume
93
145
  }) {
94
146
  const locationUrl = toValidWebsocketLocationUrl(hostConfig);
95
147
  let url = `${locationUrl}/${appId}`;
@@ -108,38 +160,142 @@ function toGlobalAppSessionId({
108
160
  if (workloadType) {
109
161
  url += `?workloadType=${workloadType}`;
110
162
  }
163
+ if (autoResume) {
164
+ url += "/auto-resume";
165
+ }
111
166
  return url;
112
167
  }
113
- async function runPendingInitialActions(initialActionsForApp, sharedSession, doc) {
114
- for (const initialAction of initialActionsForApp) {
115
- if (sharedSession.alreadyExecutedInitialActions.indexOf(initialAction) === -1) {
116
- sharedSession.alreadyExecutedInitialActions.push(initialAction);
117
- await initialAction(doc);
168
+
169
+ // src/qix/global-events.ts
170
+ var globalEventListeners = /* @__PURE__ */ new Set();
171
+ var globalStateListeners = /* @__PURE__ */ new Set();
172
+ function onWebSocketEvent(listener) {
173
+ globalEventListeners.add(listener);
174
+ return () => {
175
+ globalEventListeners.delete(listener);
176
+ };
177
+ }
178
+ function onCombinedWebSocketStateChange(listener) {
179
+ globalStateListeners.add(listener);
180
+ return () => {
181
+ globalStateListeners.delete(listener);
182
+ };
183
+ }
184
+ var globalState = {
185
+ sessionStates: {},
186
+ state: "closed"
187
+ };
188
+ function stateListener(key, event) {
189
+ if (event.eventType === "closed") {
190
+ delete globalState.sessionStates[key];
191
+ } else {
192
+ globalState.sessionStates[key] = event.eventType;
193
+ }
194
+ const states = Object.values(globalState.sessionStates);
195
+ let anySuspended = false;
196
+ let anyResuming = false;
197
+ for (const state of states) {
198
+ if (state === "suspended") {
199
+ anySuspended = true;
200
+ } else if (state === "resuming") {
201
+ anyResuming = true;
202
+ }
203
+ }
204
+ let newState;
205
+ if (states.length === 0) {
206
+ newState = "closed";
207
+ } else if (anySuspended) {
208
+ newState = "suspended";
209
+ } else if (anyResuming) {
210
+ newState = "resuming";
211
+ } else {
212
+ newState = "open";
213
+ }
214
+ if (globalState.state !== newState) {
215
+ globalState.state = newState;
216
+ for (const fn of globalStateListeners) {
217
+ fn({ state: newState });
118
218
  }
119
219
  }
120
220
  }
121
- function addInitialSharedSessionCreationAction(openAppSessionProps, action) {
122
- const key = toGlobalAppSessionId(openAppSessionProps);
123
- let initialActionArray = initialActions[key];
124
- if (!initialActionArray) {
125
- initialActionArray = initialActions[key] = [];
221
+ function triggerGlobalWebSocketEventListeners(event) {
222
+ for (const fn of globalEventListeners) {
223
+ fn(event);
126
224
  }
127
- initialActionArray.push(action);
128
- const existingSharedSession = sharedSessions[key];
129
- if (existingSharedSession) {
130
- existingSharedSession.docPromise.then((doc) => {
131
- if (doc) {
132
- runPendingInitialActions(initialActionArray, existingSharedSession, doc);
225
+ stateListener(toGlobalAppSessionId(event), event);
226
+ }
227
+
228
+ // src/qix/session/shared-sessions-phoenix.ts
229
+ function createSharedPhoenixSession(props, { onClose, onWebSocketEvent: onWebSocketEventGlobal, getInitialAppActions }) {
230
+ try {
231
+ const clients = [];
232
+ const onWebSocketEvent2 = (event) => {
233
+ onWebSocketEventGlobal(event);
234
+ for (const client of clients) {
235
+ client.onWebSocketEvent(event);
133
236
  }
237
+ };
238
+ const phoenixConnectionPromise = import("./M64RLKVG.js").then((module) => {
239
+ return module.createPhoenixConnectionEntrypoint(props, {
240
+ onWebSocketEvent: onWebSocketEvent2,
241
+ getInitialAppActions
242
+ });
134
243
  });
244
+ const docPromise = phoenixConnectionPromise.then((phoenixConnection) => phoenixConnection.doc);
245
+ const sharedSession = {
246
+ getDoc: () => docPromise,
247
+ addClient(client) {
248
+ const index = clients.indexOf(client, 0);
249
+ if (index === -1) {
250
+ clients.push(client);
251
+ }
252
+ },
253
+ removeClient(client, closeDelay) {
254
+ if (clients.length === 1) {
255
+ void phoenixConnectionPromise.then((phoenixConnection) => {
256
+ phoenixConnection.stopActivityMonitoring();
257
+ });
258
+ }
259
+ const actuallyRemove = () => {
260
+ const index = clients.indexOf(client, 0);
261
+ if (index > -1) {
262
+ clients.splice(index, 1);
263
+ }
264
+ if (clients.length === 0) {
265
+ onClose();
266
+ void phoenixConnectionPromise.then((phoenixConnection) => {
267
+ phoenixConnection.close();
268
+ });
269
+ }
270
+ };
271
+ if (closeDelay > 0) {
272
+ return new Promise((resolve) => {
273
+ setTimeout(() => {
274
+ actuallyRemove();
275
+ resolve();
276
+ }, closeDelay);
277
+ });
278
+ } else {
279
+ actuallyRemove();
280
+ return Promise.resolve();
281
+ }
282
+ },
283
+ resume: async () => {
284
+ void phoenixConnectionPromise.then((session) => session.resume());
285
+ },
286
+ initialActionsUpdated() {
287
+ void phoenixConnectionPromise.then((session) => session.initialAppActionsUpdated());
288
+ },
289
+ clientsCount: () => clients.length
290
+ };
291
+ return sharedSession;
292
+ } catch (err) {
293
+ console.error(err);
294
+ throw err;
135
295
  }
136
- return () => {
137
- const index = initialActionArray.indexOf(action);
138
- if (index > -1) {
139
- initialActionArray.splice(index, 1);
140
- }
141
- };
142
296
  }
297
+
298
+ // src/qix/session/shared-sessions.ts
143
299
  function listenForWindowsAuthenticationInformation(session) {
144
300
  let resolveAuthSuggestedInWebsocket;
145
301
  const authSuggestedInWebsocket = new Promise((resolve, reject) => {
@@ -160,10 +316,10 @@ function listenForWindowsAuthenticationInformation(session) {
160
316
  );
161
317
  return authSuggestedInWebsocket;
162
318
  }
163
- async function createAndSetupEnigmaSession(props, canRetry) {
164
- const { createEnigmaSession } = await import("./QOOCP2TS.js");
165
- const session = await createEnigmaSession(props);
166
- setupSessionListeners(session, props);
319
+ async function createAndSetupEnigmaSession(props, canRetry, onWebSocketEvent2) {
320
+ const { createEnigmaSessionEntrypoint } = await import("./M64RLKVG.js");
321
+ const session = await createEnigmaSessionEntrypoint(props);
322
+ setupSessionListeners(session, props, onWebSocketEvent2);
167
323
  let global;
168
324
  if (await isWindows(props.hostConfig)) {
169
325
  const loginInfoPromise = listenForWindowsAuthenticationInformation(session);
@@ -177,7 +333,7 @@ async function createAndSetupEnigmaSession(props, canRetry) {
177
333
  hostConfig: props.hostConfig
178
334
  });
179
335
  if (canRetry && action.retry) {
180
- return createAndSetupEnigmaSession(props, false);
336
+ return createAndSetupEnigmaSession(props, false, onWebSocketEvent2);
181
337
  }
182
338
  if (action.preventDefault) {
183
339
  return new Promise(() => {
@@ -192,100 +348,7 @@ async function createAndSetupEnigmaSession(props, canRetry) {
192
348
  global
193
349
  };
194
350
  }
195
- var globalState = {
196
- sessionStates: {},
197
- state: "closed"
198
- };
199
- function stateListener(key, event) {
200
- if (event.eventType === "closed") {
201
- delete globalState.sessionStates[key];
202
- } else {
203
- globalState.sessionStates[key] = event.eventType;
204
- }
205
- const states = Object.values(globalState.sessionStates);
206
- let anySuspended = false;
207
- let anyResuming = false;
208
- for (const state of states) {
209
- if (state === "suspended") {
210
- anySuspended = true;
211
- } else if (state === "resuming") {
212
- anyResuming = true;
213
- }
214
- }
215
- let newState;
216
- if (states.length === 0) {
217
- newState = "closed";
218
- } else if (anySuspended) {
219
- newState = "suspended";
220
- } else if (anyResuming) {
221
- newState = "resuming";
222
- } else {
223
- newState = "open";
224
- }
225
- if (globalState.state !== newState) {
226
- globalState.state = newState;
227
- for (const fn of globalStateListeners) {
228
- fn({ state: newState });
229
- }
230
- }
231
- }
232
- function setupSessionListeners(session, props) {
233
- const key = toGlobalAppSessionId(props);
234
- const eventListener = (event) => {
235
- let sharedSession = void 0;
236
- let shouldHandleEvent = false;
237
- if (key in sharedSessions) {
238
- sharedSession = sharedSessions[key];
239
- shouldHandleEvent = sharedSession.connected;
240
- } else if (key in globalState.sessionStates) {
241
- shouldHandleEvent = true;
242
- }
243
- if (!shouldHandleEvent) {
244
- return;
245
- }
246
- stateListener(key, event);
247
- for (const fn of globalEventListeners) {
248
- fn(event);
249
- }
250
- if (sharedSession) {
251
- sharedSession.clients.forEach((client) => {
252
- for (const fn of client._listeners) {
253
- fn(event);
254
- }
255
- });
256
- if (event.eventType === "suspended" && shouldAutoResume(event.code)) {
257
- sharedSession.resume().catch((err) => {
258
- });
259
- }
260
- }
261
- };
262
- const suspendListener = (event) => {
263
- if (!(key in sharedSessions)) {
264
- return;
265
- }
266
- const sharedSession = sharedSessions[key];
267
- let resumed = false;
268
- let resumePromise = Promise.resolve();
269
- sharedSession.resume = async () => {
270
- if (!resumed) {
271
- session.emit("resuming", {});
272
- resumePromise = sessionResumeWithRetry(session, props.hostConfig).catch((err) => {
273
- session.suspend();
274
- return Promise.reject(err);
275
- });
276
- resumed = true;
277
- }
278
- return resumePromise;
279
- };
280
- };
281
- session.on("suspended", (event) => {
282
- const wsEvent = {
283
- eventType: "suspended",
284
- ...props,
285
- ...event
286
- };
287
- suspendListener(wsEvent);
288
- });
351
+ function setupSessionListeners(session, props, eventListener) {
289
352
  session.on("opened", (event) => {
290
353
  const wsEvent = {
291
354
  eventType: "opened",
@@ -367,12 +430,51 @@ function shouldAutoResume(code) {
367
430
  }
368
431
  return false;
369
432
  }
370
- function createSharedSession(props) {
371
- const { sessionPromise, globalPromise } = separatePromises(createAndSetupEnigmaSession(props, true));
433
+ function createSharedEnigmaSession(props, { getInitialAppActions, onClose, onWebSocketEvent: onGlobalWebsocketEvent }) {
434
+ const clients = [];
435
+ const alreadyExecutedInitialActions = [];
436
+ async function runPendingInitialActions(initialActionsForApp, doc) {
437
+ for (const initialAction of initialActionsForApp) {
438
+ if (alreadyExecutedInitialActions.indexOf(initialAction) === -1) {
439
+ alreadyExecutedInitialActions.push(initialAction);
440
+ await initialAction(doc);
441
+ }
442
+ }
443
+ }
444
+ let resumePromise;
445
+ function onWebSocketEvent2(event) {
446
+ if (event.eventType === "suspended") {
447
+ resumePromise = void 0;
448
+ if (shouldAutoResume(event.code)) {
449
+ resume().catch((err) => {
450
+ console.error("Failed to auto-resume");
451
+ });
452
+ }
453
+ }
454
+ for (const client of clients) {
455
+ client.onWebSocketEvent(event);
456
+ }
457
+ onGlobalWebsocketEvent(event);
458
+ }
459
+ const { sessionPromise, globalPromise } = separatePromises(
460
+ createAndSetupEnigmaSession(props, true, onWebSocketEvent2)
461
+ );
462
+ async function resume() {
463
+ if (!resumePromise) {
464
+ resumePromise = (async () => {
465
+ let session = await sessionPromise;
466
+ session.emit("resuming", {});
467
+ await sessionResumeWithRetry(session, props.hostConfig).catch((err) => {
468
+ session.suspend();
469
+ return Promise.reject(err);
470
+ });
471
+ })();
472
+ }
473
+ return resumePromise;
474
+ }
372
475
  const docPromise = globalPromise.then(async (global) => {
373
476
  if (props.useSessionApp) {
374
- const global2 = await sharedSession.globalPromise;
375
- return global2.createSessionApp();
477
+ return global.createSessionApp();
376
478
  } else {
377
479
  return global.openDoc(props.appId, "", "", "", !!props.withoutData).then((doc) => {
378
480
  if (!doc) {
@@ -382,32 +484,40 @@ function createSharedSession(props) {
382
484
  return doc;
383
485
  });
384
486
  }
487
+ }).then(async (doc) => {
488
+ const initialActionsForApp = getInitialAppActions();
489
+ if (initialActionsForApp && doc) {
490
+ await runPendingInitialActions(initialActionsForApp, doc);
491
+ }
492
+ return doc;
493
+ }).catch((err) => {
494
+ closeEnigmaSession();
495
+ const errorWithReadableMessage = new Error(getHumanReadableSocketClosedErrorMessage(err.original || err, props));
496
+ Object.entries(err).forEach(([key, value]) => {
497
+ errorWithReadableMessage[key] = value;
498
+ });
499
+ return Promise.reject(errorWithReadableMessage);
385
500
  });
386
- const key = toGlobalAppSessionId(props);
387
- const clients = [];
388
501
  function closeEnigmaSession() {
389
- delete sharedSessions[key];
390
- return sharedSession.sessionPromise.then((session) => session.close()).catch(() => {
502
+ onClose();
503
+ return sessionPromise.then((session) => session.close()).catch(() => {
391
504
  });
392
505
  }
393
506
  const sharedSession = {
394
- sessionPromise,
395
- globalPromise,
396
- docPromise,
397
- clients,
507
+ getDoc: () => docPromise,
398
508
  addClient(client) {
399
- const index = sharedSession.clients.indexOf(client, 0);
509
+ const index = clients.indexOf(client, 0);
400
510
  if (index === -1) {
401
- sharedSession.clients.push(client);
511
+ clients.push(client);
402
512
  }
403
513
  },
404
514
  removeClient(client, closeDelay) {
405
515
  const actuallyRemove = () => {
406
- const index = sharedSession.clients.indexOf(client, 0);
516
+ const index = clients.indexOf(client, 0);
407
517
  if (index > -1) {
408
- sharedSession.clients.splice(index, 1);
518
+ clients.splice(index, 1);
409
519
  }
410
- if (sharedSession.clients.length === 0) {
520
+ if (clients.length === 0) {
411
521
  closeEnigmaSession();
412
522
  }
413
523
  };
@@ -423,36 +533,15 @@ function createSharedSession(props) {
423
533
  }
424
534
  return Promise.resolve();
425
535
  },
426
- alreadyExecutedInitialActions: [],
427
- resume: () => {
428
- return Promise.resolve();
536
+ resume,
537
+ initialActionsUpdated() {
538
+ getInitialAppActions();
429
539
  },
430
- connected: false
540
+ clientsCount: () => clients.length
431
541
  };
432
- sharedSession.docPromise = sharedSession.docPromise.then(async (doc) => {
433
- sharedSession.connected = true;
434
- const session = await sharedSession.sessionPromise;
435
- session.emit("opened", {});
436
- const initialActionsForApp = initialActions[key];
437
- if (initialActionsForApp && doc) {
438
- await runPendingInitialActions(initialActionsForApp, sharedSession, doc);
439
- }
440
- return doc;
441
- });
442
- sharedSession.docPromise = sharedSession.docPromise.catch((err) => {
443
- closeEnigmaSession();
444
- const errorWithReadableMessage = new Error(getHumanReadableSocketClosedErrorMessage(err, props));
445
- Object.entries(err).forEach(([key2, value]) => {
446
- errorWithReadableMessage[key2] = value;
447
- });
448
- return Promise.reject(errorWithReadableMessage);
449
- });
450
542
  return sharedSession;
451
543
  }
452
544
  var onlyOnReattach = false;
453
- function resumeShouldRejectPromiseIfNotReattached(bool) {
454
- onlyOnReattach = bool;
455
- }
456
545
  async function checkConnectivity(hostConfig) {
457
546
  let status = "online";
458
547
  const method = "get";
@@ -511,76 +600,80 @@ async function sessionResumeWithRetry(session, hostConfig) {
511
600
  }
512
601
  return Promise.resolve();
513
602
  }
603
+
604
+ // src/qix/shared-sessions-manager.ts
605
+ var initialActions = {};
606
+ var sharedSessions = {};
607
+ var externalApps = {};
514
608
  function getOrCreateSharedSession(props) {
609
+ const appSessionId = toGlobalAppSessionId(props);
610
+ const externalAppSession = externalApps[appSessionId];
611
+ if (externalAppSession) {
612
+ return externalAppSession;
613
+ }
515
614
  const key = toGlobalAppSessionId(props);
516
- sharedSessions[key] = sharedSessions[key] || createSharedSession(props);
517
- return sharedSessions[key];
518
- }
519
- function getExternalSession(externalApp, appSessionProps) {
520
- const listeners = /* @__PURE__ */ new Set();
521
- const appSession = {
522
- _listeners: listeners,
523
- getDoc: () => externalApp,
524
- onWebSocketEvent: (fn) => () => {
525
- appSession._listeners.add(fn);
526
- return () => {
527
- appSession._listeners.delete(fn);
528
- };
615
+ if (sharedSessions[key]) {
616
+ return sharedSessions[key];
617
+ }
618
+ const extraProps = {
619
+ onClose: () => {
620
+ delete sharedSessions[key];
529
621
  },
530
- resume: () => Promise.resolve(),
531
- close: () => Promise.resolve()
532
- };
533
- const triggerEventListeners = (event) => {
534
- for (const fn of globalEventListeners) {
535
- fn(event);
622
+ onWebSocketEvent: triggerGlobalWebSocketEventListeners,
623
+ getInitialAppActions: () => {
624
+ return initialActions[key] || [];
536
625
  }
537
- for (const fn of appSession._listeners) {
538
- fn(event);
626
+ };
627
+ let session;
628
+ if (props.autoResume) {
629
+ session = createSharedPhoenixSession(props, extraProps);
630
+ } else {
631
+ session = createSharedEnigmaSession(props, extraProps);
632
+ }
633
+ sharedSessions[key] = session;
634
+ return sharedSessions[key];
635
+ }
636
+ async function resumeSuspendedSessions() {
637
+ await Promise.all(
638
+ Object.values(sharedSessions).map((sharedSession) => {
639
+ return sharedSession.resume();
640
+ })
641
+ );
642
+ }
643
+ async function resumeOnlyOnReattach() {
644
+ await Promise.all(
645
+ Object.values(sharedSessions).map((sharedSession) => {
646
+ return sharedSession.resume();
647
+ })
648
+ );
649
+ }
650
+ function addInitialAppAction(openAppSessionProps, action) {
651
+ const key = toGlobalAppSessionId(openAppSessionProps);
652
+ let initialActionArray = initialActions[key];
653
+ if (!initialActionArray) {
654
+ initialActionArray = [];
655
+ initialActions[key] = initialActionArray;
656
+ }
657
+ initialActionArray.push(action);
658
+ const existingSharedSession = sharedSessions[key];
659
+ if (existingSharedSession) {
660
+ existingSharedSession.initialActionsUpdated();
661
+ }
662
+ return () => {
663
+ const index = initialActionArray.indexOf(action);
664
+ if (index > -1) {
665
+ initialActionArray.splice(index, 1);
539
666
  }
540
667
  };
541
- externalApp.then((app) => {
542
- app.session.on("opened", (event) => {
543
- const wsEvent = {
544
- eventType: "opened",
545
- ...appSessionProps,
546
- ...event
547
- };
548
- triggerEventListeners(wsEvent);
549
- });
550
- app.session.on("closed", (event) => {
551
- const wsEvent = {
552
- eventType: "closed",
553
- ...appSessionProps,
554
- ...event
555
- };
556
- triggerEventListeners(wsEvent);
557
- });
558
- app.session.on("suspended", (event) => {
559
- const wsEvent = {
560
- eventType: "suspended",
561
- ...appSessionProps,
562
- ...event
563
- };
564
- triggerEventListeners(wsEvent);
565
- });
566
- app.session.on("resuming", (event) => {
567
- const wsEvent = {
568
- eventType: "resuming",
569
- ...appSessionProps,
570
- ...event
571
- };
572
- triggerEventListeners(wsEvent);
573
- });
574
- app.session.on("resumed", (event) => {
575
- const wsEvent = {
576
- eventType: "resumed",
577
- ...appSessionProps,
578
- ...event
579
- };
580
- triggerEventListeners(wsEvent);
581
- });
668
+ }
669
+ function registerExternalAppSession(appId, enigmaDocObject) {
670
+ const appSessionId = toGlobalAppSessionId({ appId });
671
+ function onWebSocketEvent2(event) {
672
+ triggerGlobalWebSocketEventListeners(event);
673
+ }
674
+ externalApps[appSessionId] = createExternalSharedSession(Promise.resolve(enigmaDocObject), onWebSocketEvent2, {
675
+ appId
582
676
  });
583
- return appSession;
584
677
  }
585
678
 
586
679
  // src/qix/qix-functions.ts
@@ -596,103 +689,30 @@ async function createSessionApp(ttlSeconds, workloadType) {
596
689
  workloadType
597
690
  });
598
691
  }
599
- let alreadyClosed = false;
600
- const listeners = /* @__PURE__ */ new Set();
601
- const qixSessionAppSession = {
602
- getDoc: () => sharedSession.docPromise,
603
- onWebSocketEvent(fn) {
604
- qixSessionAppSession._listeners.add(fn);
605
- return () => {
606
- qixSessionAppSession._listeners.delete(fn);
607
- };
608
- },
609
- _listeners: listeners,
610
- resume: async () => {
611
- return await sharedSession.resume();
612
- },
613
- close(props) {
614
- if (!alreadyClosed) {
615
- alreadyClosed = true;
616
- const defaultDelay = isBrowserEnvironment ? 5e3 : -1;
617
- return sharedSession.removeClient(qixSessionAppSession, props?.websocketCloseDelay ?? defaultDelay);
618
- }
619
- return Promise.resolve();
620
- }
621
- };
622
- return qixSessionAppSession;
692
+ return createAppSession(sharedSession);
623
693
  }
624
694
  function openAppSession(appIdOrProps) {
625
- const appSessionProps = typeof appIdOrProps === "string" ? { appId: appIdOrProps, identity: void 0, hostConfig: void 0 } : appIdOrProps;
626
- const appSessionId = toGlobalAppSessionId(appSessionProps);
627
- const externalApp = externalApps[appSessionId];
628
- if (externalApp) {
629
- return getExternalSession(externalApp, appSessionProps);
630
- }
695
+ const appSessionProps = typeof appIdOrProps === "string" ? { appId: appIdOrProps } : appIdOrProps;
631
696
  const sharedSession = getOrCreateSharedSession(appSessionProps);
632
- const listeners = /* @__PURE__ */ new Set();
633
- let alreadyClosed = false;
634
- const qixAppSession = {
635
- getDoc: () => sharedSession.docPromise,
636
- onWebSocketEvent(fn) {
637
- qixAppSession._listeners.add(fn);
638
- return () => {
639
- qixAppSession._listeners.delete(fn);
640
- };
641
- },
642
- _listeners: listeners,
643
- resume: async () => {
644
- return await sharedSession.resume();
645
- },
646
- close(props) {
647
- if (!alreadyClosed) {
648
- alreadyClosed = true;
649
- const defaultDelay = isBrowserEnvironment ? 5e3 : -1;
650
- return sharedSession.removeClient(qixAppSession, props?.websocketCloseDelay ?? defaultDelay);
651
- }
652
- return Promise.resolve();
653
- }
654
- };
655
- sharedSession.addClient(qixAppSession);
656
- return qixAppSession;
657
- }
658
- function registerExternalAppSession(appId, enigmaDocObject) {
659
- const appSessionId = toGlobalAppSessionId({ appId });
660
- externalApps[appSessionId] = Promise.resolve(enigmaDocObject);
697
+ return createAppSession(sharedSession);
661
698
  }
662
699
  function useAppHook(react) {
663
700
  return (appId) => {
664
701
  const [app, setApp] = react.useState(void 0);
665
702
  react.useEffect(() => {
666
703
  const appSession = openAppSession(appId);
667
- appSession.getDoc().then((x) => {
704
+ void appSession.getDoc().then((x) => {
668
705
  setApp(x);
669
706
  });
670
707
  return () => {
671
708
  if (appSession) {
672
- appSession.close();
709
+ void appSession.close();
673
710
  }
674
711
  };
675
712
  }, [appId]);
676
713
  return app;
677
714
  };
678
715
  }
679
- function addInitialAppAction(openAppSessionProps, action) {
680
- return addInitialSharedSessionCreationAction(openAppSessionProps, action);
681
- }
682
- function onWebSocketEvent(fn) {
683
- return globalOnWebSocketEvent(fn);
684
- }
685
- function onCombinedWebSocketStateChange(fn) {
686
- return globalOnStateChange(fn);
687
- }
688
- async function resumeSuspendedSessions() {
689
- return resumeAll();
690
- }
691
- function resumeOnlyOnReattach(bool) {
692
- resumeShouldRejectPromiseIfNotReattached(bool);
693
- }
694
- var externalApps = {};
695
- var isBrowserEnvironment = isBrowser();
696
716
 
697
717
  // src/qix/qix.ts
698
718
  var qix = {