@arrirpc/server 0.79.0 → 0.80.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/README.md +3 -3
- package/dist/index.cjs +38 -17
- package/dist/index.d.cts +9 -5
- package/dist/index.d.mts +9 -5
- package/dist/index.d.ts +9 -5
- package/dist/index.mjs +38 -17
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -225,7 +225,7 @@ Arri Event streams sent the following event types:
|
|
|
225
225
|
- `message` - A standard message with the response data serialized as JSON
|
|
226
226
|
- `start` - A starting message to start the stream
|
|
227
227
|
- `done` - A message to tell clients that there will be no more events
|
|
228
|
-
- `
|
|
228
|
+
- `heartbeat` - A message periodically sent by the server to keep the connection alive.
|
|
229
229
|
|
|
230
230
|
```ts
|
|
231
231
|
/// message event ///
|
|
@@ -237,8 +237,8 @@ data: Response; // whatever you have specified as the response serialized to jso
|
|
|
237
237
|
event: 'done';
|
|
238
238
|
data: 'this stream has ended';
|
|
239
239
|
|
|
240
|
-
///
|
|
241
|
-
event: '
|
|
240
|
+
/// heartbeat event ///
|
|
241
|
+
event: 'heartbeat';
|
|
242
242
|
data: '';
|
|
243
243
|
```
|
|
244
244
|
|
package/dist/index.cjs
CHANGED
|
@@ -472,7 +472,7 @@ function getSchemaName(rpcName, type, schema) {
|
|
|
472
472
|
function defineEventStreamRpc(config) {
|
|
473
473
|
return {
|
|
474
474
|
...config,
|
|
475
|
-
method: config.method ?? "
|
|
475
|
+
method: config.method ?? "post",
|
|
476
476
|
isEventStream: true,
|
|
477
477
|
transport: "http"
|
|
478
478
|
};
|
|
@@ -484,16 +484,32 @@ class EventStreamConnection {
|
|
|
484
484
|
lastEventId;
|
|
485
485
|
validator;
|
|
486
486
|
// for some reason Rollup cannot output DTS when this is set to NodeJS.Timeout
|
|
487
|
-
|
|
488
|
-
|
|
487
|
+
heartbeatInterval = void 0;
|
|
488
|
+
heartbeatMs;
|
|
489
|
+
sendHeartbeat;
|
|
489
490
|
eventStream;
|
|
491
|
+
_isClosed = false;
|
|
490
492
|
constructor(event, opts) {
|
|
491
|
-
this.
|
|
493
|
+
this.heartbeatMs = opts.heartbeatMs ?? 2e4;
|
|
494
|
+
this.sendHeartbeat = opts.heartbeatEnabled ?? true;
|
|
495
|
+
h3.setResponseHeader(
|
|
496
|
+
event,
|
|
497
|
+
"heartbeat-interval",
|
|
498
|
+
this.heartbeatMs.toString()
|
|
499
|
+
);
|
|
500
|
+
this.eventStream = h3.createEventStream(event, { autoclose: false });
|
|
501
|
+
event.node.req.once("close", () => {
|
|
502
|
+
if (this._isClosed) return;
|
|
503
|
+
this.eventStream.close();
|
|
504
|
+
});
|
|
505
|
+
event.node.res.once("close", () => {
|
|
506
|
+
if (this._isClosed) return;
|
|
507
|
+
this.eventStream.close();
|
|
508
|
+
});
|
|
492
509
|
this.lastEventId = h3.getHeader(event, "Last-Event-Id");
|
|
493
|
-
this.pingIntervalMs = opts.pingInterval ?? 6e4;
|
|
494
510
|
this.validator = opts.validator;
|
|
495
511
|
this.eventStream.onClosed(() => {
|
|
496
|
-
this.
|
|
512
|
+
this._cleanup();
|
|
497
513
|
});
|
|
498
514
|
}
|
|
499
515
|
/**
|
|
@@ -505,12 +521,15 @@ class EventStreamConnection {
|
|
|
505
521
|
event: "start",
|
|
506
522
|
data: "connection successful"
|
|
507
523
|
});
|
|
508
|
-
this.
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
524
|
+
if (this.sendHeartbeat) {
|
|
525
|
+
this.heartbeatInterval = setInterval(async () => {
|
|
526
|
+
console.log("SENDING_HEARTBEAT");
|
|
527
|
+
await this.eventStream.push({
|
|
528
|
+
event: "heartbeat",
|
|
529
|
+
data: ""
|
|
530
|
+
});
|
|
531
|
+
}, this.heartbeatMs);
|
|
532
|
+
}
|
|
514
533
|
}
|
|
515
534
|
async push(data, eventId) {
|
|
516
535
|
if (!this.validator) return;
|
|
@@ -552,9 +571,10 @@ class EventStreamConnection {
|
|
|
552
571
|
errors
|
|
553
572
|
};
|
|
554
573
|
}
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
574
|
+
_cleanup() {
|
|
575
|
+
this._isClosed = true;
|
|
576
|
+
if (this.heartbeatInterval) {
|
|
577
|
+
clearInterval(this.heartbeatInterval);
|
|
558
578
|
}
|
|
559
579
|
}
|
|
560
580
|
/**
|
|
@@ -574,7 +594,7 @@ class EventStreamConnection {
|
|
|
574
594
|
function registerEventStreamRpc(router, path, procedure, opts) {
|
|
575
595
|
const paramValidator = procedure.params ? getSchemaValidator(procedure.name, "params", procedure.params) : void 0;
|
|
576
596
|
const responseValidator = procedure.response ? getSchemaValidator(procedure.name, "response", procedure.response) : void 0;
|
|
577
|
-
const httpMethod = procedure.method ?? "
|
|
597
|
+
const httpMethod = procedure.method ?? "post";
|
|
578
598
|
const handler = h3.eventHandler(async (event) => {
|
|
579
599
|
event.context.rpcName = procedure.name;
|
|
580
600
|
if (h3.isPreflightRequest(event)) {
|
|
@@ -597,7 +617,8 @@ function registerEventStreamRpc(router, path, procedure, opts) {
|
|
|
597
617
|
);
|
|
598
618
|
}
|
|
599
619
|
const stream = new EventStreamConnection(event, {
|
|
600
|
-
|
|
620
|
+
heartbeatMs: procedure.heartbeatMs,
|
|
621
|
+
heartbeatEnabled: procedure.heartbeatEnabled,
|
|
601
622
|
validator: responseValidator
|
|
602
623
|
});
|
|
603
624
|
event.context.stream = stream;
|
package/dist/index.d.cts
CHANGED
|
@@ -102,14 +102,17 @@ interface EventStreamRpcHandlerContext<TParams = any, TResponse = any> extends R
|
|
|
102
102
|
}
|
|
103
103
|
interface EventStreamConnectionOptions<TData> {
|
|
104
104
|
validator?: RequestValidator<TData>;
|
|
105
|
-
|
|
105
|
+
heartbeatMs?: number;
|
|
106
|
+
heartbeatEnabled?: boolean;
|
|
106
107
|
}
|
|
107
108
|
declare class EventStreamConnection<TData> {
|
|
108
109
|
readonly lastEventId?: string;
|
|
109
110
|
private readonly validator?;
|
|
110
|
-
private
|
|
111
|
-
private readonly
|
|
111
|
+
private heartbeatInterval;
|
|
112
|
+
private readonly heartbeatMs;
|
|
113
|
+
private readonly sendHeartbeat;
|
|
112
114
|
readonly eventStream: EventStream;
|
|
115
|
+
private _isClosed;
|
|
113
116
|
constructor(event: H3Event, opts: EventStreamConnectionOptions<TData>);
|
|
114
117
|
/**
|
|
115
118
|
* Send the stream to the client. This must be called before sending any events.
|
|
@@ -120,7 +123,7 @@ declare class EventStreamConnection<TData> {
|
|
|
120
123
|
*/
|
|
121
124
|
push(data: TData[], eventId?: string): Promise<SsePushResult[]>;
|
|
122
125
|
push(data: TData, eventId?: string): Promise<SsePushResult>;
|
|
123
|
-
private
|
|
126
|
+
private _cleanup;
|
|
124
127
|
/**
|
|
125
128
|
* Tell clients that the stream has ended and close the connection.
|
|
126
129
|
*/
|
|
@@ -152,7 +155,8 @@ interface HttpRpc<TIsEventStream extends boolean = false, TParams extends RpcPar
|
|
|
152
155
|
response: TResponse;
|
|
153
156
|
isDeprecated?: boolean;
|
|
154
157
|
isEventStream?: TIsEventStream;
|
|
155
|
-
|
|
158
|
+
heartbeatMs?: TIsEventStream extends true ? number : never;
|
|
159
|
+
heartbeatEnabled?: TIsEventStream extends true ? boolean : never;
|
|
156
160
|
handler: TIsEventStream extends true ? EventStreamRpcHandler<TParams extends RpcParamSchema<any> ? InferType<TParams> : undefined, TResponse extends RpcParamSchema<any> ? InferType<TResponse> : undefined> : RpcHandler<TParams extends RpcParamSchema<any> ? InferType<TParams> : undefined, TResponse extends RpcParamSchema<any> ? InferType<TResponse> : void>;
|
|
157
161
|
postHandler?: TIsEventStream extends true ? undefined : RpcPostHandler<TParams extends RpcParamSchema<any> ? InferType<TParams> : undefined, TResponse extends RpcParamSchema<any> ? InferType<TResponse> : undefined>;
|
|
158
162
|
}
|
package/dist/index.d.mts
CHANGED
|
@@ -102,14 +102,17 @@ interface EventStreamRpcHandlerContext<TParams = any, TResponse = any> extends R
|
|
|
102
102
|
}
|
|
103
103
|
interface EventStreamConnectionOptions<TData> {
|
|
104
104
|
validator?: RequestValidator<TData>;
|
|
105
|
-
|
|
105
|
+
heartbeatMs?: number;
|
|
106
|
+
heartbeatEnabled?: boolean;
|
|
106
107
|
}
|
|
107
108
|
declare class EventStreamConnection<TData> {
|
|
108
109
|
readonly lastEventId?: string;
|
|
109
110
|
private readonly validator?;
|
|
110
|
-
private
|
|
111
|
-
private readonly
|
|
111
|
+
private heartbeatInterval;
|
|
112
|
+
private readonly heartbeatMs;
|
|
113
|
+
private readonly sendHeartbeat;
|
|
112
114
|
readonly eventStream: EventStream;
|
|
115
|
+
private _isClosed;
|
|
113
116
|
constructor(event: H3Event, opts: EventStreamConnectionOptions<TData>);
|
|
114
117
|
/**
|
|
115
118
|
* Send the stream to the client. This must be called before sending any events.
|
|
@@ -120,7 +123,7 @@ declare class EventStreamConnection<TData> {
|
|
|
120
123
|
*/
|
|
121
124
|
push(data: TData[], eventId?: string): Promise<SsePushResult[]>;
|
|
122
125
|
push(data: TData, eventId?: string): Promise<SsePushResult>;
|
|
123
|
-
private
|
|
126
|
+
private _cleanup;
|
|
124
127
|
/**
|
|
125
128
|
* Tell clients that the stream has ended and close the connection.
|
|
126
129
|
*/
|
|
@@ -152,7 +155,8 @@ interface HttpRpc<TIsEventStream extends boolean = false, TParams extends RpcPar
|
|
|
152
155
|
response: TResponse;
|
|
153
156
|
isDeprecated?: boolean;
|
|
154
157
|
isEventStream?: TIsEventStream;
|
|
155
|
-
|
|
158
|
+
heartbeatMs?: TIsEventStream extends true ? number : never;
|
|
159
|
+
heartbeatEnabled?: TIsEventStream extends true ? boolean : never;
|
|
156
160
|
handler: TIsEventStream extends true ? EventStreamRpcHandler<TParams extends RpcParamSchema<any> ? InferType<TParams> : undefined, TResponse extends RpcParamSchema<any> ? InferType<TResponse> : undefined> : RpcHandler<TParams extends RpcParamSchema<any> ? InferType<TParams> : undefined, TResponse extends RpcParamSchema<any> ? InferType<TResponse> : void>;
|
|
157
161
|
postHandler?: TIsEventStream extends true ? undefined : RpcPostHandler<TParams extends RpcParamSchema<any> ? InferType<TParams> : undefined, TResponse extends RpcParamSchema<any> ? InferType<TResponse> : undefined>;
|
|
158
162
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -102,14 +102,17 @@ interface EventStreamRpcHandlerContext<TParams = any, TResponse = any> extends R
|
|
|
102
102
|
}
|
|
103
103
|
interface EventStreamConnectionOptions<TData> {
|
|
104
104
|
validator?: RequestValidator<TData>;
|
|
105
|
-
|
|
105
|
+
heartbeatMs?: number;
|
|
106
|
+
heartbeatEnabled?: boolean;
|
|
106
107
|
}
|
|
107
108
|
declare class EventStreamConnection<TData> {
|
|
108
109
|
readonly lastEventId?: string;
|
|
109
110
|
private readonly validator?;
|
|
110
|
-
private
|
|
111
|
-
private readonly
|
|
111
|
+
private heartbeatInterval;
|
|
112
|
+
private readonly heartbeatMs;
|
|
113
|
+
private readonly sendHeartbeat;
|
|
112
114
|
readonly eventStream: EventStream;
|
|
115
|
+
private _isClosed;
|
|
113
116
|
constructor(event: H3Event, opts: EventStreamConnectionOptions<TData>);
|
|
114
117
|
/**
|
|
115
118
|
* Send the stream to the client. This must be called before sending any events.
|
|
@@ -120,7 +123,7 @@ declare class EventStreamConnection<TData> {
|
|
|
120
123
|
*/
|
|
121
124
|
push(data: TData[], eventId?: string): Promise<SsePushResult[]>;
|
|
122
125
|
push(data: TData, eventId?: string): Promise<SsePushResult>;
|
|
123
|
-
private
|
|
126
|
+
private _cleanup;
|
|
124
127
|
/**
|
|
125
128
|
* Tell clients that the stream has ended and close the connection.
|
|
126
129
|
*/
|
|
@@ -152,7 +155,8 @@ interface HttpRpc<TIsEventStream extends boolean = false, TParams extends RpcPar
|
|
|
152
155
|
response: TResponse;
|
|
153
156
|
isDeprecated?: boolean;
|
|
154
157
|
isEventStream?: TIsEventStream;
|
|
155
|
-
|
|
158
|
+
heartbeatMs?: TIsEventStream extends true ? number : never;
|
|
159
|
+
heartbeatEnabled?: TIsEventStream extends true ? boolean : never;
|
|
156
160
|
handler: TIsEventStream extends true ? EventStreamRpcHandler<TParams extends RpcParamSchema<any> ? InferType<TParams> : undefined, TResponse extends RpcParamSchema<any> ? InferType<TResponse> : undefined> : RpcHandler<TParams extends RpcParamSchema<any> ? InferType<TParams> : undefined, TResponse extends RpcParamSchema<any> ? InferType<TResponse> : void>;
|
|
157
161
|
postHandler?: TIsEventStream extends true ? undefined : RpcPostHandler<TParams extends RpcParamSchema<any> ? InferType<TParams> : undefined, TResponse extends RpcParamSchema<any> ? InferType<TResponse> : undefined>;
|
|
158
162
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -471,7 +471,7 @@ function getSchemaName(rpcName, type, schema) {
|
|
|
471
471
|
function defineEventStreamRpc(config) {
|
|
472
472
|
return {
|
|
473
473
|
...config,
|
|
474
|
-
method: config.method ?? "
|
|
474
|
+
method: config.method ?? "post",
|
|
475
475
|
isEventStream: true,
|
|
476
476
|
transport: "http"
|
|
477
477
|
};
|
|
@@ -483,16 +483,32 @@ class EventStreamConnection {
|
|
|
483
483
|
lastEventId;
|
|
484
484
|
validator;
|
|
485
485
|
// for some reason Rollup cannot output DTS when this is set to NodeJS.Timeout
|
|
486
|
-
|
|
487
|
-
|
|
486
|
+
heartbeatInterval = void 0;
|
|
487
|
+
heartbeatMs;
|
|
488
|
+
sendHeartbeat;
|
|
488
489
|
eventStream;
|
|
490
|
+
_isClosed = false;
|
|
489
491
|
constructor(event, opts) {
|
|
490
|
-
this.
|
|
492
|
+
this.heartbeatMs = opts.heartbeatMs ?? 2e4;
|
|
493
|
+
this.sendHeartbeat = opts.heartbeatEnabled ?? true;
|
|
494
|
+
setResponseHeader(
|
|
495
|
+
event,
|
|
496
|
+
"heartbeat-interval",
|
|
497
|
+
this.heartbeatMs.toString()
|
|
498
|
+
);
|
|
499
|
+
this.eventStream = createEventStream(event, { autoclose: false });
|
|
500
|
+
event.node.req.once("close", () => {
|
|
501
|
+
if (this._isClosed) return;
|
|
502
|
+
this.eventStream.close();
|
|
503
|
+
});
|
|
504
|
+
event.node.res.once("close", () => {
|
|
505
|
+
if (this._isClosed) return;
|
|
506
|
+
this.eventStream.close();
|
|
507
|
+
});
|
|
491
508
|
this.lastEventId = getHeader(event, "Last-Event-Id");
|
|
492
|
-
this.pingIntervalMs = opts.pingInterval ?? 6e4;
|
|
493
509
|
this.validator = opts.validator;
|
|
494
510
|
this.eventStream.onClosed(() => {
|
|
495
|
-
this.
|
|
511
|
+
this._cleanup();
|
|
496
512
|
});
|
|
497
513
|
}
|
|
498
514
|
/**
|
|
@@ -504,12 +520,15 @@ class EventStreamConnection {
|
|
|
504
520
|
event: "start",
|
|
505
521
|
data: "connection successful"
|
|
506
522
|
});
|
|
507
|
-
this.
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
523
|
+
if (this.sendHeartbeat) {
|
|
524
|
+
this.heartbeatInterval = setInterval(async () => {
|
|
525
|
+
console.log("SENDING_HEARTBEAT");
|
|
526
|
+
await this.eventStream.push({
|
|
527
|
+
event: "heartbeat",
|
|
528
|
+
data: ""
|
|
529
|
+
});
|
|
530
|
+
}, this.heartbeatMs);
|
|
531
|
+
}
|
|
513
532
|
}
|
|
514
533
|
async push(data, eventId) {
|
|
515
534
|
if (!this.validator) return;
|
|
@@ -551,9 +570,10 @@ class EventStreamConnection {
|
|
|
551
570
|
errors
|
|
552
571
|
};
|
|
553
572
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
573
|
+
_cleanup() {
|
|
574
|
+
this._isClosed = true;
|
|
575
|
+
if (this.heartbeatInterval) {
|
|
576
|
+
clearInterval(this.heartbeatInterval);
|
|
557
577
|
}
|
|
558
578
|
}
|
|
559
579
|
/**
|
|
@@ -573,7 +593,7 @@ class EventStreamConnection {
|
|
|
573
593
|
function registerEventStreamRpc(router, path, procedure, opts) {
|
|
574
594
|
const paramValidator = procedure.params ? getSchemaValidator(procedure.name, "params", procedure.params) : void 0;
|
|
575
595
|
const responseValidator = procedure.response ? getSchemaValidator(procedure.name, "response", procedure.response) : void 0;
|
|
576
|
-
const httpMethod = procedure.method ?? "
|
|
596
|
+
const httpMethod = procedure.method ?? "post";
|
|
577
597
|
const handler = eventHandler(async (event) => {
|
|
578
598
|
event.context.rpcName = procedure.name;
|
|
579
599
|
if (isPreflightRequest(event)) {
|
|
@@ -596,7 +616,8 @@ function registerEventStreamRpc(router, path, procedure, opts) {
|
|
|
596
616
|
);
|
|
597
617
|
}
|
|
598
618
|
const stream = new EventStreamConnection(event, {
|
|
599
|
-
|
|
619
|
+
heartbeatMs: procedure.heartbeatMs,
|
|
620
|
+
heartbeatEnabled: procedure.heartbeatEnabled,
|
|
600
621
|
validator: responseValidator
|
|
601
622
|
});
|
|
602
623
|
event.context.stream = stream;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arrirpc/server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.80.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -23,16 +23,16 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@types/source-map-support": "^0.5.10",
|
|
26
|
-
"crossws": "^0.
|
|
27
|
-
"h3": "^1.15.
|
|
26
|
+
"crossws": "^0.4.1",
|
|
27
|
+
"h3": "^1.15.3",
|
|
28
28
|
"scule": "^1.3.0",
|
|
29
29
|
"source-map-support": "^0.5.21",
|
|
30
30
|
"uncrypto": "^0.1.3",
|
|
31
|
-
"@arrirpc/schema": "0.
|
|
32
|
-
"@arrirpc/codegen-utils": "0.
|
|
33
|
-
"arri": "0.
|
|
31
|
+
"@arrirpc/schema": "0.80.0",
|
|
32
|
+
"@arrirpc/codegen-utils": "0.80.0",
|
|
33
|
+
"arri": "0.80.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"bun-types": "^1.2.
|
|
36
|
+
"bun-types": "^1.2.15"
|
|
37
37
|
}
|
|
38
38
|
}
|