arri 0.24.0 → 0.25.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/dist/cli.cjs +6 -6
- package/dist/cli.mjs +6 -6
- package/dist/index.cjs +2 -5
- package/dist/index.d.cts +9 -29
- package/dist/index.d.mts +9 -29
- package/dist/index.d.ts +9 -29
- package/dist/index.mjs +2 -2
- package/dist/shared/{arri.b27cbd19.cjs → arri.65113bc6.cjs} +25 -119
- package/dist/shared/{arri.62a101bf.mjs → arri.ba3f283e.mjs} +27 -118
- package/package.json +10 -9
package/dist/cli.cjs
CHANGED
|
@@ -12,7 +12,7 @@ const esbuild = require('esbuild');
|
|
|
12
12
|
const esbuildPluginReplace = require('esbuild-plugin-replace');
|
|
13
13
|
const path = require('pathe');
|
|
14
14
|
const prettier = require('prettier');
|
|
15
|
-
const config = require('./shared/arri.
|
|
15
|
+
const config = require('./shared/arri.65113bc6.cjs');
|
|
16
16
|
const globby = require('globby');
|
|
17
17
|
const scule = require('scule');
|
|
18
18
|
const arriCodegenDart = require('arri-codegen-dart');
|
|
@@ -22,7 +22,7 @@ const chokidar = require('chokidar');
|
|
|
22
22
|
const Degit = require('degit');
|
|
23
23
|
require('h3');
|
|
24
24
|
require('arri-validate');
|
|
25
|
-
require('
|
|
25
|
+
require('h3-sse');
|
|
26
26
|
|
|
27
27
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
28
28
|
|
|
@@ -49,9 +49,9 @@ const Degit__default = /*#__PURE__*/_interopDefaultCompat(Degit);
|
|
|
49
49
|
|
|
50
50
|
const GEN_APP_FILE = "__arri_app.js";
|
|
51
51
|
const GEN_SERVER_ENTRY_FILE = "__arri_server.js";
|
|
52
|
-
const OUT_APP_FILE = "app.
|
|
53
|
-
const OUT_SERVER_ENTRY = "server.
|
|
54
|
-
const OUT_CODEGEN = "codegen.
|
|
52
|
+
const OUT_APP_FILE = "app.mjs";
|
|
53
|
+
const OUT_SERVER_ENTRY = "server.mjs";
|
|
54
|
+
const OUT_CODEGEN = "codegen.mjs";
|
|
55
55
|
async function setupWorkingDir(config) {
|
|
56
56
|
const arriDir = path__default.resolve(config.rootDir, config.buildDir);
|
|
57
57
|
const outDir = path__default.resolve(config.rootDir, ".output");
|
|
@@ -294,7 +294,7 @@ async function createServerEntryFile(config) {
|
|
|
294
294
|
js: `import { createRequire as topLevelCreateRequire } from 'module';
|
|
295
295
|
const require = topLevelCreateRequire(import.meta.url);`
|
|
296
296
|
},
|
|
297
|
-
plugins: [esbuildPluginReplace.replace({ "virtual:arri/app": "./app.
|
|
297
|
+
plugins: [esbuildPluginReplace.replace({ "virtual:arri/app": "./app.mjs" })],
|
|
298
298
|
allowOverwrite: true,
|
|
299
299
|
outfile: path__default.resolve(config.rootDir, ".output", OUT_SERVER_ENTRY)
|
|
300
300
|
});
|
package/dist/cli.mjs
CHANGED
|
@@ -11,7 +11,7 @@ import { build as build$1 } from 'esbuild';
|
|
|
11
11
|
import { replace } from 'esbuild-plugin-replace';
|
|
12
12
|
import path from 'pathe';
|
|
13
13
|
import prettier from 'prettier';
|
|
14
|
-
import { n as defaultConfig, m as isResolvedArriConfig, a as DEV_DEFINITION_ENDPOINT } from './shared/arri.
|
|
14
|
+
import { n as defaultConfig, m as isResolvedArriConfig, a as DEV_DEFINITION_ENDPOINT } from './shared/arri.ba3f283e.mjs';
|
|
15
15
|
import { globby } from 'globby';
|
|
16
16
|
import { camelCase, kebabCase } from 'scule';
|
|
17
17
|
import { dartClientGenerator } from 'arri-codegen-dart';
|
|
@@ -21,13 +21,13 @@ import chokidar from 'chokidar';
|
|
|
21
21
|
import Degit from 'degit';
|
|
22
22
|
import 'h3';
|
|
23
23
|
import 'arri-validate';
|
|
24
|
-
import '
|
|
24
|
+
import 'h3-sse';
|
|
25
25
|
|
|
26
26
|
const GEN_APP_FILE = "__arri_app.js";
|
|
27
27
|
const GEN_SERVER_ENTRY_FILE = "__arri_server.js";
|
|
28
|
-
const OUT_APP_FILE = "app.
|
|
29
|
-
const OUT_SERVER_ENTRY = "server.
|
|
30
|
-
const OUT_CODEGEN = "codegen.
|
|
28
|
+
const OUT_APP_FILE = "app.mjs";
|
|
29
|
+
const OUT_SERVER_ENTRY = "server.mjs";
|
|
30
|
+
const OUT_CODEGEN = "codegen.mjs";
|
|
31
31
|
async function setupWorkingDir(config) {
|
|
32
32
|
const arriDir = path.resolve(config.rootDir, config.buildDir);
|
|
33
33
|
const outDir = path.resolve(config.rootDir, ".output");
|
|
@@ -270,7 +270,7 @@ async function createServerEntryFile(config) {
|
|
|
270
270
|
js: `import { createRequire as topLevelCreateRequire } from 'module';
|
|
271
271
|
const require = topLevelCreateRequire(import.meta.url);`
|
|
272
272
|
},
|
|
273
|
-
plugins: [replace({ "virtual:arri/app": "./app.
|
|
273
|
+
plugins: [replace({ "virtual:arri/app": "./app.mjs" })],
|
|
274
274
|
allowOverwrite: true,
|
|
275
275
|
outfile: path.resolve(config.rootDir, ".output", OUT_SERVER_ENTRY)
|
|
276
276
|
});
|
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const config = require('./shared/arri.
|
|
3
|
+
const config = require('./shared/arri.65113bc6.cjs');
|
|
4
4
|
const h3 = require('h3');
|
|
5
5
|
require('arri-validate');
|
|
6
|
-
require('
|
|
6
|
+
require('h3-sse');
|
|
7
7
|
require('arri-codegen-utils');
|
|
8
8
|
require('scule');
|
|
9
9
|
|
|
@@ -23,8 +23,6 @@ exports.defineEventStreamRpc = config.defineEventStreamRpc;
|
|
|
23
23
|
exports.defineRoute = config.defineRoute;
|
|
24
24
|
exports.defineRpc = config.defineRpc;
|
|
25
25
|
exports.errorResponseFromValidationErrors = config.errorResponseFromValidationErrors;
|
|
26
|
-
exports.formatSse = config.formatSse;
|
|
27
|
-
exports.formatSseList = config.formatSseList;
|
|
28
26
|
exports.getRpcParamName = config.getRpcParamName;
|
|
29
27
|
exports.getRpcPath = config.getRpcPath;
|
|
30
28
|
exports.getRpcResponseName = config.getRpcResponseName;
|
|
@@ -38,7 +36,6 @@ exports.isRpcParamSchema = config.isRpcParamSchema;
|
|
|
38
36
|
exports.registerEventStreamRpc = config.registerEventStreamRpc;
|
|
39
37
|
exports.registerRoute = config.registerRoute;
|
|
40
38
|
exports.registerRpc = config.registerRpc;
|
|
41
|
-
exports.setSseHeaders = config.setSseHeaders;
|
|
42
39
|
exports.validateRpcRequestInput = config.validateRpcRequestInput;
|
|
43
40
|
exports.defineMiddleware = defineMiddleware;
|
|
44
41
|
Object.keys(h3).forEach(function (k) {
|
package/dist/index.d.cts
CHANGED
|
@@ -2,6 +2,7 @@ import { HttpMethod, RpcHttpMethod, RpcDefinition, SchemaFormProperties, SchemaF
|
|
|
2
2
|
import { AObjectSchema, ASchema, InferType, a, ValidationError, ValueError, ARecordSchema, ADiscriminatorSchema } from 'arri-validate';
|
|
3
3
|
import { H3EventContext, H3Event, Router, H3Error, App } from 'h3';
|
|
4
4
|
export * from 'h3';
|
|
5
|
+
import { EventStream } from 'h3-sse';
|
|
5
6
|
import { BuildOptions } from 'esbuild';
|
|
6
7
|
|
|
7
8
|
interface MiddlewareEventContext extends H3EventContext {
|
|
@@ -58,19 +59,15 @@ declare function errorResponseFromValidationErrors(errors: ValidationError["erro
|
|
|
58
59
|
type StatusCode = number | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 507 | 511;
|
|
59
60
|
declare function handleH3Error(err: unknown, event: H3Event, onError: ArriOptions["onError"]): Promise<void>;
|
|
60
61
|
|
|
61
|
-
declare function setSseHeaders(event: H3Event): void;
|
|
62
62
|
declare function defineEventStreamRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined | never = undefined>(config: Omit<EventStreamRpc<TParams, TResponse>, "isEventStream">): EventStreamRpc<TParams, TResponse>;
|
|
63
63
|
declare function isEventStreamRpc(input: unknown): input is EventStreamRpc<any, any>;
|
|
64
64
|
interface EventStreamRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> extends Omit<Rpc<true, TParams, TResponse>, "handler" | "postHandler"> {
|
|
65
65
|
isEventStream: true;
|
|
66
66
|
handler: EventStreamRpcHandler<TParams extends RpcParamSchema ? InferType<TParams> : undefined, TResponse extends RpcParamSchema ? InferType<TResponse> : undefined>;
|
|
67
67
|
}
|
|
68
|
-
type EventStreamRpcHandler<TParams, TResponse> = (context: EventStreamRpcHandlerContext<TParams, TResponse>, event:
|
|
69
|
-
interface EventStreamRpcEvent<TParams, TResponse> extends RpcEvent<TParams> {
|
|
70
|
-
connection: EventStreamConnection<TResponse>;
|
|
71
|
-
}
|
|
68
|
+
type EventStreamRpcHandler<TParams, TResponse> = (context: EventStreamRpcHandlerContext<TParams, TResponse>, event: RpcEvent<TResponse>) => void | Promise<void>;
|
|
72
69
|
interface EventStreamRpcHandlerContext<TParams = any, TResponse = any> extends RpcHandlerContext<TParams> {
|
|
73
|
-
|
|
70
|
+
stream: EventStreamConnection<TResponse>;
|
|
74
71
|
}
|
|
75
72
|
interface EventStreamConnectionOptions<TData> {
|
|
76
73
|
validator: (input: unknown) => input is TData;
|
|
@@ -78,29 +75,14 @@ interface EventStreamConnectionOptions<TData> {
|
|
|
78
75
|
serializer: (input: TData) => string;
|
|
79
76
|
pingInterval?: number;
|
|
80
77
|
}
|
|
81
|
-
/**
|
|
82
|
-
* A server sent event
|
|
83
|
-
*/
|
|
84
|
-
interface Sse {
|
|
85
|
-
id?: string;
|
|
86
|
-
event?: string;
|
|
87
|
-
data: string;
|
|
88
|
-
}
|
|
89
|
-
declare function formatSse({ id, data, event }: Sse): string;
|
|
90
|
-
declare function formatSseList(events: Sse[]): string;
|
|
91
78
|
declare class EventStreamConnection<TData> {
|
|
92
|
-
|
|
93
|
-
private readonly writable;
|
|
94
|
-
private readonly readable;
|
|
95
|
-
private readonly writer;
|
|
96
|
-
private writerIsClosed;
|
|
97
|
-
private readonly encoder;
|
|
79
|
+
private readonly h3Event;
|
|
98
80
|
private readonly validationErrors;
|
|
99
81
|
private readonly validator;
|
|
100
82
|
private readonly serializer;
|
|
101
|
-
private readonly h3Event;
|
|
102
83
|
private pingInterval;
|
|
103
84
|
private readonly pingIntervalMs;
|
|
85
|
+
readonly eventStream: EventStream;
|
|
104
86
|
constructor(event: H3Event, opts: EventStreamConnectionOptions<TData>);
|
|
105
87
|
/**
|
|
106
88
|
* Start sending the event stream to the client
|
|
@@ -115,15 +97,13 @@ declare class EventStreamConnection<TData> {
|
|
|
115
97
|
* Publish an error event. This will trigger the `onError` hooks of any connected clients.
|
|
116
98
|
*/
|
|
117
99
|
pushError(error: ErrorResponse, eventId?: string): Promise<void>;
|
|
118
|
-
private publishEvents;
|
|
119
|
-
private publishEvent;
|
|
120
100
|
private cleanup;
|
|
121
101
|
/**
|
|
122
102
|
* Tell clients that the stream has ended and close the connection.
|
|
123
103
|
*/
|
|
124
|
-
|
|
125
|
-
on(event: "
|
|
126
|
-
on(event: "
|
|
104
|
+
close(): Promise<void>;
|
|
105
|
+
on(event: "close", callback: () => any): void;
|
|
106
|
+
on(event: "request:close", callback: () => any): void;
|
|
127
107
|
}
|
|
128
108
|
declare function registerEventStreamRpc(router: Router, path: string, procedure: EventStreamRpc<any, any> & {
|
|
129
109
|
name: string;
|
|
@@ -257,4 +237,4 @@ type ResolvedArriConfig = Required<ArriConfig>;
|
|
|
257
237
|
declare const defaultConfig: Required<ArriConfig>;
|
|
258
238
|
declare function defineConfig(config: ArriConfig): ResolvedArriConfig;
|
|
259
239
|
|
|
260
|
-
export { ArriApp, type ArriConfig, type ArriOptions, type ArriRoute, ArriRouter, type ArriRouterBase, DEV_DEFINITION_ENDPOINT, DEV_ENDPOINT_ROOT, ErrorResponse, EventStreamConnection, type EventStreamConnectionOptions, type EventStreamRpc, type
|
|
240
|
+
export { ArriApp, type ArriConfig, type ArriOptions, type ArriRoute, ArriRouter, type ArriRouterBase, DEV_DEFINITION_ENDPOINT, DEV_ENDPOINT_ROOT, ErrorResponse, EventStreamConnection, type EventStreamConnectionOptions, type EventStreamRpc, type EventStreamRpcHandler, type EventStreamRpcHandlerContext, type ExtractParam, type ExtractParams, type HandlerContext, type HttpRpc, type Middleware, type MiddlewareEvent, type MiddlewareEventContext, type ModelMap, type NamedRpc, type PostRouteEvent, type PostRouteEventContext, type ResolvedArriConfig, type RouteEvent, type RouteEventContext, type RouteOptions, type Rpc, type RpcEvent, type RpcHandler, type RpcHandlerContext, type RpcParamSchema, type RpcPostEvent, type RpcPostHandler, type RpcPostHandlerContext, type StatusCode, createRpcDefinition, defaultConfig, defineConfig, defineError, defineEventStreamRpc, defineMiddleware, defineRoute, defineRpc, errorResponseFromValidationErrors, getRpcParamName, getRpcPath, getRpcResponseName, handleH3Error, handleRoute, isArriConfig, isEventStreamRpc, isResolvedArriConfig, isRpc, isRpcParamSchema, registerEventStreamRpc, registerRoute, registerRpc, validateRpcRequestInput };
|
package/dist/index.d.mts
CHANGED
|
@@ -2,6 +2,7 @@ import { HttpMethod, RpcHttpMethod, RpcDefinition, SchemaFormProperties, SchemaF
|
|
|
2
2
|
import { AObjectSchema, ASchema, InferType, a, ValidationError, ValueError, ARecordSchema, ADiscriminatorSchema } from 'arri-validate';
|
|
3
3
|
import { H3EventContext, H3Event, Router, H3Error, App } from 'h3';
|
|
4
4
|
export * from 'h3';
|
|
5
|
+
import { EventStream } from 'h3-sse';
|
|
5
6
|
import { BuildOptions } from 'esbuild';
|
|
6
7
|
|
|
7
8
|
interface MiddlewareEventContext extends H3EventContext {
|
|
@@ -58,19 +59,15 @@ declare function errorResponseFromValidationErrors(errors: ValidationError["erro
|
|
|
58
59
|
type StatusCode = number | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 507 | 511;
|
|
59
60
|
declare function handleH3Error(err: unknown, event: H3Event, onError: ArriOptions["onError"]): Promise<void>;
|
|
60
61
|
|
|
61
|
-
declare function setSseHeaders(event: H3Event): void;
|
|
62
62
|
declare function defineEventStreamRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined | never = undefined>(config: Omit<EventStreamRpc<TParams, TResponse>, "isEventStream">): EventStreamRpc<TParams, TResponse>;
|
|
63
63
|
declare function isEventStreamRpc(input: unknown): input is EventStreamRpc<any, any>;
|
|
64
64
|
interface EventStreamRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> extends Omit<Rpc<true, TParams, TResponse>, "handler" | "postHandler"> {
|
|
65
65
|
isEventStream: true;
|
|
66
66
|
handler: EventStreamRpcHandler<TParams extends RpcParamSchema ? InferType<TParams> : undefined, TResponse extends RpcParamSchema ? InferType<TResponse> : undefined>;
|
|
67
67
|
}
|
|
68
|
-
type EventStreamRpcHandler<TParams, TResponse> = (context: EventStreamRpcHandlerContext<TParams, TResponse>, event:
|
|
69
|
-
interface EventStreamRpcEvent<TParams, TResponse> extends RpcEvent<TParams> {
|
|
70
|
-
connection: EventStreamConnection<TResponse>;
|
|
71
|
-
}
|
|
68
|
+
type EventStreamRpcHandler<TParams, TResponse> = (context: EventStreamRpcHandlerContext<TParams, TResponse>, event: RpcEvent<TResponse>) => void | Promise<void>;
|
|
72
69
|
interface EventStreamRpcHandlerContext<TParams = any, TResponse = any> extends RpcHandlerContext<TParams> {
|
|
73
|
-
|
|
70
|
+
stream: EventStreamConnection<TResponse>;
|
|
74
71
|
}
|
|
75
72
|
interface EventStreamConnectionOptions<TData> {
|
|
76
73
|
validator: (input: unknown) => input is TData;
|
|
@@ -78,29 +75,14 @@ interface EventStreamConnectionOptions<TData> {
|
|
|
78
75
|
serializer: (input: TData) => string;
|
|
79
76
|
pingInterval?: number;
|
|
80
77
|
}
|
|
81
|
-
/**
|
|
82
|
-
* A server sent event
|
|
83
|
-
*/
|
|
84
|
-
interface Sse {
|
|
85
|
-
id?: string;
|
|
86
|
-
event?: string;
|
|
87
|
-
data: string;
|
|
88
|
-
}
|
|
89
|
-
declare function formatSse({ id, data, event }: Sse): string;
|
|
90
|
-
declare function formatSseList(events: Sse[]): string;
|
|
91
78
|
declare class EventStreamConnection<TData> {
|
|
92
|
-
|
|
93
|
-
private readonly writable;
|
|
94
|
-
private readonly readable;
|
|
95
|
-
private readonly writer;
|
|
96
|
-
private writerIsClosed;
|
|
97
|
-
private readonly encoder;
|
|
79
|
+
private readonly h3Event;
|
|
98
80
|
private readonly validationErrors;
|
|
99
81
|
private readonly validator;
|
|
100
82
|
private readonly serializer;
|
|
101
|
-
private readonly h3Event;
|
|
102
83
|
private pingInterval;
|
|
103
84
|
private readonly pingIntervalMs;
|
|
85
|
+
readonly eventStream: EventStream;
|
|
104
86
|
constructor(event: H3Event, opts: EventStreamConnectionOptions<TData>);
|
|
105
87
|
/**
|
|
106
88
|
* Start sending the event stream to the client
|
|
@@ -115,15 +97,13 @@ declare class EventStreamConnection<TData> {
|
|
|
115
97
|
* Publish an error event. This will trigger the `onError` hooks of any connected clients.
|
|
116
98
|
*/
|
|
117
99
|
pushError(error: ErrorResponse, eventId?: string): Promise<void>;
|
|
118
|
-
private publishEvents;
|
|
119
|
-
private publishEvent;
|
|
120
100
|
private cleanup;
|
|
121
101
|
/**
|
|
122
102
|
* Tell clients that the stream has ended and close the connection.
|
|
123
103
|
*/
|
|
124
|
-
|
|
125
|
-
on(event: "
|
|
126
|
-
on(event: "
|
|
104
|
+
close(): Promise<void>;
|
|
105
|
+
on(event: "close", callback: () => any): void;
|
|
106
|
+
on(event: "request:close", callback: () => any): void;
|
|
127
107
|
}
|
|
128
108
|
declare function registerEventStreamRpc(router: Router, path: string, procedure: EventStreamRpc<any, any> & {
|
|
129
109
|
name: string;
|
|
@@ -257,4 +237,4 @@ type ResolvedArriConfig = Required<ArriConfig>;
|
|
|
257
237
|
declare const defaultConfig: Required<ArriConfig>;
|
|
258
238
|
declare function defineConfig(config: ArriConfig): ResolvedArriConfig;
|
|
259
239
|
|
|
260
|
-
export { ArriApp, type ArriConfig, type ArriOptions, type ArriRoute, ArriRouter, type ArriRouterBase, DEV_DEFINITION_ENDPOINT, DEV_ENDPOINT_ROOT, ErrorResponse, EventStreamConnection, type EventStreamConnectionOptions, type EventStreamRpc, type
|
|
240
|
+
export { ArriApp, type ArriConfig, type ArriOptions, type ArriRoute, ArriRouter, type ArriRouterBase, DEV_DEFINITION_ENDPOINT, DEV_ENDPOINT_ROOT, ErrorResponse, EventStreamConnection, type EventStreamConnectionOptions, type EventStreamRpc, type EventStreamRpcHandler, type EventStreamRpcHandlerContext, type ExtractParam, type ExtractParams, type HandlerContext, type HttpRpc, type Middleware, type MiddlewareEvent, type MiddlewareEventContext, type ModelMap, type NamedRpc, type PostRouteEvent, type PostRouteEventContext, type ResolvedArriConfig, type RouteEvent, type RouteEventContext, type RouteOptions, type Rpc, type RpcEvent, type RpcHandler, type RpcHandlerContext, type RpcParamSchema, type RpcPostEvent, type RpcPostHandler, type RpcPostHandlerContext, type StatusCode, createRpcDefinition, defaultConfig, defineConfig, defineError, defineEventStreamRpc, defineMiddleware, defineRoute, defineRpc, errorResponseFromValidationErrors, getRpcParamName, getRpcPath, getRpcResponseName, handleH3Error, handleRoute, isArriConfig, isEventStreamRpc, isResolvedArriConfig, isRpc, isRpcParamSchema, registerEventStreamRpc, registerRoute, registerRpc, validateRpcRequestInput };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { HttpMethod, RpcHttpMethod, RpcDefinition, SchemaFormProperties, SchemaF
|
|
|
2
2
|
import { AObjectSchema, ASchema, InferType, a, ValidationError, ValueError, ARecordSchema, ADiscriminatorSchema } from 'arri-validate';
|
|
3
3
|
import { H3EventContext, H3Event, Router, H3Error, App } from 'h3';
|
|
4
4
|
export * from 'h3';
|
|
5
|
+
import { EventStream } from 'h3-sse';
|
|
5
6
|
import { BuildOptions } from 'esbuild';
|
|
6
7
|
|
|
7
8
|
interface MiddlewareEventContext extends H3EventContext {
|
|
@@ -58,19 +59,15 @@ declare function errorResponseFromValidationErrors(errors: ValidationError["erro
|
|
|
58
59
|
type StatusCode = number | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 507 | 511;
|
|
59
60
|
declare function handleH3Error(err: unknown, event: H3Event, onError: ArriOptions["onError"]): Promise<void>;
|
|
60
61
|
|
|
61
|
-
declare function setSseHeaders(event: H3Event): void;
|
|
62
62
|
declare function defineEventStreamRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined | never = undefined>(config: Omit<EventStreamRpc<TParams, TResponse>, "isEventStream">): EventStreamRpc<TParams, TResponse>;
|
|
63
63
|
declare function isEventStreamRpc(input: unknown): input is EventStreamRpc<any, any>;
|
|
64
64
|
interface EventStreamRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> extends Omit<Rpc<true, TParams, TResponse>, "handler" | "postHandler"> {
|
|
65
65
|
isEventStream: true;
|
|
66
66
|
handler: EventStreamRpcHandler<TParams extends RpcParamSchema ? InferType<TParams> : undefined, TResponse extends RpcParamSchema ? InferType<TResponse> : undefined>;
|
|
67
67
|
}
|
|
68
|
-
type EventStreamRpcHandler<TParams, TResponse> = (context: EventStreamRpcHandlerContext<TParams, TResponse>, event:
|
|
69
|
-
interface EventStreamRpcEvent<TParams, TResponse> extends RpcEvent<TParams> {
|
|
70
|
-
connection: EventStreamConnection<TResponse>;
|
|
71
|
-
}
|
|
68
|
+
type EventStreamRpcHandler<TParams, TResponse> = (context: EventStreamRpcHandlerContext<TParams, TResponse>, event: RpcEvent<TResponse>) => void | Promise<void>;
|
|
72
69
|
interface EventStreamRpcHandlerContext<TParams = any, TResponse = any> extends RpcHandlerContext<TParams> {
|
|
73
|
-
|
|
70
|
+
stream: EventStreamConnection<TResponse>;
|
|
74
71
|
}
|
|
75
72
|
interface EventStreamConnectionOptions<TData> {
|
|
76
73
|
validator: (input: unknown) => input is TData;
|
|
@@ -78,29 +75,14 @@ interface EventStreamConnectionOptions<TData> {
|
|
|
78
75
|
serializer: (input: TData) => string;
|
|
79
76
|
pingInterval?: number;
|
|
80
77
|
}
|
|
81
|
-
/**
|
|
82
|
-
* A server sent event
|
|
83
|
-
*/
|
|
84
|
-
interface Sse {
|
|
85
|
-
id?: string;
|
|
86
|
-
event?: string;
|
|
87
|
-
data: string;
|
|
88
|
-
}
|
|
89
|
-
declare function formatSse({ id, data, event }: Sse): string;
|
|
90
|
-
declare function formatSseList(events: Sse[]): string;
|
|
91
78
|
declare class EventStreamConnection<TData> {
|
|
92
|
-
|
|
93
|
-
private readonly writable;
|
|
94
|
-
private readonly readable;
|
|
95
|
-
private readonly writer;
|
|
96
|
-
private writerIsClosed;
|
|
97
|
-
private readonly encoder;
|
|
79
|
+
private readonly h3Event;
|
|
98
80
|
private readonly validationErrors;
|
|
99
81
|
private readonly validator;
|
|
100
82
|
private readonly serializer;
|
|
101
|
-
private readonly h3Event;
|
|
102
83
|
private pingInterval;
|
|
103
84
|
private readonly pingIntervalMs;
|
|
85
|
+
readonly eventStream: EventStream;
|
|
104
86
|
constructor(event: H3Event, opts: EventStreamConnectionOptions<TData>);
|
|
105
87
|
/**
|
|
106
88
|
* Start sending the event stream to the client
|
|
@@ -115,15 +97,13 @@ declare class EventStreamConnection<TData> {
|
|
|
115
97
|
* Publish an error event. This will trigger the `onError` hooks of any connected clients.
|
|
116
98
|
*/
|
|
117
99
|
pushError(error: ErrorResponse, eventId?: string): Promise<void>;
|
|
118
|
-
private publishEvents;
|
|
119
|
-
private publishEvent;
|
|
120
100
|
private cleanup;
|
|
121
101
|
/**
|
|
122
102
|
* Tell clients that the stream has ended and close the connection.
|
|
123
103
|
*/
|
|
124
|
-
|
|
125
|
-
on(event: "
|
|
126
|
-
on(event: "
|
|
104
|
+
close(): Promise<void>;
|
|
105
|
+
on(event: "close", callback: () => any): void;
|
|
106
|
+
on(event: "request:close", callback: () => any): void;
|
|
127
107
|
}
|
|
128
108
|
declare function registerEventStreamRpc(router: Router, path: string, procedure: EventStreamRpc<any, any> & {
|
|
129
109
|
name: string;
|
|
@@ -257,4 +237,4 @@ type ResolvedArriConfig = Required<ArriConfig>;
|
|
|
257
237
|
declare const defaultConfig: Required<ArriConfig>;
|
|
258
238
|
declare function defineConfig(config: ArriConfig): ResolvedArriConfig;
|
|
259
239
|
|
|
260
|
-
export { ArriApp, type ArriConfig, type ArriOptions, type ArriRoute, ArriRouter, type ArriRouterBase, DEV_DEFINITION_ENDPOINT, DEV_ENDPOINT_ROOT, ErrorResponse, EventStreamConnection, type EventStreamConnectionOptions, type EventStreamRpc, type
|
|
240
|
+
export { ArriApp, type ArriConfig, type ArriOptions, type ArriRoute, ArriRouter, type ArriRouterBase, DEV_DEFINITION_ENDPOINT, DEV_ENDPOINT_ROOT, ErrorResponse, EventStreamConnection, type EventStreamConnectionOptions, type EventStreamRpc, type EventStreamRpcHandler, type EventStreamRpcHandlerContext, type ExtractParam, type ExtractParams, type HandlerContext, type HttpRpc, type Middleware, type MiddlewareEvent, type MiddlewareEventContext, type ModelMap, type NamedRpc, type PostRouteEvent, type PostRouteEventContext, type ResolvedArriConfig, type RouteEvent, type RouteEventContext, type RouteOptions, type Rpc, type RpcEvent, type RpcHandler, type RpcHandlerContext, type RpcParamSchema, type RpcPostEvent, type RpcPostHandler, type RpcPostHandlerContext, type StatusCode, createRpcDefinition, defaultConfig, defineConfig, defineError, defineEventStreamRpc, defineMiddleware, defineRoute, defineRpc, errorResponseFromValidationErrors, getRpcParamName, getRpcPath, getRpcResponseName, handleH3Error, handleRoute, isArriConfig, isEventStreamRpc, isResolvedArriConfig, isRpc, isRpcParamSchema, registerEventStreamRpc, registerRoute, registerRpc, validateRpcRequestInput };
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { A as ArriApp, p as ArriRouter, a as DEV_DEFINITION_ENDPOINT, D as DEV_ENDPOINT_ROOT, E as ErrorResponse,
|
|
1
|
+
export { A as ArriApp, p as ArriRouter, a as DEV_DEFINITION_ENDPOINT, D as DEV_ENDPOINT_ROOT, E as ErrorResponse, x as EventStreamConnection, c as createRpcDefinition, n as defaultConfig, o as defineConfig, h as defineError, u as defineEventStreamRpc, q as defineRoute, d as defineRpc, j as errorResponseFromValidationErrors, e as getRpcParamName, g as getRpcPath, f as getRpcResponseName, k as handleH3Error, t as handleRoute, l as isArriConfig, w as isEventStreamRpc, m as isResolvedArriConfig, b as isRpc, i as isRpcParamSchema, y as registerEventStreamRpc, s as registerRoute, r as registerRpc, v as validateRpcRequestInput } from './shared/arri.ba3f283e.mjs';
|
|
2
2
|
export * from 'h3';
|
|
3
3
|
import 'arri-validate';
|
|
4
|
-
import '
|
|
4
|
+
import 'h3-sse';
|
|
5
5
|
import 'arri-codegen-utils';
|
|
6
6
|
import 'scule';
|
|
7
7
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const h3 = require('h3');
|
|
4
4
|
const arriValidate = require('arri-validate');
|
|
5
|
-
const
|
|
5
|
+
const h3Sse = require('h3-sse');
|
|
6
6
|
const arriCodegenUtils = require('arri-codegen-utils');
|
|
7
7
|
const scule = require('scule');
|
|
8
8
|
|
|
@@ -433,19 +433,6 @@ var __publicField$2 = (obj, key, value) => {
|
|
|
433
433
|
__defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
434
434
|
return value;
|
|
435
435
|
};
|
|
436
|
-
function setSseHeaders(event) {
|
|
437
|
-
const isHttp2 = event._http2 === true;
|
|
438
|
-
const input = {
|
|
439
|
-
"Content-Type": "text/event-stream",
|
|
440
|
-
"Cache-Control": "private, no-cache, no-store, no-transform, must-revalidate, max-age=0",
|
|
441
|
-
Pragma: "no-cache",
|
|
442
|
-
"X-Accel-Buffering": "no"
|
|
443
|
-
};
|
|
444
|
-
if (!isHttp2) {
|
|
445
|
-
input.Connection = "keep-alive";
|
|
446
|
-
}
|
|
447
|
-
h3.setResponseHeaders(event, input);
|
|
448
|
-
}
|
|
449
436
|
function defineEventStreamRpc(config) {
|
|
450
437
|
return {
|
|
451
438
|
...config,
|
|
@@ -456,69 +443,33 @@ function defineEventStreamRpc(config) {
|
|
|
456
443
|
function isEventStreamRpc(input) {
|
|
457
444
|
return isRpc(input) && "isEventStream" in input && input.isEventStream === true;
|
|
458
445
|
}
|
|
459
|
-
function formatSse({ id, data, event }) {
|
|
460
|
-
const parts = [];
|
|
461
|
-
if (id) {
|
|
462
|
-
parts.push(`id: ${id}`);
|
|
463
|
-
}
|
|
464
|
-
if (event) {
|
|
465
|
-
parts.push(`event: ${event}`);
|
|
466
|
-
}
|
|
467
|
-
parts.push(`data: ${data}`);
|
|
468
|
-
const payload = `${parts.join("\n")}
|
|
469
|
-
|
|
470
|
-
`;
|
|
471
|
-
return payload;
|
|
472
|
-
}
|
|
473
|
-
function formatSseList(events) {
|
|
474
|
-
let output = "";
|
|
475
|
-
for (const event of events) {
|
|
476
|
-
output += formatSse(event);
|
|
477
|
-
}
|
|
478
|
-
return output;
|
|
479
|
-
}
|
|
480
446
|
class EventStreamConnection {
|
|
481
447
|
constructor(event, opts) {
|
|
482
|
-
__publicField$2(this, "
|
|
483
|
-
__publicField$2(this, "writable");
|
|
484
|
-
__publicField$2(this, "readable");
|
|
485
|
-
__publicField$2(this, "writer");
|
|
486
|
-
__publicField$2(this, "writerIsClosed", false);
|
|
487
|
-
__publicField$2(this, "encoder");
|
|
448
|
+
__publicField$2(this, "h3Event");
|
|
488
449
|
__publicField$2(this, "validationErrors");
|
|
489
450
|
__publicField$2(this, "validator");
|
|
490
451
|
__publicField$2(this, "serializer");
|
|
491
|
-
__publicField$2(this, "h3Event");
|
|
492
452
|
// for some reason Rollup cannot output DTS when this is set to NodeJS.Timeout
|
|
493
453
|
__publicField$2(this, "pingInterval");
|
|
494
454
|
__publicField$2(this, "pingIntervalMs");
|
|
455
|
+
__publicField$2(this, "eventStream");
|
|
495
456
|
this.h3Event = event;
|
|
496
|
-
|
|
497
|
-
this.lastEventId = id;
|
|
498
|
-
const { readable, writable } = new TransformStream();
|
|
499
|
-
this.writable = writable;
|
|
500
|
-
this.readable = readable;
|
|
501
|
-
this.writer = writable.getWriter();
|
|
502
|
-
this.encoder = new TextEncoder();
|
|
457
|
+
this.eventStream = h3Sse.createEventStream(event, true);
|
|
503
458
|
this.pingIntervalMs = opts.pingInterval ?? 6e4;
|
|
504
459
|
this.serializer = opts.serializer;
|
|
505
460
|
this.validator = opts.validator;
|
|
506
461
|
this.validationErrors = opts.validationErrors;
|
|
507
|
-
|
|
508
|
-
this.
|
|
462
|
+
this.eventStream.on("close", () => {
|
|
463
|
+
this.cleanup();
|
|
509
464
|
});
|
|
510
465
|
}
|
|
511
466
|
/**
|
|
512
467
|
* Start sending the event stream to the client
|
|
513
468
|
*/
|
|
514
469
|
start() {
|
|
515
|
-
|
|
516
|
-
h3.setResponseStatus(this.h3Event, 200);
|
|
517
|
-
this.h3Event._handled = true;
|
|
518
|
-
void h3.sendStream(this.h3Event, this.readable);
|
|
470
|
+
void h3Sse.sendEventStream(this.h3Event, this.eventStream);
|
|
519
471
|
this.pingInterval = setInterval(async () => {
|
|
520
|
-
await this.
|
|
521
|
-
id: this.lastEventId,
|
|
472
|
+
await this.eventStream.push({
|
|
522
473
|
event: "ping",
|
|
523
474
|
data: ""
|
|
524
475
|
});
|
|
@@ -548,11 +499,11 @@ class EventStreamConnection {
|
|
|
548
499
|
data: JSON.stringify(errorResponse2)
|
|
549
500
|
});
|
|
550
501
|
}
|
|
551
|
-
await this.
|
|
502
|
+
await this.eventStream.push(events);
|
|
552
503
|
return;
|
|
553
504
|
}
|
|
554
505
|
if (this.validator(data)) {
|
|
555
|
-
await this.
|
|
506
|
+
await this.eventStream.push({
|
|
556
507
|
id: eventId,
|
|
557
508
|
event: "message",
|
|
558
509
|
data: this.serializer(data)
|
|
@@ -565,7 +516,7 @@ class EventStreamConnection {
|
|
|
565
516
|
statusMessage: "Failed to serialize response. Response does not match specified schema.",
|
|
566
517
|
data: errors
|
|
567
518
|
};
|
|
568
|
-
await this.
|
|
519
|
+
await this.eventStream.push({
|
|
569
520
|
id: eventId,
|
|
570
521
|
event: "error",
|
|
571
522
|
data: JSON.stringify(errorResponse)
|
|
@@ -591,79 +542,34 @@ class EventStreamConnection {
|
|
|
591
542
|
* Publish an error event. This will trigger the `onError` hooks of any connected clients.
|
|
592
543
|
*/
|
|
593
544
|
async pushError(error, eventId) {
|
|
594
|
-
await this.
|
|
545
|
+
await this.eventStream.push({
|
|
595
546
|
id: eventId,
|
|
596
547
|
event: "error",
|
|
597
548
|
data: JSON.stringify(error)
|
|
598
549
|
});
|
|
599
550
|
}
|
|
600
|
-
|
|
601
|
-
const payload = formatSseList(events);
|
|
602
|
-
if (this.writerIsClosed) {
|
|
603
|
-
try {
|
|
604
|
-
this.h3Event.node.res.end();
|
|
605
|
-
} catch (_) {
|
|
606
|
-
await this.cleanup();
|
|
607
|
-
}
|
|
608
|
-
return;
|
|
609
|
-
}
|
|
610
|
-
await this.writer.write(this.encoder.encode(payload));
|
|
611
|
-
}
|
|
612
|
-
async publishEvent(event) {
|
|
613
|
-
const payload = formatSse(event);
|
|
614
|
-
if (this.writerIsClosed) {
|
|
615
|
-
try {
|
|
616
|
-
this.h3Event.node.res.end();
|
|
617
|
-
} catch (_) {
|
|
618
|
-
await this.cleanup();
|
|
619
|
-
}
|
|
620
|
-
return;
|
|
621
|
-
}
|
|
622
|
-
await this.writer.write(this.encoder.encode(payload));
|
|
623
|
-
}
|
|
624
|
-
async cleanup() {
|
|
551
|
+
cleanup() {
|
|
625
552
|
if (this.pingInterval) {
|
|
626
553
|
clearInterval(this.pingInterval);
|
|
627
554
|
}
|
|
628
|
-
if (!this.writerIsClosed) {
|
|
629
|
-
try {
|
|
630
|
-
await this.writer.close();
|
|
631
|
-
} catch (_) {
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
555
|
}
|
|
635
556
|
/**
|
|
636
557
|
* Tell clients that the stream has ended and close the connection.
|
|
637
558
|
*/
|
|
638
|
-
async
|
|
639
|
-
await this.
|
|
559
|
+
async close() {
|
|
560
|
+
await this.eventStream.push({
|
|
640
561
|
event: "done",
|
|
641
562
|
data: "this stream has ended"
|
|
642
563
|
}).catch();
|
|
643
|
-
await
|
|
644
|
-
node_process.nextTick(() => {
|
|
645
|
-
try {
|
|
646
|
-
this.h3Event.node.res.end();
|
|
647
|
-
resolve(true);
|
|
648
|
-
} catch (err) {
|
|
649
|
-
reject(err);
|
|
650
|
-
}
|
|
651
|
-
});
|
|
652
|
-
});
|
|
564
|
+
await this.eventStream.close();
|
|
653
565
|
}
|
|
654
566
|
on(event, callback) {
|
|
655
567
|
switch (event) {
|
|
656
|
-
case "
|
|
657
|
-
this.
|
|
658
|
-
await callback();
|
|
659
|
-
await this.cleanup();
|
|
660
|
-
});
|
|
568
|
+
case "close":
|
|
569
|
+
this.eventStream.on("close", callback);
|
|
661
570
|
break;
|
|
662
|
-
case "
|
|
663
|
-
this.
|
|
664
|
-
await callback();
|
|
665
|
-
await this.cleanup();
|
|
666
|
-
});
|
|
571
|
+
case "request:close":
|
|
572
|
+
this.eventStream.on("request:close", callback);
|
|
667
573
|
break;
|
|
668
574
|
}
|
|
669
575
|
}
|
|
@@ -697,7 +603,7 @@ function registerEventStreamRpc(router, path, procedure, opts) {
|
|
|
697
603
|
procedure.params
|
|
698
604
|
);
|
|
699
605
|
}
|
|
700
|
-
const
|
|
606
|
+
const stream = new EventStreamConnection(event, {
|
|
701
607
|
pingInterval: procedure.pingInterval,
|
|
702
608
|
validator: responseValidator?.validate ?? function() {
|
|
703
609
|
return true;
|
|
@@ -712,11 +618,14 @@ function registerEventStreamRpc(router, path, procedure, opts) {
|
|
|
712
618
|
return [];
|
|
713
619
|
}
|
|
714
620
|
});
|
|
715
|
-
event.context.
|
|
621
|
+
event.context.stream = stream;
|
|
716
622
|
await procedure.handler(
|
|
717
623
|
event.context,
|
|
718
624
|
event
|
|
719
625
|
);
|
|
626
|
+
if (!event.handled && !stream.eventStream._handled) {
|
|
627
|
+
await h3Sse.sendEventStream(event, stream.eventStream);
|
|
628
|
+
}
|
|
720
629
|
} catch (err) {
|
|
721
630
|
await handleH3Error(err, event, opts.onError);
|
|
722
631
|
}
|
|
@@ -1102,8 +1011,6 @@ exports.defineEventStreamRpc = defineEventStreamRpc;
|
|
|
1102
1011
|
exports.defineRoute = defineRoute;
|
|
1103
1012
|
exports.defineRpc = defineRpc;
|
|
1104
1013
|
exports.errorResponseFromValidationErrors = errorResponseFromValidationErrors;
|
|
1105
|
-
exports.formatSse = formatSse;
|
|
1106
|
-
exports.formatSseList = formatSseList;
|
|
1107
1014
|
exports.getRpcParamName = getRpcParamName;
|
|
1108
1015
|
exports.getRpcPath = getRpcPath;
|
|
1109
1016
|
exports.getRpcResponseName = getRpcResponseName;
|
|
@@ -1117,5 +1024,4 @@ exports.isRpcParamSchema = isRpcParamSchema;
|
|
|
1117
1024
|
exports.registerEventStreamRpc = registerEventStreamRpc;
|
|
1118
1025
|
exports.registerRoute = registerRoute;
|
|
1119
1026
|
exports.registerRpc = registerRpc;
|
|
1120
|
-
exports.setSseHeaders = setSseHeaders;
|
|
1121
1027
|
exports.validateRpcRequestInput = validateRpcRequestInput;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createError, isError, setResponseStatus, send, eventHandler, isPreflightRequest, setResponseHeader, readRawBody, getValidatedQuery,
|
|
1
|
+
import { createError, isError, setResponseStatus, send, eventHandler, isPreflightRequest, setResponseHeader, readRawBody, getValidatedQuery, defineEventHandler, getQuery, setHeader, createRouter, createApp, sendError } from 'h3';
|
|
2
2
|
import { a, isAObjectSchema, isARecordSchema, isADiscriminatorSchema } from 'arri-validate';
|
|
3
|
-
import {
|
|
3
|
+
import { createEventStream, sendEventStream } from 'h3-sse';
|
|
4
4
|
import { isRpcHttpMethod, removeDisallowedChars } from 'arri-codegen-utils';
|
|
5
5
|
import { kebabCase, pascalCase } from 'scule';
|
|
6
6
|
|
|
@@ -431,19 +431,6 @@ var __publicField$2 = (obj, key, value) => {
|
|
|
431
431
|
__defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
432
432
|
return value;
|
|
433
433
|
};
|
|
434
|
-
function setSseHeaders(event) {
|
|
435
|
-
const isHttp2 = event._http2 === true;
|
|
436
|
-
const input = {
|
|
437
|
-
"Content-Type": "text/event-stream",
|
|
438
|
-
"Cache-Control": "private, no-cache, no-store, no-transform, must-revalidate, max-age=0",
|
|
439
|
-
Pragma: "no-cache",
|
|
440
|
-
"X-Accel-Buffering": "no"
|
|
441
|
-
};
|
|
442
|
-
if (!isHttp2) {
|
|
443
|
-
input.Connection = "keep-alive";
|
|
444
|
-
}
|
|
445
|
-
setResponseHeaders(event, input);
|
|
446
|
-
}
|
|
447
434
|
function defineEventStreamRpc(config) {
|
|
448
435
|
return {
|
|
449
436
|
...config,
|
|
@@ -454,69 +441,33 @@ function defineEventStreamRpc(config) {
|
|
|
454
441
|
function isEventStreamRpc(input) {
|
|
455
442
|
return isRpc(input) && "isEventStream" in input && input.isEventStream === true;
|
|
456
443
|
}
|
|
457
|
-
function formatSse({ id, data, event }) {
|
|
458
|
-
const parts = [];
|
|
459
|
-
if (id) {
|
|
460
|
-
parts.push(`id: ${id}`);
|
|
461
|
-
}
|
|
462
|
-
if (event) {
|
|
463
|
-
parts.push(`event: ${event}`);
|
|
464
|
-
}
|
|
465
|
-
parts.push(`data: ${data}`);
|
|
466
|
-
const payload = `${parts.join("\n")}
|
|
467
|
-
|
|
468
|
-
`;
|
|
469
|
-
return payload;
|
|
470
|
-
}
|
|
471
|
-
function formatSseList(events) {
|
|
472
|
-
let output = "";
|
|
473
|
-
for (const event of events) {
|
|
474
|
-
output += formatSse(event);
|
|
475
|
-
}
|
|
476
|
-
return output;
|
|
477
|
-
}
|
|
478
444
|
class EventStreamConnection {
|
|
479
445
|
constructor(event, opts) {
|
|
480
|
-
__publicField$2(this, "
|
|
481
|
-
__publicField$2(this, "writable");
|
|
482
|
-
__publicField$2(this, "readable");
|
|
483
|
-
__publicField$2(this, "writer");
|
|
484
|
-
__publicField$2(this, "writerIsClosed", false);
|
|
485
|
-
__publicField$2(this, "encoder");
|
|
446
|
+
__publicField$2(this, "h3Event");
|
|
486
447
|
__publicField$2(this, "validationErrors");
|
|
487
448
|
__publicField$2(this, "validator");
|
|
488
449
|
__publicField$2(this, "serializer");
|
|
489
|
-
__publicField$2(this, "h3Event");
|
|
490
450
|
// for some reason Rollup cannot output DTS when this is set to NodeJS.Timeout
|
|
491
451
|
__publicField$2(this, "pingInterval");
|
|
492
452
|
__publicField$2(this, "pingIntervalMs");
|
|
453
|
+
__publicField$2(this, "eventStream");
|
|
493
454
|
this.h3Event = event;
|
|
494
|
-
|
|
495
|
-
this.lastEventId = id;
|
|
496
|
-
const { readable, writable } = new TransformStream();
|
|
497
|
-
this.writable = writable;
|
|
498
|
-
this.readable = readable;
|
|
499
|
-
this.writer = writable.getWriter();
|
|
500
|
-
this.encoder = new TextEncoder();
|
|
455
|
+
this.eventStream = createEventStream(event, true);
|
|
501
456
|
this.pingIntervalMs = opts.pingInterval ?? 6e4;
|
|
502
457
|
this.serializer = opts.serializer;
|
|
503
458
|
this.validator = opts.validator;
|
|
504
459
|
this.validationErrors = opts.validationErrors;
|
|
505
|
-
|
|
506
|
-
this.
|
|
460
|
+
this.eventStream.on("close", () => {
|
|
461
|
+
this.cleanup();
|
|
507
462
|
});
|
|
508
463
|
}
|
|
509
464
|
/**
|
|
510
465
|
* Start sending the event stream to the client
|
|
511
466
|
*/
|
|
512
467
|
start() {
|
|
513
|
-
|
|
514
|
-
setResponseStatus(this.h3Event, 200);
|
|
515
|
-
this.h3Event._handled = true;
|
|
516
|
-
void sendStream(this.h3Event, this.readable);
|
|
468
|
+
void sendEventStream(this.h3Event, this.eventStream);
|
|
517
469
|
this.pingInterval = setInterval(async () => {
|
|
518
|
-
await this.
|
|
519
|
-
id: this.lastEventId,
|
|
470
|
+
await this.eventStream.push({
|
|
520
471
|
event: "ping",
|
|
521
472
|
data: ""
|
|
522
473
|
});
|
|
@@ -546,11 +497,11 @@ class EventStreamConnection {
|
|
|
546
497
|
data: JSON.stringify(errorResponse2)
|
|
547
498
|
});
|
|
548
499
|
}
|
|
549
|
-
await this.
|
|
500
|
+
await this.eventStream.push(events);
|
|
550
501
|
return;
|
|
551
502
|
}
|
|
552
503
|
if (this.validator(data)) {
|
|
553
|
-
await this.
|
|
504
|
+
await this.eventStream.push({
|
|
554
505
|
id: eventId,
|
|
555
506
|
event: "message",
|
|
556
507
|
data: this.serializer(data)
|
|
@@ -563,7 +514,7 @@ class EventStreamConnection {
|
|
|
563
514
|
statusMessage: "Failed to serialize response. Response does not match specified schema.",
|
|
564
515
|
data: errors
|
|
565
516
|
};
|
|
566
|
-
await this.
|
|
517
|
+
await this.eventStream.push({
|
|
567
518
|
id: eventId,
|
|
568
519
|
event: "error",
|
|
569
520
|
data: JSON.stringify(errorResponse)
|
|
@@ -589,79 +540,34 @@ class EventStreamConnection {
|
|
|
589
540
|
* Publish an error event. This will trigger the `onError` hooks of any connected clients.
|
|
590
541
|
*/
|
|
591
542
|
async pushError(error, eventId) {
|
|
592
|
-
await this.
|
|
543
|
+
await this.eventStream.push({
|
|
593
544
|
id: eventId,
|
|
594
545
|
event: "error",
|
|
595
546
|
data: JSON.stringify(error)
|
|
596
547
|
});
|
|
597
548
|
}
|
|
598
|
-
|
|
599
|
-
const payload = formatSseList(events);
|
|
600
|
-
if (this.writerIsClosed) {
|
|
601
|
-
try {
|
|
602
|
-
this.h3Event.node.res.end();
|
|
603
|
-
} catch (_) {
|
|
604
|
-
await this.cleanup();
|
|
605
|
-
}
|
|
606
|
-
return;
|
|
607
|
-
}
|
|
608
|
-
await this.writer.write(this.encoder.encode(payload));
|
|
609
|
-
}
|
|
610
|
-
async publishEvent(event) {
|
|
611
|
-
const payload = formatSse(event);
|
|
612
|
-
if (this.writerIsClosed) {
|
|
613
|
-
try {
|
|
614
|
-
this.h3Event.node.res.end();
|
|
615
|
-
} catch (_) {
|
|
616
|
-
await this.cleanup();
|
|
617
|
-
}
|
|
618
|
-
return;
|
|
619
|
-
}
|
|
620
|
-
await this.writer.write(this.encoder.encode(payload));
|
|
621
|
-
}
|
|
622
|
-
async cleanup() {
|
|
549
|
+
cleanup() {
|
|
623
550
|
if (this.pingInterval) {
|
|
624
551
|
clearInterval(this.pingInterval);
|
|
625
552
|
}
|
|
626
|
-
if (!this.writerIsClosed) {
|
|
627
|
-
try {
|
|
628
|
-
await this.writer.close();
|
|
629
|
-
} catch (_) {
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
553
|
}
|
|
633
554
|
/**
|
|
634
555
|
* Tell clients that the stream has ended and close the connection.
|
|
635
556
|
*/
|
|
636
|
-
async
|
|
637
|
-
await this.
|
|
557
|
+
async close() {
|
|
558
|
+
await this.eventStream.push({
|
|
638
559
|
event: "done",
|
|
639
560
|
data: "this stream has ended"
|
|
640
561
|
}).catch();
|
|
641
|
-
await
|
|
642
|
-
nextTick(() => {
|
|
643
|
-
try {
|
|
644
|
-
this.h3Event.node.res.end();
|
|
645
|
-
resolve(true);
|
|
646
|
-
} catch (err) {
|
|
647
|
-
reject(err);
|
|
648
|
-
}
|
|
649
|
-
});
|
|
650
|
-
});
|
|
562
|
+
await this.eventStream.close();
|
|
651
563
|
}
|
|
652
564
|
on(event, callback) {
|
|
653
565
|
switch (event) {
|
|
654
|
-
case "
|
|
655
|
-
this.
|
|
656
|
-
await callback();
|
|
657
|
-
await this.cleanup();
|
|
658
|
-
});
|
|
566
|
+
case "close":
|
|
567
|
+
this.eventStream.on("close", callback);
|
|
659
568
|
break;
|
|
660
|
-
case "
|
|
661
|
-
this.
|
|
662
|
-
await callback();
|
|
663
|
-
await this.cleanup();
|
|
664
|
-
});
|
|
569
|
+
case "request:close":
|
|
570
|
+
this.eventStream.on("request:close", callback);
|
|
665
571
|
break;
|
|
666
572
|
}
|
|
667
573
|
}
|
|
@@ -695,7 +601,7 @@ function registerEventStreamRpc(router, path, procedure, opts) {
|
|
|
695
601
|
procedure.params
|
|
696
602
|
);
|
|
697
603
|
}
|
|
698
|
-
const
|
|
604
|
+
const stream = new EventStreamConnection(event, {
|
|
699
605
|
pingInterval: procedure.pingInterval,
|
|
700
606
|
validator: responseValidator?.validate ?? function() {
|
|
701
607
|
return true;
|
|
@@ -710,11 +616,14 @@ function registerEventStreamRpc(router, path, procedure, opts) {
|
|
|
710
616
|
return [];
|
|
711
617
|
}
|
|
712
618
|
});
|
|
713
|
-
event.context.
|
|
619
|
+
event.context.stream = stream;
|
|
714
620
|
await procedure.handler(
|
|
715
621
|
event.context,
|
|
716
622
|
event
|
|
717
623
|
);
|
|
624
|
+
if (!event.handled && !stream.eventStream._handled) {
|
|
625
|
+
await sendEventStream(event, stream.eventStream);
|
|
626
|
+
}
|
|
718
627
|
} catch (err) {
|
|
719
628
|
await handleH3Error(err, event, opts.onError);
|
|
720
629
|
}
|
|
@@ -1086,4 +995,4 @@ function defineConfig(config) {
|
|
|
1086
995
|
};
|
|
1087
996
|
}
|
|
1088
997
|
|
|
1089
|
-
export { ArriApp as A,
|
|
998
|
+
export { ArriApp as A, DEV_ENDPOINT_ROOT as D, ErrorResponse as E, DEV_DEFINITION_ENDPOINT as a, isRpc as b, createRpcDefinition as c, defineRpc as d, getRpcParamName as e, getRpcResponseName as f, getRpcPath as g, defineError as h, isRpcParamSchema as i, errorResponseFromValidationErrors as j, handleH3Error as k, isArriConfig as l, isResolvedArriConfig as m, defaultConfig as n, defineConfig as o, ArriRouter as p, defineRoute as q, registerRpc as r, registerRoute as s, handleRoute as t, defineEventStreamRpc as u, validateRpcRequestInput as v, isEventStreamRpc as w, EventStreamConnection as x, registerEventStreamRpc as y };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arri",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -26,28 +26,29 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@joshmossas/listhen": "1.6.0",
|
|
29
|
-
"c12": "^1.
|
|
29
|
+
"c12": "^1.9.0",
|
|
30
30
|
"chokidar": "^3.6.0",
|
|
31
31
|
"citty": "^0.1.6",
|
|
32
32
|
"consola": "^3.2.3",
|
|
33
33
|
"degit": "^2.8.4",
|
|
34
|
-
"esbuild": "^0.20.
|
|
34
|
+
"esbuild": "^0.20.1",
|
|
35
35
|
"esbuild-plugin-replace": "^1.4.0",
|
|
36
36
|
"globby": "^14.0.1",
|
|
37
|
-
"h3": "^1.10.
|
|
37
|
+
"h3": "^1.10.2",
|
|
38
|
+
"h3-sse": "^0.0.7",
|
|
38
39
|
"jiti": "^1.21.0",
|
|
39
40
|
"ofetch": "^1.3.3",
|
|
40
41
|
"pathe": "^1.1.2",
|
|
41
42
|
"prettier": "^3.2.5",
|
|
42
43
|
"scule": "^1.3.0",
|
|
43
44
|
"uncrypto": "^0.1.3",
|
|
44
|
-
"arri-codegen-
|
|
45
|
-
"arri-
|
|
46
|
-
"arri-
|
|
47
|
-
"arri-codegen-
|
|
45
|
+
"arri-codegen-ts": "0.25.0",
|
|
46
|
+
"arri-codegen-utils": "0.25.0",
|
|
47
|
+
"arri-validate": "0.25.0",
|
|
48
|
+
"arri-codegen-dart": "0.25.0"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
51
|
"@types/degit": "^2.8.6",
|
|
51
|
-
"bun-types": "^1.0.
|
|
52
|
+
"bun-types": "^1.0.28"
|
|
52
53
|
}
|
|
53
54
|
}
|