arri 0.36.0 → 0.37.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/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import { HttpMethod, RpcHttpMethod, HttpRpcDefinition, SchemaFormProperties, SchemaFormDiscriminator, SchemaFormValues, AppDefinition, ClientGenerator } from 'arri-codegen-utils';
2
- import { AObjectSchema, a, ValidationError, ASchema, InferType, ValueError, ADiscriminatorSchema } from 'arri-validate';
1
+ import { HttpMethod, WsRpcDefinition, RpcHttpMethod, HttpRpcDefinition, SchemaFormProperties, SchemaFormDiscriminator, SchemaFormValues, AppDefinition, ClientGenerator } from 'arri-codegen-utils';
2
+ import { AObjectSchema, a, ValidationError, ASchema, InferType, ValueError, CompiledValidator, ADiscriminatorSchema } from 'arri-validate';
3
3
  import { H3Error, H3Event, H3EventContext, Router, App } from 'h3';
4
4
  export * from 'h3';
5
5
  import { EventStream } from 'h3-sse';
6
+ import { Peer, WSError } from 'crossws';
6
7
  import { BuildOptions } from 'esbuild';
7
8
 
8
9
  declare class ArriServerError extends Error {
@@ -67,7 +68,7 @@ type RouteOptions = Pick<ArriOptions, "onAfterResponse" | "onBeforeResponse" | "
67
68
  declare function registerRoute(router: Router, route: ArriRoute<any>, opts: RouteOptions): void;
68
69
  declare function handleRoute(router: Router, method: HttpMethod, route: ArriRoute<any>, opts: RouteOptions): void;
69
70
 
70
- declare function defineEventStreamRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined | never = undefined>(config: Omit<EventStreamRpc<TParams, TResponse>, "isEventStream">): EventStreamRpc<TParams, TResponse>;
71
+ declare function defineEventStreamRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined | never = undefined>(config: Omit<EventStreamRpc<TParams, TResponse>, "isEventStream" | "transport">): EventStreamRpc<TParams, TResponse>;
71
72
  declare function isEventStreamRpc(input: unknown): input is EventStreamRpc<any, any>;
72
73
  interface EventStreamRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> extends Omit<Rpc<true, TParams, TResponse>, "handler" | "postHandler"> {
73
74
  isEventStream: true;
@@ -116,12 +117,62 @@ declare function registerEventStreamRpc(router: Router, path: string, procedure:
116
117
  name: string;
117
118
  }, opts: RouteOptions): void;
118
119
 
120
+ interface NamedWebsocketRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> extends WebsocketRpc<TParams, TResponse> {
121
+ name: string;
122
+ }
123
+ interface WebsocketRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> {
124
+ transport: "ws";
125
+ description?: string;
126
+ path?: string;
127
+ isDeprecated?: boolean;
128
+ params: TParams;
129
+ response: TResponse;
130
+ pingInterval?: boolean;
131
+ handler: WebSocketRpcHandler<TParams extends RpcParamSchema ? InferType<TParams> : undefined, TResponse extends RpcParamSchema ? InferType<TResponse> : undefined>;
132
+ }
133
+ interface WsPeerOpts<TResponse> {
134
+ validator?: CompiledValidator<ASchema<TResponse>>;
135
+ context: WsPeerContext;
136
+ }
137
+ interface WsPeerContext extends Record<string, any> {
138
+ rpcName: string;
139
+ queryParams?: Record<string, string>;
140
+ clientAddress?: string;
141
+ }
142
+ declare class WsPeer<TResponse> {
143
+ private readonly _peer;
144
+ private readonly _validator?;
145
+ context: WsPeerContext;
146
+ url: string;
147
+ constructor(peer: Peer, opts: WsPeerOpts<TResponse>);
148
+ send(data: TResponse): number | undefined;
149
+ sendError(err: ArriServerErrorResponse): number;
150
+ close(): void;
151
+ subscribe(channel: string): void;
152
+ unsubscribe(channel: string): void;
153
+ publish(channel: string, message: TResponse): void;
154
+ readyState(): (0 | 1 | 2 | 3) | -1;
155
+ }
156
+ interface WebSocketRpcHandler<TParams, TResponse> {
157
+ onOpen: (peer: WsPeer<TResponse>) => void;
158
+ onMessage: (peer: WsPeer<TResponse>, message: TParams) => void;
159
+ onClose: (peer: WsPeer<TResponse>, details: {
160
+ code?: number;
161
+ reason?: string;
162
+ }) => void;
163
+ onError: (peer: WsPeer<TResponse>, error: WSError) => void;
164
+ }
165
+ declare function defineWebsocketRpc<TParams extends RpcParamSchema | undefined, TResponse extends RpcParamSchema | undefined>(def: Omit<WebsocketRpc<TParams, TResponse>, "transport">): WebsocketRpc<TParams, TResponse>;
166
+ declare function registerWebsocketRpc(router: Router, path: string, rpc: NamedWebsocketRpc<any, any>): void;
167
+ declare function createWsRpcDefinition(rpcName: string, path: string, rpc: NamedWebsocketRpc<any, any>): WsRpcDefinition;
168
+
119
169
  type RpcParamSchema<TObjectInner = any, TDiscriminatorInner = any> = AObjectSchema<TObjectInner> | ADiscriminatorSchema<TDiscriminatorInner>;
120
170
  declare function isRpcParamSchema(input: unknown): input is RpcParamSchema;
121
171
  interface NamedRpc<TIsEventStream extends boolean = false, TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> extends Rpc<TIsEventStream, TParams, TResponse> {
122
172
  name: string;
123
173
  }
124
174
  interface Rpc<TIsEventStream extends boolean = false, TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> {
175
+ transport: "http";
125
176
  method?: RpcHttpMethod;
126
177
  path?: string;
127
178
  description?: string;
@@ -151,16 +202,17 @@ interface RpcPostEvent<TParams = undefined, TResponse = undefined> extends Omit<
151
202
  type RpcHandler<TParams, TResponse> = (context: RpcHandlerContext<TParams>, event: RpcEvent<TParams>) => TResponse | Promise<TResponse>;
152
203
  type RpcPostHandler<TParams, TResponse> = (context: RpcPostHandlerContext<TParams, TResponse>, event: RpcPostEvent<TParams, TResponse>) => any;
153
204
  declare function isRpc(input: unknown): input is Rpc<any, any>;
154
- declare function defineRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined | never = undefined>(config: HttpRpc<TParams, TResponse>): Rpc<false, TParams, TResponse>;
205
+ declare function defineRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined | never = undefined>(config: Omit<HttpRpc<TParams, TResponse>, "transport">): Rpc<false, TParams, TResponse>;
155
206
  declare function createHttpRpcDefinition(rpcName: string, httpPath: string, procedure: Rpc<any, any, any>): HttpRpcDefinition;
156
207
  declare function getRpcPath(rpcName: string, prefix?: string): string;
157
- declare function getRpcParamName(rpcName: string, procedure: Rpc<any, any, any>): string | undefined;
158
- declare function getRpcResponseName(rpcName: string, procedure: Rpc<any, any, any>): string | undefined;
208
+ declare function getRpcParamName(rpcName: string, procedure: Rpc<any, any, any> | WebsocketRpc<any, any>): string | undefined;
209
+ declare function getRpcResponseName(rpcName: string, procedure: Rpc<any, any, any> | WebsocketRpc<any, any>): string | undefined;
159
210
  declare function registerRpc(router: Router, path: string, procedure: NamedRpc<any, any, any>, opts: RouteOptions): void;
160
211
  declare function validateRpcRequestInput(event: H3Event, httpMethod: RpcHttpMethod, schema: ASchema): Promise<void>;
161
212
 
162
213
  interface ArriRouterBase {
163
- rpc: <TIsEventStream extends boolean, TParams extends AObjectSchema<any, any> | undefined, TResponse extends AObjectSchema<any, any> | undefined>(procedure: NamedRpc<TIsEventStream, TParams, TResponse>) => void;
214
+ rpc: <TIsEventStream extends boolean, TParams extends AObjectSchema<any, any> | undefined, TResponse extends AObjectSchema<any, any> | undefined>(procedure: Omit<NamedRpc<TIsEventStream, TParams, TResponse>, "transport">) => void;
215
+ wsRpc: <TParams extends RpcParamSchema | undefined, TResponse extends RpcParamSchema | undefined>(procedure: Omit<NamedWebsocketRpc<TParams, TResponse>, "transport">) => void;
164
216
  route: <TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends ASchema<any> = any, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>) => void;
165
217
  registerModels: (models: ModelMap) => void;
166
218
  }
@@ -168,10 +220,11 @@ declare class ArriRouter implements ArriRouterBase {
168
220
  private readonly procedures;
169
221
  private readonly routes;
170
222
  private readonly models;
171
- rpc<TIsEventStream extends boolean = false, TParams extends AObjectSchema<any, any> | undefined = undefined, TResponse extends AObjectSchema<any, any> | undefined = undefined>(procedure: NamedRpc<TIsEventStream, TParams, TResponse>): void;
223
+ rpc<TIsEventStream extends boolean = false, TParams extends AObjectSchema<any, any> | undefined = undefined, TResponse extends AObjectSchema<any, any> | undefined = undefined>(procedure: Omit<NamedRpc<TIsEventStream, TParams, TResponse>, "transport">): void;
224
+ wsRpc<TParams extends RpcParamSchema | undefined, TResponse extends RpcParamSchema | undefined>(procedure: Omit<NamedWebsocketRpc<TParams, TResponse>, "transport">): void;
172
225
  route<TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends ASchema<any> = any, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>): void;
173
226
  registerModels(models: ModelMap): void;
174
- getProcedures(): NamedRpc<any, any, any>[];
227
+ getProcedures(): (NamedWebsocketRpc<any, any> | NamedRpc<any, any, any>)[];
175
228
  getRoutes(): ArriRoute<any, any, any, any>[];
176
229
  getModels(): ModelMap;
177
230
  }
