libmodulor 0.21.0 → 0.23.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/CHANGELOG.md +17 -0
- package/README.md +1 -1
- package/dist/esm/apps/Helper/src/lib/project.js +7 -7
- package/dist/esm/apps/Helper/src/ucds/CreateProjectUCD.d.ts +1 -0
- package/dist/esm/apps/Helper/src/ucds/CreateProjectUCD.js +20 -13
- package/dist/esm/dt/DataType.d.ts +2 -1
- package/dist/esm/dt/DataTypes.js +1 -0
- package/dist/esm/dt/final/TTransportType.d.ts +8 -0
- package/dist/esm/dt/final/TTransportType.js +16 -0
- package/dist/esm/dt/index.d.ts +1 -0
- package/dist/esm/dt/index.js +1 -0
- package/dist/esm/error/funcs.d.ts +2 -0
- package/dist/esm/error/funcs.js +19 -0
- package/dist/esm/error/index.d.ts +1 -0
- package/dist/esm/error/index.js +1 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.react.d.ts +1 -1
- package/dist/esm/index.react.js +1 -1
- package/dist/esm/std/HTTPAPICallExecutor.d.ts +16 -7
- package/dist/esm/std/HTTPAPICaller.d.ts +8 -1
- package/dist/esm/std/JWTManager.d.ts +16 -1
- package/dist/esm/std/LLMManager.d.ts +20 -3
- package/dist/esm/std/impl/FakeClockManager.d.ts +6 -0
- package/dist/esm/std/impl/FakeClockManager.js +19 -0
- package/dist/esm/std/impl/FakeHTTPAPICallExecutor.js +19 -18
- package/dist/esm/std/impl/FakeLLMManager.d.ts +4 -0
- package/dist/esm/std/impl/FakeLLMManager.js +40 -0
- package/dist/esm/std/impl/JoseJWTManager.d.ts +3 -2
- package/dist/esm/std/impl/JoseJWTManager.js +4 -0
- package/dist/esm/std/impl/MistralAILLMManager.js +12 -0
- package/dist/esm/std/impl/OllamaLLMManager.d.ts +7 -2
- package/dist/esm/std/impl/OllamaLLMManager.js +32 -5
- package/dist/esm/std/impl/OpenAILLMManager.js +9 -0
- package/dist/esm/std/impl/SimpleHTTPAPICaller.d.ts +7 -3
- package/dist/esm/std/impl/SimpleHTTPAPICaller.js +68 -15
- package/dist/esm/target/lib/cli/CommandExecutor.js +9 -1
- package/dist/esm/target/lib/client/consts.js +1 -0
- package/dist/esm/target/lib/react/UCPanel.d.ts +11 -10
- package/dist/esm/target/lib/react/UCPanel.js +2 -2
- package/dist/esm/target/lib/react/useUC.js +11 -1
- package/dist/esm/target/lib/server/ServerManager.d.ts +1 -0
- package/dist/esm/target/lib/server/ServerRequestHandler.d.ts +3 -2
- package/dist/esm/target/lib/server/ServerRequestHandler.js +2 -2
- package/dist/esm/target/lib/server/consts.js +1 -0
- package/dist/esm/target/lib/server-express/funcs.js +53 -1
- package/dist/esm/target/lib/server-hono/funcs.js +65 -2
- package/dist/esm/target/lib/server-node/funcs.d.ts +2 -2
- package/dist/esm/target/lib/server-node/funcs.js +11 -1
- package/dist/esm/target/lib/server-node/types.d.ts +1 -0
- package/dist/esm/target/node-express-server/NodeExpressServerManager.d.ts +2 -2
- package/dist/esm/target/node-express-server/NodeExpressServerManager.js +2 -1
- package/dist/esm/target/node-hono-server/NodeHonoServerManager.d.ts +2 -2
- package/dist/esm/target/node-hono-server/NodeHonoServerManager.js +2 -1
- package/dist/esm/testing/impl/newNodeAppTester.js +3 -2
- package/dist/esm/testing/workers/UCExecutor.js +39 -1
- package/dist/esm/uc/ext.d.ts +7 -1
- package/dist/esm/uc/impl/HTTPUCTransporter.d.ts +2 -2
- package/dist/esm/uc/impl/HTTPUCTransporter.js +3 -1
- package/dist/esm/uc/impl/SimpleUCManager.d.ts +3 -3
- package/dist/esm/uc/impl/SimpleUCManager.js +23 -4
- package/dist/esm/uc/lifecycle/client/SendClientMain.d.ts +1 -1
- package/dist/esm/uc/lifecycle/client/SendClientMain.js +5 -2
- package/dist/esm/uc/main.d.ts +8 -1
- package/dist/esm/uc/manager.d.ts +11 -2
- package/dist/esm/uc/output.d.ts +1 -0
- package/dist/esm/uc/output.js +10 -1
- package/dist/esm/uc/transporter.d.ts +7 -1
- package/dist/esm/utils/async/types.d.ts +2 -0
- package/dist/esm/utils/async/types.js +1 -0
- package/dist/esm/utils/http/NDJSONStreamManager.d.ts +13 -0
- package/dist/esm/utils/http/NDJSONStreamManager.js +45 -0
- package/dist/esm/utils/http/SSEStreamManager.d.ts +13 -0
- package/dist/esm/utils/http/SSEStreamManager.js +60 -0
- package/dist/esm/utils/http/nd-json.d.ts +1 -0
- package/dist/esm/utils/http/nd-json.js +2 -0
- package/dist/esm/utils/http/sse.d.ts +14 -0
- package/dist/esm/utils/http/sse.js +24 -0
- package/dist/esm/utils/http/status.d.ts +4 -0
- package/dist/esm/utils/http/status.js +9 -0
- package/dist/esm/utils/index.d.ts +6 -0
- package/dist/esm/utils/index.js +4 -0
- package/dist/esm/utils/streams/types.d.ts +17 -0
- package/dist/esm/utils/streams/types.js +1 -0
- package/package.json +15 -15
- package/pnpm-workspace.yaml +1 -0
|
@@ -5,16 +5,26 @@ export function listen(server, entrypointsBuilder, logger, settingsManager) {
|
|
|
5
5
|
logger.info(`Listening on ${entrypointsBuilder.exec().http}`);
|
|
6
6
|
});
|
|
7
7
|
}
|
|
8
|
-
export async function stop(server) {
|
|
8
|
+
export async function stop(server, settingsManager) {
|
|
9
9
|
if (!server?.listening) {
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
|
+
const mode = settingsManager.get()('server_stop_mode');
|
|
12
13
|
// As stated in the docs of `close`, only awaiting `.close` is not enough to make sure all the connections are closed.
|
|
13
14
|
// Hence the wrapping in a promise, where the callback is called when the 'close' event is emitted.
|
|
14
15
|
return new Promise((resolve, reject) => {
|
|
15
16
|
if (!server) {
|
|
16
17
|
return resolve();
|
|
17
18
|
}
|
|
19
|
+
switch (mode) {
|
|
20
|
+
case 'aggressive':
|
|
21
|
+
server.closeAllConnections();
|
|
22
|
+
break;
|
|
23
|
+
case 'patient':
|
|
24
|
+
break;
|
|
25
|
+
default:
|
|
26
|
+
((_) => { })(mode);
|
|
27
|
+
}
|
|
18
28
|
server.close((err) => {
|
|
19
29
|
if (err) {
|
|
20
30
|
return reject(err);
|
|
@@ -3,3 +3,4 @@ import type https from 'node:https';
|
|
|
3
3
|
import type { ServerManagerSettings } from '../server/ServerManager.js';
|
|
4
4
|
export type Server = http.Server | https.Server;
|
|
5
5
|
export type ListenSettings = Pick<ServerManagerSettings, 'server_binding_host' | 'server_binding_port'>;
|
|
6
|
+
export type StopSettings = Pick<ServerManagerSettings, 'server_stop_mode'>;
|
|
@@ -8,8 +8,8 @@ import type { ServerManager, ServerManagerSettings } from '../lib/server/ServerM
|
|
|
8
8
|
import { ServerRequestHandler } from '../lib/server/ServerRequestHandler.js';
|
|
9
9
|
import { ServerSSLCertLoader } from '../lib/server/ServerSSLCertLoader.js';
|
|
10
10
|
import { HelmetMiddlewareBuilder } from '../lib/server-express/HelmetMiddlewareBuilder.js';
|
|
11
|
-
import type { ListenSettings } from '../lib/server-node/types.js';
|
|
12
|
-
type S = ListenSettings & Pick<LoggerSettings, 'logger_level'> & Pick<ServerManagerSettings, 'server_tmp_path'
|
|
11
|
+
import type { ListenSettings, StopSettings } from '../lib/server-node/types.js';
|
|
12
|
+
type S = ListenSettings & Pick<LoggerSettings, 'logger_level'> & Pick<ServerManagerSettings, 'server_tmp_path'> & StopSettings;
|
|
13
13
|
export declare class NodeExpressServerManager implements Configurable<S>, ServerManager {
|
|
14
14
|
private entrypointsBuilder;
|
|
15
15
|
protected environmentManager: EnvironmentManager;
|
|
@@ -47,6 +47,7 @@ let NodeExpressServerManager = class NodeExpressServerManager {
|
|
|
47
47
|
logger_level: this.settingsManager.get()('logger_level'),
|
|
48
48
|
server_binding_host: this.settingsManager.get()('server_binding_host'),
|
|
49
49
|
server_binding_port: this.settingsManager.get()('server_binding_port'),
|
|
50
|
+
server_stop_mode: this.settingsManager.get()('server_stop_mode'),
|
|
50
51
|
server_tmp_path: this.settingsManager.get()('server_tmp_path'),
|
|
51
52
|
};
|
|
52
53
|
}
|
|
@@ -79,7 +80,7 @@ let NodeExpressServerManager = class NodeExpressServerManager {
|
|
|
79
80
|
listen(this.server, this.entrypointsBuilder, this.logger, this.settingsManager);
|
|
80
81
|
}
|
|
81
82
|
async stop() {
|
|
82
|
-
await stop(this.server);
|
|
83
|
+
await stop(this.server, this.settingsManager);
|
|
83
84
|
}
|
|
84
85
|
async warmUp() {
|
|
85
86
|
// Nothing to do
|
|
@@ -7,8 +7,8 @@ import { EntrypointsBuilder } from '../lib/server/EntrypointsBuilder.js';
|
|
|
7
7
|
import type { ServerManager } from '../lib/server/ServerManager.js';
|
|
8
8
|
import { ServerRequestHandler } from '../lib/server/ServerRequestHandler.js';
|
|
9
9
|
import { ServerSSLCertLoader } from '../lib/server/ServerSSLCertLoader.js';
|
|
10
|
-
import type { ListenSettings } from '../lib/server-node/types.js';
|
|
11
|
-
type S = ListenSettings;
|
|
10
|
+
import type { ListenSettings, StopSettings } from '../lib/server-node/types.js';
|
|
11
|
+
type S = ListenSettings & StopSettings;
|
|
12
12
|
export declare class NodeHonoServerManager implements Configurable<S>, ServerManager {
|
|
13
13
|
private entrypointsBuilder;
|
|
14
14
|
protected environmentManager: EnvironmentManager;
|
|
@@ -44,6 +44,7 @@ let NodeHonoServerManager = class NodeHonoServerManager {
|
|
|
44
44
|
return {
|
|
45
45
|
server_binding_host: this.settingsManager.get()('server_binding_host'),
|
|
46
46
|
server_binding_port: this.settingsManager.get()('server_binding_port'),
|
|
47
|
+
server_stop_mode: this.settingsManager.get()('server_stop_mode'),
|
|
47
48
|
};
|
|
48
49
|
}
|
|
49
50
|
getRuntime() {
|
|
@@ -75,7 +76,7 @@ let NodeHonoServerManager = class NodeHonoServerManager {
|
|
|
75
76
|
listen(this.server, this.entrypointsBuilder, this.logger, this.settingsManager);
|
|
76
77
|
}
|
|
77
78
|
async stop() {
|
|
78
|
-
await stop(this.server);
|
|
79
|
+
await stop(this.server, this.settingsManager);
|
|
79
80
|
}
|
|
80
81
|
async warmUp() {
|
|
81
82
|
// Nothing to do
|
|
@@ -18,8 +18,8 @@ export async function newNodeAppTester(serverPortRangeStart, idx, args) {
|
|
|
18
18
|
const settings = {
|
|
19
19
|
...STD_DEFAULT_JWT_MANAGER_SETTINGS,
|
|
20
20
|
...TARGET_DEFAULT_SERVER_MANAGER_SETTINGS,
|
|
21
|
-
jwt_manager_audience: '
|
|
22
|
-
jwt_manager_issuer: '
|
|
21
|
+
jwt_manager_audience: 'libmodulor-test',
|
|
22
|
+
jwt_manager_issuer: 'libmodulor-test',
|
|
23
23
|
jwt_manager_secret: new TPassword().example(),
|
|
24
24
|
logger_level,
|
|
25
25
|
server_basic_auth_entries: {
|
|
@@ -28,6 +28,7 @@ export async function newNodeAppTester(serverPortRangeStart, idx, args) {
|
|
|
28
28
|
server_binding_port: serverPortRangeStart + idx,
|
|
29
29
|
server_private_api_key_entries: [new TApiKey().example()],
|
|
30
30
|
server_public_api_key_entries: [new TApiKey().example()],
|
|
31
|
+
server_stop_mode: 'aggressive',
|
|
31
32
|
};
|
|
32
33
|
const container = new Container(CONTAINER_OPTS);
|
|
33
34
|
bindCommon(container, () => settings);
|
|
@@ -13,6 +13,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
13
13
|
var UCExecutor_1;
|
|
14
14
|
import { inject, injectable } from 'inversify';
|
|
15
15
|
import { rInput, UCBuilder, } from '../../uc/index.js';
|
|
16
|
+
const ERR_CLIENT_EXPECTED_UCOR = (name) => `${name} client is expected to return an ucor`;
|
|
16
17
|
const ERR_CLIENT_EXPECTED_OUTPUT = (name) => `${name} client is expected to return an output but returned nothing`;
|
|
17
18
|
const ERR_CLIENT_UNEXPECTED_OUTPUT = (name) => `${name} client is expected to return nothing but returned an output`;
|
|
18
19
|
let UCExecutor = class UCExecutor {
|
|
@@ -70,7 +71,44 @@ let UCExecutor = class UCExecutor {
|
|
|
70
71
|
out.io.i = input;
|
|
71
72
|
out.hash = this.cryptoManager.hash(UCExecutor_1.HASH_ALG, [name, JSON.stringify(args), JSON.stringify(input)].join(UCExecutor_1.HASH_SEP), UCExecutor_1.HASH_BTT_ENCODING);
|
|
72
73
|
try {
|
|
73
|
-
|
|
74
|
+
let ucor;
|
|
75
|
+
const transportType = ucd.ext?.http?.transportType ?? 'standard';
|
|
76
|
+
switch (transportType) {
|
|
77
|
+
case 'standard':
|
|
78
|
+
ucor = await this.ucManager.execClient(uc);
|
|
79
|
+
break;
|
|
80
|
+
case 'stream': {
|
|
81
|
+
try {
|
|
82
|
+
let abort;
|
|
83
|
+
await this.ucManager.execClient(uc, {
|
|
84
|
+
registerAbort: (func) => {
|
|
85
|
+
abort = func;
|
|
86
|
+
},
|
|
87
|
+
stream: {
|
|
88
|
+
onClose: async () => { },
|
|
89
|
+
onData: async (ucor2) => {
|
|
90
|
+
if (!ucor) {
|
|
91
|
+
ucor = ucor2;
|
|
92
|
+
abort();
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
onDone: async () => { },
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
if (err.name !== 'AbortError') {
|
|
101
|
+
throw err;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
default:
|
|
107
|
+
((_) => { })(transportType);
|
|
108
|
+
}
|
|
109
|
+
if (!ucor) {
|
|
110
|
+
throw new Error(ERR_CLIENT_EXPECTED_UCOR(name));
|
|
111
|
+
}
|
|
74
112
|
const output = ucor.output();
|
|
75
113
|
if (uc.hasOutputParts() && !output) {
|
|
76
114
|
throw new Error(ERR_CLIENT_EXPECTED_OUTPUT(name));
|
package/dist/esm/uc/ext.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { HTTPMethod, URLPath } from '../dt/index.js';
|
|
1
|
+
import type { HTTPMethod, TransportType, URLPath } from '../dt/index.js';
|
|
2
2
|
import type { UCOPIBase } from './opi.js';
|
|
3
3
|
import type { UCOutput } from './output.js';
|
|
4
4
|
import type { UCMountingPoint } from './utils/ucMountingPoint.js';
|
|
@@ -41,5 +41,11 @@ export interface UCExt<OPI0 extends UCOPIBase | undefined = undefined, OPI1 exte
|
|
|
41
41
|
* @returns
|
|
42
42
|
*/
|
|
43
43
|
transform?: (output: UCOutput<OPI0, OPI1>) => object;
|
|
44
|
+
/**
|
|
45
|
+
* The way the output is transported
|
|
46
|
+
*
|
|
47
|
+
* By default, it's `standard`.
|
|
48
|
+
*/
|
|
49
|
+
transportType?: TransportType;
|
|
44
50
|
};
|
|
45
51
|
}
|
|
@@ -3,7 +3,7 @@ import type { ServerClientManager, ServerClientManagerSettings } from '../../tar
|
|
|
3
3
|
import type { UCInput } from '../input.js';
|
|
4
4
|
import type { UCOPIBase } from '../opi.js';
|
|
5
5
|
import type { UCOutputOrNothing } from '../output.js';
|
|
6
|
-
import type { UCTransporter } from '../transporter.js';
|
|
6
|
+
import type { UCTransporter, UCTransporterOpts } from '../transporter.js';
|
|
7
7
|
import type { UC } from '../UC.js';
|
|
8
8
|
type S = Pick<ServerClientManagerSettings, 'server_cookies_name_auth' | 'server_public_api_key_header_name'>;
|
|
9
9
|
export declare class HTTPUCTransporter implements Configurable<S>, UCTransporter {
|
|
@@ -12,6 +12,6 @@ export declare class HTTPUCTransporter implements Configurable<S>, UCTransporter
|
|
|
12
12
|
private settingsManager;
|
|
13
13
|
constructor(httpAPICaller: HTTPAPICaller, serverClientManager: ServerClientManager, settingsManager: SettingsManager<S>);
|
|
14
14
|
s(): S;
|
|
15
|
-
send<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>): Promise<UCOutputOrNothing<OPI0, OPI1>>;
|
|
15
|
+
send<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>, opts: UCTransporterOpts<OPI0, OPI1>): Promise<UCOutputOrNothing<OPI0, OPI1>>;
|
|
16
16
|
}
|
|
17
17
|
export {};
|
|
@@ -29,7 +29,7 @@ let HTTPUCTransporter = class HTTPUCTransporter {
|
|
|
29
29
|
server_public_api_key_header_name: this.settingsManager.get()('server_public_api_key_header_name'),
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
-
async send(uc) {
|
|
32
|
+
async send(uc, opts) {
|
|
33
33
|
const { auth, def: { sec }, } = uc;
|
|
34
34
|
const baseURL = await this.serverClientManager.baseURL({ auth });
|
|
35
35
|
const { contentType, envelope, method, path } = ucHTTPContract(uc);
|
|
@@ -96,10 +96,12 @@ let HTTPUCTransporter = class HTTPUCTransporter {
|
|
|
96
96
|
contentType,
|
|
97
97
|
errBuilder: async (error) => error.message,
|
|
98
98
|
method,
|
|
99
|
+
registerAbort: opts.registerAbort,
|
|
99
100
|
req: {
|
|
100
101
|
builder: async () => rInput(uc, { ignoreUndefined: true }),
|
|
101
102
|
envelope,
|
|
102
103
|
},
|
|
104
|
+
stream: opts.stream,
|
|
103
105
|
urlBuilder: async () => `${baseURL}${path}`,
|
|
104
106
|
});
|
|
105
107
|
// In case of 204, we get an empty object.
|
|
@@ -7,7 +7,7 @@ import { UCOutputReader } from '../helpers/UCOutputReader.js';
|
|
|
7
7
|
import type { UCInit } from '../init.js';
|
|
8
8
|
import type { UCInput } from '../input.js';
|
|
9
9
|
import type { UCMain } from '../main.js';
|
|
10
|
-
import type { UCManager, UCManagerPersistOpts } from '../manager.js';
|
|
10
|
+
import type { UCManager, UCManagerExecClientOpts, UCManagerExecServerOpts, UCManagerPersistOpts } from '../manager.js';
|
|
11
11
|
import type { UCOPIBase } from '../opi.js';
|
|
12
12
|
import type { UCOutputOrNothing } from '../output.js';
|
|
13
13
|
import type { UC } from '../UC.js';
|
|
@@ -29,8 +29,8 @@ export declare class SimpleUCManager implements UCManager {
|
|
|
29
29
|
constructor(ucClientConfirmManager: UCClientConfirmManager, clockManager: ClockManager, cryptoManager: CryptoManager, logger: Logger, ucDataStore: UCDataStore, ucExecChecker: UCExecChecker, ucInputFilesProcessor: UCInputFilesProcessor, ucInputValidator: UCInputValidator, ucInitProvider: Provider<UCInit>, ucMainProvider: Provider<UCMain>);
|
|
30
30
|
commitTx(): Promise<void>;
|
|
31
31
|
confirmClient<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>): Promise<boolean>;
|
|
32
|
-
execClient<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>): Promise<UCOutputReader<I, OPI0, OPI1>>;
|
|
33
|
-
execServer<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>): Promise<UCOutputOrNothing<OPI0, OPI1>>;
|
|
32
|
+
execClient<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>, opts?: UCManagerExecClientOpts<I, OPI0, OPI1>): Promise<UCOutputReader<I, OPI0, OPI1>>;
|
|
33
|
+
execServer<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>, opts?: UCManagerExecServerOpts<OPI0, OPI1>): Promise<UCOutputOrNothing<OPI0, OPI1>>;
|
|
34
34
|
initServer<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>): Promise<void>;
|
|
35
35
|
startTx(): Promise<void>;
|
|
36
36
|
persist<I extends UCInput | undefined = undefined, D extends UCData | null = null, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>, data?: D, opts?: UCManagerPersistOpts): Promise<UCDataStoreRecord<I, D>>;
|
|
@@ -59,7 +59,7 @@ let SimpleUCManager = class SimpleUCManager {
|
|
|
59
59
|
}
|
|
60
60
|
return this.ucClientConfirmManager.exec(def);
|
|
61
61
|
}
|
|
62
|
-
async execClient(uc) {
|
|
62
|
+
async execClient(uc, opts) {
|
|
63
63
|
const { lifecycle, metadata } = uc.def;
|
|
64
64
|
const { client, server } = lifecycle;
|
|
65
65
|
if (!client) {
|
|
@@ -81,10 +81,23 @@ let SimpleUCManager = class SimpleUCManager {
|
|
|
81
81
|
await this.ucInputFilesProcessor.exec({ uc });
|
|
82
82
|
}
|
|
83
83
|
const main = (await this.ucMainProvider(client.main));
|
|
84
|
-
const
|
|
84
|
+
const streamOpts = opts?.stream;
|
|
85
|
+
const output = await main.exec({
|
|
86
|
+
opts: {
|
|
87
|
+
registerAbort: opts?.registerAbort,
|
|
88
|
+
stream: streamOpts
|
|
89
|
+
? {
|
|
90
|
+
onClose: streamOpts.onClose,
|
|
91
|
+
onData: (output) => streamOpts.onData(new UCOutputReader(uc.def, output ?? undefined)),
|
|
92
|
+
onDone: streamOpts.onDone,
|
|
93
|
+
}
|
|
94
|
+
: undefined,
|
|
95
|
+
},
|
|
96
|
+
uc,
|
|
97
|
+
});
|
|
85
98
|
return new UCOutputReader(uc.def, output ?? undefined);
|
|
86
99
|
}
|
|
87
|
-
async execServer(uc) {
|
|
100
|
+
async execServer(uc, opts) {
|
|
88
101
|
const { lifecycle, metadata } = uc.def;
|
|
89
102
|
const { server } = lifecycle;
|
|
90
103
|
if (typeof server !== 'object') {
|
|
@@ -101,7 +114,13 @@ let SimpleUCManager = class SimpleUCManager {
|
|
|
101
114
|
this.ucInputValidator.exec({ uc });
|
|
102
115
|
await this.ucInputFilesProcessor.exec({ uc });
|
|
103
116
|
const main = (await this.ucMainProvider(server.main));
|
|
104
|
-
|
|
117
|
+
const output = main.exec({
|
|
118
|
+
opts: {
|
|
119
|
+
stream: opts?.stream,
|
|
120
|
+
},
|
|
121
|
+
uc,
|
|
122
|
+
});
|
|
123
|
+
return output;
|
|
105
124
|
}
|
|
106
125
|
async initServer(uc) {
|
|
107
126
|
const { lifecycle, metadata } = uc.def;
|
|
@@ -6,5 +6,5 @@ import type { UCTransporter } from '../../transporter.js';
|
|
|
6
6
|
export declare class SendClientMain<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> implements UCMain<I, OPI0, OPI1> {
|
|
7
7
|
private ucTransporter;
|
|
8
8
|
constructor(ucTransporter: UCTransporter);
|
|
9
|
-
exec({ uc, }: UCMainInput<I, OPI0, OPI1>): Promise<UCOutputOrNothing<OPI0, OPI1>>;
|
|
9
|
+
exec({ opts, uc, }: UCMainInput<I, OPI0, OPI1>): Promise<UCOutputOrNothing<OPI0, OPI1>>;
|
|
10
10
|
}
|
|
@@ -16,8 +16,11 @@ let SendClientMain = class SendClientMain {
|
|
|
16
16
|
constructor(ucTransporter) {
|
|
17
17
|
this.ucTransporter = ucTransporter;
|
|
18
18
|
}
|
|
19
|
-
async exec({ uc, }) {
|
|
20
|
-
return this.ucTransporter.send(uc
|
|
19
|
+
async exec({ opts, uc, }) {
|
|
20
|
+
return this.ucTransporter.send(uc, {
|
|
21
|
+
registerAbort: opts?.registerAbort,
|
|
22
|
+
stream: opts?.stream,
|
|
23
|
+
});
|
|
21
24
|
}
|
|
22
25
|
};
|
|
23
26
|
SendClientMain = __decorate([
|
package/dist/esm/uc/main.d.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import type { Worker } from '../std/index.js';
|
|
2
|
+
import type { RegisterAbortFunc, StreamConfig } from '../utils/index.js';
|
|
2
3
|
import type { UCInput } from './input.js';
|
|
3
4
|
import type { UCOPIBase } from './opi.js';
|
|
4
|
-
import type { UCOutputOrNothing } from './output.js';
|
|
5
|
+
import type { UCOutput, UCOutputOrNothing } from './output.js';
|
|
5
6
|
import type { UC } from './UC.js';
|
|
7
|
+
export type UCMainStream<OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> = StreamConfig<UCOutput<OPI0, OPI1>>;
|
|
8
|
+
export interface UCMainOpts<OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> {
|
|
9
|
+
registerAbort?: RegisterAbortFunc | undefined;
|
|
10
|
+
stream?: UCMainStream<OPI0, OPI1> | undefined;
|
|
11
|
+
}
|
|
6
12
|
export interface UCMainInput<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> {
|
|
13
|
+
opts?: UCMainOpts<OPI0, OPI1>;
|
|
7
14
|
uc: UC<I, OPI0, OPI1>;
|
|
8
15
|
}
|
|
9
16
|
export interface UCMain<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> extends Worker<UCMainInput<I, OPI0, OPI1>, Promise<UCOutputOrNothing<OPI0, OPI1>>> {
|
package/dist/esm/uc/manager.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { UUID } from '../dt/index.js';
|
|
2
|
+
import type { RegisterAbortFunc, StreamConfig } from '../utils/index.js';
|
|
2
3
|
import type { UCData } from './data.js';
|
|
3
4
|
import type { UCDataStoreRecord } from './data-store.js';
|
|
4
5
|
import type { UCExecMode } from './exec.js';
|
|
5
6
|
import type { UCOutputReader } from './helpers/UCOutputReader.js';
|
|
6
7
|
import type { UCInput } from './input.js';
|
|
8
|
+
import type { UCMainStream } from './main.js';
|
|
7
9
|
import type { UCOPIBase } from './opi.js';
|
|
8
10
|
import type { UCOutputOrNothing } from './output.js';
|
|
9
11
|
import type { UC } from './UC.js';
|
|
@@ -23,11 +25,18 @@ export interface UCManagerPersistOpts {
|
|
|
23
25
|
*/
|
|
24
26
|
organizationId?: UUID;
|
|
25
27
|
}
|
|
28
|
+
export interface UCManagerExecClientOpts<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> {
|
|
29
|
+
registerAbort?: RegisterAbortFunc | undefined;
|
|
30
|
+
stream?: StreamConfig<UCOutputReader<I, OPI0, OPI1>> | undefined;
|
|
31
|
+
}
|
|
32
|
+
export interface UCManagerExecServerOpts<OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> {
|
|
33
|
+
stream?: UCMainStream<OPI0, OPI1> | undefined;
|
|
34
|
+
}
|
|
26
35
|
export interface UCManager {
|
|
27
36
|
commitTx(): Promise<void>;
|
|
28
37
|
confirmClient<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>): Promise<boolean>;
|
|
29
|
-
execClient<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>): Promise<UCOutputReader<I, OPI0, OPI1>>;
|
|
30
|
-
execServer<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>): Promise<UCOutputOrNothing<OPI0, OPI1>>;
|
|
38
|
+
execClient<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>, opts?: UCManagerExecClientOpts<I, OPI0, OPI1>): Promise<UCOutputReader<I, OPI0, OPI1>>;
|
|
39
|
+
execServer<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>, opts?: UCManagerExecServerOpts<OPI0, OPI1>): Promise<UCOutputOrNothing<OPI0, OPI1>>;
|
|
31
40
|
initServer<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>): Promise<void>;
|
|
32
41
|
startTx(): Promise<void>;
|
|
33
42
|
persist<I extends UCInput | undefined = undefined, D extends UCData | null = null, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>, data?: D, opts?: UCManagerPersistOpts): Promise<UCDataStoreRecord<I, D>>;
|
package/dist/esm/uc/output.d.ts
CHANGED
package/dist/esm/uc/output.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
import type { RegisterAbortFunc } from '../utils/index.js';
|
|
1
2
|
import type { UCInput } from './input.js';
|
|
3
|
+
import type { UCMainStream } from './main.js';
|
|
2
4
|
import type { UCOPIBase } from './opi.js';
|
|
3
5
|
import type { UCOutputOrNothing } from './output.js';
|
|
4
6
|
import type { UC } from './UC.js';
|
|
7
|
+
export interface UCTransporterOpts<OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> {
|
|
8
|
+
registerAbort?: RegisterAbortFunc | undefined;
|
|
9
|
+
stream?: UCMainStream<OPI0, OPI1> | undefined;
|
|
10
|
+
}
|
|
5
11
|
export interface UCTransporter {
|
|
6
|
-
send<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>): Promise<UCOutputOrNothing<OPI0, OPI1>>;
|
|
12
|
+
send<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>, opts?: UCTransporterOpts<OPI0, OPI1>): Promise<UCOutputOrNothing<OPI0, OPI1>>;
|
|
7
13
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { HTTPAPICallExecutorResBody, Worker } from '../../std/index.js';
|
|
2
|
+
type Encoding = 'utf-8';
|
|
3
|
+
interface I<D extends object = object> {
|
|
4
|
+
abortController: AbortController;
|
|
5
|
+
encoding?: Encoding | undefined;
|
|
6
|
+
onData: (data: D) => Promise<void>;
|
|
7
|
+
reader: ReturnType<HTTPAPICallExecutorResBody['getReader']>;
|
|
8
|
+
}
|
|
9
|
+
export declare class NDJSONStreamManager implements Worker<I, Promise<void>> {
|
|
10
|
+
private static DEFAULT_ENCODING;
|
|
11
|
+
exec({ abortController, encoding, onData, reader, }: I): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var NDJSONStreamManager_1;
|
|
8
|
+
import { injectable } from 'inversify';
|
|
9
|
+
import { NDJSON_DATA_SEP } from './nd-json.js';
|
|
10
|
+
let NDJSONStreamManager = class NDJSONStreamManager {
|
|
11
|
+
static { NDJSONStreamManager_1 = this; }
|
|
12
|
+
static DEFAULT_ENCODING = 'utf-8';
|
|
13
|
+
async exec({ abortController, encoding = NDJSONStreamManager_1.DEFAULT_ENCODING, onData, reader, }) {
|
|
14
|
+
const decoder = new TextDecoder(encoding);
|
|
15
|
+
let buffer = '';
|
|
16
|
+
while (true) {
|
|
17
|
+
if (abortController.signal.aborted) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const { done, value } = await reader.read();
|
|
21
|
+
if (done) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
buffer += decoder.decode(value, { stream: true });
|
|
25
|
+
const parts = buffer.split(NDJSON_DATA_SEP);
|
|
26
|
+
// Remove the last part that is potentially not complete yet.
|
|
27
|
+
buffer = parts.pop() ?? '';
|
|
28
|
+
for (const part of parts) {
|
|
29
|
+
const lines = part.split(NDJSON_DATA_SEP);
|
|
30
|
+
for (const line of lines) {
|
|
31
|
+
try {
|
|
32
|
+
onData(JSON.parse(line));
|
|
33
|
+
}
|
|
34
|
+
catch (_err) {
|
|
35
|
+
// Ignore invalid message
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
NDJSONStreamManager = NDJSONStreamManager_1 = __decorate([
|
|
43
|
+
injectable()
|
|
44
|
+
], NDJSONStreamManager);
|
|
45
|
+
export { NDJSONStreamManager };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { HTTPAPICallExecutorResBody, Worker } from '../../std/index.js';
|
|
2
|
+
type Encoding = 'utf-8';
|
|
3
|
+
interface I<D extends object = object> {
|
|
4
|
+
abortController: AbortController;
|
|
5
|
+
encoding?: Encoding | undefined;
|
|
6
|
+
onData: (data: D) => Promise<void>;
|
|
7
|
+
reader: ReturnType<HTTPAPICallExecutorResBody['getReader']>;
|
|
8
|
+
}
|
|
9
|
+
export declare class SSEStreamManager implements Worker<I, Promise<void>> {
|
|
10
|
+
private static DEFAULT_ENCODING;
|
|
11
|
+
exec({ abortController, encoding, onData, reader, }: I): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var SSEStreamManager_1;
|
|
8
|
+
import { injectable } from 'inversify';
|
|
9
|
+
import { throwCustomError } from '../../error/index.js';
|
|
10
|
+
import { isSSEError, parseDataLine, SSE_DATA_SEP, SSE_MSG_SEP } from './sse.js';
|
|
11
|
+
let SSEStreamManager = class SSEStreamManager {
|
|
12
|
+
static { SSEStreamManager_1 = this; }
|
|
13
|
+
static DEFAULT_ENCODING = 'utf-8';
|
|
14
|
+
async exec({ abortController, encoding = SSEStreamManager_1.DEFAULT_ENCODING, onData, reader, }) {
|
|
15
|
+
const decoder = new TextDecoder(encoding);
|
|
16
|
+
let buffer = '';
|
|
17
|
+
while (true) {
|
|
18
|
+
if (abortController.signal.aborted) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const { done, value } = await reader.read();
|
|
22
|
+
if (done) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
buffer += decoder.decode(value, { stream: true });
|
|
26
|
+
const parts = buffer.split(SSE_MSG_SEP);
|
|
27
|
+
// Remove the last part that is potentially not complete yet.
|
|
28
|
+
buffer = parts.pop() ?? '';
|
|
29
|
+
for (const part of parts) {
|
|
30
|
+
const lines = part.split(SSE_DATA_SEP);
|
|
31
|
+
let data = '';
|
|
32
|
+
for (const line of lines) {
|
|
33
|
+
data += parseDataLine(line);
|
|
34
|
+
}
|
|
35
|
+
if (!data) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
let parsedData;
|
|
39
|
+
try {
|
|
40
|
+
parsedData = JSON.parse(data);
|
|
41
|
+
}
|
|
42
|
+
catch (_err) {
|
|
43
|
+
// Ignore invalid message
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (isSSEError(parsedData)) {
|
|
47
|
+
const { message, status } = parsedData;
|
|
48
|
+
throwCustomError(message, status);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
onData(parsedData);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
SSEStreamManager = SSEStreamManager_1 = __decorate([
|
|
58
|
+
injectable()
|
|
59
|
+
], SSEStreamManager);
|
|
60
|
+
export { SSEStreamManager };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const NDJSON_DATA_SEP = "\n";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ErrorMessage, HTTPStatusNumber } from '../../dt/index.js';
|
|
2
|
+
export declare const SSE_HEADERS: [string, string][];
|
|
3
|
+
export declare const SSE_DATA_PREFIX = "data:";
|
|
4
|
+
export declare const SSE_DATA_SEP = "\n";
|
|
5
|
+
export declare const SSE_MSG_SEP = "\n\n";
|
|
6
|
+
export type SSEStreamDataCleanUpFunc = () => void;
|
|
7
|
+
export interface SSEError {
|
|
8
|
+
message: ErrorMessage;
|
|
9
|
+
status: HTTPStatusNumber;
|
|
10
|
+
}
|
|
11
|
+
export declare function fmtSSEError(err: SSEError): string;
|
|
12
|
+
export declare function fmtSingleDataMsg<D extends object = object>(data: D): string;
|
|
13
|
+
export declare function isSSEError(err: unknown): err is SSEError;
|
|
14
|
+
export declare function parseDataLine(line: string): string;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events
|
|
2
|
+
export const SSE_HEADERS = [
|
|
3
|
+
['Cache-Control', 'no-cache'],
|
|
4
|
+
['Content-Type', 'text/event-stream'],
|
|
5
|
+
['Connection', 'keep-alive'],
|
|
6
|
+
];
|
|
7
|
+
export const SSE_DATA_PREFIX = 'data:';
|
|
8
|
+
export const SSE_DATA_SEP = '\n';
|
|
9
|
+
export const SSE_MSG_SEP = '\n\n';
|
|
10
|
+
export function fmtSSEError(err) {
|
|
11
|
+
return `${SSE_DATA_PREFIX} ${JSON.stringify(err)}${SSE_MSG_SEP}`;
|
|
12
|
+
}
|
|
13
|
+
export function fmtSingleDataMsg(data) {
|
|
14
|
+
return `${SSE_DATA_PREFIX} ${JSON.stringify(data)}${SSE_MSG_SEP}`;
|
|
15
|
+
}
|
|
16
|
+
export function isSSEError(err) {
|
|
17
|
+
return 'message' in err && 'status' in err;
|
|
18
|
+
}
|
|
19
|
+
export function parseDataLine(line) {
|
|
20
|
+
if (!line.startsWith(SSE_DATA_PREFIX)) {
|
|
21
|
+
return '';
|
|
22
|
+
}
|
|
23
|
+
return `${line.slice(SSE_DATA_PREFIX.length).trim()}${SSE_DATA_SEP}`;
|
|
24
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { HTTPStatusNumber } from '../../dt/index.js';
|
|
2
|
+
export declare function isError(status: HTTPStatusNumber): boolean;
|
|
3
|
+
export declare function isClientError(status: HTTPStatusNumber): boolean;
|
|
4
|
+
export declare function isServerError(status: HTTPStatusNumber): boolean;
|