@synnaxlabs/freighter 0.2.0 → 0.6.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.
Files changed (175) hide show
  1. package/.eslintrc.cjs +18 -0
  2. package/LICENSE +4 -21
  3. package/dist/alamos.d.ts +3 -0
  4. package/{build/module/lib → dist}/errors.d.ts +35 -40
  5. package/dist/freighter.cjs.js +2 -0
  6. package/dist/freighter.cjs.js.map +1 -0
  7. package/dist/freighter.es.js +8460 -0
  8. package/dist/freighter.es.js.map +1 -0
  9. package/dist/http.d.ts +20 -0
  10. package/dist/index.d.ts +8 -0
  11. package/{build/module/lib → dist}/middleware.d.ts +11 -8
  12. package/{build/main/lib → dist}/stream.d.ts +11 -11
  13. package/{build/main/lib → dist}/transport.d.ts +2 -2
  14. package/dist/unary.d.ts +16 -0
  15. package/dist/websocket.d.ts +24 -0
  16. package/package.json +31 -99
  17. package/src/alamos.ts +40 -0
  18. package/src/errors.spec.ts +94 -0
  19. package/src/errors.ts +205 -0
  20. package/src/http.spec.ts +67 -0
  21. package/src/http.ts +115 -0
  22. package/src/index.ts +21 -20
  23. package/src/{lib/middleware.ts → middleware.ts} +29 -19
  24. package/src/{lib/stream.ts → stream.ts} +23 -14
  25. package/src/transport.ts +23 -0
  26. package/src/unary.ts +44 -0
  27. package/src/websocket.spec.ts +119 -0
  28. package/src/websocket.ts +203 -0
  29. package/tsconfig.json +5 -42
  30. package/tsconfig.vite.json +4 -0
  31. package/vite.config.ts +16 -0
  32. package/.editorconfig +0 -15
  33. package/.eslintrc.json +0 -33
  34. package/.gitignore +0 -9
  35. package/.nyc_output/3238f10e-9572-49ec-ab9d-28cbcaa6152a.json +0 -1
  36. package/.nyc_output/4e78a5c9-c0ca-4664-aa04-f478522608eb.json +0 -1
  37. package/.nyc_output/6a2244f2-5aea-45c7-8eeb-e14b454f0096.json +0 -1
  38. package/.nyc_output/dd1075a0-827b-4154-a75e-9bc90a4e16d0.json +0 -1
  39. package/.nyc_output/f829ad27-9bcd-4604-ae57-aae8c6f28d51.json +0 -1
  40. package/.nyc_output/fabc60f1-8fc5-4a1e-bea0-dc1fbcc31c9c.json +0 -1
  41. package/.nyc_output/processinfo/3238f10e-9572-49ec-ab9d-28cbcaa6152a.json +0 -1
  42. package/.nyc_output/processinfo/4e78a5c9-c0ca-4664-aa04-f478522608eb.json +0 -1
  43. package/.nyc_output/processinfo/6a2244f2-5aea-45c7-8eeb-e14b454f0096.json +0 -1
  44. package/.nyc_output/processinfo/dd1075a0-827b-4154-a75e-9bc90a4e16d0.json +0 -1
  45. package/.nyc_output/processinfo/f829ad27-9bcd-4604-ae57-aae8c6f28d51.json +0 -1
  46. package/.nyc_output/processinfo/fabc60f1-8fc5-4a1e-bea0-dc1fbcc31c9c.json +0 -1
  47. package/.nyc_output/processinfo/index.json +0 -1
  48. package/.prettierignore +0 -2
  49. package/.prettierrc +0 -3
  50. package/.vscode/settings.json +0 -4
  51. package/build/main/index.d.ts +0 -9
  52. package/build/main/index.js +0 -29
  53. package/build/main/lib/caseconv.d.ts +0 -2
  54. package/build/main/lib/caseconv.js +0 -14
  55. package/build/main/lib/encoder.d.ts +0 -59
  56. package/build/main/lib/encoder.js +0 -57
  57. package/build/main/lib/encoder.spec.d.ts +0 -1
  58. package/build/main/lib/encoder.spec.js +0 -26
  59. package/build/main/lib/errors.d.ts +0 -87
  60. package/build/main/lib/errors.js +0 -189
  61. package/build/main/lib/errors.spec.js +0 -88
  62. package/build/main/lib/http.d.ts +0 -50
  63. package/build/main/lib/http.js +0 -114
  64. package/build/main/lib/http.spec.js +0 -59
  65. package/build/main/lib/middleware.d.ts +0 -45
  66. package/build/main/lib/middleware.js +0 -38
  67. package/build/main/lib/runtime.d.ts +0 -5
  68. package/build/main/lib/runtime.js +0 -24
  69. package/build/main/lib/stream.js +0 -3
  70. package/build/main/lib/transport.js +0 -3
  71. package/build/main/lib/unary.d.ts +0 -15
  72. package/build/main/lib/unary.js +0 -3
  73. package/build/main/lib/url.d.ts +0 -38
  74. package/build/main/lib/url.js +0 -65
  75. package/build/main/lib/url.spec.d.ts +0 -1
  76. package/build/main/lib/url.spec.js +0 -41
  77. package/build/main/lib/util/log.d.ts +0 -2
  78. package/build/main/lib/util/log.js +0 -15
  79. package/build/main/lib/websocket.d.ts +0 -25
  80. package/build/main/lib/websocket.js +0 -172
  81. package/build/main/lib/websocket.spec.js +0 -86
  82. package/build/main/lib/ws.spec.d.ts +0 -1
  83. package/build/main/lib/ws.spec.js +0 -115
  84. package/build/module/index.d.ts +0 -9
  85. package/build/module/index.js +0 -7
  86. package/build/module/lib/caseconv.d.ts +0 -2
  87. package/build/module/lib/caseconv.js +0 -12
  88. package/build/module/lib/encoder.d.ts +0 -59
  89. package/build/module/lib/encoder.js +0 -47
  90. package/build/module/lib/encoder.spec.d.ts +0 -1
  91. package/build/module/lib/encoder.spec.js +0 -21
  92. package/build/module/lib/errors.js +0 -164
  93. package/build/module/lib/errors.spec.d.ts +0 -1
  94. package/build/module/lib/errors.spec.js +0 -85
  95. package/build/module/lib/http.d.ts +0 -50
  96. package/build/module/lib/http.js +0 -108
  97. package/build/module/lib/http.spec.d.ts +0 -1
  98. package/build/module/lib/http.spec.js +0 -54
  99. package/build/module/lib/middleware.js +0 -32
  100. package/build/module/lib/runtime.d.ts +0 -5
  101. package/build/module/lib/runtime.js +0 -21
  102. package/build/module/lib/stream.d.ts +0 -76
  103. package/build/module/lib/stream.js +0 -2
  104. package/build/module/lib/transport.d.ts +0 -13
  105. package/build/module/lib/transport.js +0 -2
  106. package/build/module/lib/unary.d.ts +0 -15
  107. package/build/module/lib/unary.js +0 -2
  108. package/build/module/lib/url.d.ts +0 -38
  109. package/build/module/lib/url.js +0 -65
  110. package/build/module/lib/url.spec.d.ts +0 -1
  111. package/build/module/lib/url.spec.js +0 -34
  112. package/build/module/lib/util/log.d.ts +0 -2
  113. package/build/module/lib/util/log.js +0 -11
  114. package/build/module/lib/websocket.d.ts +0 -25
  115. package/build/module/lib/websocket.js +0 -181
  116. package/build/module/lib/websocket.spec.d.ts +0 -1
  117. package/build/module/lib/websocket.spec.js +0 -82
  118. package/build/module/lib/ws.spec.d.ts +0 -1
  119. package/build/module/lib/ws.spec.js +0 -94
  120. package/build/tsconfig.module.tsbuildinfo +0 -1
  121. package/build/tsconfig.tsbuildinfo +0 -1
  122. package/coverage/base.css +0 -224
  123. package/coverage/block-navigation.js +0 -87
  124. package/coverage/caseconv.ts.html +0 -124
  125. package/coverage/encoder.ts.html +0 -403
  126. package/coverage/errors.ts.html +0 -727
  127. package/coverage/favicon.png +0 -0
  128. package/coverage/http.ts.html +0 -532
  129. package/coverage/index.html +0 -221
  130. package/coverage/lcov-report/base.css +0 -224
  131. package/coverage/lcov-report/block-navigation.js +0 -87
  132. package/coverage/lcov-report/caseconv.ts.html +0 -124
  133. package/coverage/lcov-report/encoder.ts.html +0 -403
  134. package/coverage/lcov-report/errors.ts.html +0 -727
  135. package/coverage/lcov-report/favicon.png +0 -0
  136. package/coverage/lcov-report/http.ts.html +0 -532
  137. package/coverage/lcov-report/index.html +0 -221
  138. package/coverage/lcov-report/middleware.ts.html +0 -286
  139. package/coverage/lcov-report/prettify.css +0 -1
  140. package/coverage/lcov-report/prettify.js +0 -2
  141. package/coverage/lcov-report/runtime.ts.html +0 -154
  142. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  143. package/coverage/lcov-report/sorter.js +0 -196
  144. package/coverage/lcov-report/url.ts.html +0 -322
  145. package/coverage/lcov-report/websocket.ts.html +0 -760
  146. package/coverage/lcov.info +0 -552
  147. package/coverage/middleware.ts.html +0 -286
  148. package/coverage/prettify.css +0 -1
  149. package/coverage/prettify.js +0 -2
  150. package/coverage/runtime.ts.html +0 -154
  151. package/coverage/sort-arrow-sprite.png +0 -0
  152. package/coverage/sorter.js +0 -196
  153. package/coverage/url.ts.html +0 -322
  154. package/coverage/websocket.ts.html +0 -760
  155. package/src/lib/caseconv.ts +0 -13
  156. package/src/lib/encoder.spec.ts +0 -23
  157. package/src/lib/encoder.ts +0 -105
  158. package/src/lib/errors.spec.ts +0 -98
  159. package/src/lib/errors.ts +0 -214
  160. package/src/lib/http.spec.ts +0 -85
  161. package/src/lib/http.ts +0 -149
  162. package/src/lib/runtime.ts +0 -23
  163. package/src/lib/transport.ts +0 -14
  164. package/src/lib/unary.ts +0 -21
  165. package/src/lib/url.spec.ts +0 -37
  166. package/src/lib/url.ts +0 -79
  167. package/src/lib/util/log.ts +0 -12
  168. package/src/lib/websocket.spec.ts +0 -106
  169. package/src/lib/websocket.ts +0 -225
  170. package/src/types/example.d.ts +0 -24
  171. package/tsconfig.module.json +0 -9
  172. package/yarn.lock +0 -5878
  173. /package/{build/main/lib → dist}/errors.spec.d.ts +0 -0
  174. /package/{build/main/lib → dist}/http.spec.d.ts +0 -0
  175. /package/{build/main/lib → dist}/websocket.spec.d.ts +0 -0
