@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 +9 -0
- package/README.md +11 -0
- package/dist/index.cjs +465 -0
- package/dist/index.d.cts +129 -0
- package/dist/index.d.mts +129 -0
- package/dist/index.d.ts +129 -0
- package/dist/index.mjs +451 -0
- package/package.json +33 -0
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
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;
|
package/dist/index.d.cts
ADDED
|
@@ -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.d.mts
ADDED
|
@@ -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.d.ts
ADDED
|
@@ -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
|
+
}
|