@arrirpc/server 0.53.1 → 0.54.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 +37 -24
- package/dist/index.cjs +17 -26
- package/dist/index.d.cts +11 -7
- package/dist/index.d.mts +11 -7
- package/dist/index.d.ts +11 -7
- package/dist/index.mjs +17 -26
- package/package.json +9 -10
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@ Typescript implementation of [Arri RPC](/README.md). It's built on top of [H3](h
|
|
|
14
14
|
- [Manual Routing](#manual-routing)
|
|
15
15
|
- [Creating Event Stream Procedures](#creating-event-stream-procedures)
|
|
16
16
|
- [Creating Websocket Procedures](#creating-websocket-procedures-experimental)
|
|
17
|
+
- [Adding to the RPC Context](#adding-to-the-rpc-context)
|
|
17
18
|
- [Adding Non-RPC Routes](#adding-non-rpc-routes)
|
|
18
19
|
- [Adding Middleware](#adding-middleware)
|
|
19
20
|
- [Key Concepts](#key-concepts)
|
|
@@ -136,7 +137,7 @@ Setup your npm scripts:
|
|
|
136
137
|
|
|
137
138
|
### Creating Procedures
|
|
138
139
|
|
|
139
|
-
#### File Based
|
|
140
|
+
#### File Based Routing
|
|
140
141
|
|
|
141
142
|
Arri RPC comes with an optional file based router that will automatically register functions in the `./procedures` directory that end with the `.rpc.ts` file extension.
|
|
142
143
|
|
|
@@ -192,7 +193,7 @@ app.rpc('sayHello', {...})
|
|
|
192
193
|
|
|
193
194
|
// using a sub-router
|
|
194
195
|
const app = new ArriApp();
|
|
195
|
-
const router = new
|
|
196
|
+
const router = new ArriRouter();
|
|
196
197
|
router.rpc('sayHello', {...})
|
|
197
198
|
app.use(router)
|
|
198
199
|
```
|
|
@@ -404,12 +405,12 @@ app.rpc("sayHello", {
|
|
|
404
405
|
});
|
|
405
406
|
```
|
|
406
407
|
|
|
407
|
-
To get type safety for these new properties create a `.d.ts` file and augment the `ArriEventContext` provided by `@
|
|
408
|
+
To get type safety for these new properties create a `.d.ts` file and augment the `ArriEventContext` provided by `@arrirpc/server`
|
|
408
409
|
|
|
409
410
|
```ts
|
|
410
|
-
import "@
|
|
411
|
+
import "@arrirpc/server";
|
|
411
412
|
|
|
412
|
-
declare module "@
|
|
413
|
+
declare module "@arrirpc/server" {
|
|
413
414
|
interface ArriEventContext {
|
|
414
415
|
user?: {
|
|
415
416
|
id: number;
|
|
@@ -422,26 +423,25 @@ declare module "@arri/server" {
|
|
|
422
423
|
|
|
423
424
|
### Adding Client Generators
|
|
424
425
|
|
|
425
|
-
Right now Arri RPC has client generators for the following languages:
|
|
426
|
-
|
|
427
|
-
- typescript
|
|
428
|
-
- dart
|
|
429
|
-
- kotlin
|
|
430
|
-
|
|
431
426
|
```ts
|
|
432
427
|
// arri.config.ts
|
|
433
428
|
import { defineConfig, generators } from "arri";
|
|
434
429
|
|
|
435
430
|
export default defineConfig({
|
|
436
431
|
// rest of config
|
|
437
|
-
|
|
432
|
+
generators: [
|
|
438
433
|
generators.typescriptClient({...}),
|
|
439
434
|
generators.dartClient({...}),
|
|
440
435
|
generators.kotlinClient({...})
|
|
436
|
+
generators.someGenerator({...})
|
|
441
437
|
]
|
|
442
438
|
});
|
|
443
439
|
```
|
|
444
440
|
|
|
441
|
+
For info on what generators are available see [here](/README.md#client-generators)
|
|
442
|
+
|
|
443
|
+
For info on how to create your own generator see []
|
|
444
|
+
|
|
445
445
|
## Key Concepts
|
|
446
446
|
|
|
447
447
|
### Arri Definition File
|
|
@@ -545,20 +545,33 @@ You can access H3 events from inside procedures handlers.
|
|
|
545
545
|
|
|
546
546
|
```ts
|
|
547
547
|
defineRpc({
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
)
|
|
548
|
+
params: undefined,
|
|
549
|
+
response: undefined,
|
|
550
|
+
handler(_, event) {
|
|
551
|
+
getRequestIP(event);
|
|
552
|
+
},
|
|
553
|
+
});
|
|
554
554
|
|
|
555
555
|
defineEventStreamRpc({
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
)
|
|
556
|
+
params: undefined,
|
|
557
|
+
response: undefined,
|
|
558
|
+
handler(_, event) {
|
|
559
|
+
getRequestIP(event);
|
|
560
|
+
},
|
|
561
|
+
});
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
#### Manually Starting an Arri Server
|
|
565
|
+
|
|
566
|
+
Arri server is just an H3 app under the hood so you can start it the same way you would start an H3 app. Although you should note that currently the filed based router only works when using the Arri CLI.
|
|
567
|
+
|
|
568
|
+
```ts
|
|
569
|
+
import { createServer } from "node:http";
|
|
570
|
+
import { ArriApp, toNodeListener } from "@arrirpc/server";
|
|
571
|
+
|
|
572
|
+
const app = new ArriApp();
|
|
573
|
+
|
|
574
|
+
createServer(toNodeListener(app.h3App)).listen(process.env.PORT || 3000);
|
|
562
575
|
```
|
|
563
576
|
|
|
564
577
|
## Arri CLI
|
package/dist/index.cjs
CHANGED
|
@@ -4,7 +4,6 @@ const codegenUtils = require('@arrirpc/codegen-utils');
|
|
|
4
4
|
const arri = require('arri');
|
|
5
5
|
const h3 = require('h3');
|
|
6
6
|
const schema = require('@arrirpc/schema');
|
|
7
|
-
const h3Sse = require('h3-sse');
|
|
8
7
|
const scule = require('scule');
|
|
9
8
|
|
|
10
9
|
var __defProp$4 = Object.defineProperty;
|
|
@@ -502,13 +501,13 @@ class EventStreamConnection {
|
|
|
502
501
|
__publicField$3(this, "pingInterval");
|
|
503
502
|
__publicField$3(this, "pingIntervalMs");
|
|
504
503
|
__publicField$3(this, "eventStream");
|
|
505
|
-
this.eventStream =
|
|
506
|
-
this.lastEventId =
|
|
504
|
+
this.eventStream = h3.createEventStream(event);
|
|
505
|
+
this.lastEventId = h3.getHeader(event, "Last-Event-Id");
|
|
507
506
|
this.pingIntervalMs = opts.pingInterval ?? 6e4;
|
|
508
507
|
this.serializer = opts.serializer;
|
|
509
508
|
this.validator = opts.validator;
|
|
510
509
|
this.validationErrors = opts.validationErrors;
|
|
511
|
-
this.eventStream.
|
|
510
|
+
this.eventStream.onClosed(() => {
|
|
512
511
|
this.cleanup();
|
|
513
512
|
});
|
|
514
513
|
}
|
|
@@ -526,6 +525,7 @@ class EventStreamConnection {
|
|
|
526
525
|
}
|
|
527
526
|
async push(data, eventId) {
|
|
528
527
|
if (Array.isArray(data)) {
|
|
528
|
+
const results = [];
|
|
529
529
|
const events = [];
|
|
530
530
|
for (const item of data) {
|
|
531
531
|
if (this.validator(item)) {
|
|
@@ -534,21 +534,17 @@ class EventStreamConnection {
|
|
|
534
534
|
event: "message",
|
|
535
535
|
data: this.serializer(item)
|
|
536
536
|
});
|
|
537
|
+
results.push({ success: true });
|
|
537
538
|
continue;
|
|
538
539
|
}
|
|
539
540
|
const errors2 = this.validationErrors(item);
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
});
|
|
544
|
-
events.push({
|
|
545
|
-
id: eventId,
|
|
546
|
-
event: "error",
|
|
547
|
-
data: JSON.stringify(errorResponse2)
|
|
541
|
+
results.push({
|
|
542
|
+
success: false,
|
|
543
|
+
errors: errors2
|
|
548
544
|
});
|
|
549
545
|
}
|
|
550
546
|
await this.eventStream.push(events);
|
|
551
|
-
return;
|
|
547
|
+
return results;
|
|
552
548
|
}
|
|
553
549
|
if (this.validator(data)) {
|
|
554
550
|
await this.eventStream.push({
|
|
@@ -556,18 +552,13 @@ class EventStreamConnection {
|
|
|
556
552
|
event: "message",
|
|
557
553
|
data: this.serializer(data)
|
|
558
554
|
});
|
|
559
|
-
return;
|
|
555
|
+
return { success: true };
|
|
560
556
|
}
|
|
561
557
|
const errors = this.validationErrors(data);
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
}
|
|
566
|
-
await this.eventStream.push({
|
|
567
|
-
id: eventId,
|
|
568
|
-
event: "error",
|
|
569
|
-
data: JSON.stringify(errorResponse)
|
|
570
|
-
});
|
|
558
|
+
return {
|
|
559
|
+
success: false,
|
|
560
|
+
errors
|
|
561
|
+
};
|
|
571
562
|
}
|
|
572
563
|
cleanup() {
|
|
573
564
|
if (this.pingInterval) {
|
|
@@ -584,8 +575,8 @@ class EventStreamConnection {
|
|
|
584
575
|
}).catch();
|
|
585
576
|
await this.eventStream.close();
|
|
586
577
|
}
|
|
587
|
-
|
|
588
|
-
this.eventStream.
|
|
578
|
+
onClosed(cb) {
|
|
579
|
+
this.eventStream.onClosed(cb);
|
|
589
580
|
}
|
|
590
581
|
}
|
|
591
582
|
function registerEventStreamRpc(router, path, procedure, opts) {
|
|
@@ -640,7 +631,7 @@ function registerEventStreamRpc(router, path, procedure, opts) {
|
|
|
640
631
|
event.context,
|
|
641
632
|
event
|
|
642
633
|
);
|
|
643
|
-
if (!event.handled
|
|
634
|
+
if (!event.handled) {
|
|
644
635
|
stream.send();
|
|
645
636
|
}
|
|
646
637
|
} catch (err) {
|
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { HttpMethod, WsRpcDefinition, RpcHttpMethod, HttpRpcDefinition, SchemaFormProperties, SchemaFormDiscriminator, SchemaFormValues, AppDefinition } from '@arrirpc/codegen-utils';
|
|
2
2
|
import { AObjectSchema, a, ValidationError, ASchema, InferType, ValueError, CompiledValidator, ADiscriminatorSchema } from '@arrirpc/schema';
|
|
3
|
-
import { H3Error, H3Event, H3EventContext, Router, App } from 'h3';
|
|
3
|
+
import { StatusCode, H3Error, H3Event, H3EventContext, Router, EventStream, App } from 'h3';
|
|
4
4
|
export * from 'h3';
|
|
5
|
-
import { EventStream } from 'h3-sse';
|
|
6
5
|
import { Peer, WSError } from 'crossws';
|
|
7
6
|
|
|
8
7
|
declare class ArriServerError extends Error {
|
|
@@ -24,7 +23,6 @@ declare const ArriServerErrorResponse: AObjectSchema<{
|
|
|
24
23
|
type ArriServerErrorResponse = a.infer<typeof ArriServerErrorResponse>;
|
|
25
24
|
declare function defineError(statusCode: StatusCode, input?: Partial<Omit<ArriServerErrorResponse, "code" | "stack">>): ArriServerError;
|
|
26
25
|
declare function errorResponseFromValidationErrors(errors: ValidationError["errors"], prefixText?: string): H3Error;
|
|
27
|
-
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;
|
|
28
26
|
declare function handleH3Error(err: unknown, event: H3Event, onError: ArriOptions["onError"], debug: boolean): Promise<void>;
|
|
29
27
|
|
|
30
28
|
type ArriEventContext = Record<string, any>;
|
|
@@ -108,15 +106,21 @@ declare class EventStreamConnection<TData> {
|
|
|
108
106
|
/**
|
|
109
107
|
* Publish a new event. Events published with this hook will trigger the `onData()` hooks of any connected clients.
|
|
110
108
|
*/
|
|
111
|
-
push(data: TData[], eventId?: string): Promise<
|
|
112
|
-
push(data: TData, eventId?: string): Promise<
|
|
109
|
+
push(data: TData[], eventId?: string): Promise<SsePushResult[]>;
|
|
110
|
+
push(data: TData, eventId?: string): Promise<SsePushResult>;
|
|
113
111
|
private cleanup;
|
|
114
112
|
/**
|
|
115
113
|
* Tell clients that the stream has ended and close the connection.
|
|
116
114
|
*/
|
|
117
115
|
close(): Promise<void>;
|
|
118
|
-
|
|
116
|
+
onClosed(cb: () => any): void;
|
|
119
117
|
}
|
|
118
|
+
type SsePushResult = {
|
|
119
|
+
success: true;
|
|
120
|
+
} | {
|
|
121
|
+
success: false;
|
|
122
|
+
errors: ValueError[];
|
|
123
|
+
};
|
|
120
124
|
declare function registerEventStreamRpc(router: Router, path: string, procedure: EventStreamRpc<any, any> & {
|
|
121
125
|
name: string;
|
|
122
126
|
}, opts: RouteOptions): void;
|
|
@@ -280,4 +284,4 @@ interface ArriOptions {
|
|
|
280
284
|
onError?: (error: ArriServerError, event: MiddlewareEvent) => void | Promise<void>;
|
|
281
285
|
}
|
|
282
286
|
|
|
283
|
-
export { ArriApp, type ArriEventContext, type ArriOptions, type ArriRoute, ArriRouter, type ArriRouterBase, ArriServerError, ArriServerErrorResponse, type DefinitionMap, EventStreamConnection, type EventStreamConnectionOptions, type EventStreamRpc, type EventStreamRpcHandler, type EventStreamRpcHandlerContext, type ExtractParam, type ExtractParams, type HttpRpc, type Middleware, type MiddlewareEvent, type MiddlewareEventContext, type NamedRpc, type NamedWebsocketRpc, type PostRouteEvent, type RouteEvent, type RouteEventContext, type RouteOptions, type RoutePostEventContext, type Rpc, type RpcEvent, type RpcEventContext, type RpcHandler, type RpcParamSchema, type RpcPostEvent, type RpcPostEventContext, type RpcPostHandler, type
|
|
287
|
+
export { ArriApp, type ArriEventContext, type ArriOptions, type ArriRoute, ArriRouter, type ArriRouterBase, ArriServerError, ArriServerErrorResponse, type DefinitionMap, EventStreamConnection, type EventStreamConnectionOptions, type EventStreamRpc, type EventStreamRpcHandler, type EventStreamRpcHandlerContext, type ExtractParam, type ExtractParams, type HttpRpc, type Middleware, type MiddlewareEvent, type MiddlewareEventContext, type NamedRpc, type NamedWebsocketRpc, type PostRouteEvent, type RouteEvent, type RouteEventContext, type RouteOptions, type RoutePostEventContext, type Rpc, type RpcEvent, type RpcEventContext, type RpcHandler, type RpcParamSchema, type RpcPostEvent, type RpcPostEventContext, type RpcPostHandler, type SsePushResult, type WebSocketRpcHandler, type WebsocketRpc, WsPeer, type WsPeerContext, createAppDefinition, createHttpRpcDefinition, createWsRpcDefinition, defineError, defineEventStreamRpc, defineMiddleware, defineRoute, defineRpc, defineWebsocketRpc, errorResponseFromValidationErrors, getRpcParamName, getRpcPath, getRpcResponseName, handleH3Error, handleRoute, isEventStreamRpc, isRpc, isRpcParamSchema, registerEventStreamRpc, registerRoute, registerRpc, registerWebsocketRpc, validateRpcRequestInput };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { HttpMethod, WsRpcDefinition, RpcHttpMethod, HttpRpcDefinition, SchemaFormProperties, SchemaFormDiscriminator, SchemaFormValues, AppDefinition } from '@arrirpc/codegen-utils';
|
|
2
2
|
import { AObjectSchema, a, ValidationError, ASchema, InferType, ValueError, CompiledValidator, ADiscriminatorSchema } from '@arrirpc/schema';
|
|
3
|
-
import { H3Error, H3Event, H3EventContext, Router, App } from 'h3';
|
|
3
|
+
import { StatusCode, H3Error, H3Event, H3EventContext, Router, EventStream, App } from 'h3';
|
|
4
4
|
export * from 'h3';
|
|
5
|
-
import { EventStream } from 'h3-sse';
|
|
6
5
|
import { Peer, WSError } from 'crossws';
|
|
7
6
|
|
|
8
7
|
declare class ArriServerError extends Error {
|
|
@@ -24,7 +23,6 @@ declare const ArriServerErrorResponse: AObjectSchema<{
|
|
|
24
23
|
type ArriServerErrorResponse = a.infer<typeof ArriServerErrorResponse>;
|
|
25
24
|
declare function defineError(statusCode: StatusCode, input?: Partial<Omit<ArriServerErrorResponse, "code" | "stack">>): ArriServerError;
|
|
26
25
|
declare function errorResponseFromValidationErrors(errors: ValidationError["errors"], prefixText?: string): H3Error;
|
|
27
|
-
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;
|
|
28
26
|
declare function handleH3Error(err: unknown, event: H3Event, onError: ArriOptions["onError"], debug: boolean): Promise<void>;
|
|
29
27
|
|
|
30
28
|
type ArriEventContext = Record<string, any>;
|
|
@@ -108,15 +106,21 @@ declare class EventStreamConnection<TData> {
|
|
|
108
106
|
/**
|
|
109
107
|
* Publish a new event. Events published with this hook will trigger the `onData()` hooks of any connected clients.
|
|
110
108
|
*/
|
|
111
|
-
push(data: TData[], eventId?: string): Promise<
|
|
112
|
-
push(data: TData, eventId?: string): Promise<
|
|
109
|
+
push(data: TData[], eventId?: string): Promise<SsePushResult[]>;
|
|
110
|
+
push(data: TData, eventId?: string): Promise<SsePushResult>;
|
|
113
111
|
private cleanup;
|
|
114
112
|
/**
|
|
115
113
|
* Tell clients that the stream has ended and close the connection.
|
|
116
114
|
*/
|
|
117
115
|
close(): Promise<void>;
|
|
118
|
-
|
|
116
|
+
onClosed(cb: () => any): void;
|
|
119
117
|
}
|
|
118
|
+
type SsePushResult = {
|
|
119
|
+
success: true;
|
|
120
|
+
} | {
|
|
121
|
+
success: false;
|
|
122
|
+
errors: ValueError[];
|
|
123
|
+
};
|
|
120
124
|
declare function registerEventStreamRpc(router: Router, path: string, procedure: EventStreamRpc<any, any> & {
|
|
121
125
|
name: string;
|
|
122
126
|
}, opts: RouteOptions): void;
|
|
@@ -280,4 +284,4 @@ interface ArriOptions {
|
|
|
280
284
|
onError?: (error: ArriServerError, event: MiddlewareEvent) => void | Promise<void>;
|
|
281
285
|
}
|
|
282
286
|
|
|
283
|
-
export { ArriApp, type ArriEventContext, type ArriOptions, type ArriRoute, ArriRouter, type ArriRouterBase, ArriServerError, ArriServerErrorResponse, type DefinitionMap, EventStreamConnection, type EventStreamConnectionOptions, type EventStreamRpc, type EventStreamRpcHandler, type EventStreamRpcHandlerContext, type ExtractParam, type ExtractParams, type HttpRpc, type Middleware, type MiddlewareEvent, type MiddlewareEventContext, type NamedRpc, type NamedWebsocketRpc, type PostRouteEvent, type RouteEvent, type RouteEventContext, type RouteOptions, type RoutePostEventContext, type Rpc, type RpcEvent, type RpcEventContext, type RpcHandler, type RpcParamSchema, type RpcPostEvent, type RpcPostEventContext, type RpcPostHandler, type
|
|
287
|
+
export { ArriApp, type ArriEventContext, type ArriOptions, type ArriRoute, ArriRouter, type ArriRouterBase, ArriServerError, ArriServerErrorResponse, type DefinitionMap, EventStreamConnection, type EventStreamConnectionOptions, type EventStreamRpc, type EventStreamRpcHandler, type EventStreamRpcHandlerContext, type ExtractParam, type ExtractParams, type HttpRpc, type Middleware, type MiddlewareEvent, type MiddlewareEventContext, type NamedRpc, type NamedWebsocketRpc, type PostRouteEvent, type RouteEvent, type RouteEventContext, type RouteOptions, type RoutePostEventContext, type Rpc, type RpcEvent, type RpcEventContext, type RpcHandler, type RpcParamSchema, type RpcPostEvent, type RpcPostEventContext, type RpcPostHandler, type SsePushResult, type WebSocketRpcHandler, type WebsocketRpc, WsPeer, type WsPeerContext, createAppDefinition, createHttpRpcDefinition, createWsRpcDefinition, defineError, defineEventStreamRpc, defineMiddleware, defineRoute, defineRpc, defineWebsocketRpc, errorResponseFromValidationErrors, getRpcParamName, getRpcPath, getRpcResponseName, handleH3Error, handleRoute, isEventStreamRpc, isRpc, isRpcParamSchema, registerEventStreamRpc, registerRoute, registerRpc, registerWebsocketRpc, validateRpcRequestInput };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { HttpMethod, WsRpcDefinition, RpcHttpMethod, HttpRpcDefinition, SchemaFormProperties, SchemaFormDiscriminator, SchemaFormValues, AppDefinition } from '@arrirpc/codegen-utils';
|
|
2
2
|
import { AObjectSchema, a, ValidationError, ASchema, InferType, ValueError, CompiledValidator, ADiscriminatorSchema } from '@arrirpc/schema';
|
|
3
|
-
import { H3Error, H3Event, H3EventContext, Router, App } from 'h3';
|
|
3
|
+
import { StatusCode, H3Error, H3Event, H3EventContext, Router, EventStream, App } from 'h3';
|
|
4
4
|
export * from 'h3';
|
|
5
|
-
import { EventStream } from 'h3-sse';
|
|
6
5
|
import { Peer, WSError } from 'crossws';
|
|
7
6
|
|
|
8
7
|
declare class ArriServerError extends Error {
|
|
@@ -24,7 +23,6 @@ declare const ArriServerErrorResponse: AObjectSchema<{
|
|
|
24
23
|
type ArriServerErrorResponse = a.infer<typeof ArriServerErrorResponse>;
|
|
25
24
|
declare function defineError(statusCode: StatusCode, input?: Partial<Omit<ArriServerErrorResponse, "code" | "stack">>): ArriServerError;
|
|
26
25
|
declare function errorResponseFromValidationErrors(errors: ValidationError["errors"], prefixText?: string): H3Error;
|
|
27
|
-
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;
|
|
28
26
|
declare function handleH3Error(err: unknown, event: H3Event, onError: ArriOptions["onError"], debug: boolean): Promise<void>;
|
|
29
27
|
|
|
30
28
|
type ArriEventContext = Record<string, any>;
|
|
@@ -108,15 +106,21 @@ declare class EventStreamConnection<TData> {
|
|
|
108
106
|
/**
|
|
109
107
|
* Publish a new event. Events published with this hook will trigger the `onData()` hooks of any connected clients.
|
|
110
108
|
*/
|
|
111
|
-
push(data: TData[], eventId?: string): Promise<
|
|
112
|
-
push(data: TData, eventId?: string): Promise<
|
|
109
|
+
push(data: TData[], eventId?: string): Promise<SsePushResult[]>;
|
|
110
|
+
push(data: TData, eventId?: string): Promise<SsePushResult>;
|
|
113
111
|
private cleanup;
|
|
114
112
|
/**
|
|
115
113
|
* Tell clients that the stream has ended and close the connection.
|
|
116
114
|
*/
|
|
117
115
|
close(): Promise<void>;
|
|
118
|
-
|
|
116
|
+
onClosed(cb: () => any): void;
|
|
119
117
|
}
|
|
118
|
+
type SsePushResult = {
|
|
119
|
+
success: true;
|
|
120
|
+
} | {
|
|
121
|
+
success: false;
|
|
122
|
+
errors: ValueError[];
|
|
123
|
+
};
|
|
120
124
|
declare function registerEventStreamRpc(router: Router, path: string, procedure: EventStreamRpc<any, any> & {
|
|
121
125
|
name: string;
|
|
122
126
|
}, opts: RouteOptions): void;
|
|
@@ -280,4 +284,4 @@ interface ArriOptions {
|
|
|
280
284
|
onError?: (error: ArriServerError, event: MiddlewareEvent) => void | Promise<void>;
|
|
281
285
|
}
|
|
282
286
|
|
|
283
|
-
export { ArriApp, type ArriEventContext, type ArriOptions, type ArriRoute, ArriRouter, type ArriRouterBase, ArriServerError, ArriServerErrorResponse, type DefinitionMap, EventStreamConnection, type EventStreamConnectionOptions, type EventStreamRpc, type EventStreamRpcHandler, type EventStreamRpcHandlerContext, type ExtractParam, type ExtractParams, type HttpRpc, type Middleware, type MiddlewareEvent, type MiddlewareEventContext, type NamedRpc, type NamedWebsocketRpc, type PostRouteEvent, type RouteEvent, type RouteEventContext, type RouteOptions, type RoutePostEventContext, type Rpc, type RpcEvent, type RpcEventContext, type RpcHandler, type RpcParamSchema, type RpcPostEvent, type RpcPostEventContext, type RpcPostHandler, type
|
|
287
|
+
export { ArriApp, type ArriEventContext, type ArriOptions, type ArriRoute, ArriRouter, type ArriRouterBase, ArriServerError, ArriServerErrorResponse, type DefinitionMap, EventStreamConnection, type EventStreamConnectionOptions, type EventStreamRpc, type EventStreamRpcHandler, type EventStreamRpcHandlerContext, type ExtractParam, type ExtractParams, type HttpRpc, type Middleware, type MiddlewareEvent, type MiddlewareEventContext, type NamedRpc, type NamedWebsocketRpc, type PostRouteEvent, type RouteEvent, type RouteEventContext, type RouteOptions, type RoutePostEventContext, type Rpc, type RpcEvent, type RpcEventContext, type RpcHandler, type RpcParamSchema, type RpcPostEvent, type RpcPostEventContext, type RpcPostHandler, type SsePushResult, type WebSocketRpcHandler, type WebsocketRpc, WsPeer, type WsPeerContext, createAppDefinition, createHttpRpcDefinition, createWsRpcDefinition, defineError, defineEventStreamRpc, defineMiddleware, defineRoute, defineRpc, defineWebsocketRpc, errorResponseFromValidationErrors, getRpcParamName, getRpcPath, getRpcResponseName, handleH3Error, handleRoute, isEventStreamRpc, isRpc, isRpcParamSchema, registerEventStreamRpc, registerRoute, registerRpc, registerWebsocketRpc, validateRpcRequestInput };
|
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { isRpcHttpMethod, removeDisallowedChars, SCHEMA_VERSION } from '@arrirpc/codegen-utils';
|
|
2
2
|
import { DEV_DEFINITION_ENDPOINT } from 'arri';
|
|
3
|
-
import { isError, setResponseStatus, setResponseHeader, send, eventHandler, isPreflightRequest, readRawBody, getValidatedQuery, defineEventHandler, getQuery, setHeader, defineWebSocketHandler, createRouter, createApp } from 'h3';
|
|
3
|
+
import { isError, setResponseStatus, setResponseHeader, send, eventHandler, isPreflightRequest, readRawBody, getValidatedQuery, createEventStream, getHeader, defineEventHandler, getQuery, setHeader, defineWebSocketHandler, createRouter, createApp } from 'h3';
|
|
4
4
|
export * from 'h3';
|
|
5
5
|
import { a, isAObjectSchema, isADiscriminatorSchema } from '@arrirpc/schema';
|
|
6
|
-
import { createEventStream } from 'h3-sse';
|
|
7
6
|
import { kebabCase, pascalCase } from 'scule';
|
|
8
7
|
|
|
9
8
|
var __defProp$4 = Object.defineProperty;
|
|
@@ -502,12 +501,12 @@ class EventStreamConnection {
|
|
|
502
501
|
__publicField$3(this, "pingIntervalMs");
|
|
503
502
|
__publicField$3(this, "eventStream");
|
|
504
503
|
this.eventStream = createEventStream(event);
|
|
505
|
-
this.lastEventId =
|
|
504
|
+
this.lastEventId = getHeader(event, "Last-Event-Id");
|
|
506
505
|
this.pingIntervalMs = opts.pingInterval ?? 6e4;
|
|
507
506
|
this.serializer = opts.serializer;
|
|
508
507
|
this.validator = opts.validator;
|
|
509
508
|
this.validationErrors = opts.validationErrors;
|
|
510
|
-
this.eventStream.
|
|
509
|
+
this.eventStream.onClosed(() => {
|
|
511
510
|
this.cleanup();
|
|
512
511
|
});
|
|
513
512
|
}
|
|
@@ -525,6 +524,7 @@ class EventStreamConnection {
|
|
|
525
524
|
}
|
|
526
525
|
async push(data, eventId) {
|
|
527
526
|
if (Array.isArray(data)) {
|
|
527
|
+
const results = [];
|
|
528
528
|
const events = [];
|
|
529
529
|
for (const item of data) {
|
|
530
530
|
if (this.validator(item)) {
|
|
@@ -533,21 +533,17 @@ class EventStreamConnection {
|
|
|
533
533
|
event: "message",
|
|
534
534
|
data: this.serializer(item)
|
|
535
535
|
});
|
|
536
|
+
results.push({ success: true });
|
|
536
537
|
continue;
|
|
537
538
|
}
|
|
538
539
|
const errors2 = this.validationErrors(item);
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
});
|
|
543
|
-
events.push({
|
|
544
|
-
id: eventId,
|
|
545
|
-
event: "error",
|
|
546
|
-
data: JSON.stringify(errorResponse2)
|
|
540
|
+
results.push({
|
|
541
|
+
success: false,
|
|
542
|
+
errors: errors2
|
|
547
543
|
});
|
|
548
544
|
}
|
|
549
545
|
await this.eventStream.push(events);
|
|
550
|
-
return;
|
|
546
|
+
return results;
|
|
551
547
|
}
|
|
552
548
|
if (this.validator(data)) {
|
|
553
549
|
await this.eventStream.push({
|
|
@@ -555,18 +551,13 @@ class EventStreamConnection {
|
|
|
555
551
|
event: "message",
|
|
556
552
|
data: this.serializer(data)
|
|
557
553
|
});
|
|
558
|
-
return;
|
|
554
|
+
return { success: true };
|
|
559
555
|
}
|
|
560
556
|
const errors = this.validationErrors(data);
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
}
|
|
565
|
-
await this.eventStream.push({
|
|
566
|
-
id: eventId,
|
|
567
|
-
event: "error",
|
|
568
|
-
data: JSON.stringify(errorResponse)
|
|
569
|
-
});
|
|
557
|
+
return {
|
|
558
|
+
success: false,
|
|
559
|
+
errors
|
|
560
|
+
};
|
|
570
561
|
}
|
|
571
562
|
cleanup() {
|
|
572
563
|
if (this.pingInterval) {
|
|
@@ -583,8 +574,8 @@ class EventStreamConnection {
|
|
|
583
574
|
}).catch();
|
|
584
575
|
await this.eventStream.close();
|
|
585
576
|
}
|
|
586
|
-
|
|
587
|
-
this.eventStream.
|
|
577
|
+
onClosed(cb) {
|
|
578
|
+
this.eventStream.onClosed(cb);
|
|
588
579
|
}
|
|
589
580
|
}
|
|
590
581
|
function registerEventStreamRpc(router, path, procedure, opts) {
|
|
@@ -639,7 +630,7 @@ function registerEventStreamRpc(router, path, procedure, opts) {
|
|
|
639
630
|
event.context,
|
|
640
631
|
event
|
|
641
632
|
);
|
|
642
|
-
if (!event.handled
|
|
633
|
+
if (!event.handled) {
|
|
643
634
|
stream.send();
|
|
644
635
|
}
|
|
645
636
|
} catch (err) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arrirpc/server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.54.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -24,19 +24,18 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@types/source-map-support": "^0.5.10",
|
|
26
26
|
"crossws": "^0.2.4",
|
|
27
|
-
"h3": "^1.
|
|
28
|
-
"h3-sse": "^0.0.12",
|
|
27
|
+
"h3": "^1.12.0",
|
|
29
28
|
"scule": "^1.3.0",
|
|
30
29
|
"source-map-support": "^0.5.21",
|
|
31
30
|
"uncrypto": "^0.1.3",
|
|
32
|
-
"@arrirpc/codegen-dart": "0.
|
|
33
|
-
"@arrirpc/codegen-utils": "0.
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"@arrirpc/
|
|
37
|
-
"@arrirpc/codegen-
|
|
31
|
+
"@arrirpc/codegen-dart": "0.54.0",
|
|
32
|
+
"@arrirpc/codegen-utils": "0.54.0",
|
|
33
|
+
"@arrirpc/codegen-ts": "0.54.0",
|
|
34
|
+
"arri": "0.54.0",
|
|
35
|
+
"@arrirpc/schema": "0.54.0",
|
|
36
|
+
"@arrirpc/codegen-kotlin": "0.54.0"
|
|
38
37
|
},
|
|
39
38
|
"devDependencies": {
|
|
40
|
-
"bun-types": "^1.1.
|
|
39
|
+
"bun-types": "^1.1.15"
|
|
41
40
|
}
|
|
42
41
|
}
|