@@ -195,9 +248,11 @@ declare class ArriApp implements ArriRouterBase {
195
248
  private readonly _onBeforeResponse;
196
249
  private readonly _onError;
197
250
  private readonly _debug;
251
+ readonly definitionPath: string;
198
252
  constructor(opts?: ArriOptions);
199
253
  use(input: Middleware | ArriRouter): void;
200
- rpc<TIsEventStream extends boolean = false, TParams extends AObjectSchema<any, any> | undefined = undefined, TResponse extends AObjectSchema<any, any> | undefined = undefined>(procedure: NamedRpc<TIsEventStream, TParams, TResponse>): void;
254
+ rpc<TIsEventStream extends boolean = false, TParams extends AObjectSchema<any, any> | undefined = undefined, TResponse extends AObjectSchema<any, any> | undefined = undefined>(procedure: Omit<NamedRpc<TIsEventStream, TParams, TResponse>, "transport">): void;
255
+ wsRpc<TParams extends RpcParamSchema | undefined, TResponse extends RpcParamSchema | undefined>(procedure: Omit<NamedWebsocketRpc<TParams, TResponse>, "transport">): void;
201
256
  route<TPath extends string, TQuery extends AObjectSchema<any, any>, TBody extends ASchema<any>, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>): void;
202
257
  registerModels(models: ModelMap): void;
