@synnaxlabs/freighter 0.43.0 → 0.44.1

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/http.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import { binary, URL } from '@synnaxlabs/x';
2
- import { z } from 'zod/v4';
2
+ import { z } from 'zod';
3
3
  import { MiddlewareCollector } from './middleware';
4
4
  import { UnaryClient } from './unary';
5
5
  export declare const CONTENT_TYPE_HEADER_KEY = "Content-Type";
6
+ export declare const shouldCastToUnreachable: (err: Error) => boolean;
6
7
  /**
7
8
  * HTTPClientFactory provides a POST and GET implementation of the Unary
8
9
  * protocol.
@@ -13,7 +14,6 @@ export declare const CONTENT_TYPE_HEADER_KEY = "Content-Type";
13
14
  export declare class HTTPClient extends MiddlewareCollector implements UnaryClient {
14
15
  endpoint: URL;
15
16
  encoder: binary.Codec;
16
- fetch: typeof fetch;
17
17
  constructor(endpoint: URL, encoder: binary.Codec, secure?: boolean);
18
18
  get headers(): Record<string, string>;
19
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]>;
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,MAAM,EAAmB,KAAK,GAAG,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,QAAQ,CAAC;AAGhC,OAAO,EAAgB,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,eAAO,MAAM,uBAAuB,iBAAiB,CAAC;AAoBtD;;;;;;GAMG;AACH,qBAAa,UAAW,SAAQ,mBAAoB,YAAW,WAAW;IACxE,QAAQ,EAAE,GAAG,CAAC;IACd,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC;IACtB,KAAK,EAAE,OAAO,KAAK,CAAC;gBAER,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAE,OAAe;IAczE,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;CAyDhD"}
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;CAuDhD"}
package/dist/stream.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { z } from 'zod/v4';
1
+ import { z } from 'zod';
2
2
  import { Transport } from './transport';
3
3
  /**
4
4
  * Interface for an entity that receives a stream of responses.
@@ -1 +1 @@
1
- {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,QAAQ,CAAC;AAEhC,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,EAC5B,cAAc,CAAC,EAAE,CAAC;CAAG;AAEzB;;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;;;;;;;;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,EAC5B,cAAc,CAAC,EAAE,CAAC;CAAG;AAEzB;;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"}
package/dist/unary.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { breaker } from '@synnaxlabs/x';
2
- import { z } from 'zod/v4';
2
+ import { z } from 'zod';
3
3
  import { Transport } from './transport';
4
4
  /**
5
5
  * An interface for an entity that implements a simple request-response
@@ -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,QAAQ,CAAC;AAIhC,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,WA4BF,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;;;;;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,5 +1,5 @@
1
1
  import { binary, errors, URL } from '@synnaxlabs/x';
2
- import { z } from 'zod/v4';
2
+ import { z } from 'zod';
3
3
  import { MiddlewareCollector } from './middleware';
4
4
  import { Stream, StreamClient } from './stream';
5
5
  export type WebsocketMessage<P = unknown> = {
@@ -1 +1 @@
1
- {"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"AASA,OAAO,EACL,KAAK,MAAM,EAEX,MAAM,EAEN,KAAK,GAAG,EACT,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAI3B,OAAO,EAAgB,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAc1D,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;AA+GF,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;IAmB1B,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;AA+GF,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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synnaxlabs/freighter",
3
- "version": "0.43.0",
3
+ "version": "0.44.1",
4
4
  "type": "module",
5
5
  "description": "a modular transport abstraction",
6
6
  "repository": "https://github.com/synnaxlabs/synnax/tree/main/freighter/ts",
@@ -14,23 +14,21 @@
14
14
  "control systems"
15
15
  ],
16
16
  "dependencies": {
17
- "node-fetch": "^2.7.0",
18
- "ws": "^8.18.2",
19
- "zod": "^3.25.63",
20
- "@synnaxlabs/alamos": "0.43.0",
21
- "@synnaxlabs/x": "0.43.0"
17
+ "zod": "^4.0.2",
18
+ "@synnaxlabs/alamos": "^0.44.1",
19
+ "@synnaxlabs/x": "^0.44.3"
22
20
  },
23
21
  "devDependencies": {
24
- "@types/node": "^24.0.1",
25
- "@vitest/coverage-v8": "^3.2.3",
26
- "eslint": "^9.28.0",
22
+ "@types/node": "^24.0.12",
23
+ "@vitest/coverage-v8": "^3.2.4",
24
+ "eslint": "^9.30.1",
27
25
  "madge": "^8.0.0",
28
26
  "typescript": "^5.8.3",
29
- "vite": "^6.3.5",
30
- "vitest": "^3.2.3",
31
- "@synnaxlabs/tsconfig": "0.0.2",
32
- "@synnaxlabs/vite-plugin": "0.43.0",
33
- "eslint-config-synnaxlabs": "0.43.0"
27
+ "vite": "^7.0.4",
28
+ "vitest": "^3.2.4",
29
+ "eslint-config-synnaxlabs": "^0.43.0",
30
+ "@synnaxlabs/vite-plugin": "^0.43.0",
31
+ "@synnaxlabs/tsconfig": "^0.43.0"
34
32
  },
35
33
  "main": "dist/freighter.cjs",
36
34
  "module": "dist/freighter.js",
@@ -40,8 +38,8 @@
40
38
  "check-types": "tsc --noEmit",
41
39
  "watch": "tsc --noEmit && vite build --watch",
42
40
  "test": "vitest",
43
- "lint": "eslint --cache",
44
- "fix": "eslint --cache --fix",
41
+ "lint": "eslint",
42
+ "fix": "eslint --fix",
45
43
  "madge": "madge --circular src"
46
44
  }
47
45
  }
package/src/http.spec.ts CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  import { binary, URL } from "@synnaxlabs/x";
11
11
  import { describe, expect, test } from "vitest";
12
- import { z } from "zod/v4";
12
+ import { z } from "zod";
13
13
 
14
14
  import { Unreachable } from "@/errors";
15
15
  import { HTTPClient } from "@/http";
package/src/http.ts CHANGED
@@ -7,8 +7,8 @@
7
7
  // License, use of this software will be governed by the Apache License, Version 2.0,
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
- import { type binary, errors, runtime, type URL } from "@synnaxlabs/x";
11
- import { type z } from "zod/v4";
10
+ import { type binary, errors, type URL } from "@synnaxlabs/x";
11
+ import { type z } from "zod";
12
12
 
13
13
  import { Unreachable } from "@/errors";
14
14
  import { type Context, MiddlewareCollector } from "@/middleware";
@@ -16,21 +16,38 @@ import { type UnaryClient } from "@/unary";
16
16
 
17
17
  export const CONTENT_TYPE_HEADER_KEY = "Content-Type";
18
18
 
19
- const resolveFetchAPI = (protocol: "http" | "https"): typeof fetch => {
20
- if (runtime.RUNTIME !== "node") return fetch;
21
- // eslint-disable-next-line @typescript-eslint/no-require-imports
22
- const _fetch: typeof fetch = require("node-fetch");
23
- if (protocol === "http") return _fetch;
24
- // eslint-disable-next-line @typescript-eslint/no-require-imports
25
- const https = require("https");
26
- const agent = new https.Agent({ rejectUnauthorized: false });
27
- // @ts-expect-error - TS doesn't know about qhis option
28
- return async (info, init) => await _fetch(info, { ...init, agent });
29
- };
19
+ const UNREACHABLE_CODES = new Set([
20
+ "ECONNREFUSED",
21
+ "ECONNRESET",
22
+ "ETIMEDOUT",
23
+ "EPIPE",
24
+ "UND_ERR_CONNECT_TIMEOUT",
25
+ "UND_ERR_SOCKET",
26
+ ]);
27
+
28
+ export const shouldCastToUnreachable = (err: Error): boolean => {
29
+ // First try Node/Undici codes
30
+ const code = (err as any)?.cause?.code ?? (err as any)?.code ?? (err as any)?.errno;
31
+ if (typeof code === "string" && UNREACHABLE_CODES.has(code)) return true;
32
+
33
+ // Browser/Safari fallback: detect canonical network-failure TypeError messages
34
+ if (err.name === "TypeError") {
35
+ const msg = String(err.message || "").toLowerCase();
36
+ if (/load failed|failed to fetch|networkerror|network error/.test(msg)) {
37
+ // Optionally gate on being online:
38
+ if (typeof navigator !== "undefined" && navigator.onLine === false) return true;
39
+ // If you want to be conservative, return false here and treat generically.
40
+ // If you want parity with Node for user messaging, you can return true.
41
+ return true;
42
+ }
43
+ }
30
44
 
31
- const shouldCastToUnreachable = (err: Error): boolean =>
32
- ("code" in err && err.code === "ECONNREFUSED") ||
33
- err.message.toLowerCase().includes("load failed");
45
+ // Abort should not be "unreachable"
46
+ if ((err as any)?.name === "AbortError" || (err as any)?.code === "ABORT_ERR")
47
+ return false;
48
+
49
+ return false;
50
+ };
34
51
 
35
52
  const HTTP_STATUS_BAD_REQUEST = 400;
36
53
 
@@ -44,13 +61,11 @@ const HTTP_STATUS_BAD_REQUEST = 400;
44
61
  export class HTTPClient extends MiddlewareCollector implements UnaryClient {
45
62
  endpoint: URL;
46
63
  encoder: binary.Codec;
47
- fetch: typeof fetch;
48
64
 
49
65
  constructor(endpoint: URL, encoder: binary.Codec, secure: boolean = false) {
50
66
  super();
51
67
  this.endpoint = endpoint.replace({ protocol: secure ? "https" : "http" });
52
68
  this.encoder = encoder;
53
- this.fetch = resolveFetchAPI(this.endpoint.protocol as "http" | "https");
54
69
 
55
70
  return new Proxy(this, {
56
71
  get: (target, prop, receiver) => {
@@ -93,12 +108,10 @@ export class HTTPClient extends MiddlewareCollector implements UnaryClient {
93
108
  };
94
109
  let httpRes: Response;
95
110
  try {
96
- const f = resolveFetchAPI(ctx.protocol as "http" | "https");
97
- httpRes = await f(ctx.target, request);
98
- } catch (err_) {
99
- let err = err_ as Error;
100
- if (shouldCastToUnreachable(err)) err = new Unreachable({ url });
101
- return [outCtx, err];
111
+ httpRes = await fetch(ctx.target, request);
112
+ } catch (e) {
113
+ if (!(e instanceof Error)) throw e;
114
+ return [outCtx, shouldCastToUnreachable(e) ? new Unreachable({ url }) : e];
102
115
  }
103
116
  const data = await httpRes.arrayBuffer();
104
117
  if (httpRes?.ok) {
package/src/stream.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  // License, use of this software will be governed by the Apache License, Version 2.0,
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
- import { type z } from "zod/v4";
10
+ import { type z } from "zod";
11
11
 
12
12
  import { type Transport } from "@/transport";
13
13
 
package/src/unary.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
10
  import { breaker } from "@synnaxlabs/x";
11
- import { type z } from "zod/v4";
11
+ import { type z } from "zod";
12
12
 
13
13
  import { Unreachable } from "@/errors";
14
14
  import { type Middleware } from "@/middleware";
@@ -59,6 +59,7 @@ export const unaryWithBreaker = (
59
59
  const [res, err] = await this.wrapped.send(target, req, reqSchema, resSchema);
60
60
  if (err == null) return [res, null];
61
61
  if (!Unreachable.matches(err)) return [null, err];
62
+ console.warn(`[freighter] ${brk.retryMessage}`, err);
62
63
  if (!(await brk.wait())) return [res, err];
63
64
  } while (true);
64
65
  }
@@ -9,7 +9,7 @@
9
9
 
10
10
  import { binary, errors, URL } from "@synnaxlabs/x";
11
11
  import { describe, expect, test } from "vitest";
12
- import { z } from "zod/v4";
12
+ import { z } from "zod";
13
13
 
14
14
  import { EOF } from "@/errors";
15
15
  import { type Context } from "@/middleware";
package/src/websocket.ts CHANGED
@@ -7,26 +7,14 @@
7
7
  // License, use of this software will be governed by the Apache License, Version 2.0,
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
- import {
11
- type binary,
12
- buildQueryString,
13
- errors,
14
- runtime,
15
- type URL,
16
- } from "@synnaxlabs/x";
17
- import { z } from "zod/v4";
10
+ import { type binary, buildQueryString, errors, type URL } from "@synnaxlabs/x";
11
+ import { z } from "zod";
18
12
 
19
13
  import { EOF, StreamClosed } from "@/errors";
20
14
  import { CONTENT_TYPE_HEADER_KEY } from "@/http";
21
15
  import { type Context, MiddlewareCollector } from "@/middleware";
22
16
  import { type Stream, type StreamClient } from "@/stream";
23
17
 
24
- const resolveWebSocketConstructor = (): ((target: string) => WebSocket) => {
25
- if (runtime.RUNTIME !== "node") return (t) => new WebSocket(t);
26
- // eslint-disable-next-line @typescript-eslint/no-require-imports
27
- return (t) => new (require("ws").WebSocket)(t, { rejectUnauthorized: false });
28
- };
29
-
30
18
  const wsMessageZ = z.object({
31
19
  type: z.enum(["data", "close", "open"]),
32
20
  payload: z.unknown(),
@@ -187,12 +175,11 @@ export class WebSocketClient extends MiddlewareCollector implements StreamClient
187
175
  reqSchema: RQ,
188
176
  resSchema: RS,
189
177
  ): Promise<Stream<RQ, RS>> {
190
- const SocketConstructor = resolveWebSocketConstructor();
191
178
  let stream: Stream<RQ, RS> | undefined;
192
179
  const [, error] = await this.executeMiddleware(
193
180
  { target, protocol: "websocket", params: {}, role: "client" },
194
181
  async (ctx: Context): Promise<[Context, Error | null]> => {
195
- const ws = SocketConstructor(this.buildURL(target, ctx));
182
+ const ws = new WebSocket(this.buildURL(target, ctx));
196
183
  const outCtx: Context = { ...ctx, params: {} };
197
184
  ws.binaryType = WebSocketClient.MESSAGE_TYPE;
198
185
  const streamOrErr = await this.wrapSocket(ws, reqSchema, resSchema);