package/dist/http.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ import { type URL, type binary } from "@synnaxlabs/x";
2
+ import { type z } from "zod";
3
+ import { MiddlewareCollector } from './middleware';
4
+ import { type UnaryClient } from './unary';
5
+ export declare const CONTENT_TYPE_HEADER_KEY = "Content-Type";
6
+ /**
7
+ * HTTPClientFactory provides a POST and GET implementation of the Unary
8
+ * protocol.
9
+ *
10
+ * @param url - The base URL of the API.
11
+ * @param encoder - The encoder/decoder to use for the request/response.
12
+ */
13
+ export declare class HTTPClient extends MiddlewareCollector implements UnaryClient {
14
+ endpoint: URL;
15
+ encoder: binary.EncoderDecoder;
16
+ fetch: typeof fetch;
17
+ constructor(endpoint: URL, encoder: binary.EncoderDecoder, secure?: boolean);
18
+ get headers(): Record<string, string>;
19
+ send<RQ extends z.ZodTypeAny, RS extends z.ZodTypeAny = RQ>(target: string, req: z.input<RQ> | null, resSchema: RS | null): Promise<[z.output<RS> | null, Error | null]>;
20
+ }
@@ -0,0 +1,8 @@
1
+ export { BaseTypedError, decodeError, encodeError, EOF, errorZ, registerError, StreamClosed, Unreachable, } from './errors';
2
+ export type { ErrorPayload as ErrorPayload, TypedError } from './errors';
3
+ export { HTTPClient } from './http';
4
+ export type { Context as MetaData, Middleware, Next } from './middleware';
5
+ export type { Stream, StreamClient } from './stream';
6
+ export type { UnaryClient } from './unary';
7
+ export { sendRequired } from './unary';
8
+ export { WebSocketClient } from './websocket';
@@ -1,28 +1,31 @@
1
1
  /**
2
- * MetaData is the metadata associated with a freighter transport request.
2
+ * Context is the metadata associated with a freighter transport request.
3
3
  *
4
4
  * @property target - The target the request is being issued to.
5
5
  * @property protocol - The protocol used to issue the request.
6
6
  * @property params - Arbitrary string parameters that can be set by client side
7
7
  * middleware and read by server side middleware.
8
8
  */