203
258
  getAppDefinition(): AppDefinition;
@@ -247,4 +302,4 @@ type ResolvedArriConfig = Required<ArriConfig>;
247
302
  declare const defaultConfig: Required<ArriConfig>;
248
303
  declare function defineConfig(config: ArriConfig): ResolvedArriConfig;
249
304
 
250
- export { ArriApp, type ArriConfig, type ArriOptions, type ArriRoute, ArriRouter, type ArriRouterBase, ArriServerError, ArriServerErrorResponse, DEV_DEFINITION_ENDPOINT, DEV_ENDPOINT_ROOT, 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, createAppDefinition, createHttpRpcDefinition, defaultConfig, defineConfig, defineError, defineEventStreamRpc, defineMiddleware, defineRoute, defineRpc, errorResponseFromValidationErrors, getRpcParamName, getRpcPath, getRpcResponseName, handleH3Error, handleRoute, isArriConfig, isEventStreamRpc, isResolvedArriConfig, isRpc, isRpcParamSchema, registerEventStreamRpc, registerRoute, registerRpc, validateRpcRequestInput };
305
+ export { ArriApp, type ArriConfig, type ArriOptions, type ArriRoute, ArriRouter, type ArriRouterBase, ArriServerError, ArriServerErrorResponse, DEV_DEFINITION_ENDPOINT, DEV_ENDPOINT_ROOT, 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 NamedWebsocketRpc, 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, type WebSocketRpcHandler, type WebsocketRpc, WsPeer, type WsPeerContext, createAppDefinition, createHttpRpcDefinition, createWsRpcDefinition, defaultConfig, defineConfig, defineError, defineEventStreamRpc, defineMiddleware, defineRoute, defineRpc, defineWebsocketRpc, errorResponseFromValidationErrors, getRpcParamName, getRpcPath, getRpcResponseName, handleH3Error, handleRoute, isArriConfig, isEventStreamRpc, isResolvedArriConfig, isRpc, isRpcParamSchema, registerEventStreamRpc, registerRoute, registerRpc, registerWebsocketRpc, validateRpcRequestInput };
package/dist/index.mjs CHANGED
@@ -1,6 +1,7 @@
1
- export { A as ArriApp, t as ArriRouter, j as ArriServerError, k as ArriServerErrorResponse, a as DEV_DEFINITION_ENDPOINT, D as DEV_ENDPOINT_ROOT, E as EventStreamConnection, c as createAppDefinition, e as createHttpRpcDefinition, q as defaultConfig, s as defineConfig, l as defineError, y as defineEventStreamRpc, u as defineRoute, d as defineRpc, m as errorResponseFromValidationErrors, f as getRpcParamName, g as getRpcPath, h as getRpcResponseName, n as handleH3Error, x as handleRoute, o as isArriConfig, z as isEventStreamRpc, p as isResolvedArriConfig, b as isRpc, i as isRpcParamSchema, B as registerEventStreamRpc, w as registerRoute, r as registerRpc, v as validateRpcRequestInput } from './shared/arri.b0950dad.mjs';
1
+ export { A as ArriApp, t as ArriRouter, j as ArriServerError, k as ArriServerErrorResponse, a as DEV_DEFINITION_ENDPOINT, D as DEV_ENDPOINT_ROOT, E as EventStreamConnection, W as WsPeer, c as createAppDefinition, e as createHttpRpcDefinition, G as createWsRpcDefinition, q as defaultConfig, s as defineConfig, l as defineError, y as defineEventStreamRpc, u as defineRoute, d as defineRpc, C as defineWebsocketRpc, m as errorResponseFromValidationErrors, f as getRpcParamName, g as getRpcPath, h as getRpcResponseName, n as handleH3Error, x as handleRoute, o as isArriConfig, z as isEventStreamRpc, p as isResolvedArriConfig, b as isRpc, i as isRpcParamSchema, B as registerEventStreamRpc, w as registerRoute, r as registerRpc, F as registerWebsocketRpc, v as validateRpcRequestInput } from './shared/arri.90dd1716.mjs';
2
2
  export * from 'h3';
