@kapeta/local-cluster-service 0.58.1 → 0.58.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/cjs/src/storm/PromiseQueue.d.ts +16 -0
- package/dist/cjs/src/storm/PromiseQueue.js +64 -0
- package/dist/cjs/src/storm/events.d.ts +2 -0
- package/dist/cjs/src/storm/routes.js +13 -4
- package/dist/cjs/src/storm/stormClient.d.ts +1 -0
- package/dist/esm/src/storm/PromiseQueue.d.ts +16 -0
- package/dist/esm/src/storm/PromiseQueue.js +64 -0
- package/dist/esm/src/storm/events.d.ts +2 -0
- package/dist/esm/src/storm/routes.js +13 -4
- package/dist/esm/src/storm/stormClient.d.ts +1 -0
- package/package.json +1 -1
- package/src/storm/PromiseQueue.ts +86 -0
- package/src/storm/events.ts +2 -0
- package/src/storm/routes.ts +43 -29
- package/src/storm/stormClient.ts +1 -0
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
## [0.58.3](https://github.com/kapetacom/local-cluster-service/compare/v0.58.2...v0.58.3) (2024-07-26)
|
2
|
+
|
3
|
+
|
4
|
+
### Bug Fixes
|
5
|
+
|
6
|
+
* Ensure that we can control concurrency in page generation ([#203](https://github.com/kapetacom/local-cluster-service/issues/203)) ([4a919e0](https://github.com/kapetacom/local-cluster-service/commit/4a919e013b20f10d4199927970fbe38091a2b858))
|
7
|
+
|
8
|
+
## [0.58.2](https://github.com/kapetacom/local-cluster-service/compare/v0.58.1...v0.58.2) (2024-07-25)
|
9
|
+
|
10
|
+
|
11
|
+
### Bug Fixes
|
12
|
+
|
13
|
+
* Include title in journeys and pages ([16def8d](https://github.com/kapetacom/local-cluster-service/commit/16def8d726fb3b922ffc6934ce59c981996c3523))
|
14
|
+
|
1
15
|
## [0.58.1](https://github.com/kapetacom/local-cluster-service/compare/v0.58.0...v0.58.1) (2024-07-24)
|
2
16
|
|
3
17
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright 2023 Kapeta Inc.
|
3
|
+
* SPDX-License-Identifier: BUSL-1.1
|
4
|
+
*/
|
5
|
+
export type Future<T> = () => Promise<T>;
|
6
|
+
export declare class PromiseQueue {
|
7
|
+
private readonly queue;
|
8
|
+
private readonly active;
|
9
|
+
private readonly maxConcurrency;
|
10
|
+
constructor(maxConcurrency?: number);
|
11
|
+
private toInternal;
|
12
|
+
add<T>(future: Future<T>): Promise<T>;
|
13
|
+
private next;
|
14
|
+
cancel(): void;
|
15
|
+
wait(): Promise<void>;
|
16
|
+
}
|
@@ -0,0 +1,64 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.PromiseQueue = void 0;
|
4
|
+
class PromiseQueue {
|
5
|
+
queue = [];
|
6
|
+
active = [];
|
7
|
+
// Maximum number of concurrent promises
|
8
|
+
maxConcurrency;
|
9
|
+
constructor(maxConcurrency = 5) {
|
10
|
+
this.maxConcurrency = maxConcurrency;
|
11
|
+
}
|
12
|
+
toInternal(future) {
|
13
|
+
let resolve = () => { };
|
14
|
+
let reject = () => { };
|
15
|
+
const promise = new Promise((res, rej) => {
|
16
|
+
resolve = res;
|
17
|
+
reject = rej;
|
18
|
+
});
|
19
|
+
return {
|
20
|
+
execute: future,
|
21
|
+
promise,
|
22
|
+
resolve,
|
23
|
+
reject,
|
24
|
+
};
|
25
|
+
}
|
26
|
+
add(future) {
|
27
|
+
const internal = this.toInternal(future);
|
28
|
+
this.queue.push(internal);
|
29
|
+
this.next();
|
30
|
+
return internal.promise;
|
31
|
+
}
|
32
|
+
next() {
|
33
|
+
if (this.active.length >= this.maxConcurrency) {
|
34
|
+
return false;
|
35
|
+
}
|
36
|
+
if (this.queue.length === 0) {
|
37
|
+
return false;
|
38
|
+
}
|
39
|
+
const future = this.queue.shift();
|
40
|
+
if (!future) {
|
41
|
+
return false;
|
42
|
+
}
|
43
|
+
const promise = future
|
44
|
+
.execute()
|
45
|
+
.then(future.resolve)
|
46
|
+
.catch(future.reject)
|
47
|
+
.finally(() => {
|
48
|
+
this.active.splice(this.active.indexOf(promise), 1);
|
49
|
+
this.next();
|
50
|
+
});
|
51
|
+
this.active.push(promise);
|
52
|
+
return this.next();
|
53
|
+
}
|
54
|
+
cancel() {
|
55
|
+
this.queue.splice(0, this.queue.length);
|
56
|
+
this.active.splice(0, this.active.length);
|
57
|
+
}
|
58
|
+
async wait() {
|
59
|
+
while (this.queue.length > 0 || this.active.length > 0) {
|
60
|
+
await Promise.all(this.active);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
64
|
+
exports.PromiseQueue = PromiseQueue;
|
@@ -268,6 +268,7 @@ export interface StormEventPhases {
|
|
268
268
|
}
|
269
269
|
export interface Page {
|
270
270
|
name: string;
|
271
|
+
title: string;
|
271
272
|
description: string;
|
272
273
|
content: string;
|
273
274
|
path: string;
|
@@ -282,6 +283,7 @@ export interface StormEventPage {
|
|
282
283
|
}
|
283
284
|
export interface UserJourneyScreen {
|
284
285
|
name: string;
|
286
|
+
title: string;
|
285
287
|
filename: string;
|
286
288
|
requirements: string;
|
287
289
|
path: string;
|
@@ -19,6 +19,7 @@ const event_parser_1 = require("./event-parser");
|
|
19
19
|
const codegen_1 = require("./codegen");
|
20
20
|
const assetManager_1 = require("../assetManager");
|
21
21
|
const node_uuid_1 = __importDefault(require("node-uuid"));
|
22
|
+
const PromiseQueue_1 = require("./PromiseQueue");
|
22
23
|
const router = (0, express_promise_router_1.default)();
|
23
24
|
router.use('/', cors_1.corsHandler);
|
24
25
|
router.use('/', stringBody_1.stringBody);
|
@@ -61,6 +62,10 @@ router.post('/:handle/ui', async (req, res) => {
|
|
61
62
|
res.set('Access-Control-Expose-Headers', stormClient_1.ConversationIdHeader);
|
62
63
|
res.set(stormClient_1.ConversationIdHeader, userJourneysStream.getConversationId());
|
63
64
|
const promises = {};
|
65
|
+
const queue = new PromiseQueue_1.PromiseQueue(10);
|
66
|
+
onRequestAborted(req, res, () => {
|
67
|
+
queue.cancel();
|
68
|
+
});
|
64
69
|
userJourneysStream.on('data', async (data) => {
|
65
70
|
try {
|
66
71
|
console.log('Processing user journey event', data);
|
@@ -68,11 +73,14 @@ router.post('/:handle/ui', async (req, res) => {
|
|
68
73
|
if (data.type !== 'USER_JOURNEY') {
|
69
74
|
return;
|
70
75
|
}
|
76
|
+
if (userJourneysStream.isAborted()) {
|
77
|
+
return;
|
78
|
+
}
|
71
79
|
data.payload.screens.forEach((screen) => {
|
72
80
|
if (screen.name in promises) {
|
73
81
|
return;
|
74
82
|
}
|
75
|
-
promises[screen.name] = new Promise(async (resolve, reject) => {
|
83
|
+
promises[screen.name] = queue.add(() => new Promise(async (resolve, reject) => {
|
76
84
|
try {
|
77
85
|
const innerConversationId = node_uuid_1.default.v4();
|
78
86
|
const screenStream = await stormClient_1.stormClient.createUIPage({
|
@@ -81,13 +89,13 @@ router.post('/:handle/ui', async (req, res) => {
|
|
81
89
|
path: screen.path,
|
82
90
|
description: screen.requirements,
|
83
91
|
name: screen.name,
|
92
|
+
title: screen.title,
|
84
93
|
filename: screen.filename,
|
85
94
|
}, innerConversationId);
|
86
95
|
screenStream.on('data', (screenData) => {
|
87
96
|
if (screenData.type === 'PAGE') {
|
88
97
|
screenData.payload.conversationId = innerConversationId;
|
89
98
|
}
|
90
|
-
console.log('Processing screen event', screenData);
|
91
99
|
sendEvent(res, screenData);
|
92
100
|
});
|
93
101
|
screenStream.on('end', () => {
|
@@ -95,9 +103,10 @@ router.post('/:handle/ui', async (req, res) => {
|
|
95
103
|
});
|
96
104
|
}
|
97
105
|
catch (e) {
|
106
|
+
console.error('Failed to process screen', e);
|
98
107
|
reject(e);
|
99
108
|
}
|
100
|
-
});
|
109
|
+
}));
|
101
110
|
});
|
102
111
|
}
|
103
112
|
catch (e) {
|
@@ -105,10 +114,10 @@ router.post('/:handle/ui', async (req, res) => {
|
|
105
114
|
}
|
106
115
|
});
|
107
116
|
await waitForStormStream(userJourneysStream);
|
117
|
+
await queue.wait();
|
108
118
|
if (userJourneysStream.isAborted()) {
|
109
119
|
return;
|
110
120
|
}
|
111
|
-
await Promise.all(Object.values(promises));
|
112
121
|
sendDone(res);
|
113
122
|
}
|
114
123
|
catch (err) {
|
@@ -0,0 +1,16 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright 2023 Kapeta Inc.
|
3
|
+
* SPDX-License-Identifier: BUSL-1.1
|
4
|
+
*/
|
5
|
+
export type Future<T> = () => Promise<T>;
|
6
|
+
export declare class PromiseQueue {
|
7
|
+
private readonly queue;
|
8
|
+
private readonly active;
|
9
|
+
private readonly maxConcurrency;
|
10
|
+
constructor(maxConcurrency?: number);
|
11
|
+
private toInternal;
|
12
|
+
add<T>(future: Future<T>): Promise<T>;
|
13
|
+
private next;
|
14
|
+
cancel(): void;
|
15
|
+
wait(): Promise<void>;
|
16
|
+
}
|
@@ -0,0 +1,64 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.PromiseQueue = void 0;
|
4
|
+
class PromiseQueue {
|
5
|
+
queue = [];
|
6
|
+
active = [];
|
7
|
+
// Maximum number of concurrent promises
|
8
|
+
maxConcurrency;
|
9
|
+
constructor(maxConcurrency = 5) {
|
10
|
+
this.maxConcurrency = maxConcurrency;
|
11
|
+
}
|
12
|
+
toInternal(future) {
|
13
|
+
let resolve = () => { };
|
14
|
+
let reject = () => { };
|
15
|
+
const promise = new Promise((res, rej) => {
|
16
|
+
resolve = res;
|
17
|
+
reject = rej;
|
18
|
+
});
|
19
|
+
return {
|
20
|
+
execute: future,
|
21
|
+
promise,
|
22
|
+
resolve,
|
23
|
+
reject,
|
24
|
+
};
|
25
|
+
}
|
26
|
+
add(future) {
|
27
|
+
const internal = this.toInternal(future);
|
28
|
+
this.queue.push(internal);
|
29
|
+
this.next();
|
30
|
+
return internal.promise;
|
31
|
+
}
|
32
|
+
next() {
|
33
|
+
if (this.active.length >= this.maxConcurrency) {
|
34
|
+
return false;
|
35
|
+
}
|
36
|
+
if (this.queue.length === 0) {
|
37
|
+
return false;
|
38
|
+
}
|
39
|
+
const future = this.queue.shift();
|
40
|
+
if (!future) {
|
41
|
+
return false;
|
42
|
+
}
|
43
|
+
const promise = future
|
44
|
+
.execute()
|
45
|
+
.then(future.resolve)
|
46
|
+
.catch(future.reject)
|
47
|
+
.finally(() => {
|
48
|
+
this.active.splice(this.active.indexOf(promise), 1);
|
49
|
+
this.next();
|
50
|
+
});
|
51
|
+
this.active.push(promise);
|
52
|
+
return this.next();
|
53
|
+
}
|
54
|
+
cancel() {
|
55
|
+
this.queue.splice(0, this.queue.length);
|
56
|
+
this.active.splice(0, this.active.length);
|
57
|
+
}
|
58
|
+
async wait() {
|
59
|
+
while (this.queue.length > 0 || this.active.length > 0) {
|
60
|
+
await Promise.all(this.active);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
64
|
+
exports.PromiseQueue = PromiseQueue;
|
@@ -268,6 +268,7 @@ export interface StormEventPhases {
|
|
268
268
|
}
|
269
269
|
export interface Page {
|
270
270
|
name: string;
|
271
|
+
title: string;
|
271
272
|
description: string;
|
272
273
|
content: string;
|
273
274
|
path: string;
|
@@ -282,6 +283,7 @@ export interface StormEventPage {
|
|
282
283
|
}
|
283
284
|
export interface UserJourneyScreen {
|
284
285
|
name: string;
|
286
|
+
title: string;
|
285
287
|
filename: string;
|
286
288
|
requirements: string;
|
287
289
|
path: string;
|
@@ -19,6 +19,7 @@ const event_parser_1 = require("./event-parser");
|
|
19
19
|
const codegen_1 = require("./codegen");
|
20
20
|
const assetManager_1 = require("../assetManager");
|
21
21
|
const node_uuid_1 = __importDefault(require("node-uuid"));
|
22
|
+
const PromiseQueue_1 = require("./PromiseQueue");
|
22
23
|
const router = (0, express_promise_router_1.default)();
|
23
24
|
router.use('/', cors_1.corsHandler);
|
24
25
|
router.use('/', stringBody_1.stringBody);
|
@@ -61,6 +62,10 @@ router.post('/:handle/ui', async (req, res) => {
|
|
61
62
|
res.set('Access-Control-Expose-Headers', stormClient_1.ConversationIdHeader);
|
62
63
|
res.set(stormClient_1.ConversationIdHeader, userJourneysStream.getConversationId());
|
63
64
|
const promises = {};
|
65
|
+
const queue = new PromiseQueue_1.PromiseQueue(10);
|
66
|
+
onRequestAborted(req, res, () => {
|
67
|
+
queue.cancel();
|
68
|
+
});
|
64
69
|
userJourneysStream.on('data', async (data) => {
|
65
70
|
try {
|
66
71
|
console.log('Processing user journey event', data);
|
@@ -68,11 +73,14 @@ router.post('/:handle/ui', async (req, res) => {
|
|
68
73
|
if (data.type !== 'USER_JOURNEY') {
|
69
74
|
return;
|
70
75
|
}
|
76
|
+
if (userJourneysStream.isAborted()) {
|
77
|
+
return;
|
78
|
+
}
|
71
79
|
data.payload.screens.forEach((screen) => {
|
72
80
|
if (screen.name in promises) {
|
73
81
|
return;
|
74
82
|
}
|
75
|
-
promises[screen.name] = new Promise(async (resolve, reject) => {
|
83
|
+
promises[screen.name] = queue.add(() => new Promise(async (resolve, reject) => {
|
76
84
|
try {
|
77
85
|
const innerConversationId = node_uuid_1.default.v4();
|
78
86
|
const screenStream = await stormClient_1.stormClient.createUIPage({
|
@@ -81,13 +89,13 @@ router.post('/:handle/ui', async (req, res) => {
|
|
81
89
|
path: screen.path,
|
82
90
|
description: screen.requirements,
|
83
91
|
name: screen.name,
|
92
|
+
title: screen.title,
|
84
93
|
filename: screen.filename,
|
85
94
|
}, innerConversationId);
|
86
95
|
screenStream.on('data', (screenData) => {
|
87
96
|
if (screenData.type === 'PAGE') {
|
88
97
|
screenData.payload.conversationId = innerConversationId;
|
89
98
|
}
|
90
|
-
console.log('Processing screen event', screenData);
|
91
99
|
sendEvent(res, screenData);
|
92
100
|
});
|
93
101
|
screenStream.on('end', () => {
|
@@ -95,9 +103,10 @@ router.post('/:handle/ui', async (req, res) => {
|
|
95
103
|
});
|
96
104
|
}
|
97
105
|
catch (e) {
|
106
|
+
console.error('Failed to process screen', e);
|
98
107
|
reject(e);
|
99
108
|
}
|
100
|
-
});
|
109
|
+
}));
|
101
110
|
});
|
102
111
|
}
|
103
112
|
catch (e) {
|
@@ -105,10 +114,10 @@ router.post('/:handle/ui', async (req, res) => {
|
|
105
114
|
}
|
106
115
|
});
|
107
116
|
await waitForStormStream(userJourneysStream);
|
117
|
+
await queue.wait();
|
108
118
|
if (userJourneysStream.isAborted()) {
|
109
119
|
return;
|
110
120
|
}
|
111
|
-
await Promise.all(Object.values(promises));
|
112
121
|
sendDone(res);
|
113
122
|
}
|
114
123
|
catch (err) {
|
package/package.json
CHANGED
@@ -0,0 +1,86 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright 2023 Kapeta Inc.
|
3
|
+
* SPDX-License-Identifier: BUSL-1.1
|
4
|
+
*/
|
5
|
+
export type Future<T> = () => Promise<T>;
|
6
|
+
|
7
|
+
type InternalFuture<T> = {
|
8
|
+
execute: Future<T>;
|
9
|
+
promise: Promise<T>;
|
10
|
+
resolve: (value: T) => void;
|
11
|
+
reject: (reason: any) => void;
|
12
|
+
};
|
13
|
+
|
14
|
+
export class PromiseQueue {
|
15
|
+
private readonly queue: InternalFuture<any>[] = [];
|
16
|
+
private readonly active: Promise<any>[] = [];
|
17
|
+
|
18
|
+
// Maximum number of concurrent promises
|
19
|
+
private readonly maxConcurrency: number;
|
20
|
+
|
21
|
+
constructor(maxConcurrency: number = 5) {
|
22
|
+
this.maxConcurrency = maxConcurrency;
|
23
|
+
}
|
24
|
+
|
25
|
+
private toInternal<T>(future: Future<T>): InternalFuture<T> {
|
26
|
+
let resolve: (value: T) => void = () => {};
|
27
|
+
let reject: (reason: any) => void = () => {};
|
28
|
+
|
29
|
+
const promise = new Promise<T>((res, rej) => {
|
30
|
+
resolve = res;
|
31
|
+
reject = rej;
|
32
|
+
});
|
33
|
+
return {
|
34
|
+
execute: future,
|
35
|
+
promise,
|
36
|
+
resolve,
|
37
|
+
reject,
|
38
|
+
};
|
39
|
+
}
|
40
|
+
|
41
|
+
public add<T>(future: Future<T>) {
|
42
|
+
const internal = this.toInternal<T>(future);
|
43
|
+
this.queue.push(internal);
|
44
|
+
this.next();
|
45
|
+
|
46
|
+
return internal.promise;
|
47
|
+
}
|
48
|
+
|
49
|
+
private next(): boolean {
|
50
|
+
if (this.active.length >= this.maxConcurrency) {
|
51
|
+
return false;
|
52
|
+
}
|
53
|
+
if (this.queue.length === 0) {
|
54
|
+
return false;
|
55
|
+
}
|
56
|
+
|
57
|
+
const future = this.queue.shift();
|
58
|
+
if (!future) {
|
59
|
+
return false;
|
60
|
+
}
|
61
|
+
|
62
|
+
const promise = future
|
63
|
+
.execute()
|
64
|
+
.then(future.resolve)
|
65
|
+
.catch(future.reject)
|
66
|
+
.finally(() => {
|
67
|
+
this.active.splice(this.active.indexOf(promise), 1);
|
68
|
+
this.next();
|
69
|
+
});
|
70
|
+
|
71
|
+
this.active.push(promise);
|
72
|
+
|
73
|
+
return this.next();
|
74
|
+
}
|
75
|
+
|
76
|
+
public cancel() {
|
77
|
+
this.queue.splice(0, this.queue.length);
|
78
|
+
this.active.splice(0, this.active.length);
|
79
|
+
}
|
80
|
+
|
81
|
+
public async wait() {
|
82
|
+
while (this.queue.length > 0 || this.active.length > 0) {
|
83
|
+
await Promise.all(this.active);
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
package/src/storm/events.ts
CHANGED
@@ -318,6 +318,7 @@ export interface StormEventPhases {
|
|
318
318
|
|
319
319
|
export interface Page {
|
320
320
|
name: string;
|
321
|
+
title: string;
|
321
322
|
description: string;
|
322
323
|
content: string;
|
323
324
|
path: string;
|
@@ -335,6 +336,7 @@ export interface StormEventPage {
|
|
335
336
|
|
336
337
|
export interface UserJourneyScreen {
|
337
338
|
name: string;
|
339
|
+
title: string;
|
338
340
|
filename: string;
|
339
341
|
requirements: string;
|
340
342
|
path: string;
|
package/src/storm/routes.ts
CHANGED
@@ -24,6 +24,7 @@ import {
|
|
24
24
|
import { StormCodegen } from './codegen';
|
25
25
|
import { assetManager } from '../assetManager';
|
26
26
|
import uuid from 'node-uuid';
|
27
|
+
import { PromiseQueue } from './PromiseQueue';
|
27
28
|
|
28
29
|
const router = Router();
|
29
30
|
|
@@ -82,6 +83,11 @@ router.post('/:handle/ui', async (req: KapetaBodyRequest, res: Response) => {
|
|
82
83
|
|
83
84
|
const promises: { [key: string]: Promise<void> } = {};
|
84
85
|
|
86
|
+
const queue = new PromiseQueue(10);
|
87
|
+
onRequestAborted(req, res, () => {
|
88
|
+
queue.cancel();
|
89
|
+
});
|
90
|
+
|
85
91
|
userJourneysStream.on('data', async (data: StormEvent) => {
|
86
92
|
try {
|
87
93
|
console.log('Processing user journey event', data);
|
@@ -90,38 +96,47 @@ router.post('/:handle/ui', async (req: KapetaBodyRequest, res: Response) => {
|
|
90
96
|
return;
|
91
97
|
}
|
92
98
|
|
99
|
+
if (userJourneysStream.isAborted()) {
|
100
|
+
return;
|
101
|
+
}
|
102
|
+
|
93
103
|
data.payload.screens.forEach((screen) => {
|
94
104
|
if (screen.name in promises) {
|
95
105
|
return;
|
96
106
|
}
|
97
|
-
promises[screen.name] =
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
107
|
+
promises[screen.name] = queue.add(
|
108
|
+
() =>
|
109
|
+
new Promise(async (resolve, reject) => {
|
110
|
+
try {
|
111
|
+
const innerConversationId = uuid.v4();
|
112
|
+
const screenStream = await stormClient.createUIPage(
|
113
|
+
{
|
114
|
+
prompt: screen.requirements,
|
115
|
+
method: screen.method,
|
116
|
+
path: screen.path,
|
117
|
+
description: screen.requirements,
|
118
|
+
name: screen.name,
|
119
|
+
title: screen.title,
|
120
|
+
filename: screen.filename,
|
121
|
+
},
|
122
|
+
innerConversationId
|
123
|
+
);
|
124
|
+
screenStream.on('data', (screenData: StormEvent) => {
|
125
|
+
if (screenData.type === 'PAGE') {
|
126
|
+
screenData.payload.conversationId = innerConversationId;
|
127
|
+
}
|
128
|
+
|
129
|
+
sendEvent(res, screenData);
|
130
|
+
});
|
131
|
+
screenStream.on('end', () => {
|
132
|
+
resolve();
|
133
|
+
});
|
134
|
+
} catch (e: any) {
|
135
|
+
console.error('Failed to process screen', e);
|
136
|
+
reject(e);
|
114
137
|
}
|
115
|
-
|
116
|
-
|
117
|
-
});
|
118
|
-
screenStream.on('end', () => {
|
119
|
-
resolve();
|
120
|
-
});
|
121
|
-
} catch (e: any) {
|
122
|
-
reject(e);
|
123
|
-
}
|
124
|
-
});
|
138
|
+
})
|
139
|
+
);
|
125
140
|
});
|
126
141
|
} catch (e) {
|
127
142
|
console.error('Failed to process event', e);
|
@@ -129,13 +144,12 @@ router.post('/:handle/ui', async (req: KapetaBodyRequest, res: Response) => {
|
|
129
144
|
});
|
130
145
|
|
131
146
|
await waitForStormStream(userJourneysStream);
|
147
|
+
await queue.wait();
|
132
148
|
|
133
149
|
if (userJourneysStream.isAborted()) {
|
134
150
|
return;
|
135
151
|
}
|
136
152
|
|
137
|
-
await Promise.all(Object.values(promises));
|
138
|
-
|
139
153
|
sendDone(res);
|
140
154
|
} catch (err: any) {
|
141
155
|
sendError(err, res);
|