@arrirpc/client 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright 2024 Joshua Sosso
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # arri-client
2
+
3
+ This library was generated with [Nx](https://nx.dev).
4
+
5
+ ## Building
6
+
7
+ Run `nx build arri-client` to build the library.
8
+
9
+ ## Running unit tests
10
+
11
+ Run `nx test arri-client` to execute the unit tests via [Jest](https://jestjs.io).
package/dist/index.cjs ADDED
@@ -0,0 +1,465 @@
1
+ 'use strict';
2
+
3
+ const ofetch = require('ofetch');
4
+ const eventSourcePlus = require('event-source-plus');
5
+ const NodeWebsocket = require('ws');
6
+
7
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
8
+
9
+ const NodeWebsocket__default = /*#__PURE__*/_interopDefaultCompat(NodeWebsocket);
10
+
11
+ var __defProp$1 = Object.defineProperty;
12
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
+ var __publicField$1 = (obj, key, value) => {
14
+ __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
15
+ return value;
16
+ };
17
+ function isArriError(input) {
18
+ if (typeof input !== "object" || input === null) {
19
+ return false;
20
+ }
21
+ if ("stack" in input && typeof input !== "string") {
22
+ return false;
23
+ }
24
+ if ("serverStack" in input && typeof input !== "string") {
25
+ return false;
26
+ }
27
+ return "code" in input && typeof input.code === "number" && "message" in input && typeof input.message === "string";
28
+ }
29
+ class ArriErrorInstance extends Error {
30
+ constructor(input) {
31
+ super(input.message);
32
+ __publicField$1(this, "code");
33
+ __publicField$1(this, "data");
34
+ __publicField$1(this, "serverStack");
35
+ __publicField$1(this, "_internalMessage");
36
+ this.code = input.code;
37
+ this.serverStack = input.stack;
38
+ this._internalMessage = input.message;
39
+ this.data = input.data;
40
+ }
41
+ toJSON() {
42
+ const stack = this.serverStack ?? this.stack;
43
+ return {
44
+ code: this.code,
45
+ message: this._internalMessage,
46
+ stack: stack?.split("\n").map((l) => l.trim()),
47
+ data: this.data
48
+ };
49
+ }
50
+ static fromJson(json) {
51
+ let parsedJson = json;
52
+ if (typeof parsedJson === "string") {
53
+ try {
54
+ parsedJson = JSON.parse(parsedJson);
55
+ } catch (_) {
56
+ }
57
+ }
58
+ if (typeof parsedJson !== "object" || parsedJson === null) {
59
+ return new ArriErrorInstance({
60
+ code: 500,
61
+ message: "Unknown error",
62
+ data: parsedJson
63
+ });
64
+ }
65
+ return new ArriErrorInstance({
66
+ code: "code" in parsedJson && typeof parsedJson.code === "number" ? parsedJson.code : 500,
67
+ message: "message" in parsedJson && typeof parsedJson.message === "string" ? parsedJson.message : "",
68
+ stack: "stack" in parsedJson && Array.isArray(parsedJson.stack) ? parsedJson.stack.join("\n") : void 0,
69
+ data: "data" in parsedJson ? parsedJson.data : void 0
70
+ });
71
+ }
72
+ }
73
+
74
+ async function arriRequest(opts) {
75
+ let url = opts.url;
76
+ let body;
77
+ let contentType;
78
+ switch (opts.method) {
79
+ case "get":
80
+ case "head":
81
+ if (opts.params && typeof opts.params === "object") {
82
+ const urlParts = [];
83
+ Object.keys(opts.params).forEach((key) => {
84
+ urlParts.push(`${key}=${opts.params[key]}`);
85
+ });
86
+ url = `${opts.url}?${urlParts.join("&")}`;
87
+ }
88
+ break;
89
+ default:
90
+ if (opts.params && typeof opts.params === "object") {
91
+ body = opts.serializer(opts.params);
92
+ contentType = "application/json";
93
+ }
94
+ break;
95
+ }
96
+ try {
97
+ let headers = {};
98
+ if (typeof opts.headers === "function") {
99
+ headers = opts.headers();
100
+ } else {
101
+ headers = opts.headers ?? {};
102
+ }
103
+ if (contentType)
104
+ headers["Content-Type"] = contentType;
105
+ if (opts.clientVersion)
106
+ headers["client-version"] = opts.clientVersion;
107
+ const result = await ofetch.ofetch(url, {
108
+ method: opts.method,
109
+ body,
110
+ headers
111
+ });
112
+ return opts.parser(result);
113
+ } catch (err) {
114
+ const error = err;
115
+ if (isArriError(error.data)) {
116
+ throw new ArriErrorInstance(error.data);
117
+ } else {
118
+ throw new ArriErrorInstance({
119
+ code: error.statusCode ?? 500,
120
+ message: error.statusMessage ?? error.message ?? `Error connecting to ${url}`,
121
+ data: error.data,
122
+ stack: error.stack
123
+ });
124
+ }
125
+ }
126
+ }
127
+ async function arriSafeRequest(opts) {
128
+ try {
129
+ const result = await arriRequest(opts);
130
+ return {
131
+ success: true,
132
+ value: result
133
+ };
134
+ } catch (err) {
135
+ if (err instanceof ArriErrorInstance) {
136
+ return {
137
+ success: false,
138
+ error: err
139
+ };
140
+ }
141
+ if (err instanceof ofetch.FetchError) {
142
+ return {
143
+ success: false,
144
+ error: new ArriErrorInstance({
145
+ code: err.statusCode ?? 0,
146
+ message: err.statusMessage ?? "",
147
+ stack: err.stack,
148
+ data: err.data
149
+ })
150
+ };
151
+ }
152
+ return {
153
+ success: false,
154
+ error: new ArriErrorInstance({
155
+ code: 500,
156
+ message: `Unknown error connecting to ${opts.url}`,
157
+ data: err
158
+ })
159
+ };
160
+ }
161
+ }
162
+
163
+ function arriSseRequest(opts, options) {
164
+ let url = opts.url;
165
+ let body;
166
+ switch (opts.method) {
167
+ case "get":
168
+ case "head":
169
+ if (opts.params && typeof opts.params === "object" && opts.params !== null) {
170
+ const urlParts = [];
171
+ Object.keys(opts.params).forEach((key) => {
172
+ urlParts.push(`${key}=${opts.params[key]}`);
173
+ });
174
+ url = `${opts.url}?${urlParts.join("&")}`;
175
+ }
176
+ break;
177
+ default:
178
+ if (opts.params && typeof opts.params === "object") {
179
+ body = opts.serializer(opts.params);
180
+ }
181
+ break;
182
+ }
183
+ const eventSource = new eventSourcePlus.EventSourcePlus(url, {
184
+ method: opts.method ?? "get",
185
+ headers: () => {
186
+ let headers;
187
+ if (typeof opts.headers === "function") {
188
+ headers = opts.headers();
189
+ } else {
190
+ headers = opts.headers ?? {};
191
+ }
192
+ if (opts.clientVersion) {
193
+ headers["client-version"] = opts.clientVersion;
194
+ }
195
+ return headers;
196
+ },
197
+ body,
198
+ maxRetryCount: options.maxRetryCount,
199
+ maxRetryInterval: options.maxRetryInterval
200
+ });
201
+ const controller = eventSource.listen({
202
+ onMessage(message) {
203
+ if (message.event === "message" || message.event === void 0 || message.event === "") {
204
+ options.onMessage?.(opts.parser(message.data));
205
+ return;
206
+ }
207
+ if (message.event === "error") {
208
+ options.onErrorMessage?.(
209
+ ArriErrorInstance.fromJson(message.data)
210
+ );
211
+ return;
212
+ }
213
+ if (message.event === "done") {
214
+ controller.abort();
215
+ }
216
+ },
217
+ onRequest(context) {
218
+ options.onRequest?.(context);
219
+ },
220
+ onRequestError(context) {
221
+ options.onRequestError?.({
222
+ ...context,
223
+ error: new ArriErrorInstance({
224
+ code: 0,
225
+ message: context.error.message,
226
+ data: context.error
227
+ })
228
+ });
229
+ },
230
+ onResponse(context) {
231
+ options.onResponse?.(context);
232
+ },
233
+ async onResponseError(context) {
234
+ if (!options.onResponseError) {
235
+ return;
236
+ }
237
+ try {
238
+ const arriError = ArriErrorInstance.fromJson(
239
+ await context.response.json()
240
+ );
241
+ options.onResponseError({
242
+ ...context,
243
+ error: arriError
244
+ });
245
+ } catch (_) {
246
+ const arriError = new ArriErrorInstance({
247
+ code: context.response.status ?? 0,
248
+ message: context.response.statusText
249
+ });
250
+ options.onResponseError({ ...context, error: arriError });
251
+ }
252
+ }
253
+ });
254
+ return controller;
255
+ }
256
+ function parseSseEvent(input, dataParser) {
257
+ let id;
258
+ let event;
259
+ let data;
260
+ const lines = input.split("\n");
261
+ for (const line of lines) {
262
+ if (line.startsWith("id:")) {
263
+ id = line.substring(3).trim();
264
+ continue;
265
+ }
266
+ if (line.startsWith("event:")) {
267
+ event = line.substring(6).trim();
268
+ continue;
269
+ }
270
+ if (line.startsWith("data:")) {
271
+ data = dataParser(line.substring(5).trim());
272
+ }
273
+ }
274
+ if (!data) {
275
+ return void 0;
276
+ }
277
+ return {
278
+ id,
279
+ event,
280
+ data
281
+ };
282
+ }
283
+ function parseSseEvents(input, dataParser) {
284
+ const eventStrings = input.split("\n\n");
285
+ const events = [];
286
+ for (const str of eventStrings) {
287
+ const event = parseSseEvent(str, dataParser);
288
+ if (event) {
289
+ events.push(event);
290
+ }
291
+ }
292
+ return events;
293
+ }
294
+
295
+ var __defProp = Object.defineProperty;
296
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
297
+ var __publicField = (obj, key, value) => {
298
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
299
+ return value;
300
+ };
301
+ function isBrowser() {
302
+ return typeof window !== "undefined";
303
+ }
304
+ function connectWebsocket(url, protocol) {
305
+ if (isBrowser()) {
306
+ return new WebSocket(url, protocol);
307
+ }
308
+ return new NodeWebsocket__default(url, {
309
+ protocol
310
+ });
311
+ }
312
+ function arriWsRequest(opts, retryCount = 0) {
313
+ let url = opts.url.replace("http://", "ws://").replace("https://", "wss://");
314
+ let headers;
315
+ if (typeof opts.headers === "function") {
316
+ headers = opts.headers();
317
+ } else {
318
+ headers = opts.headers;
319
+ }
320
+ if (headers) {
321
+ if (opts.clientVersion)
322
+ headers["client-version"] = opts.clientVersion;
323
+ const queryParts = [];
324
+ for (const key of Object.keys(headers)) {
325
+ queryParts.push(`${key}=${headers[key]}`);
326
+ }
327
+ url += `?${queryParts.join("&")}`;
328
+ }
329
+ try {
330
+ const controller = new WsController({
331
+ url,
332
+ parser: opts.parser,
333
+ serializer: opts.serializer ?? ((_) => ""),
334
+ onOpen: opts.onOpen,
335
+ onClose: opts.onClose,
336
+ onMessage: opts.onMessage,
337
+ onErrorMessage: opts.onError,
338
+ onConnectionError: opts.onConnectionError
339
+ });
340
+ return controller;
341
+ } catch (err) {
342
+ console.error(err);
343
+ if (opts.onConnectionError) {
344
+ opts.onConnectionError(err);
345
+ }
346
+ return arriWsRequest(opts, retryCount + 1);
347
+ }
348
+ }
349
+ class WsController {
350
+ constructor(opts) {
351
+ __publicField(this, "url");
352
+ __publicField(this, "_ws");
353
+ __publicField(this, "_serializer");
354
+ __publicField(this, "_parser");
355
+ __publicField(this, "onMessage");
356
+ __publicField(this, "onErrorMessage");
357
+ __publicField(this, "onConnectionError");
358
+ __publicField(this, "onOpen");
359
+ __publicField(this, "onClose");
360
+ this.url = opts.url;
361
+ this._serializer = opts.serializer;
362
+ this._parser = opts.parser;
363
+ this.onOpen = opts.onOpen;
364
+ this.onClose = opts.onClose;
365
+ this.onErrorMessage = opts.onErrorMessage;
366
+ this.onConnectionError = opts.onConnectionError;
367
+ this.onMessage = opts.onMessage;
368
+ }
369
+ connect() {
370
+ this._ws = connectWebsocket(this.url);
371
+ this._ws.onopen = () => {
372
+ this.onOpen?.();
373
+ };
374
+ this._ws.onclose = () => {
375
+ this.onClose?.();
376
+ };
377
+ this._ws.onmessage = (event) => {
378
+ this._handleMessage(event);
379
+ };
380
+ this._ws.onerror = (event) => {
381
+ this.onConnectionError?.(
382
+ new ArriErrorInstance({
383
+ code: "errno" in event.error && typeof event.error.errno === "number" ? event.error.errno : 0,
384
+ message: event.error instanceof Error ? event.error.message : `Error connecting to ${this.url}`,
385
+ data: event.error,
386
+ stack: event.error instanceof Error ? event.error.stack : void 0
387
+ })
388
+ );
389
+ };
390
+ }
391
+ readyState() {
392
+ return this._ws?.readyState ?? -1;
393
+ }
394
+ send(message) {
395
+ const payload = this._serializer(message);
396
+ this._ws?.send(payload);
397
+ }
398
+ close() {
399
+ this._ws?.close();
400
+ }
401
+ _handleMessage(msg) {
402
+ if (typeof msg.data !== "string") {
403
+ return;
404
+ }
405
+ const response = parsedWsResponse(msg.data);
406
+ switch (response.event) {
407
+ case "error": {
408
+ if (!this.onErrorMessage) {
409
+ return;
410
+ }
411
+ const err = ArriErrorInstance.fromJson(response.data);
412
+ this.onErrorMessage(err);
413
+ break;
414
+ }
415
+ case "message": {
416
+ if (!this.onMessage) {
417
+ return;
418
+ }
419
+ const msg2 = this._parser(response.data);
420
+ this.onMessage(msg2);
421
+ break;
422
+ }
423
+ default:
424
+ console.warn("Invalid response from server", msg);
425
+ break;
426
+ }
427
+ }
428
+ }
429
+ function parsedWsResponse(input) {
430
+ const lines = input.split("\n");
431
+ let event = "unknown";
432
+ let data = "";
433
+ for (const line of lines) {
434
+ const trimmedLine = line.trim();
435
+ if (trimmedLine.startsWith("event: ")) {
436
+ switch (trimmedLine.substring(6).trim()) {
437
+ case "error":
438
+ event = "error";
439
+ break;
440
+ case "message":
441
+ event = "message";
442
+ break;
443
+ }
444
+ continue;
445
+ }
446
+ if (trimmedLine.startsWith("data: ")) {
447
+ data = trimmedLine.substring(5).trim();
448
+ continue;
449
+ }
450
+ }
451
+ return {
452
+ event,
453
+ data
454
+ };
455
+ }
456
+
457
+ exports.ArriErrorInstance = ArriErrorInstance;
458
+ exports.arriRequest = arriRequest;
459
+ exports.arriSafeRequest = arriSafeRequest;
460
+ exports.arriSseRequest = arriSseRequest;
461
+ exports.arriWsRequest = arriWsRequest;
462
+ exports.isArriError = isArriError;
463
+ exports.parseSseEvent = parseSseEvent;
464
+ exports.parseSseEvents = parseSseEvents;
465
+ exports.parsedWsResponse = parsedWsResponse;
@@ -0,0 +1,129 @@
1
+ import { HttpMethod, OnRequestContext, OnRequestErrorContext, OnResponseContext, OnResponseErrorContext, EventSourceController } from 'event-source-plus';
2
+
3
+ interface ArriError {
4
+ code: number;
5
+ message: string;
6
+ data?: any;
7
+ stack?: string;
8
+ serverStack?: string;
9
+ }
10
+ declare function isArriError(input: unknown): input is ArriError;
11
+ declare class ArriErrorInstance extends Error implements ArriError {
12
+ code: number;
13
+ data?: any;
14
+ serverStack?: string;
15
+ private readonly _internalMessage;
16
+ constructor(input: {
17
+ code: number;
18
+ message: string;
19
+ stack?: string;
20
+ data?: any;
21
+ });
22
+ toJSON(): {
23
+ code: number;
24
+ message: string;
25
+ stack: string[] | undefined;
26
+ data: any;
27
+ };
28
+ static fromJson(json: unknown): ArriErrorInstance;
29
+ }
30
+
31
+ interface ArriRequestOpts<TType, TParams extends Record<any, any> | undefined = undefined> {
32
+ url: string;
33
+ method: HttpMethod;
34
+ headers?: Record<string, string> | (() => Record<string, string>);
35
+ params?: TParams;
36
+ parser: (input: unknown) => TType;
37
+ serializer: (input: TParams) => TParams extends undefined ? undefined : string;
38
+ clientVersion?: string;
39
+ }
40
+ declare function arriRequest<TType, TParams extends Record<any, any> | undefined = undefined>(opts: ArriRequestOpts<TType, TParams>): Promise<TType>;
41
+ declare function arriSafeRequest<TType, TParams extends Record<any, any> | undefined = undefined>(opts: ArriRequestOpts<TType, TParams>): Promise<SafeResponse<TType>>;
42
+ type SafeResponse<T> = {
43
+ success: true;
44
+ value: T;
45
+ } | {
46
+ success: false;
47
+ error: ArriErrorInstance;
48
+ };
49
+
50
+ interface SseEvent<TData = string> {
51
+ id?: string;
52
+ event?: string;
53
+ data: TData;
54
+ }
55
+ interface SseOptions<TData> {
56
+ onMessage?: (data: TData) => any;
57
+ onErrorMessage?: (error: ArriErrorInstance) => any;
58
+ onRequest?: (context: OnRequestContext) => any;
59
+ onRequestError?: (context: Omit<OnRequestErrorContext, "error"> & {
60
+ error: ArriErrorInstance;
61
+ }) => any;
62
+ onResponse?: (context: OnResponseContext) => any;
63
+ onResponseError?: (context: Omit<OnResponseErrorContext, "error"> & {
64
+ error: ArriErrorInstance;
65
+ }) => any;
66
+ onClose?: () => any;
67
+ maxRetryCount?: number;
68
+ maxRetryInterval?: number;
69
+ }
70
+ declare function arriSseRequest<TType, TParams extends Record<any, any> | undefined = undefined>(opts: ArriRequestOpts<TType, TParams>, options: SseOptions<TType>): EventSourceController;
71
+ declare function parseSseEvent<TData = string>(input: string, dataParser: (input: string) => TData): SseEvent<TData> | undefined;
72
+ declare function parseSseEvents<TData = string>(input: string, dataParser: (input: string) => TData): SseEvent<TData>[];
73
+
74
+ interface WsControllerOptions<TParams, TResponse> {
75
+ url: string;
76
+ serializer: (input: TParams) => string;
77
+ parser: (input: unknown) => TResponse;
78
+ onMessage?: WsMessageHook<TResponse>;
79
+ onErrorMessage?: WsErrorHook;
80
+ onConnectionError?: WsErrorHook;
81
+ onOpen?: () => any;
82
+ onClose?: () => any;
83
+ }
84
+ interface WsOptions<TResponse> {
85
+ onMessage?: WsMessageHook<TResponse>;
86
+ onError?: WsErrorHook;
87
+ onConnectionError?: WsErrorHook;
88
+ onOpen?: () => any;
89
+ onClose?: () => any;
90
+ }
91
+ interface ArriWsRequestOptions<TParams = any, TResponse = any> {
92
+ url: string;
93
+ headers?: Record<string, string> | (() => Record<string, string>);
94
+ params?: TParams;
95
+ parser: (input: unknown) => TResponse;
96
+ serializer: (input: TParams) => string;
97
+ onMessage?: WsMessageHook<TResponse>;
98
+ onError?: WsErrorHook;
99
+ onConnectionError?: WsErrorHook;
100
+ onOpen?: () => any;
101
+ onClose?: () => any;
102
+ clientVersion?: string;
103
+ }
104
+ declare function arriWsRequest<TParams extends Record<any, any> | undefined = undefined, TResponse = any>(opts: ArriWsRequestOptions<TParams, TResponse>, retryCount?: number): WsController<TParams, TResponse>;
105
+ type WsErrorHook = (err: ArriErrorInstance) => void;
106
+ type WsMessageHook<TResponse> = (msg: TResponse) => any;
107
+ declare class WsController<TParams, TResponse> {
108
+ url: string;
109
+ private _ws?;
110
+ private readonly _serializer;
111
+ private readonly _parser;
112
+ onMessage?: WsMessageHook<TResponse>;
113
+ onErrorMessage?: WsErrorHook;
114
+ onConnectionError?: WsErrorHook;
115
+ onOpen?: () => any;
116
+ onClose?: () => any;
117
+ constructor(opts: WsControllerOptions<TParams, TResponse>);
118
+ connect(): void;
119
+ readyState(): number;
120
+ send(message: TParams): void;
121
+ close(): void;
122
+ private _handleMessage;
123
+ }
124
+ declare function parsedWsResponse(input: string): {
125
+ event: "message" | "error" | "unknown";
126
+ data: string;
127
+ };
128
+
129
+ export { type ArriError, ArriErrorInstance, type ArriRequestOpts, type SafeResponse, type SseEvent, type SseOptions, type WsOptions, arriRequest, arriSafeRequest, arriSseRequest, arriWsRequest, isArriError, parseSseEvent, parseSseEvents, parsedWsResponse };
@@ -0,0 +1,129 @@
1
+ import { HttpMethod, OnRequestContext, OnRequestErrorContext, OnResponseContext, OnResponseErrorContext, EventSourceController } from 'event-source-plus';
2
+
3
+ interface ArriError {
4
+ code: number;
5
+ message: string;
6
+ data?: any;
7
+ stack?: string;
8
+ serverStack?: string;
9
+ }
10
+ declare function isArriError(input: unknown): input is ArriError;
11
+ declare class ArriErrorInstance extends Error implements ArriError {
12
+ code: number;
13
+ data?: any;
14
+ serverStack?: string;
15
+ private readonly _internalMessage;
16
+ constructor(input: {
17
+ code: number;
18
+ message: string;
19
+ stack?: string;
20
+ data?: any;
21
+ });
22
+ toJSON(): {
23
+ code: number;
24
+ message: string;
25
+ stack: string[] | undefined;
26
+ data: any;
27
+ };
28
+ static fromJson(json: unknown): ArriErrorInstance;
29
+ }
30
+
31
+ interface ArriRequestOpts<TType, TParams extends Record<any, any> | undefined = undefined> {
32
+ url: string;
33
+ method: HttpMethod;
34
+ headers?: Record<string, string> | (() => Record<string, string>);
35
+ params?: TParams;
36
+ parser: (input: unknown) => TType;
37
+ serializer: (input: TParams) => TParams extends undefined ? undefined : string;
38
+ clientVersion?: string;
39
+ }
40
+ declare function arriRequest<TType, TParams extends Record<any, any> | undefined = undefined>(opts: ArriRequestOpts<TType, TParams>): Promise<TType>;
41
+ declare function arriSafeRequest<TType, TParams extends Record<any, any> | undefined = undefined>(opts: ArriRequestOpts<TType, TParams>): Promise<SafeResponse<TType>>;
42
+ type SafeResponse<T> = {
43
+ success: true;
44
+ value: T;
45
+ } | {
46
+ success: false;
47
+ error: ArriErrorInstance;
48
+ };
49
+
50
+ interface SseEvent<TData = string> {
51
+ id?: string;
52
+ event?: string;
53
+ data: TData;
54
+ }
55
+ interface SseOptions<TData> {
56
+ onMessage?: (data: TData) => any;
57
+ onErrorMessage?: (error: ArriErrorInstance) => any;
58
+ onRequest?: (context: OnRequestContext) => any;
59
+ onRequestError?: (context: Omit<OnRequestErrorContext, "error"> & {
60
+ error: ArriErrorInstance;
61
+ }) => any;
62
+ onResponse?: (context: OnResponseContext) => any;
63
+ onResponseError?: (context: Omit<OnResponseErrorContext, "error"> & {
64
+ error: ArriErrorInstance;
65
+ }) => any;
66
+ onClose?: () => any;
67
+ maxRetryCount?: number;
68
+ maxRetryInterval?: number;
69
+ }
70
+ declare function arriSseRequest<TType, TParams extends Record<any, any> | undefined = undefined>(opts: ArriRequestOpts<TType, TParams>, options: SseOptions<TType>): EventSourceController;
71
+ declare function parseSseEvent<TData = string>(input: string, dataParser: (input: string) => TData): SseEvent<TData> | undefined;
72
+ declare function parseSseEvents<TData = string>(input: string, dataParser: (input: string) => TData): SseEvent<TData>[];
73
+
74
+ interface WsControllerOptions<TParams, TResponse> {
75
+ url: string;
76
+ serializer: (input: TParams) => string;
77
+ parser: (input: unknown) => TResponse;
78
+ onMessage?: WsMessageHook<TResponse>;
79
+ onErrorMessage?: WsErrorHook;
80
+ onConnectionError?: WsErrorHook;
81
+ onOpen?: () => any;
82
+ onClose?: () => any;
83
+ }
84
+ interface WsOptions<TResponse> {
85
+ onMessage?: WsMessageHook<TResponse>;
86
+ onError?: WsErrorHook;
87
+ onConnectionError?: WsErrorHook;
88
+ onOpen?: () => any;
89
+ onClose?: () => any;
90
+ }
91
+ interface ArriWsRequestOptions<TParams = any, TResponse = any> {
92
+ url: string;
93
+ headers?: Record<string, string> | (() => Record<string, string>);
94
+ params?: TParams;
95
+ parser: (input: unknown) => TResponse;
96
+ serializer: (input: TParams) => string;
97
+ onMessage?: WsMessageHook<TResponse>;
98
+ onError?: WsErrorHook;
99
+ onConnectionError?: WsErrorHook;
100
+ onOpen?: () => any;
101
+ onClose?: () => any;
102
+ clientVersion?: string;
103
+ }
104
+ declare function arriWsRequest<TParams extends Record<any, any> | undefined = undefined, TResponse = any>(opts: ArriWsRequestOptions<TParams, TResponse>, retryCount?: number): WsController<TParams, TResponse>;
105
+ type WsErrorHook = (err: ArriErrorInstance) => void;
106
+ type WsMessageHook<TResponse> = (msg: TResponse) => any;
107
+ declare class WsController<TParams, TResponse> {
108
+ url: string;
109
+ private _ws?;
110
+ private readonly _serializer;
111
+ private readonly _parser;
112
+ onMessage?: WsMessageHook<TResponse>;
113
+ onErrorMessage?: WsErrorHook;
114
+ onConnectionError?: WsErrorHook;
115
+ onOpen?: () => any;
116
+ onClose?: () => any;
117
+ constructor(opts: WsControllerOptions<TParams, TResponse>);
118
+ connect(): void;
119
+ readyState(): number;
120
+ send(message: TParams): void;
121
+ close(): void;
122
+ private _handleMessage;
123
+ }
124
+ declare function parsedWsResponse(input: string): {
125
+ event: "message" | "error" | "unknown";
126
+ data: string;
127
+ };
128
+
129
+ export { type ArriError, ArriErrorInstance, type ArriRequestOpts, type SafeResponse, type SseEvent, type SseOptions, type WsOptions, arriRequest, arriSafeRequest, arriSseRequest, arriWsRequest, isArriError, parseSseEvent, parseSseEvents, parsedWsResponse };
@@ -0,0 +1,129 @@
1
+ import { HttpMethod, OnRequestContext, OnRequestErrorContext, OnResponseContext, OnResponseErrorContext, EventSourceController } from 'event-source-plus';
2
+
3
+ interface ArriError {
4
+ code: number;
5
+ message: string;
6
+ data?: any;
7
+ stack?: string;
8
+ serverStack?: string;
9
+ }
10
+ declare function isArriError(input: unknown): input is ArriError;
11
+ declare class ArriErrorInstance extends Error implements ArriError {
12
+ code: number;
13
+ data?: any;
14
+ serverStack?: string;
15
+ private readonly _internalMessage;
16
+ constructor(input: {
17
+ code: number;
18
+ message: string;
19
+ stack?: string;
20
+ data?: any;
21
+ });
22
+ toJSON(): {
23
+ code: number;
24
+ message: string;
25
+ stack: string[] | undefined;
26
+ data: any;
27
+ };
28
+ static fromJson(json: unknown): ArriErrorInstance;
29
+ }
30
+
31
+ interface ArriRequestOpts<TType, TParams extends Record<any, any> | undefined = undefined> {
32
+ url: string;
33
+ method: HttpMethod;
34
+ headers?: Record<string, string> | (() => Record<string, string>);
35
+ params?: TParams;
36
+ parser: (input: unknown) => TType;
37
+ serializer: (input: TParams) => TParams extends undefined ? undefined : string;
38
+ clientVersion?: string;
39
+ }
40
+ declare function arriRequest<TType, TParams extends Record<any, any> | undefined = undefined>(opts: ArriRequestOpts<TType, TParams>): Promise<TType>;
41
+ declare function arriSafeRequest<TType, TParams extends Record<any, any> | undefined = undefined>(opts: ArriRequestOpts<TType, TParams>): Promise<SafeResponse<TType>>;
42
+ type SafeResponse<T> = {
43
+ success: true;
44
+ value: T;
45
+ } | {
46
+ success: false;
47
+ error: ArriErrorInstance;
48
+ };
49
+
50
+ interface SseEvent<TData = string> {
51
+ id?: string;
52
+ event?: string;
53
+ data: TData;
54
+ }
55
+ interface SseOptions<TData> {
56
+ onMessage?: (data: TData) => any;
57
+ onErrorMessage?: (error: ArriErrorInstance) => any;
58
+ onRequest?: (context: OnRequestContext) => any;
59
+ onRequestError?: (context: Omit<OnRequestErrorContext, "error"> & {
60
+ error: ArriErrorInstance;
61
+ }) => any;
62
+ onResponse?: (context: OnResponseContext) => any;
63
+ onResponseError?: (context: Omit<OnResponseErrorContext, "error"> & {
64
+ error: ArriErrorInstance;
65
+ }) => any;
66
+ onClose?: () => any;
67
+ maxRetryCount?: number;
68
+ maxRetryInterval?: number;
69
+ }
70
+ declare function arriSseRequest<TType, TParams extends Record<any, any> | undefined = undefined>(opts: ArriRequestOpts<TType, TParams>, options: SseOptions<TType>): EventSourceController;
71
+ declare function parseSseEvent<TData = string>(input: string, dataParser: (input: string) => TData): SseEvent<TData> | undefined;
72
+ declare function parseSseEvents<TData = string>(input: string, dataParser: (input: string) => TData): SseEvent<TData>[];
73
+
74
+ interface WsControllerOptions<TParams, TResponse> {
75
+ url: string;
76
+ serializer: (input: TParams) => string;
77
+ parser: (input: unknown) => TResponse;
78
+ onMessage?: WsMessageHook<TResponse>;
79
+ onErrorMessage?: WsErrorHook;
80
+ onConnectionError?: WsErrorHook;
81
+ onOpen?: () => any;
82
+ onClose?: () => any;
83
+ }
84
+ interface WsOptions<TResponse> {
85
+ onMessage?: WsMessageHook<TResponse>;
86
+ onError?: WsErrorHook;
87
+ onConnectionError?: WsErrorHook;
88
+ onOpen?: () => any;
89
+ onClose?: () => any;
90
+ }
91
+ interface ArriWsRequestOptions<TParams = any, TResponse = any> {
92
+ url: string;
93
+ headers?: Record<string, string> | (() => Record<string, string>);
94
+ params?: TParams;
95
+ parser: (input: unknown) => TResponse;
96
+ serializer: (input: TParams) => string;
97
+ onMessage?: WsMessageHook<TResponse>;
98
+ onError?: WsErrorHook;
99
+ onConnectionError?: WsErrorHook;
100
+ onOpen?: () => any;
101
+ onClose?: () => any;
102
+ clientVersion?: string;
103
+ }
104
+ declare function arriWsRequest<TParams extends Record<any, any> | undefined = undefined, TResponse = any>(opts: ArriWsRequestOptions<TParams, TResponse>, retryCount?: number): WsController<TParams, TResponse>;
105
+ type WsErrorHook = (err: ArriErrorInstance) => void;
106
+ type WsMessageHook<TResponse> = (msg: TResponse) => any;
107
+ declare class WsController<TParams, TResponse> {
108
+ url: string;
109
+ private _ws?;
110
+ private readonly _serializer;
111
+ private readonly _parser;
112
+ onMessage?: WsMessageHook<TResponse>;
113
+ onErrorMessage?: WsErrorHook;
114
+ onConnectionError?: WsErrorHook;
115
+ onOpen?: () => any;
116
+ onClose?: () => any;
117
+ constructor(opts: WsControllerOptions<TParams, TResponse>);
118
+ connect(): void;
119
+ readyState(): number;
120
+ send(message: TParams): void;
121
+ close(): void;
122
+ private _handleMessage;
123
+ }
124
+ declare function parsedWsResponse(input: string): {
125
+ event: "message" | "error" | "unknown";
126
+ data: string;
127
+ };
128
+
129
+ export { type ArriError, ArriErrorInstance, type ArriRequestOpts, type SafeResponse, type SseEvent, type SseOptions, type WsOptions, arriRequest, arriSafeRequest, arriSseRequest, arriWsRequest, isArriError, parseSseEvent, parseSseEvents, parsedWsResponse };
package/dist/index.mjs ADDED
@@ -0,0 +1,451 @@
1
+ import { ofetch, FetchError } from 'ofetch';
2
+ import { EventSourcePlus } from 'event-source-plus';
3
+ import NodeWebsocket from 'ws';
4
+
5
+ var __defProp$1 = Object.defineProperty;
6
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __publicField$1 = (obj, key, value) => {
8
+ __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
9
+ return value;
10
+ };
11
+ function isArriError(input) {
12
+ if (typeof input !== "object" || input === null) {
13
+ return false;
14
+ }
15
+ if ("stack" in input && typeof input !== "string") {
16
+ return false;
17
+ }
18
+ if ("serverStack" in input && typeof input !== "string") {
19
+ return false;
20
+ }
21
+ return "code" in input && typeof input.code === "number" && "message" in input && typeof input.message === "string";
22
+ }
23
+ class ArriErrorInstance extends Error {
24
+ constructor(input) {
25
+ super(input.message);
26
+ __publicField$1(this, "code");
27
+ __publicField$1(this, "data");
28
+ __publicField$1(this, "serverStack");
29
+ __publicField$1(this, "_internalMessage");
30
+ this.code = input.code;
31
+ this.serverStack = input.stack;
32
+ this._internalMessage = input.message;
33
+ this.data = input.data;
34
+ }
35
+ toJSON() {
36
+ const stack = this.serverStack ?? this.stack;
37
+ return {
38
+ code: this.code,
39
+ message: this._internalMessage,
40
+ stack: stack?.split("\n").map((l) => l.trim()),
41
+ data: this.data
42
+ };
43
+ }
44
+ static fromJson(json) {
45
+ let parsedJson = json;
46
+ if (typeof parsedJson === "string") {
47
+ try {
48
+ parsedJson = JSON.parse(parsedJson);
49
+ } catch (_) {
50
+ }
51
+ }
52
+ if (typeof parsedJson !== "object" || parsedJson === null) {
53
+ return new ArriErrorInstance({
54
+ code: 500,
55
+ message: "Unknown error",
56
+ data: parsedJson
57
+ });
58
+ }
59
+ return new ArriErrorInstance({
60
+ code: "code" in parsedJson && typeof parsedJson.code === "number" ? parsedJson.code : 500,
61
+ message: "message" in parsedJson && typeof parsedJson.message === "string" ? parsedJson.message : "",
62
+ stack: "stack" in parsedJson && Array.isArray(parsedJson.stack) ? parsedJson.stack.join("\n") : void 0,
63
+ data: "data" in parsedJson ? parsedJson.data : void 0
64
+ });
65
+ }
66
+ }
67
+
68
+ async function arriRequest(opts) {
69
+ let url = opts.url;
70
+ let body;
71
+ let contentType;
72
+ switch (opts.method) {
73
+ case "get":
74
+ case "head":
75
+ if (opts.params && typeof opts.params === "object") {
76
+ const urlParts = [];
77
+ Object.keys(opts.params).forEach((key) => {
78
+ urlParts.push(`${key}=${opts.params[key]}`);
79
+ });
80
+ url = `${opts.url}?${urlParts.join("&")}`;
81
+ }
82
+ break;
83
+ default:
84
+ if (opts.params && typeof opts.params === "object") {
85
+ body = opts.serializer(opts.params);
86
+ contentType = "application/json";
87
+ }
88
+ break;
89
+ }
90
+ try {
91
+ let headers = {};
92
+ if (typeof opts.headers === "function") {
93
+ headers = opts.headers();
94
+ } else {
95
+ headers = opts.headers ?? {};
96
+ }
97
+ if (contentType)
98
+ headers["Content-Type"] = contentType;
99
+ if (opts.clientVersion)
100
+ headers["client-version"] = opts.clientVersion;
101
+ const result = await ofetch(url, {
102
+ method: opts.method,
103
+ body,
104
+ headers
105
+ });
106
+ return opts.parser(result);
107
+ } catch (err) {
108
+ const error = err;
109
+ if (isArriError(error.data)) {
110
+ throw new ArriErrorInstance(error.data);
111
+ } else {
112
+ throw new ArriErrorInstance({
113
+ code: error.statusCode ?? 500,
114
+ message: error.statusMessage ?? error.message ?? `Error connecting to ${url}`,
115
+ data: error.data,
116
+ stack: error.stack
117
+ });
118
+ }
119
+ }
120
+ }
121
+ async function arriSafeRequest(opts) {
122
+ try {
123
+ const result = await arriRequest(opts);
124
+ return {
125
+ success: true,
126
+ value: result
127
+ };
128
+ } catch (err) {
129
+ if (err instanceof ArriErrorInstance) {
130
+ return {
131
+ success: false,
132
+ error: err
133
+ };
134
+ }
135
+ if (err instanceof FetchError) {
136
+ return {
137
+ success: false,
138
+ error: new ArriErrorInstance({
139
+ code: err.statusCode ?? 0,
140
+ message: err.statusMessage ?? "",
141
+ stack: err.stack,
142
+ data: err.data
143
+ })
144
+ };
145
+ }
146
+ return {
147
+ success: false,
148
+ error: new ArriErrorInstance({
149
+ code: 500,
150
+ message: `Unknown error connecting to ${opts.url}`,
151
+ data: err
152
+ })
153
+ };
154
+ }
155
+ }
156
+
157
+ function arriSseRequest(opts, options) {
158
+ let url = opts.url;
159
+ let body;
160
+ switch (opts.method) {
161
+ case "get":
162
+ case "head":
163
+ if (opts.params && typeof opts.params === "object" && opts.params !== null) {
164
+ const urlParts = [];
165
+ Object.keys(opts.params).forEach((key) => {
166
+ urlParts.push(`${key}=${opts.params[key]}`);
167
+ });
168
+ url = `${opts.url}?${urlParts.join("&")}`;
169
+ }
170
+ break;
171
+ default:
172
+ if (opts.params && typeof opts.params === "object") {
173
+ body = opts.serializer(opts.params);
174
+ }
175
+ break;
176
+ }
177
+ const eventSource = new EventSourcePlus(url, {
178
+ method: opts.method ?? "get",
179
+ headers: () => {
180
+ let headers;
181
+ if (typeof opts.headers === "function") {
182
+ headers = opts.headers();
183
+ } else {
184
+ headers = opts.headers ?? {};
185
+ }
186
+ if (opts.clientVersion) {
187
+ headers["client-version"] = opts.clientVersion;
188
+ }
189
+ return headers;
190
+ },
191
+ body,
192
+ maxRetryCount: options.maxRetryCount,
193
+ maxRetryInterval: options.maxRetryInterval
194
+ });
195
+ const controller = eventSource.listen({
196
+ onMessage(message) {
197
+ if (message.event === "message" || message.event === void 0 || message.event === "") {
198
+ options.onMessage?.(opts.parser(message.data));
199
+ return;
200
+ }
201
+ if (message.event === "error") {
202
+ options.onErrorMessage?.(
203
+ ArriErrorInstance.fromJson(message.data)
204
+ );
205
+ return;
206
+ }
207
+ if (message.event === "done") {
208
+ controller.abort();
209
+ }
210
+ },
211
+ onRequest(context) {
212
+ options.onRequest?.(context);
213
+ },
214
+ onRequestError(context) {
215
+ options.onRequestError?.({
216
+ ...context,
217
+ error: new ArriErrorInstance({
218
+ code: 0,
219
+ message: context.error.message,
220
+ data: context.error
221
+ })
222
+ });
223
+ },
224
+ onResponse(context) {
225
+ options.onResponse?.(context);
226
+ },
227
+ async onResponseError(context) {
228
+ if (!options.onResponseError) {
229
+ return;
230
+ }
231
+ try {
232
+ const arriError = ArriErrorInstance.fromJson(
233
+ await context.response.json()
234
+ );
235
+ options.onResponseError({
236
+ ...context,
237
+ error: arriError
238
+ });
239
+ } catch (_) {
240
+ const arriError = new ArriErrorInstance({
241
+ code: context.response.status ?? 0,
242
+ message: context.response.statusText
243
+ });
244
+ options.onResponseError({ ...context, error: arriError });
245
+ }
246
+ }
247
+ });
248
+ return controller;
249
+ }
250
+ function parseSseEvent(input, dataParser) {
251
+ let id;
252
+ let event;
253
+ let data;
254
+ const lines = input.split("\n");
255
+ for (const line of lines) {
256
+ if (line.startsWith("id:")) {
257
+ id = line.substring(3).trim();
258
+ continue;
259
+ }
260
+ if (line.startsWith("event:")) {
261
+ event = line.substring(6).trim();
262
+ continue;
263
+ }
264
+ if (line.startsWith("data:")) {
265
+ data = dataParser(line.substring(5).trim());
266
+ }
267
+ }
268
+ if (!data) {
269
+ return void 0;
270
+ }
271
+ return {
272
+ id,
273
+ event,
274
+ data
275
+ };
276
+ }
277
+ function parseSseEvents(input, dataParser) {
278
+ const eventStrings = input.split("\n\n");
279
+ const events = [];
280
+ for (const str of eventStrings) {
281
+ const event = parseSseEvent(str, dataParser);
282
+ if (event) {
283
+ events.push(event);
284
+ }
285
+ }
286
+ return events;
287
+ }
288
+
289
+ var __defProp = Object.defineProperty;
290
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
291
+ var __publicField = (obj, key, value) => {
292
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
293
+ return value;
294
+ };
295
+ function isBrowser() {
296
+ return typeof window !== "undefined";
297
+ }
298
+ function connectWebsocket(url, protocol) {
299
+ if (isBrowser()) {
300
+ return new WebSocket(url, protocol);
301
+ }
302
+ return new NodeWebsocket(url, {
303
+ protocol
304
+ });
305
+ }
306
+ function arriWsRequest(opts, retryCount = 0) {
307
+ let url = opts.url.replace("http://", "ws://").replace("https://", "wss://");
308
+ let headers;
309
+ if (typeof opts.headers === "function") {
310
+ headers = opts.headers();
311
+ } else {
312
+ headers = opts.headers;
313
+ }
314
+ if (headers) {
315
+ if (opts.clientVersion)
316
+ headers["client-version"] = opts.clientVersion;
317
+ const queryParts = [];
318
+ for (const key of Object.keys(headers)) {
319
+ queryParts.push(`${key}=${headers[key]}`);
320
+ }
321
+ url += `?${queryParts.join("&")}`;
322
+ }
323
+ try {
324
+ const controller = new WsController({
325
+ url,
326
+ parser: opts.parser,
327
+ serializer: opts.serializer ?? ((_) => ""),
328
+ onOpen: opts.onOpen,
329
+ onClose: opts.onClose,
330
+ onMessage: opts.onMessage,
331
+ onErrorMessage: opts.onError,
332
+ onConnectionError: opts.onConnectionError
333
+ });
334
+ return controller;
335
+ } catch (err) {
336
+ console.error(err);
337
+ if (opts.onConnectionError) {
338
+ opts.onConnectionError(err);
339
+ }
340
+ return arriWsRequest(opts, retryCount + 1);
341
+ }
342
+ }
343
+ class WsController {
344
+ constructor(opts) {
345
+ __publicField(this, "url");
346
+ __publicField(this, "_ws");
347
+ __publicField(this, "_serializer");
348
+ __publicField(this, "_parser");
349
+ __publicField(this, "onMessage");
350
+ __publicField(this, "onErrorMessage");
351
+ __publicField(this, "onConnectionError");
352
+ __publicField(this, "onOpen");
353
+ __publicField(this, "onClose");
354
+ this.url = opts.url;
355
+ this._serializer = opts.serializer;
356
+ this._parser = opts.parser;
357
+ this.onOpen = opts.onOpen;
358
+ this.onClose = opts.onClose;
359
+ this.onErrorMessage = opts.onErrorMessage;
360
+ this.onConnectionError = opts.onConnectionError;
361
+ this.onMessage = opts.onMessage;
362
+ }
363
+ connect() {
364
+ this._ws = connectWebsocket(this.url);
365
+ this._ws.onopen = () => {
366
+ this.onOpen?.();
367
+ };
368
+ this._ws.onclose = () => {
369
+ this.onClose?.();
370
+ };
371
+ this._ws.onmessage = (event) => {
372
+ this._handleMessage(event);
373
+ };
374
+ this._ws.onerror = (event) => {
375
+ this.onConnectionError?.(
376
+ new ArriErrorInstance({
377
+ code: "errno" in event.error && typeof event.error.errno === "number" ? event.error.errno : 0,
378
+ message: event.error instanceof Error ? event.error.message : `Error connecting to ${this.url}`,
379
+ data: event.error,
380
+ stack: event.error instanceof Error ? event.error.stack : void 0
381
+ })
382
+ );
383
+ };
384
+ }
385
+ readyState() {
386
+ return this._ws?.readyState ?? -1;
387
+ }
388
+ send(message) {
389
+ const payload = this._serializer(message);
390
+ this._ws?.send(payload);
391
+ }
392
+ close() {
393
+ this._ws?.close();
394
+ }
395
+ _handleMessage(msg) {
396
+ if (typeof msg.data !== "string") {
397
+ return;
398
+ }
399
+ const response = parsedWsResponse(msg.data);
400
+ switch (response.event) {
401
+ case "error": {
402
+ if (!this.onErrorMessage) {
403
+ return;
404
+ }
405
+ const err = ArriErrorInstance.fromJson(response.data);
406
+ this.onErrorMessage(err);
407
+ break;
408
+ }
409
+ case "message": {
410
+ if (!this.onMessage) {
411
+ return;
412
+ }
413
+ const msg2 = this._parser(response.data);
414
+ this.onMessage(msg2);
415
+ break;
416
+ }
417
+ default:
418
+ console.warn("Invalid response from server", msg);
419
+ break;
420
+ }
421
+ }
422
+ }
423
+ function parsedWsResponse(input) {
424
+ const lines = input.split("\n");
425
+ let event = "unknown";
426
+ let data = "";
427
+ for (const line of lines) {
428
+ const trimmedLine = line.trim();
429
+ if (trimmedLine.startsWith("event: ")) {
430
+ switch (trimmedLine.substring(6).trim()) {
431
+ case "error":
432
+ event = "error";
433
+ break;
434
+ case "message":
435
+ event = "message";
436
+ break;
437
+ }
438
+ continue;
439
+ }
440
+ if (trimmedLine.startsWith("data: ")) {
441
+ data = trimmedLine.substring(5).trim();
442
+ continue;
443
+ }
444
+ }
445
+ return {
446
+ event,
447
+ data
448
+ };
449
+ }
450
+
451
+ export { ArriErrorInstance, arriRequest, arriSafeRequest, arriSseRequest, arriWsRequest, isArriError, parseSseEvent, parseSseEvents, parsedWsResponse };
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@arrirpc/client",
3
+ "version": "0.45.0",
4
+ "type": "module",
5
+ "main": "./dist/index.cjs",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "license": "MIT",
12
+ "author": {
13
+ "name": "joshmossas",
14
+ "url": "https://github.com/joshmossas"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/modiimedia/arri/issues"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/modiimedia/arri.git",
22
+ "directory": "languages/ts/ts-client"
23
+ },
24
+ "dependencies": {
25
+ "event-source-plus": "^0.0.6",
26
+ "ofetch": "^1.3.4",
27
+ "ws": "^8.17.0",
28
+ "@arrirpc/schema": "0.45.0"
29
+ },
30
+ "devDependencies": {
31
+ "@types/ws": "^8.5.10"
32
+ }
33
+ }