3
3
  import 'arri-codegen-utils';
4
+ import 'consola';
4
5
  import 'arri-validate';
5
6
  import 'h3-sse';
6
7
  import 'scule';
@@ -1,22 +1,27 @@
1
1
  'use strict';
2
2
 
3
3
  const arriCodegenUtils = require('arri-codegen-utils');
4
+ const consola = require('consola');
4
5
  const h3 = require('h3');
5
6
  const arriValidate = require('arri-validate');
6
7
  const h3Sse = require('h3-sse');
7
8
  const scule = require('scule');
8
9
 
9
- var __defProp$3 = Object.defineProperty;
10
- var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
- var __publicField$3 = (obj, key, value) => {
12
- __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
10
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
11
+
12
+ const consola__default = /*#__PURE__*/_interopDefaultCompat(consola);
13
+
14
+ var __defProp$4 = Object.defineProperty;
15
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
16
+ var __publicField$4 = (obj, key, value) => {
17
+ __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
13
18
  return value;
14
19
  };
15
20
  class ArriServerError extends Error {
16
21
  constructor(err) {
17
22
  super(err.message);
18
- __publicField$3(this, "code");
19
- __publicField$3(this, "data");
23
+ __publicField$4(this, "code");
24
+ __publicField$4(this, "data");
20
25
  this.code = err.code;
21
26
  this.data = err.data;
22
27
  if (err.stack) {
@@ -262,6 +267,7 @@ function isRpc(input) {
262
267
  return typeof input === "object" && input !== null && "method" in input && arriCodegenUtils.isRpcHttpMethod(input.method) && "handler" in input && typeof input.handler === "function";
263
268
  }
264
269
  function defineRpc(config) {
270
+ config.transport = "http";
265
271
  return config;
266
272
  }
267
273
  function createHttpRpcDefinition(rpcName, httpPath, procedure) {
@@ -473,17 +479,18 @@ async function validateRpcRequestInput(event, httpMethod, schema) {
473
479
  }
474
480
  }
475
481
 
476
- var __defProp$2 = Object.defineProperty;
477
- var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
478
- var __publicField$2 = (obj, key, value) => {
479
- __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
482
+ var __defProp$3 = Object.defineProperty;
483
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
484
+ var __publicField$3 = (obj, key, value) => {
485
+ __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
480
486
  return value;
481
487
  };
482
488
  function defineEventStreamRpc(config) {
483
489
  return {
484
490
  ...config,
485
491
  method: config.method ?? "get",
486
- isEventStream: true
492
+ isEventStream: true,
493
+ transport: "http"
487
494
  };
488
495
  }
489
496
  function isEventStreamRpc(input) {
@@ -491,14 +498,14 @@ function isEventStreamRpc(input) {
491
498
  }
492
499
  class EventStreamConnection {
493
500
  constructor(event, opts) {
494
- __publicField$2(this, "lastEventId");
495
- __publicField$2(this, "validationErrors");
496
- __publicField$2(this, "validator");
497
- __publicField$2(this, "serializer");
501
+ __publicField$3(this, "lastEventId");
502
+ __publicField$3(this, "validationErrors");
503
+ __publicField$3(this, "validator");
504
+ __publicField$3(this, "serializer");
498
505
  // for some reason Rollup cannot output DTS when this is set to NodeJS.Timeout
499
- __publicField$2(this, "pingInterval");
500
- __publicField$2(this, "pingIntervalMs");
501
- __publicField$2(this, "eventStream");
506
+ __publicField$3(this, "pingInterval");
507
+ __publicField$3(this, "pingIntervalMs");
508
+ __publicField$3(this, "eventStream");
502
509
  this.eventStream = h3Sse.createEventStream(event);
503
510
  this.lastEventId = this.eventStream.lastEventId;
504
511
  this.pingIntervalMs = opts.pingInterval ?? 6e4;
@@ -812,19 +819,24 @@ function handleRoute(router, method, route, opts) {
812
819
  }
813
820
  }
814
821
 
815
- var __defProp$1 = Object.defineProperty;
816
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
817
- var __publicField$1 = (obj, key, value) => {
818
- __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
822
+ var __defProp$2 = Object.defineProperty;
823
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
824
+ var __publicField$2 = (obj, key, value) => {
825
+ __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
819
826
  return value;
820
827
  };
821
828
  class ArriRouter {
822
829
  constructor() {
823
- __publicField$1(this, "procedures", []);
824
- __publicField$1(this, "routes", []);
825
- __publicField$1(this, "models", {});
830
+ __publicField$2(this, "procedures", []);
831
+ __publicField$2(this, "routes", []);
832
+ __publicField$2(this, "models", {});
826
833
  }
827
834
  rpc(procedure) {
835
+ procedure.transport = "http";
836
+ this.procedures.push(procedure);
837
+ }
838
+ wsRpc(procedure) {
839
+ procedure.transport = "ws";
828
840
  this.procedures.push(procedure);
829
841
  }
830
842
  route(route) {
@@ -846,6 +858,145 @@ class ArriRouter {
846
858
  }
847
859
  }
848
860
 
861
+ var __defProp$1 = Object.defineProperty;
862
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
863
+ var __publicField$1 = (obj, key, value) => {
864
+ __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
865
+ return value;
866
+ };
867
+ class WsPeer {
868
+ constructor(peer, opts) {
869
+ __publicField$1(this, "_peer");
870
+ __publicField$1(this, "_validator");
871
+ __publicField$1(this, "context");
872
+ __publicField$1(this, "url");
873
+ this._peer = peer;
874
+ this._validator = opts.validator;
875
+ this.url = peer.url;
876
+ this.context = opts.context;
877
+ }
878
+ send(data) {
879
+ if (!this._validator) {
880
+ return;
881
+ }
882
+ if (!this._validator.validate(data)) {
883
+ return;
884
+ }
885
+ const payload = this._validator.serialize(data);
886
+ return this._peer.send(`type: message
887
+ data: ${payload}`);
888
+ }
889
+ sendError(err) {
890
+ return this._peer.send(`type: error
891
+ data: ${JSON.stringify(err)}`);
892
+ }
893
+ close() {
894
+ throw new Error("close() is not yet implemented on WsPeer");
895
+ }
896
+ subscribe(channel) {
897
+ this._peer.subscribe(channel);
898
+ }
899
+ unsubscribe(channel) {
900
+ this._peer.unsubscribe(channel);
901
+ }
902
+ publish(channel, message) {
903
+ if (!this._validator) {
904
+ return;
905
+ }
906
+ if (!this._validator.validate(message)) {
907
+ const err = {
908
+ code: 500,
909
+ message: `Error serializing message on server. The payload doesn't match the specified schema.`,
910
+ data: {
911
+ payload: message
912
+ }
913
+ };
914
+ this.sendError(err);
915
+ return;
916
+ }
917
+ const payload = this._validator.serialize(message);
918
+ this._peer.publish(channel, payload);
919
+ }
920
+ readyState() {
921
+ return this._peer.readyState;
922
+ }
923
+ }
924
+ function defineWebsocketRpc(def) {
925
+ def.transport = "ws";
926
+ return def;
927
+ }
928
+ function registerWebsocketRpc(router, path, rpc) {
929
+ let responseValidator;
930
+ let paramValidator;
931
+ try {
932
+ responseValidator = rpc.response ? arriValidate.a.compile(rpc.response) : void 0;
933
+ } catch (err) {
934
+ console.error("ERROR COMPILING VALIDATOR", err);
935
+ }
936
+ try {
937
+ paramValidator = rpc.params ? arriValidate.a.compile(rpc.params) : void 0;
938
+ } catch (err) {
939
+ console.error("ERROR COMPILING PARAMS", err);
940
+ }
941
+ const handler = h3.defineWebSocketHandler({
942
+ upgrade(req) {
943
+ },
944
+ open(peer) {
945
+ const urlParts = peer.url.split("?");
946
+ const context = {
947
+ rpcName: rpc.name,
948
+ clientAddress: peer.addr
949
+ };
950
+ if (urlParts.length > 1) {
951
+ urlParts.shift();
952
+ const queryStr = new URLSearchParams(urlParts.join("?"));
953
+ const query = {};
954
+ for (const [key, val] of queryStr.entries()) {
955
+ query[key] = val;
956
+ }
957
+ context.queryParams = query;
958
+ }
959
+ const wsPeer = new WsPeer(peer, {
960
+ validator: responseValidator,
961
+ context
962
+ });
963
+ peer.ctx.__wsPeer = wsPeer;
964
+ rpc.handler.onOpen(peer.ctx.__wsPeer);
965
+ },
966
+ message(peer, message) {
967
+ if (!paramValidator) {
968
+ return;
969
+ }
970
+ const data = paramValidator.safeParse(message.text());
971
+ if (!data.success) {
972
+ const errorResponse = {
973
+ code: 400,
974
+ message: data.error.message,
975
+ data: data.error.errors,
976
+ stack: data.error.stack?.split("\n")
977
+ };
978
+ peer.ctx.__wsPeer.sendError(errorResponse);
979
+ return;
980
+ }
981
+ rpc.handler.onMessage(peer.ctx.__wsPeer, data.value);
982
+ },
983
+ close(peer, details) {
984
+ rpc.handler.onClose(peer.ctx.__wsPeer, details);
985
+ }
986
+ });
987
+ router.use(path, handler);
988
+ }
989
+ function createWsRpcDefinition(rpcName, path, rpc) {
990
+ return {
991
+ transport: "ws",
992
+ path,
993
+ params: getRpcParamName(rpcName, rpc),
994
+ response: getRpcResponseName(rpcName, rpc),
995
+ isDeprecated: rpc.isDeprecated,
996
+ description: rpc.description
997
+ };
998
+ }
999
+
849
1000
  var __defProp = Object.defineProperty;
850
1001
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
851
1002
  var __publicField = (obj, key, value) => {
@@ -871,6 +1022,7 @@ class ArriApp {
871
1022
  __publicField(this, "_onBeforeResponse");
872
1023
  __publicField(this, "_onError");
873
1024
  __publicField(this, "_debug");
1025
+ __publicField(this, "definitionPath");
874
1026
  this.appInfo = opts?.appInfo;
875
1027
  this.h3App = h3.createApp({
876
1028
  debug: opts?.debug
@@ -883,11 +1035,15 @@ class ArriApp {
883
1035
  this._rpcRoutePrefix = opts?.rpcRoutePrefix ?? "";
884
1036
  this._rpcDefinitionPath = opts?.rpcDefinitionPath ?? "__definition";
885
1037
  this.h3App.use(this.h3Router);
1038
+ this.definitionPath = this._rpcRoutePrefix ? `/${this._rpcRoutePrefix}/${this._rpcDefinitionPath}`.split("//").join("/") : `/${this._rpcDefinitionPath}`;
886
1039
  this.h3Router.get(
887
- this._rpcRoutePrefix ? `/${this._rpcRoutePrefix}/${this._rpcDefinitionPath}`.split("//").join("/") : `/${this._rpcDefinitionPath}`,
1040
+ this.definitionPath,
888
1041
  h3.eventHandler(() => this.getAppDefinition())
889
1042
  );
890
1043
  if (process.env.ARRI_DEV_MODE === "true") {
1044
+ consola__default.info(
1045
+ `Arri definition available at \`http://<host>${this.definitionPath}\``
1046
+ );
891
1047
  this.h3Router.get(
892
1048
  DEV_DEFINITION_ENDPOINT,
893
1049
  h3.eventHandler(() => this.getAppDefinition())
@@ -918,7 +1074,11 @@ class ArriApp {
918
1074
  this.route(route);
919
1075
  }
920
1076
  for (const rpc of input.getProcedures()) {
921
- this.rpc(rpc);
1077
+ if (rpc.transport === "http") {
1078
+ this.rpc(rpc);
1079
+ } else {
1080
+ this.wsRpc(rpc);
1081
+ }
922
1082
  }
923
1083
  this.registerModels(input.getModels());
924
1084
  return;
@@ -926,26 +1086,24 @@ class ArriApp {
926
1086
  this._middlewares.push(input);
927
1087
  }
928
1088
  rpc(procedure) {
929
- const path = procedure.path ?? getRpcPath(procedure.name, this._rpcRoutePrefix);
930
- this._procedures[procedure.name] = createHttpRpcDefinition(
931
- procedure.name,
932
- path,
933
- procedure
934
- );
935
- if (isRpcParamSchema(procedure.params)) {
936
- const paramName = getRpcParamName(procedure.name, procedure);
1089
+ procedure.transport = "http";
1090
+ const p = procedure;
1091
+ const path = p.path ?? getRpcPath(p.name, this._rpcRoutePrefix);
1092
+ this._procedures[p.name] = createHttpRpcDefinition(p.name, path, p);
1093
+ if (isRpcParamSchema(p.params)) {
1094
+ const paramName = getRpcParamName(p.name, p);
937
1095
  if (paramName) {
938
- this._models[paramName] = procedure.params;
1096
+ this._models[paramName] = p.params;
939
1097
  }
940
1098
  }
941
- if (isRpcParamSchema(procedure.response)) {
942
- const responseName = getRpcResponseName(procedure.name, procedure);
1099
+ if (isRpcParamSchema(p.response)) {
1100
+ const responseName = getRpcResponseName(p.name, p);
943
1101
  if (responseName) {
944
- this._models[responseName] = procedure.response;
1102
+ this._models[responseName] = p.response;
945
1103
  }
946
1104
  }
947
- if (isEventStreamRpc(procedure)) {
948
- registerEventStreamRpc(this.h3Router, path, procedure, {
1105
+ if (isEventStreamRpc(p)) {
1106
+ registerEventStreamRpc(this.h3Router, path, p, {
949
1107
  middleware: this._middlewares,
950
1108
  onRequest: this._onRequest,
951
1109
  onError: this._onError,
@@ -955,7 +1113,7 @@ class ArriApp {
955
1113
  });
956
1114
  return;
957
1115
  }
958
- registerRpc(this.h3Router, path, procedure, {
1116
+ registerRpc(this.h3Router, path, p, {
959
1117
  middleware: this._middlewares,
960
1118
  onRequest: this._onRequest,
961
1119
  onError: this._onError,
@@ -964,6 +1122,29 @@ class ArriApp {
964
1122
  debug: this._debug
965
1123
  });
966
1124
  }
1125
+ wsRpc(procedure) {
1126
+ procedure.transport = "ws";
1127
+ const p = procedure;
1128
+ const path = procedure.path ?? getRpcPath(procedure.name, this._rpcRoutePrefix);
1129
+ this._procedures[procedure.name] = createWsRpcDefinition(
1130
+ procedure.name,
1131
+ path,
1132
+ p
1133
+ );
1134
+ if (isRpcParamSchema(procedure.params)) {
1135
+ const paramName = getRpcParamName(procedure.name, p);
1136
+ if (paramName) {
1137
+ this._models[paramName] = procedure.params;
1138
+ }
1139
+ }
1140
+ if (isRpcParamSchema(procedure.response)) {
1141
+ const responseName = getRpcResponseName(procedure.name, p);
1142
+ if (responseName) {
1143
+ this._models[responseName] = procedure.response;
1144
+ }
1145
+ }
1146
+ registerWebsocketRpc(this.h3Router, path, p);
1147
+ }
967
1148
  route(route) {
968
1149
  registerRoute(this.h3Router, route, {
969
1150
  middleware: this._middlewares,
@@ -1060,14 +1241,17 @@ exports.ArriServerErrorResponse = ArriServerErrorResponse;
1060
1241
  exports.DEV_DEFINITION_ENDPOINT = DEV_DEFINITION_ENDPOINT;
1061
1242
  exports.DEV_ENDPOINT_ROOT = DEV_ENDPOINT_ROOT;
1062
1243
  exports.EventStreamConnection = EventStreamConnection;
1244
+ exports.WsPeer = WsPeer;
1063
1245
  exports.createAppDefinition = createAppDefinition;
1064
1246
  exports.createHttpRpcDefinition = createHttpRpcDefinition;
1247
+ exports.createWsRpcDefinition = createWsRpcDefinition;
1065
1248
  exports.defaultConfig = defaultConfig;
1066
1249
  exports.defineConfig = defineConfig;
1067
1250
  exports.defineError = defineError;
1068
1251
  exports.defineEventStreamRpc = defineEventStreamRpc;
1069
1252
  exports.defineRoute = defineRoute;
1070
1253
  exports.defineRpc = defineRpc;
1254
+ exports.defineWebsocketRpc = defineWebsocketRpc;
1071
1255
  exports.errorResponseFromValidationErrors = errorResponseFromValidationErrors;
1072
1256
  exports.getRpcParamName = getRpcParamName;
1073
1257
  exports.getRpcPath = getRpcPath;
@@ -1082,4 +1266,5 @@ exports.isRpcParamSchema = isRpcParamSchema;
1082
1266
  exports.registerEventStreamRpc = registerEventStreamRpc;
1083
1267
  exports.registerRoute = registerRoute;
1084
1268
  exports.registerRpc = registerRpc;
1269
+ exports.registerWebsocketRpc = registerWebsocketRpc;
1085
1270
  exports.validateRpcRequestInput = validateRpcRequestInput;