9
- export declare type MetaData = {
9
+ export interface Context {
10
10
  target: string;
11
+ role: Role;
11
12
  protocol: string;
12
13
  params: Record<string, string>;
13
- };
14
+ }
15
+ export declare const ROLES: readonly ["client", "server"];
16
+ export type Role = (typeof ROLES)[number];
14
17
  /** Next executes the next middleware in the chain. */
15
- export declare type Next = (md: MetaData) => Promise<Error | undefined>;
18
+ export type Next = (ctx: Context) => Promise<[Context, Error | null]>;
16
19
  /**
17
20
  * Middleware represents a general middleware function that can be used to
18
21
  * parse/attach metadata to a request or alter its behavior.
19
22
  */
20
- export declare type Middleware = (md: MetaData, next: Next) => Promise<Error | undefined>;
23
+ export type Middleware = (ctx: Context, next: Next) => Promise<[Context, Error | null]>;
21
24
  /**
22
25
  * Finalizer is a middleware that is executed as the last step in the chain.
23
26
  * Finalizer middleware should be used to execute the request.
24
27
  */
25
- declare type Finalizer = (md: MetaData) => Promise<Error | undefined>;
28
+ type Finalizer = (ctx: Context) => Promise<[Context, Error | null]>;
26
29
  /**
27
30
  * MiddlewareCollector is a class that can be used to collect and execute
28
31
  * middleware in order to implement the Transport interface.
@@ -36,10 +39,10 @@ export declare class MiddlewareCollector {
36
39
  * until the end of the chain is reached. It then calls the finalizer with the
37
40
  * metadata.
38
41
  *
39
- * @param md - The metadata to pass to the middleware.
42
+ * @param ctx - The context to pass to the middleware.
40
43
  * @param finalizer - The finalizer to call with the metadata.
41
44
  * @returns An error if one was encountered, otherwise undefined.
42
45
  */
