@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
@@ -1,14 +0,0 @@
1
- import { Middleware } from './middleware';
2
-
3
- /**
4
- * Transport is a based interface that represents a general transport for
5
- * exchanging messages between a client and a server.
6
- */
7
- export interface Transport {
8
- /**
9
- * Use registers middleware that will be executed in order when the transport
10
- *
11
- * @param mw - The middleware to register.
12
- */
13
- use(...mw: Middleware[]): void;
14
- }
package/src/lib/unary.ts DELETED
@@ -1,21 +0,0 @@
1
- import { ZodSchema } from 'zod';
2
-
3
- import { Transport } from './transport';
4
-
5
- /**
6
- * An interface for an entity that implements a simple request-response
7
- * transport between two entities.
8
- */
9
- export interface UnaryClient extends Transport {
10
- /**
11
- * Sends a request to the target server and waits until a response is received.
12
- * @param target - The target server to send the request to.
13
- * @param req - The request to send.
14
- * @param resSchema - The schema to validate the response against.
15
- */
16
- send<RQ, RS>(
17
- target: string,
18
- req: RQ,
19
- resSchema: ZodSchema<RS>
20
- ): Promise<[RS | undefined, Error | undefined]>;
21
- }
@@ -1,37 +0,0 @@
1
- import test from 'ava';
2
-
3
- import URL from './url';
4
-
5
- test('URL - child', (t) => {
6
- const endpoint = new URL({
7
- host: 'localhost',
8
- port: 8080,
9
- protocol: 'http',
10
- pathPrefix: 'api',
11
- });
12
- t.is(endpoint.child('test').stringify(), 'http://localhost:8080/api/test');
13
- });
14
-
15
- test('URL - child with trailing slash', (t) => {
16
- const endpoint = new URL({
17
- host: 'localhost',
18
- port: 8080,
19
- protocol: 'http',
20
- pathPrefix: 'api',
21
- });
22
- const child = endpoint.child('test/');
23
- t.is(child.stringify(), 'http://localhost:8080/api/test');
24
- });
25
-
26
- test('URL - replacing protocol', (t) => {
27
- const endpoint = new URL({
28
- host: 'localhost',
29
- port: 8080,
30
- protocol: 'http',
31
- pathPrefix: 'api',
32
- });
33
- t.is(
34
- endpoint.child('test').replace({ protocol: 'https' }).stringify(),
35
- 'https://localhost:8080/api/test'
36
- );
37
- });
package/src/lib/url.ts DELETED
@@ -1,79 +0,0 @@
1
- type URLProps = {
2
- host: string;
3
- port: number;
4
- protocol?: string;
5
- pathPrefix?: string;
6
- params?: string;
7
- };
8
-
9
- /**
10
- * URL is a simple class for building and extending URLs.
11
- */
12
- export default class URL {
13
- protocol: string;
14
- host: string;
15
- port: number;
16
- path: string;
17
-
18
- /**
19
- * @param host - The hostname or IP address of the server.
20
- * @param port - The port number of the server.
21
- * @param protocol - The protocol to use for all requests. Defaults to "".
22
- * @param pathPrefix - A path prefix to use for all requests. Defaults to "".
23
- */
24
- constructor({ host, port, protocol = '', pathPrefix = '' }: URLProps) {
25
- this.protocol = protocol;
26
- this.host = host;
27
- this.port = port;
28
- this.path = formatPath(pathPrefix);
29
- }
30
-
31
- /**
32
- * Replaces creates a new URL with the specified properties replaced.
33
- * @param props - The properties to replace.
34
- * @returns a new URL.
35
- */
36
- replace(props: Partial<URLProps>): URL {
37
- return new URL({
38
- host: props.host || this.host,
39
- port: props.port || this.port,
40
- protocol: props.protocol || this.protocol,
41
- pathPrefix: props.pathPrefix || this.path,
42
- });
43
- }
44
-
45
- /**
46
- * Creates a new url with the given path appended to the current path.
47
- * @param path - the path to append to the URL.
48
- * @returns a new URL.
49
- */
50
- child(path: string): URL {
51
- return new URL({
52
- ...this,
53
- pathPrefix: joinPaths(this.path, path),
54
- });
55
- }
56
-
57
- /** @returns a string representation of the url */
58
- stringify(): string {
59
- return removeTrailingSlash(
60
- `${this.protocol}://${this.host}:${this.port}/${this.path}`
61
- );
62
- }
63
- }
64
-
65
- // joinPath joins the two paths, ensuring there is a single slash between them.
66
- const joinPaths = (...paths: string[]): string => {
67
- return paths.map(formatPath).join('');
68
- };
69
-
70
- const formatPath = (path: string): string => {
71
- if (!path.endsWith('/')) path += '/';
72
- if (path.startsWith('/')) path = path.slice(1);
73
- return path;
74
- };
75
-
76
- const removeTrailingSlash = (path: string): string => {
77
- if (path.endsWith('/')) path = path.slice(0, -1);
78
- return path;
79
- };
@@ -1,12 +0,0 @@
1
- import { Middleware } from '../middleware';
2
-
3
- export const logMiddleware = (): Middleware => {
4
- return async (md, next) => {
5
- console.log(JSON.stringify(md, undefined, 2));
6
- const err = await next(md);
7
- if (err) {
8
- console.log(err);
9
- }
10
- return err;
11
- };
12
- };
@@ -1,106 +0,0 @@
1
- import test from 'ava';
2
- import { z } from 'zod';
3
-
4
- import { JSONEncoderDecoder } from './encoder';
5
- import { BaseTypedError, EOF, registerError, TypedError } from './errors';
6
- import URL from './url';
7
- import { WebSocketClient } from './websocket';
8
-
9
- const url = new URL({
10
- host: '127.0.0.1',
11
- port: 8080,
12
- });
13
-
14
- const MessageSchema = z.object({
15
- id: z.number().optional(),
16
- message: z.string().optional(),
17
- });
18
-
19
- const client = new WebSocketClient(new JSONEncoderDecoder(), url);
20
-
21
- class MyCustomError extends BaseTypedError {
22
- code: number;
23
-
24
- constructor(message: string, code: number) {
25
- super(message, 'integration.error');
26
- this.code = code;
27
- }
28
- }
29
-
30
- const encodeTestError = (err: TypedError): string => {
31
- if (!(err instanceof MyCustomError)) {
32
- throw new Error('Unexpected error type');
33
- }
34
- return `${err.code},${err.message}`;
35
- };
36
-
37
- const decodeTestError = (encoded: string): TypedError => {
38
- const [code, message] = encoded.split(',');
39
- return new MyCustomError(message, parseInt(code, 10));
40
- };
41
-
42
- registerError({
43
- type: 'integration.error',
44
- encode: encodeTestError,
45
- decode: decodeTestError,
46
- });
47
-
48
- test('basic exchange', async (t) => {
49
- const stream = await client.stream(
50
- 'stream/echo',
51
- MessageSchema,
52
- MessageSchema
53
- );
54
- for (let i = 0; i < 10; i++) {
55
- stream.send({ id: i, message: 'hello' });
56
- const [response, error] = await stream.receive();
57
- t.is(error, undefined);
58
- t.is(response?.id, i + 1);
59
- t.is(response?.message, 'hello');
60
- }
61
- stream.closeSend();
62
- const [response, error] = await stream.receive();
63
- t.deepEqual(error, new EOF());
64
- t.is(response, undefined);
65
- });
66
-
67
- test('receive message after close', async (t) => {
68
- const stream = await client.stream(
69
- 'stream/sendMessageAfterClientClose',
70
- MessageSchema,
71
- MessageSchema
72
- );
73
- await stream.closeSend();
74
- let [response, error] = await stream.receive();
75
- t.is(error, undefined);
76
- t.is(response?.id, 0);
77
- t.is(response?.message, 'Close Acknowledged');
78
- [response, error] = await stream.receive();
79
- t.deepEqual(error, new EOF());
80
- });
81
-
82
- test('receive error', async (t) => {
83
- const stream = await client.stream(
84
- 'stream/receiveAndExitWithErr',
85
- MessageSchema,
86
- MessageSchema
87
- );
88
- stream.send({ id: 0, message: 'hello' });
89
- const [response, error] = await stream.receive();
90
- t.deepEqual(error, new MyCustomError('unexpected error', 1));
91
- t.is(response, undefined);
92
- });
93
-
94
- test('middleware', async (t) => {
95
- const myClient = new WebSocketClient(new JSONEncoderDecoder(), url);
96
- let c = 0;
97
- myClient.use(async (md, next): Promise<Error | undefined> => {
98
- if (md.params) {
99
- c++;
100
- md.params['Test'] = 'test';
101
- }
102
- return await next(md);
103
- });
104
- await myClient.stream('stream/middlewareCheck', MessageSchema, MessageSchema);
105
- t.is(c, 1);
106
- });
@@ -1,225 +0,0 @@
1
- import { z, ZodSchema } from 'zod';
2
-
3
- import { EncoderDecoder } from './encoder';
4
- import { decodeError, EOF, ErrorPayloadSchema, StreamClosed } from './errors';
5
- import { buildQueryString } from './http';
6
- import { CONTENT_TYPE_HEADER_KEY } from './http';
7
- import { MetaData, MiddlewareCollector } from './middleware';
8
- import { Runtime, RUNTIME } from './runtime';
9
- import { Stream, StreamClient } from './stream';
10
- import URL from './url';
11
-
12
- const resolveWebSocketConstructor = (): typeof WebSocket => {
13
- if (RUNTIME == Runtime.Node) return require('ws');
14
- return WebSocket;
15
- };
16
-
17
- enum MessageType {
18
- Data = 'data',
19
- Close = 'close',
20
- }
21
-
22
- const MessageSchema = z.object({
23
- type: z.nativeEnum(MessageType),
24
- payload: z.unknown().optional(),
25
- error: z.optional(ErrorPayloadSchema),
26
- });
27
-
28
- type Message = z.infer<typeof MessageSchema>;
29
-
30
- enum CloseCode {
31
- Normal = 1000,
32
- GoingAway = 1001,
33
- }
34
-
35
- /** WebSocketStream is an implementation of Stream that is backed by a websocket. */
36
- class WebSocketStream<RQ, RS> implements Stream<RQ, RS> {
37
- private encoder: EncoderDecoder;
38
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
39
- // @ts-ignore
40
- private reqSchema: z.ZodSchema<RQ>;
41
- private resSchema: z.ZodSchema<RS>;
42
-
43
- private ws: WebSocket;
44
- private server_closed?: Error;
45
- private send_closed: boolean;
46
- private receiveDataQueue: Message[] = [];
47
- private receiveCallbacksQueue: {
48
- resolve: (msg: Message) => void;
49
- reject: (reason: unknown) => void;
50
- }[] = [];
51
-
52
- constructor(
53
- ws: WebSocket,
54
- encoder: EncoderDecoder,
55
- reqSchema: z.ZodSchema<RQ>,
56
- resSchema: z.ZodSchema<RS>
57
- ) {
58
- this.encoder = encoder;
59
- this.reqSchema = reqSchema;
60
- this.resSchema = resSchema;
61
- this.ws = ws;
62
- this.send_closed = false;
63
- this.listenForMessages();
64
- }
65
-
66
- /** Implements the Stream protocol */
67
- send(req: RQ): Error | undefined {
68
- if (this.server_closed) return new EOF();
69
- if (this.send_closed) throw new StreamClosed();
70
-
71
- this.ws.send(
72
- this.encoder.encode({
73
- type: MessageType.Data,
74
- payload: req,
75
- error: undefined,
76
- })
77
- );
78
-
79
- return undefined;
80
- }
81
-
82
- /** Implements the Stream protocol */
83
- async receive(): Promise<[RS | undefined, Error | undefined]> {
84
- if (this.server_closed) return [undefined, this.server_closed];
85
-
86
- const msg = await this.receiveMsg();
87
-
88
- if (msg.type == MessageType.Close) {
89
- if (!msg.error) throw new Error('Message error must be defined');
90
- this.server_closed = decodeError(msg.error);
91
- return [undefined, this.server_closed];
92
- }
93
-
94
- return [this.resSchema.parse(msg.payload), undefined];
95
- }
96
-
97
- /** Implements the Stream protocol */
98
- received(): boolean {
99
- return this.receiveDataQueue.length !== 0;
100
- }
101
-
102
- /** Implements the Stream protocol */
103
- closeSend(): void {
104
- if (this.send_closed || this.server_closed) {
105
- return undefined;
106
- }
107
- const msg: Message = { type: MessageType.Close };
108
- try {
109
- this.ws.send(this.encoder.encode(msg));
110
- } finally {
111
- this.send_closed = true;
112
- }
113
- return undefined;
114
- }
115
-
116
- private async receiveMsg(): Promise<Message> {
117
- if (this.receiveDataQueue.length !== 0) {
118
- const msg = this.receiveDataQueue.shift();
119
- if (msg) return msg;
120
- throw new Error('unexpected undefined message');
121
- }
122
-
123
- return new Promise((resolve, reject) => {
124
- this.receiveCallbacksQueue.push({ resolve, reject });
125
- });
126
- }
127
-
128
- private listenForMessages(): void {
129
- this.ws.onmessage = (ev: MessageEvent) => {
130
- const msg = this.encoder.decode(ev.data, MessageSchema);
131
-
132
- if (this.receiveCallbacksQueue.length > 0) {
133
- const callback = this.receiveCallbacksQueue.shift();
134
- if (callback) callback.resolve(msg);
135
- else throw new Error('Unexpected empty callback queue');
136
- } else {
137
- this.receiveDataQueue.push(msg);
138
- }
139
- };
140
-
141
- this.ws.onclose = (ev: CloseEvent) => {
142
- if ([CloseCode.Normal, CloseCode.GoingAway].includes(ev.code)) {
143
- this.server_closed = new EOF();
144
- } else {
145
- this.server_closed = new StreamClosed();
146
- }
147
- };
148
- }
149
- }
150
-
151
- export const FREIGHTER_METADATA_PREFIX = 'freightermd';
152
-
153
- /**
154
- * WebSocketClient is an implementation of StreamClient that is backed by
155
- * websockets.
156
- */
157
- export class WebSocketClient
158
- extends MiddlewareCollector
159
- implements StreamClient
160
- {
161
- baseUrl: URL;
162
- encoder: EncoderDecoder;
163
-
164
- static readonly MESSAGE_TYPE = 'arraybuffer';
165
-
166
- /**
167
- * @param encoder - The encoder to use for encoding messages and decoding
168
- * responses.
169
- * @param baseURL - A base url to use as a prefix for all requests.
170
- */
171
- constructor(encoder: EncoderDecoder, baseURL: URL) {
172
- super();
173
- this.baseUrl = baseURL.replace({ protocol: 'ws' });
174
- this.encoder = encoder;
175
- }
176
-
177
- /** Implements the StreamClient interface. */
178
- async stream<RQ, RS>(
179
- target: string,
180
- reqSchema: ZodSchema<RQ>,
181
- resSchema: ZodSchema<RS>
182
- ): Promise<Stream<RQ, RS>> {
183
- const socketConstructor = resolveWebSocketConstructor();
184
- let stream: Stream<RQ, RS> | undefined;
185
- const error = await this.executeMiddleware(
186
- { target, protocol: 'websocket', params: {} },
187
- async (md: MetaData): Promise<Error | undefined> => {
188
- const ws = new socketConstructor(this.buildURL(target, md));
189
- ws.binaryType = WebSocketClient.MESSAGE_TYPE;
190
- const streamOrErr = await this.wrapSocket(ws, reqSchema, resSchema);
191
- if (streamOrErr instanceof Error) return streamOrErr;
192
- stream = streamOrErr;
193
- return undefined;
194
- }
195
- );
196
- if (error) throw error;
197
- return stream as Stream<RQ, RS>;
198
- }
199
-
200
- private buildURL(target: string, md: MetaData): string {
201
- const qs = buildQueryString({
202
- request: {
203
- [CONTENT_TYPE_HEADER_KEY]: this.encoder.contentType,
204
- ...md.params,
205
- },
206
- prefix: FREIGHTER_METADATA_PREFIX,
207
- });
208
- return this.baseUrl.child(target).stringify() + qs;
209
- }
210
-
211
- private async wrapSocket<RQ, RS>(
212
- ws: WebSocket,
213
- reqSchema: ZodSchema<RQ>,
214
- resSchema: ZodSchema<RS>
215
- ): Promise<WebSocketStream<RQ, RS> | Error> {
216
- return await new Promise((resolve, reject) => {
217
- ws.onopen = () => {
218
- resolve(
219
- new WebSocketStream<RQ, RS>(ws, this.encoder, reqSchema, resSchema)
220
- );
221
- };
222
- ws.onerror = (ev: Event) => reject(new Error(ev.toString()));
223
- });
224
- }
225
- }
@@ -1,24 +0,0 @@
1
- /**
2
- * If you import a dependency which does not include its own type definitions,
3
- * TypeScript will try to find a definition for it by following the `typeRoots`
4
- * compiler option in tsconfig.json. For this project, we've configured it to
5
- * fall back to this folder if nothing is found in node_modules/@types.
6
- *
7
- * Often, you can install the DefinitelyTyped
8
- * (https://github.com/DefinitelyTyped/DefinitelyTyped) type definition for the
9
- * dependency in question. However, if no one has yet contributed definitions
10
- * for the package, you may want to declare your own. (If you're using the
11
- * `noImplicitAny` compiler options, you'll be required to declare it.)
12
- *
13
- * This is an example type definition which allows import from `module-name`,
14
- * e.g.:
15
- * ```ts
16
- * import something from 'module-name';
17
- * something();
18
- * ```
19
- */
20
- declare module 'module-name' {
21
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
- const whatever: any;
23
- export = whatever;
24
- }
@@ -1,9 +0,0 @@
1
- {
2
- "extends": "./tsconfig",
3
- "compilerOptions": {
4
- "target": "esnext",
5
- "outDir": "build/module",
6
- "module": "esnext"
7
- },
8
- "exclude": ["node_modules/**"]
9
- }