@synnaxlabs/freighter 0.54.0 → 0.56.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.
@@ -1 +1 @@
1
- {"version":3,"file":"alamos.d.ts","sourceRoot":"","sources":["../../src/alamos.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAE7D,eAAO,MAAM,UAAU,GACpB,iBAAiB,eAAe,KAAG,UAenC,CAAC"}
1
+ {"version":3,"file":"alamos.d.ts","sourceRoot":"","sources":["../../src/alamos.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAE7D,eAAO,MAAM,UAAU,GACpB,iBAAiB,eAAe,KAAG,UA0BnC,CAAC"}
@@ -16,6 +16,6 @@ export declare class HTTPClient extends MiddlewareCollector implements UnaryClie
16
16
  encoder: binary.Codec;
17
17
  constructor(endpoint: URL, encoder: binary.Codec, secure?: boolean);
18
18
  get headers(): Record<string, string>;
19
- send<RQ extends z.ZodType, RS extends z.ZodType = RQ>(target: string, req: z.input<RQ> | z.infer<RQ>, reqSchema: RQ, resSchema: RS): Promise<[z.infer<RS>, null] | [null, Error]>;
19
+ send<RQ extends z.ZodType, RS extends z.ZodType = RQ>(target: string, req: z.input<RQ> | z.infer<RQ>, reqSchema: RQ, resSchema: RS): Promise<z.infer<RS>>;
20
20
  }
21
21
  //# sourceMappingURL=http.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/http.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,MAAM,EAAU,KAAK,GAAG,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,CAAC;AAG7B,OAAO,EAAgB,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,eAAO,MAAM,uBAAuB,iBAAiB,CAAC;AAWtD,eAAO,MAAM,uBAAuB,GAAI,KAAK,KAAK,KAAG,OAsBpD,CAAC;AAIF;;;;;;GAMG;AACH,qBAAa,UAAW,SAAQ,mBAAoB,YAAW,WAAW;IACxE,QAAQ,EAAE,GAAG,CAAC;IACd,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC;gBAEV,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAE,OAAe;IAazE,IAAI,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIpC;IAEK,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC,OAAO,GAAG,EAAE,EACxD,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAC9B,SAAS,EAAE,EAAE,EACb,SAAS,EAAE,EAAE,GACZ,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;CAsDhD"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/http.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,MAAM,EAAU,KAAK,GAAG,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,CAAC;AAG7B,OAAO,EAAgB,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,eAAO,MAAM,uBAAuB,iBAAiB,CAAC;AAWtD,eAAO,MAAM,uBAAuB,GAAI,KAAK,KAAK,KAAG,OAsBpD,CAAC;AAIF;;;;;;GAMG;AACH,qBAAa,UAAW,SAAQ,mBAAoB,YAAW,WAAW;IACxE,QAAQ,EAAE,GAAG,CAAC;IACd,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC;gBAEV,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAE,OAAe;IAazE,IAAI,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIpC;IAEK,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC,OAAO,GAAG,EAAE,EACxD,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAC9B,SAAS,EAAE,EAAE,EACb,SAAS,EAAE,EAAE,GACZ,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;CAkDxB"}
@@ -2,7 +2,7 @@ export { EOF, StreamClosed, Unreachable } from './errors';
2
2
  export { HTTPClient } from './http';
3
3
  export { type Context, type Middleware, type Next } from './middleware';
4
4
  export { type Stream, type StreamClient } from './stream';
5
- export { sendRequired, type UnaryClient, unaryWithBreaker } from './unary';
5
+ export { type UnaryClient, unaryWithBreaker } from './unary';
6
6
  export { WebSocketClient } from './websocket';
7
7
  export { type WebsocketMessage } from './websocket';
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,KAAK,WAAW,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
@@ -14,36 +14,40 @@ export interface Context {
14
14
  }
15
15
  export declare const ROLES: readonly ["client", "server"];
16
16
  export type Role = (typeof ROLES)[number];
17
- /** Next executes the next middleware in the chain. */
18
- export type Next = (ctx: Context) => Promise<[Context, Error | null]>;
19
17
  /**
20
- * Middleware represents a general middleware function that can be used to
21
- * parse/attach metadata to a request or alter its behavior.
18
+ * Next executes the next middleware in the chain, returning the resulting context. It
19
+ * throws if any downstream middleware or the finalizer throws.
22
20
  */
23
- export type Middleware = (ctx: Context, next: Next) => Promise<[Context, Error | null]>;
21
+ export type Next = (ctx: Context) => Promise<Context>;
24
22
  /**
25
- * Finalizer is a middleware that is executed as the last step in the chain.
26
- * Finalizer middleware should be used to execute the request.
23
+ * Middleware represents a general middleware function that can be used to parse/attach
24
+ * metadata to a request or alter its behavior. It should call next to continue the
25
+ * chain and may throw to abort the request.
27
26
  */
28
- type Finalizer = (ctx: Context) => Promise<[Context, Error | null]>;
27
+ export type Middleware = (ctx: Context, next: Next) => Promise<Context>;
29
28
  /**
30
- * MiddlewareCollector is a class that can be used to collect and execute
31
- * middleware in order to implement the Transport interface.
29
+ * Finalizer is a middleware that is executed as the last step in the chain. Finalizer
30
+ * middleware should be used to execute the request. It throws if the request fails.
31
+ */
32
+ type Finalizer = (ctx: Context) => Promise<Context>;
33
+ /**
34
+ * MiddlewareCollector is a class that can be used to collect and execute middleware in
35
+ * order to implement the Transport interface.
32
36
  */
33
37
  export declare class MiddlewareCollector {
34
38
  middleware: Middleware[];
35
39
  /** Implements the Transport interface */
36
40
  use(...mw: Middleware[]): void;
37
41
  /**
38
- * Executes middleware in order, passing the the metadata to each middleware
39
- * until the end of the chain is reached. It then calls the finalizer with the
40
- * metadata.
42
+ * Executes middleware in order, passing the the metadata to each middleware until the
43
+ * end of the chain is reached. It then calls the finalizer with the metadata.
41
44
  *
42
45
  * @param ctx - The context to pass to the middleware.
43
46
  * @param finalizer - The finalizer to call with the metadata.
44
- * @returns An error if one was encountered, otherwise undefined.
47
+ * @returns The context produced by the chain. Throws if any middleware or the
48
+ * finalizer throws.
45
49
  */
46
- executeMiddleware(ctx: Context, finalizer: Finalizer): Promise<[Context, Error | null]>;
50
+ executeMiddleware(ctx: Context, finalizer: Finalizer): Promise<Context>;
47
51
  }
48
52
  export {};
49
53
  //# sourceMappingURL=middleware.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/middleware.ts"],"names":[],"mappings":"AASA;;;;;;;GAOG;AACH,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,eAAO,MAAM,KAAK,+BAAgC,CAAC;AACnD,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1C,sDAAsD;AACtD,MAAM,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,OAAO,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC;AAEtE;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,OAAO,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC;AAExF;;;GAGG;AACH,KAAK,SAAS,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,OAAO,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC;AAEpE;;;GAGG;AACH,qBAAa,mBAAmB;IAC9B,UAAU,EAAE,UAAU,EAAE,CAAM;IAE9B,yCAAyC;IACzC,GAAG,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,GAAG,IAAI;IAI9B;;;;;;;;OAQG;IACG,iBAAiB,CACrB,GAAG,EAAE,OAAO,EACZ,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,CAAC,OAAO,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC;CAUpC"}
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/middleware.ts"],"names":[],"mappings":"AASA;;;;;;;GAOG;AACH,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,eAAO,MAAM,KAAK,+BAAgC,CAAC;AACnD,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1C;;;GAGG;AACH,MAAM,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtD;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAExE;;;GAGG;AACH,KAAK,SAAS,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpD;;;GAGG;AACH,qBAAa,mBAAmB;IAC9B,UAAU,EAAE,UAAU,EAAE,CAAM;IAE9B,yCAAyC;IACzC,GAAG,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,GAAG,IAAI;IAI9B;;;;;;;;OAQG;IACG,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;CAU9E"}
@@ -5,15 +5,14 @@ import { Transport } from './transport';
5
5
  */
6
6
  export interface StreamReceiver<RS extends z.ZodType> {
7
7
  /**
8
- * Receives a response from the stream. It's not safe to call receive
9
- * concurrently.
8
+ * Receives a response from the stream. It's not safe to call receive concurrently.
10
9
  *
11
- * @returns freighter.EOF: if the server closed the stream nominally.
12
- * @returns Error: if the server closed the stream abnormally,
13
- * returns the error the server returned.
14
- * @raises Error: if the transport fails.
10
+ * @returns the next response from the stream.
11
+ * @throws freighter.EOF: if the server closed the stream nominally.
12
+ * @throws Error: if the server closed the stream abnormally, throws the error the
13
+ * server returned, or a transport error if the transport itself failed.
15
14
  */
16
- receive: () => Promise<[z.infer<RS>, null] | [null, Error]>;
15
+ receive: () => Promise<z.infer<RS>>;
17
16
  /**
18
17
  * @returns true if the stream has received a response
19
18
  */
@@ -24,17 +23,16 @@ export interface StreamReceiver<RS extends z.ZodType> {
24
23
  */
25
24
  export interface StreamSender<RQ extends z.ZodType> {
26
25
  /**
27
- * Sends a request to the stream. It is not safe to call send concurrently
28
- * with closeSend or send.
26
+ * Sends a request to the stream. It is not safe to call send concurrently with
27
+ * closeSend or send.
29
28
 
30
29
  * @param req - the request to send.
31
- * @returns freighter.EOF: if the server closed the stream. The caller
32
- * can discover the error returned by the server by calling receive().
33
- * @returns undefined: if the message was sent successfully.
34
- * @raises freighter.StreamClosed: if the client called close_send()
35
- * @raises Error: if the transport fails.
30
+ * @throws freighter.EOF: if the server closed the stream. The caller can discover the
31
+ * error returned by the server by calling receive().
32
+ * @throws freighter.StreamClosed: if the client called closeSend().
33
+ * @throws Error: if the transport fails.
36
34
  */
37
- send: (req: z.input<RQ> | z.infer<RQ>) => Error | null;
35
+ send: (req: z.input<RQ> | z.infer<RQ>) => void;
38
36
  }
39
37
  /**
40
38
  * Extension of the StreamSender interface that allows the client to close the sending
@@ -42,13 +40,13 @@ export interface StreamSender<RQ extends z.ZodType> {
42
40
  */
43
41
  export interface StreamSenderCloser<RQ extends z.ZodType> extends StreamSender<RQ> {
44
42
  /**
45
- * Lets the server know no more messages will be sent. If the client attempts
46
- * to call send() after calling closeSend(), a freighter.StreamClosed
47
- * exception will be raised. close_send is idempotent. If the server has
48
- * already closed the stream, close_send will do nothing.
43
+ * Lets the server know no more messages will be sent. If the client attempts to call
44
+ * send() after calling closeSend(), a freighter.StreamClosed exception will be raised.
45
+ * close_send is idempotent. If the server has already closed the stream, close_send
46
+ * will do nothing.
49
47
 
50
- * After calling close_send, the client is responsible for calling receive()
51
- * to successfully receive the server's acknowledgement.
48
+ * After calling close_send, the client is responsible for calling receive() to
49
+ * successfully receive the server's acknowledgement.
52
50
  */
53
51
  closeSend: () => void;
54
52
  }
@@ -62,15 +60,15 @@ export interface Stream<RQ extends z.ZodType, RS extends z.ZodType = RQ> extends
62
60
  */
63
61
  export interface StreamClient extends Transport {
64
62
  /**
65
- * Dials the target and returns a stream that can be used to issue requests
66
- * and receive responses
63
+ * Dials the target and returns a stream that can be used to issue requests and
64
+ * receive responses
67
65
  *
68
- * @param target - The target to dial. In some implementations, this may be
69
- * an endpoint path, or in others, a complete hostname or URL.
70
- * @param reqSchema - The schema for the request type. This is used to
71
- * validate the request before sending it.
72
- * @param resSchema - The schema for the response type. This is used to
73
- * validate the response before returning it.
66
+ * @param target - The target to dial. In some implementations, this may be an
67
+ * endpoint path, or in others, a complete hostname or URL.
68
+ * @param reqSchema - The schema for the request type. This is used to validate the
69
+ * request before sending it.
70
+ * @param resSchema - The schema for the response type. This is used to validate the
71
+ * response before returning it.
74
72
  */
75
73
  stream: <RQ extends z.ZodType, RS extends z.ZodType = RQ>(target: string, reqSchema: RQ, resSchema: RS) => Promise<Stream<RQ, RS>>;
76
74
  }
@@ -1 +1 @@
1
- {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/stream.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,cAAc,CAAC,EAAE,SAAS,CAAC,CAAC,OAAO;IAClD;;;;;;;;OAQG;IACH,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;IAE5D;;OAEG;IACH,QAAQ,EAAE,MAAM,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,EAAE,SAAS,CAAC,CAAC,OAAO;IAChD;;;;;;;;;;MAUE;IACF,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,KAAK,GAAG,IAAI,CAAC;CACxD;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB,CAAC,EAAE,SAAS,CAAC,CAAC,OAAO,CAAE,SAAQ,YAAY,CAAC,EAAE,CAAC;IAChF;;;;;;;;OAQG;IACH,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC,OAAO,GAAG,EAAE,CACrE,SAAQ,kBAAkB,CAAC,EAAE,CAAC,EAAE,cAAc,CAAC,EAAE,CAAC;CAAG;AAEvD;;GAEG;AACH,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC7C;;;;;;;;;;OAUG;IACH,MAAM,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC,OAAO,GAAG,EAAE,EACtD,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,EAAE,EACb,SAAS,EAAE,EAAE,KACV,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;CAC9B"}
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/stream.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,cAAc,CAAC,EAAE,SAAS,CAAC,CAAC,OAAO;IAClD;;;;;;;OAOG;IACH,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAEpC;;OAEG;IACH,QAAQ,EAAE,MAAM,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,EAAE,SAAS,CAAC,CAAC,OAAO;IAChD;;;;;;;;;MASE;IACF,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC;CAChD;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB,CAAC,EAAE,SAAS,CAAC,CAAC,OAAO,CAAE,SAAQ,YAAY,CAAC,EAAE,CAAC;IAChF;;;;;;;;OAQG;IACH,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC,OAAO,GAAG,EAAE,CACrE,SAAQ,kBAAkB,CAAC,EAAE,CAAC,EAAE,cAAc,CAAC,EAAE,CAAC;CAAG;AAEvD;;GAEG;AACH,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC7C;;;;;;;;;;OAUG;IACH,MAAM,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC,OAAO,GAAG,EAAE,EACtD,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,EAAE,EACb,SAAS,EAAE,EAAE,KACV,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;CAC9B"}
@@ -2,8 +2,8 @@ import { breaker } from '@synnaxlabs/x';
2
2
  import { z } from 'zod';
3
3
  import { Transport } from './transport';
4
4
  /**
5
- * An interface for an entity that implements a simple request-response
6
- * transport between two entities.
5
+ * An interface for an entity that implements a simple request-response transport
6
+ * between two entities.
7
7
  */
8
8
  export interface UnaryClient extends Transport {
9
9
  /**
@@ -11,9 +11,10 @@ export interface UnaryClient extends Transport {
11
11
  * @param target - The target server to send the request to.
12
12
  * @param req - The request to send.
13
13
  * @param resSchema - The schema to validate the response against.
14
+ * @returns the decoded response.
15
+ * @throws Error: if the server returns an error or the transport fails.
14
16
  */
15
- send: <RQ extends z.ZodType, RS extends z.ZodType = RQ>(target: string, req: z.input<RQ> | z.infer<RQ>, reqSchema: RQ, resSchema: RS) => Promise<[z.infer<RS>, null] | [null, Error]>;
17
+ send: <RQ extends z.ZodType, RS extends z.ZodType = RQ>(target: string, req: z.input<RQ> | z.infer<RQ>, reqSchema: RQ, resSchema: RS) => Promise<z.infer<RS>>;
16
18
  }
17
19
  export declare const unaryWithBreaker: (base: UnaryClient, cfg: breaker.Config) => UnaryClient;
18
- export declare const sendRequired: <RQ extends z.ZodType, RS extends z.ZodType = RQ>(client: UnaryClient, target: string, req: z.input<RQ> | z.infer<RQ>, reqSchema: RQ, resSchema: RS) => Promise<z.infer<RS>>;
19
20
  //# sourceMappingURL=unary.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"unary.d.ts","sourceRoot":"","sources":["../../src/unary.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,CAAC;AAI7B,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;;GAGG;AACH,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C;;;;;OAKG;IACH,IAAI,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC,OAAO,GAAG,EAAE,EACpD,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAC9B,SAAS,EAAE,EAAE,EACb,SAAS,EAAE,EAAE,KACV,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;CACnD;AAED,eAAO,MAAM,gBAAgB,GAC3B,MAAM,WAAW,EACjB,KAAK,OAAO,CAAC,MAAM,KAClB,WA6BF,CAAC;AAEF,eAAO,MAAM,YAAY,GAAU,EAAE,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC,OAAO,GAAG,EAAE,EAChF,QAAQ,WAAW,EACnB,QAAQ,MAAM,EACd,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAC9B,WAAW,EAAE,EACb,WAAW,EAAE,KACZ,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAIrB,CAAC"}
1
+ {"version":3,"file":"unary.d.ts","sourceRoot":"","sources":["../../src/unary.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,CAAC;AAI7B,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;;GAGG;AACH,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C;;;;;;;OAOG;IACH,IAAI,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC,OAAO,GAAG,EAAE,EACpD,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAC9B,SAAS,EAAE,EAAE,EACb,SAAS,EAAE,EAAE,KACV,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;CAC3B;AAED,eAAO,MAAM,gBAAgB,GAC3B,MAAM,WAAW,EACjB,KAAK,OAAO,CAAC,MAAM,KAClB,WA+BF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/websocket.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,MAAM,EAAoB,MAAM,EAAE,KAAK,GAAG,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAgB,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAQ1D,MAAM,MAAM,gBAAgB,CAAC,CAAC,GAAG,OAAO,IAAI;IAC1C,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,CAAC,CAAC;CACb,CAAC;AAgHF,eAAO,MAAM,yBAAyB,iBAAiB,CAAC;AAIxD;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,mBAAoB,YAAW,YAAY;IAC9E,OAAO,EAAE,GAAG,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAEhB,MAAM,CAAC,QAAQ,CAAC,YAAY,iBAAiB;IAE7C;;;;OAIG;gBACS,YAAY,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,UAAQ;IAOpE,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,eAAe;IAM/C,6CAA6C;IACvC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC,OAAO,GAAG,EAAE,EAC1D,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,EAAE,EACb,SAAS,EAAE,EAAE,GACZ,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAkB1B,OAAO,CAAC,QAAQ;YAWF,UAAU;CAsBzB"}
1
+ {"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/websocket.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,MAAM,EAAoB,MAAM,EAAE,KAAK,GAAG,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAgB,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAQ1D,MAAM,MAAM,gBAAgB,CAAC,CAAC,GAAG,OAAO,IAAI;IAC1C,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,CAAC,CAAC;CACb,CAAC;AA8GF,eAAO,MAAM,yBAAyB,iBAAiB,CAAC;AAIxD;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,mBAAoB,YAAW,YAAY;IAC9E,OAAO,EAAE,GAAG,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAEhB,MAAM,CAAC,QAAQ,CAAC,YAAY,iBAAiB;IAE7C;;;;OAIG;gBACS,YAAY,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,UAAQ;IAOpE,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,eAAe;IAM/C,6CAA6C;IACvC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC,OAAO,GAAG,EAAE,EAC1D,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,EAAE,EACb,SAAS,EAAE,EAAE,GACZ,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAe1B,OAAO,CAAC,QAAQ;YAWF,UAAU;CAmBzB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synnaxlabs/freighter",
3
- "version": "0.54.0",
3
+ "version": "0.56.0",
4
4
  "type": "module",
5
5
  "description": "a modular transport abstraction",
6
6
  "repository": "https://github.com/synnaxlabs/synnax/tree/main/freighter/ts",
@@ -14,21 +14,21 @@
14
14
  "control systems"
15
15
  ],
16
16
  "dependencies": {
17
- "zod": "^4.3.6",
18
- "@synnaxlabs/alamos": "^0.54.0",
19
- "@synnaxlabs/x": "^0.54.0"
17
+ "zod": "^4.4.3",
18
+ "@synnaxlabs/alamos": "^0.56.0",
19
+ "@synnaxlabs/x": "^0.56.0"
20
20
  },
21
21
  "devDependencies": {
22
- "@types/node": "^25.5.0",
23
- "@vitest/coverage-v8": "^4.1.2",
24
- "eslint": "^10.1.0",
22
+ "@types/node": "^25.9.0",
23
+ "@vitest/coverage-v8": "^4.1.6",
24
+ "eslint": "^10.4.0",
25
25
  "madge": "^8.0.0",
26
- "typescript": "^6.0.2",
27
- "vite": "^8.0.3",
28
- "vitest": "^4.1.2",
26
+ "typescript": "^6.0.3",
27
+ "vite": "^8.0.13",
28
+ "vitest": "^4.1.6",
29
29
  "@synnaxlabs/eslint-config": "^0.0.0",
30
- "@synnaxlabs/vite-plugin": "^0.0.0",
31
- "@synnaxlabs/tsconfig": "^0.0.0"
30
+ "@synnaxlabs/tsconfig": "^0.0.0",
31
+ "@synnaxlabs/vite-plugin": "^0.0.0"
32
32
  },
33
33
  "main": "dist/freighter.cjs",
34
34
  "module": "dist/freighter.js",
package/src/alamos.ts CHANGED
@@ -15,18 +15,29 @@ export const middleware =
15
15
  (instrumentation: Instrumentation): Middleware =>
16
16
  async (context, next) => {
17
17
  if (context.role === "client") instrumentation.T.propagate(context.params);
18
-
19
- const [res, exc] = await instrumentation.T.trace(
20
- context.target,
21
- "debug",
22
- async (span): Promise<[Context, Error | null]> => {
23
- const [ctx, err] = await next(context);
24
- if (err != null) span.recordError(err);
25
- return [ctx, err];
26
- },
27
- );
28
- log(context, instrumentation, exc);
29
- return [res, exc];
18
+ try {
19
+ const res = await instrumentation.T.trace(
20
+ context.target,
21
+ "debug",
22
+ async (span): Promise<Context> => {
23
+ try {
24
+ return await next(context);
25
+ } catch (err) {
26
+ if (err instanceof Error) span.recordError(err);
27
+ throw err;
28
+ }
29
+ },
30
+ );
31
+ log(context, instrumentation, null);
32
+ return res;
33
+ } catch (err) {
34
+ log(
35
+ context,
36
+ instrumentation,
37
+ err instanceof Error ? err : new Error(String(err)),
38
+ );
39
+ throw err;
40
+ }
30
41
  };
31
42
 
32
43
  const log = (
package/src/http.spec.ts CHANGED
@@ -30,28 +30,19 @@ const messageZ = z.object({
30
30
 
31
31
  describe("http", () => {
32
32
  test("echo", async () => {
33
- const [response, error] = await client.send<typeof messageZ>(
33
+ const response = await client.send(
34
34
  "/echo",
35
- {
36
- id: 1,
37
- message: "hello",
38
- },
35
+ { id: 1, message: "hello" },
39
36
  messageZ,
40
37
  messageZ,
41
38
  );
42
- expect(error).toBeNull();
43
39
  expect(response).toEqual({ id: 2, message: "hello" });
44
40
  });
45
41
 
46
42
  test("not found", async () => {
47
- const [response, error] = await client.send<typeof messageZ>(
48
- "/not-found",
49
- {},
50
- messageZ,
51
- messageZ,
43
+ await expect(client.send("/not-found", {}, messageZ, messageZ)).rejects.toThrow(
44
+ "Not Found",
52
45
  );
53
- expect(error?.message).toEqual("Not Found");
54
- expect(response).toBeNull();
55
46
  });
56
47
 
57
48
  test("middleware", async () => {
@@ -59,34 +50,17 @@ describe("http", () => {
59
50
  md.params.Test = "test";
60
51
  return await next(md);
61
52
  });
62
- const [response, error] = await client.send<typeof messageZ>(
63
- "/middlewareCheck",
64
- {},
65
- messageZ,
66
- messageZ,
67
- );
68
- expect(error).toBeNull();
69
- expect(response?.message).toEqual("");
53
+ const response = await client.send("/middlewareCheck", {}, messageZ, messageZ);
54
+ expect(response.message).toEqual("");
70
55
  });
71
56
 
72
57
  test("unreachable", async () => {
73
58
  const c = new HTTPClient(
74
- new URL({
75
- host: "127.0.0.1",
76
- protocol: "http",
77
- port: 9999,
78
- pathPrefix: "unary",
79
- }),
59
+ new URL({ host: "127.0.0.1", protocol: "http", port: 9999, pathPrefix: "unary" }),
80
60
  new binary.JSONCodec(),
81
61
  );
82
- const [response, error] = await c.send<typeof messageZ>(
83
- "/unreachable",
84
- {},
85
- messageZ,
86
- messageZ,
87
- );
88
- expect(error).toBeInstanceOf(Unreachable);
89
- expect(error?.message).toEqual("Unreachable");
90
- expect(response).toBeNull();
62
+ const send = c.send("/unreachable", {}, messageZ, messageZ);
63
+ await expect(send).rejects.toThrow(Unreachable);
64
+ await expect(send).rejects.toThrow("Unreachable");
91
65
  });
92
66
  });
package/src/http.ts CHANGED
@@ -86,20 +86,20 @@ export class HTTPClient extends MiddlewareCollector implements UnaryClient {
86
86
  req: z.input<RQ> | z.infer<RQ>,
87
87
  reqSchema: RQ,
88
88
  resSchema: RS,
89
- ): Promise<[z.infer<RS>, null] | [null, Error]> {
89
+ ): Promise<z.infer<RS>> {
90
90
  let res: z.infer<RS> | null = null;
91
91
  const url = this.endpoint.child(target);
92
92
  const request: RequestInit = {};
93
93
  request.method = "POST";
94
94
  request.body = this.encoder.encode(req, reqSchema) as BodyInit;
95
- const [, err] = await this.executeMiddleware(
95
+ await this.executeMiddleware(
96
96
  {
97
97
  target: url.toString(),
98
98
  protocol: this.endpoint.protocol,
99
99
  params: {},
100
100
  role: "client",
101
101
  },
102
- async (ctx: Context): Promise<[Context, Error | null]> => {
102
+ async (ctx: Context): Promise<Context> => {
103
103
  const outCtx: Context = { ...ctx, params: {} };
104
104
  request.headers = {
105
105
  ...this.headers,
@@ -110,34 +110,30 @@ export class HTTPClient extends MiddlewareCollector implements UnaryClient {
110
110
  httpRes = await fetch(ctx.target, request);
111
111
  } catch (e) {
112
112
  if (!(e instanceof Error)) throw e;
113
- return [outCtx, shouldCastToUnreachable(e) ? new Unreachable({ url }) : e];
113
+ throw shouldCastToUnreachable(e) ? new Unreachable({ url }) : e;
114
114
  }
115
115
  const data = await httpRes.arrayBuffer();
116
116
  if (httpRes?.ok) {
117
117
  if (resSchema != null) res = this.encoder.decode<RS>(data, resSchema);
118
- return [outCtx, null];
118
+ return outCtx;
119
119
  }
120
+ if (httpRes.status !== HTTP_STATUS_BAD_REQUEST)
121
+ throw new Error(httpRes.statusText);
122
+ let decoded: Error | null;
120
123
  try {
121
- if (httpRes.status !== HTTP_STATUS_BAD_REQUEST)
122
- return [outCtx, new Error(httpRes.statusText)];
123
- const err = this.encoder.decode(data, errors.payloadZ);
124
- const decoded = errors.decode(err);
125
- return [outCtx, decoded];
124
+ decoded = errors.decode(this.encoder.decode(data, errors.payloadZ));
126
125
  } catch (e) {
127
- return [
128
- outCtx,
129
- new Error(
130
- `[freighter] - failed to decode error: ${httpRes.statusText}: ${
131
- (e as Error).message
132
- }`,
133
- ),
134
- ];
126
+ if (!(e instanceof Error)) throw e;
127
+ throw new Error(
128
+ `[freighter] - failed to decode error: ${httpRes.statusText}: ${e.message}`,
129
+ { cause: e },
130
+ );
135
131
  }
132
+ throw decoded ?? new Error(httpRes.statusText);
136
133
  },
137
134
  );
138
135
 
139
- if (err != null) return [null, err];
140
136
  if (res == null) throw new Error("Response must be defined");
141
- return [res, null];
137
+ return res;
142
138
  }
143
139
  }
package/src/index.ts CHANGED
@@ -11,6 +11,6 @@ export { EOF, StreamClosed, Unreachable } from "@/errors";
11
11
  export { HTTPClient } from "@/http";
12
12
  export { type Context, type Middleware, type Next } from "@/middleware";
13
13
  export { type Stream, type StreamClient } from "@/stream";
14
- export { sendRequired, type UnaryClient, unaryWithBreaker } from "@/unary";
14
+ export { type UnaryClient, unaryWithBreaker } from "@/unary";
15
15
  export { WebSocketClient } from "@/websocket";
16
16
  export { type WebsocketMessage } from "@/websocket";
package/src/middleware.ts CHANGED
@@ -25,24 +25,28 @@ export interface Context {
25
25
  export const ROLES = ["client", "server"] as const;
26
26
  export type Role = (typeof ROLES)[number];
27
27
 
28
- /** Next executes the next middleware in the chain. */
29
- export type Next = (ctx: Context) => Promise<[Context, Error | null]>;
28
+ /**
29
+ * Next executes the next middleware in the chain, returning the resulting context. It
30
+ * throws if any downstream middleware or the finalizer throws.
31
+ */
32
+ export type Next = (ctx: Context) => Promise<Context>;
30
33
 
31
34
  /**
32
- * Middleware represents a general middleware function that can be used to
33
- * parse/attach metadata to a request or alter its behavior.
35
+ * Middleware represents a general middleware function that can be used to parse/attach
36
+ * metadata to a request or alter its behavior. It should call next to continue the
37
+ * chain and may throw to abort the request.
34
38
  */
35
- export type Middleware = (ctx: Context, next: Next) => Promise<[Context, Error | null]>;
39
+ export type Middleware = (ctx: Context, next: Next) => Promise<Context>;
36
40
 
37
41
  /**
38
- * Finalizer is a middleware that is executed as the last step in the chain.
39
- * Finalizer middleware should be used to execute the request.
42
+ * Finalizer is a middleware that is executed as the last step in the chain. Finalizer
43
+ * middleware should be used to execute the request. It throws if the request fails.
40
44
  */
41
- type Finalizer = (ctx: Context) => Promise<[Context, Error | null]>;
45
+ type Finalizer = (ctx: Context) => Promise<Context>;
42
46
 
43
47
  /**
44
- * MiddlewareCollector is a class that can be used to collect and execute
45
- * middleware in order to implement the Transport interface.
48
+ * MiddlewareCollector is a class that can be used to collect and execute middleware in
49
+ * order to implement the Transport interface.
46
50
  */
47
51
  export class MiddlewareCollector {
48
52
  middleware: Middleware[] = [];
@@ -53,20 +57,17 @@ export class MiddlewareCollector {
53
57
  }
54
58
 
55
59
  /**
56
- * Executes middleware in order, passing the the metadata to each middleware
57
- * until the end of the chain is reached. It then calls the finalizer with the
58
- * metadata.
60
+ * Executes middleware in order, passing the the metadata to each middleware until the
61
+ * end of the chain is reached. It then calls the finalizer with the metadata.
59
62
  *
60
63
  * @param ctx - The context to pass to the middleware.
61
64
  * @param finalizer - The finalizer to call with the metadata.
62
- * @returns An error if one was encountered, otherwise undefined.
65
+ * @returns The context produced by the chain. Throws if any middleware or the
66
+ * finalizer throws.
63
67
  */
64
- async executeMiddleware(
65
- ctx: Context,
66
- finalizer: Finalizer,
67
- ): Promise<[Context, Error | null]> {
68
+ async executeMiddleware(ctx: Context, finalizer: Finalizer): Promise<Context> {
68
69
  let i = 0;
69
- const next = async (md: Context): Promise<[Context, Error | null]> => {
70
+ const next = async (md: Context): Promise<Context> => {
70
71
  if (i === this.middleware.length) return await finalizer(md);
71
72
  const _mw = this.middleware[i];
72
73
  i++;