43
- executeMiddleware(md: MetaData, finalizer: Finalizer): Promise<Error | undefined>;
46
+ executeMiddleware(ctx: Context, finalizer: Finalizer): Promise<[Context, Error | null]>;
44
47
  }
45
48
  export {};
@@ -1,9 +1,9 @@
1
- import { ZodSchema } from 'zod';
2
- import { Transport } from './transport';
1
+ import { type z } from "zod";
2
+ import { type Transport } from './transport';
3
3
  /**
4
4
  * Interface for an entity that receives a stream of responses.
5
5
  */
6
- export interface StreamReceiver<RS> {
6
+ export interface StreamReceiver<RS extends z.ZodTypeAny> {
7
7
  /**
8
8
  * Receives a response from the stream. It's not safe to call receive
9
9
  * concurrently.
@@ -13,16 +13,16 @@ export interface StreamReceiver<RS> {
13
13
  * returns the error the server returned.
14
14
  * @raises Error: if the transport fails.
15
15
  */
16
- receive(): Promise<[RS | undefined, Error | undefined]>;
16
+ receive: () => Promise<[z.output<RS>, null] | [null, Error]>;
17
17
  /**
18
18
  * @returns true if the stream has received a response
19
19
  */
20
- received(): boolean;
20
+ received: () => boolean;
21
21
  }
22
22
  /**
23
23
  * Interface for an entity that sends a stream of requests.
24
24
  */
25
- export interface StreamSender<RQ> {
25
+ export interface StreamSender<RQ extends z.ZodTypeAny> {
26
26
  /**
27
27
  * Sends a request to the stream. It is not safe to call send concurrently
28
28
  * with closeSend or send.
@@ -34,13 +34,13 @@ export interface StreamSender<RQ> {
34
34
  * @raises freighter.StreamClosed: if the client called close_send()
35
35
  * @raises Error: if the transport fails.
36
36
  */
37
- send(req: RQ): Error | undefined;
37
+ send: (req: z.input<RQ>) => Error | null;
38
38
  }
39
39
  /**
40
40
  * Extension of the StreamSender interface that allows the client to close the sending
41
41
  * direction of the stream when finished issuing requrest.
42
42
  */
43
- export interface StreamSenderCloser<RQ> extends StreamSender<RQ> {
43
+ export interface StreamSenderCloser<RQ extends z.ZodTypeAny> extends StreamSender<RQ> {
44
44
  /**
45
45
  * Lets the server know no more messages will be sent. If the client attempts
46
46
  * to call send() after calling closeSend(), a freighter.StreamClosed
@@ -50,12 +50,12 @@ export interface StreamSenderCloser<RQ> extends StreamSender<RQ> {
50
50
  * After calling close_send, the client is responsible for calling receive()
51
51
  * to successfully receive the server's acknowledgement.
52
52
  */
53
- closeSend(): void;
53
+ closeSend: () => void;
54
54
  }
55
55
  /**
56
56
  * Interface for a bidirectional stream between a client and a server.
57
57
  */
58
- export interface Stream<RQ, RS> extends StreamSenderCloser<RQ>, StreamReceiver<RS> {
58
+ export interface Stream<RQ extends z.ZodTypeAny, RS extends z.ZodTypeAny = RQ> extends StreamSenderCloser<RQ>, StreamReceiver<RS> {
59
59
  }
60
60
  /**
61
61
  * Interface for a bidirectional stream between a client and a server.
@@ -72,5 +72,5 @@ export interface StreamClient extends Transport {
72
72
  * @param resSchema - The schema for the response type. This is used to
73
73
  * validate the response before returning it.
74
74
  */
75
- stream<RQ, RS>(target: string, reqSchema: ZodSchema<RQ>, resSchema: ZodSchema<RS>): Promise<Stream<RQ, RS>>;
75
+ stream: <RQ extends z.ZodTypeAny, RS extends z.ZodTypeAny = RQ>(target: string, reqSchema: RQ, resSchema: RS) => Promise<Stream<RQ, RS>>;
76
76
  }
@@ -1,4 +1,4 @@
1
- import { Middleware } from './middleware';
1
+ import { type Middleware } from './middleware';
2
2
  /**
3
3
  * Transport is a based interface that represents a general transport for
4
4
  * exchanging messages between a client and a server.
@@ -9,5 +9,5 @@ export interface Transport {
9
9
  *
10
10
  * @param mw - The middleware to register.
11
11
  */
12
- use(...mw: Middleware[]): void;
12
+ use: (...mw: Middleware[]) => void;
13
13
  }
@@ -0,0 +1,16 @@
1
+ import { type z } from "zod";
2
+ import { type Transport } from './transport';
3
+ /**
4
+ * An interface for an entity that implements a simple request-response
5
+ * transport between two entities.
6
+ */
7
+ export interface UnaryClient extends Transport {
8
+ /**
9
+ * Sends a request to the target server and waits until a response is received.
10
+ * @param target - The target server to send the request to.
11
+ * @param req - The request to send.
12
+ * @param resSchema - The schema to validate the response against.
13
+ */
14
+ send: <RQ extends z.ZodTypeAny, RS extends z.ZodTypeAny = RQ>(target: string, req: z.input<RQ> | null, resSchema: RS | null) => Promise<[z.output<RS>, null] | [null, Error]>;
15
+ }
16
+ export declare const sendRequired: <RQ extends z.ZodTypeAny, RS extends z.ZodTypeAny = RQ>(client: UnaryClient, target: string, req: z.input<RQ> | z.output<RQ>, resSchema: RS | null) => Promise<z.output<RS>>;
@@ -0,0 +1,24 @@
1
+ import { type URL, type binary } from "@synnaxlabs/x";
2
+ import { z } from "zod";
3
+ import { MiddlewareCollector } from './middleware';
4
+ import type { Stream, StreamClient } from './stream';
5
+ export declare const FREIGHTER_METADATA_PREFIX = "freighterctx";
6
+ /**
7
+ * WebSocketClient is an implementation of StreamClient that is backed by
8
+ * websockets.
9
+ */
10
+ export declare class WebSocketClient extends MiddlewareCollector implements StreamClient {
11
+ baseUrl: URL;
12
+ encoder: binary.EncoderDecoder;
13
+ static readonly MESSAGE_TYPE = "arraybuffer";
14
+ /**
15
+ * @param encoder - The encoder to use for encoding messages and decoding
16
+ * responses.
17
+ * @param baseEndpoint - A base url to use as a prefix for all requests.
18
+ */
19
+ constructor(baseEndpoint: URL, encoder: binary.EncoderDecoder, secure?: boolean);
20
+ /** Implements the StreamClient interface. */
21
+ stream<RQ extends z.ZodTypeAny, RS extends z.ZodTypeAny = RQ>(target: string, reqSchema: RQ, resSchema: RS): Promise<Stream<RQ, RS>>;
22
+ private buildURL;
23
+ private wrapSocket;
24
+ }
package/package.json CHANGED
@@ -1,119 +1,51 @@
1
1
  {
2
2
  "name": "@synnaxlabs/freighter",
3
- "version": "0.2.0",
3
+ "private": false,
4
+ "version": "0.6.0",
5
+ "type": "module",
4
6
  "description": "a modular transport abstraction",
5
- "main": "build/main/index.js",
6
- "typings": "build/main/index.d.ts",
7
- "module": "build/module/index.js",
8
- "repository": "https://github.com/synnaxlabs/synnax",
9
- "license": "MIT",
7
+ "repository": "https://github.com/synnaxlabs/synnax/tree/main/freighter/ts",
8
+ "licens": "MIT",
10
9
  "keywords": [
11
10
  "synnax",
12
11
  "grpc",
13
12
  "transport",
14
- "client",
15
13
  "data acquisition",
16
14
  "big data",
17
15
  "telemetry",
18
16
  "control systems"
19
17
  ],
20
- "scripts": {
21
- "build": "run-p build:*",
22
- "build:main": "tsc -p tsconfig.json",
23
- "build:module": "tsc -p tsconfig.module.json",
24
- "fix": "run-s fix:*",
25
- "fix:prettier": "prettier \"src/**/*.ts\" --write",
26
- "fix:lint": "eslint src --ext .ts --fix",
27
- "test": "run-s build test:*",
28
- "test:lint": "eslint src --ext .ts",
29
- "test:prettier": "prettier \"src/**/*.ts\" --list-different",
30
- "test:unit": "nyc --silent ava",
31
- "check-cli": "run-s test diff-integration-tests check-integration-tests",
32
- "check-integration-tests": "run-s check-integration-test:*",
33
- "diff-integration-tests": "mkdir -p diff && rm -rf diff/test && cp -r test diff/test && rm -rf diff/test/test-*/.git && cd diff && git init --quiet && git add -A && git commit --quiet --no-verify --allow-empty -m 'WIP' && echo '\\n\\nCommitted most recent integration test output in the \"diff\" directory. Review the changes with \"cd diff && git diff HEAD\" or your preferred git diff viewer.'",
34
- "watch:build": "tsc -p tsconfig.json -w",
35
- "watch:test": "nyc --silent ava --watch",
36
- "cov": "run-s build test:unit cov:html cov:lcov",
37
- "cov:html": "nyc report --reporter=html",
38
- "cov:lcov": "nyc report --reporter=lcov",
39
- "cov:send": "run-s cov:lcov && codecov",
40
- "cov:check": "nyc report && nyc check-coverage --lines 100 --functions 100 --branches 100",
41
- "doc": "run-s doc:html && open-cli build/docs/index.html",
42
- "doc:html": "typedoc src/ --exclude **/*.spec.ts --target ES6 --mode file --out build/docs",
43
- "doc:json": "typedoc src/ --exclude **/*.spec.ts --target ES6 --mode file --json build/docs/typedoc.json",
44
- "doc:publish": "gh-pages -m \"[ci skip] Updates\" -d build/docs",
45
- "version": "standard-version",
46
- "reset-hard": "git clean -dfx && git reset --hard && yarn",
47
- "prepare-release": "run-s reset-hard test cov:check doc:html version doc:publish"
48
- },
49
18
  "engines": {
50
- "node": ">=10"
19
+ "node": ">=18"
51
20
  },
52
21
  "dependencies": {
53
- "@bitauth/libauth": "^1.17.1",
54
- "axios": "^0.27.2",
55
22
  "js-convert-case": "^4.2.0",
56
- "msgpackr": "^1.7.0",
57
- "prettier-plugin-jsdoc": "^0.4.2",
58
- "ws": "^8.8.1",
59
- "zod": "^3.19.1"
23
+ "msgpackr": "^1.10.0",
24
+ "node-fetch": "2.6.11",
25
+ "ws": "^8.15.1",
26
+ "zod": "3.22.4",
27
+ "@synnaxlabs/alamos": "0.1.0",
28
+ "@synnaxlabs/x": "0.9.0"
60
29
  },
61
30
  "devDependencies": {
62
- "@ava/typescript": "^1.1.1",
63
- "@istanbuljs/nyc-config-typescript": "^1.0.1",
64
- "@typescript-eslint/eslint-plugin": "^4.0.1",
65
- "@typescript-eslint/parser": "^4.0.1",
66
- "ava": "^3.12.1",
67
- "codecov": "^3.5.0",
68
- "cspell": "^4.1.0",
69
- "cz-conventional-changelog": "^3.3.0",
70
- "eslint": "^7.8.0",
71
- "eslint-config-prettier": "^6.11.0",
72
- "eslint-plugin-eslint-comments": "^3.2.0",
73
- "eslint-plugin-import": "^2.22.0",
74
- "gh-pages": "^3.1.0",
75
- "npm-run-all": "^4.1.5",
76
- "nyc": "^15.1.0",
77
- "open-cli": "^6.0.1",
78
- "prettier": "^2.7.1",
79
- "standard-version": "^9.0.0",
80
- "ts-node": "^9.0.0",
81
- "typedoc": "^0.19.0",
82
- "typescript": "^4.0.2"
83
- },
84
- "files": [
85
- "build/main",
86
- "build/module",
87
- "!**/*.spec.*",
88
- "!**/*.json",
89
- "CHANGELOG.md",
90
- "LICENSE",
91
- "README.md"
92
- ],
93
- "ava": {
94
- "failFast": true,
95
- "timeout": "60s",
96
- "typescript": {
97
- "rewritePaths": {
98
- "src/": "build/main/"
99
- }
100
- },
101
- "files": [
102
- "!build/module/**"
103
- ]
31
+ "@types/node": "^20.10.5",
32
+ "@vitest/coverage-v8": "^1.2.2",
33
+ "typescript": "^5.3.3",
34
+ "vite": "^5.1.2",
35
+ "vitest": "^1.2.2",
36
+ "@synnaxlabs/vite-plugin": "0.0.1",
37
+ "@synnaxlabs/tsconfig": "0.0.1",
38
+ "eslint-config-synnaxlabs": "0.0.1"
104
39
  },
105
- "config": {
106
- "commitizen": {
107
- "path": "cz-conventional-changelog"
108
- }
109
- },
110
- "prettier": {
111
- "singleQuote": true
112
- },
113
- "nyc": {
114
- "extends": "@istanbuljs/nyc-config-typescript",
115
- "exclude": [
116
- "**/*.spec.js"
117
- ]
40
+ "main": "dist/freighter.cjs.js",
41
+ "module": "dist/freighter.es.js",
42
+ "types": "dist/index.d.ts",
43
+ "scripts": {
44
+ "build": "tsc --noEmit && vite build",
45
+ "watch": "tsc --noEmit && vite build --watch",
46
+ "test": "vitest",
47
+ "cov": "vitest --coverage",
48
+ "lint": "eslint \"src/**/*.ts*\"",
49
+ "fix": "eslint \"src/**/*.ts*\" --fix"
118
50
  }
119
- }
51
+ }
package/src/alamos.ts ADDED
@@ -0,0 +1,40 @@
1
+ // Copyright 2023 Synnax Labs, Inc.
2
+ //
3
+ // Use of this software is governed by the Business Source License included in the file
4
+ // licenses/BSL.txt.
5
+ //
6
+ // As of the Change Date specified in that file, in accordance with the Business Source
7
+ // License, use of this software will be governed by the Apache License, Version 2.0,
8
+ // included in the file licenses/APL.txt.
9
+
10
+ import { type Instrumentation } from "@synnaxlabs/alamos";
11
+
12
+ import { type Middleware, type Context } from "@/middleware";
13
+
14
+ export const middleware =
15
+ (instrumentation: Instrumentation): Middleware =>
16
+ async (context, next) => {
17
+ if (context.role === "client") instrumentation.T.propagate(context.params);
18
+ const [res, exc] = await instrumentation.T.trace(
19
+ context.target,
20
+ "debug",
21
+ async (span): Promise<[Context, Error | null]> => {
22
+ const [ctx, err] = await next(context);
23
+ if (err != null) span.recordError(err);
24
+ return [ctx, err];
25
+ },
26
+ );
27
+ log(context, instrumentation, exc);
28
+ return [res, exc];
29
+ };
30
+
31
+ const log = (
32
+ context: Context,
33
+ instrumentation: Instrumentation,
34
+ err: Error | null,
35
+ ): void =>
36
+ err != null
37
+ ? instrumentation.L.error(
38
+ `${context.target} ${context.protocol} failed: ${err.message}`,
39
+ )
40
+ : instrumentation.L.debug(`${context.target} ${context.protocol}`);
@@ -0,0 +1,94 @@
1
+ // Copyright 2023 Synnax Labs, Inc.
2
+ //
3
+ // Use of this software is governed by the Business Source License included in the file
4
+ // licenses/BSL.txt.
5
+ //
6
+ // As of the Change Date specified in that file, in accordance with the Business Source
7
+ // License, use of this software will be governed by the Apache License, Version 2.0,
8
+ // included in the file licenses/APL.txt.
9
+
10
+ import { describe, expect, test } from "vitest";
11
+
12
+ import {
13
+ BaseTypedError,
14
+ EOF,
15
+ FREIGHTER,
16
+ NONE,
17
+ StreamClosed,
18
+ type TypedError,
19
+ UNKNOWN,
20
+ UnknownError,
21
+ Unreachable,
22
+ assertErrorType,
23
+ decodeError,
24
+ encodeError,
25
+ isTypedError,
26
+ registerError,
27
+ type ErrorPayload,
28
+ } from "@/errors";
29
+
30
+ class MyCustomError extends BaseTypedError {
31
+ constructor(message: string) {
32
+ super(message, "MyCustomError");
33
+ }
34
+ }
35
+
36
+ const myCustomErrorEncoder = (error: MyCustomError): ErrorPayload => {
37
+ return { type: "MyCustomError", data: error.message };
38
+ };
39
+
40
+ const myCustomErrorDecoder = (encoded: ErrorPayload): TypedError => {
41
+ return new MyCustomError(encoded.data);
42
+ };
43
+
44
+ describe("errors", () => {
45
+ test("isTypedError", () => {
46
+ const error = new MyCustomError("test");
47
+ const fError = isTypedError(error);
48
+ expect(fError).toBeTruthy();
49
+ expect(error.type).toEqual("MyCustomError");
50
+ });
51
+
52
+ test("encoding and decoding a custom error through registry", () => {
53
+ registerError({
54
+ encode: myCustomErrorEncoder,
55
+ decode: myCustomErrorDecoder,
56
+ });
57
+ const error = new MyCustomError("test");
58
+ const encoded = encodeError(error);
59
+ expect(encoded.type).toEqual("MyCustomError");
60
+ expect(encoded.data).toEqual("test");
61
+ const decoded = assertErrorType<MyCustomError>(
62
+ "MyCustomError",
63
+ decodeError(encoded),
64
+ );
65
+ expect(decoded.message).toEqual("test");
66
+ });
67
+
68
+ test("encoding and decoding a null error", () => {
69
+ const encoded = encodeError(null);
70
+ expect(encoded.type).toEqual(NONE);
71
+ expect(encoded.data).toEqual("");
72
+ const decoded = decodeError(encoded);
73
+ expect(decoded).toBeNull();
74
+ });
75
+
76
+ test("encoding and decoding an unrecognized error", () => {
77
+ const error = new Error("test");
78
+ const encoded = encodeError(error);
79
+ expect(encoded.type).toEqual(UNKNOWN);
80
+ expect(encoded.data).toEqual("{}");
81
+ const decoded = decodeError(encoded);
82
+ expect(decoded).toEqual(new UnknownError("{}"));
83
+ });
84
+
85
+ test("encoding and decoding freighter errors", () => {
86
+ [new EOF(), new StreamClosed(), new Unreachable()].forEach((error) => {
87
+ const encoded = encodeError(error);
88
+ expect(encoded.type).toEqual(FREIGHTER);
89
+ expect(encoded.data).toEqual(error.message);
90
+ const decoded = decodeError(encoded);
91
+ expect(decoded).toEqual(error);
92
+ });
93
+ });
94
+ });