@rocksky/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +279 -0
  3. package/dist/client.d.ts +107 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/errors.d.ts +26 -0
  6. package/dist/errors.d.ts.map +1 -0
  7. package/dist/http.d.ts +28 -0
  8. package/dist/http.d.ts.map +1 -0
  9. package/dist/index.d.ts +18 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +1492 -0
  12. package/dist/namespaces/_helpers.d.ts +9 -0
  13. package/dist/namespaces/_helpers.d.ts.map +1 -0
  14. package/dist/namespaces/actor.d.ts +30 -0
  15. package/dist/namespaces/actor.d.ts.map +1 -0
  16. package/dist/namespaces/album.d.ts +18 -0
  17. package/dist/namespaces/album.d.ts.map +1 -0
  18. package/dist/namespaces/apikey.d.ts +27 -0
  19. package/dist/namespaces/apikey.d.ts.map +1 -0
  20. package/dist/namespaces/artist.d.ts +31 -0
  21. package/dist/namespaces/artist.d.ts.map +1 -0
  22. package/dist/namespaces/charts.d.ts +25 -0
  23. package/dist/namespaces/charts.d.ts.map +1 -0
  24. package/dist/namespaces/dropbox.d.ts +19 -0
  25. package/dist/namespaces/dropbox.d.ts.map +1 -0
  26. package/dist/namespaces/feed.d.ts +38 -0
  27. package/dist/namespaces/feed.d.ts.map +1 -0
  28. package/dist/namespaces/googledrive.d.ts +16 -0
  29. package/dist/namespaces/googledrive.d.ts.map +1 -0
  30. package/dist/namespaces/graph.d.ts +28 -0
  31. package/dist/namespaces/graph.d.ts.map +1 -0
  32. package/dist/namespaces/like.d.ts +14 -0
  33. package/dist/namespaces/like.d.ts.map +1 -0
  34. package/dist/namespaces/mirror.d.ts +15 -0
  35. package/dist/namespaces/mirror.d.ts.map +1 -0
  36. package/dist/namespaces/player.d.ts +41 -0
  37. package/dist/namespaces/player.d.ts.map +1 -0
  38. package/dist/namespaces/playlist.d.ts +40 -0
  39. package/dist/namespaces/playlist.d.ts.map +1 -0
  40. package/dist/namespaces/scrobble.d.ts +43 -0
  41. package/dist/namespaces/scrobble.d.ts.map +1 -0
  42. package/dist/namespaces/shout.d.ts +38 -0
  43. package/dist/namespaces/shout.d.ts.map +1 -0
  44. package/dist/namespaces/song.d.ts +48 -0
  45. package/dist/namespaces/song.d.ts.map +1 -0
  46. package/dist/namespaces/spotify.d.ts +17 -0
  47. package/dist/namespaces/spotify.d.ts.map +1 -0
  48. package/dist/namespaces/stats.d.ts +14 -0
  49. package/dist/namespaces/stats.d.ts.map +1 -0
  50. package/dist/paginate.d.ts +38 -0
  51. package/dist/paginate.d.ts.map +1 -0
  52. package/dist/pipe.d.ts +36 -0
  53. package/dist/pipe.d.ts.map +1 -0
  54. package/dist/realtime.d.ts +144 -0
  55. package/dist/realtime.d.ts.map +1 -0
  56. package/dist/types.d.ts +29 -0
  57. package/dist/types.d.ts.map +1 -0
  58. package/package.json +65 -0
  59. package/src/client.ts +235 -0
  60. package/src/errors.ts +47 -0
  61. package/src/http.ts +195 -0
  62. package/src/index.ts +85 -0
  63. package/src/namespaces/_helpers.ts +17 -0
  64. package/src/namespaces/actor.ts +89 -0
  65. package/src/namespaces/album.ts +34 -0
  66. package/src/namespaces/apikey.ts +50 -0
  67. package/src/namespaces/artist.ts +74 -0
  68. package/src/namespaces/charts.ts +47 -0
  69. package/src/namespaces/dropbox.ts +47 -0
  70. package/src/namespaces/feed.ts +106 -0
  71. package/src/namespaces/googledrive.ts +36 -0
  72. package/src/namespaces/graph.ts +63 -0
  73. package/src/namespaces/like.ts +40 -0
  74. package/src/namespaces/mirror.ts +31 -0
  75. package/src/namespaces/player.ts +127 -0
  76. package/src/namespaces/playlist.ts +85 -0
  77. package/src/namespaces/scrobble.ts +67 -0
  78. package/src/namespaces/shout.ts +90 -0
  79. package/src/namespaces/song.ts +81 -0
  80. package/src/namespaces/spotify.ts +52 -0
  81. package/src/namespaces/stats.ts +23 -0
  82. package/src/paginate.ts +90 -0
  83. package/src/pipe.ts +146 -0
  84. package/src/realtime.ts +408 -0
  85. package/src/types.ts +41 -0
package/dist/index.js ADDED
@@ -0,0 +1,1492 @@
1
+ // src/errors.ts
2
+ class RockskyError extends Error {
3
+ cause;
4
+ constructor(message, options) {
5
+ super(message);
6
+ this.name = "RockskyError";
7
+ this.cause = options?.cause;
8
+ }
9
+ }
10
+
11
+ class RockskyHttpError extends RockskyError {
12
+ status;
13
+ statusText;
14
+ url;
15
+ body;
16
+ constructor(args) {
17
+ const message = args.message ?? `Rocksky API ${args.status} ${args.statusText} at ${args.url}`;
18
+ super(message);
19
+ this.name = "RockskyHttpError";
20
+ this.status = args.status;
21
+ this.statusText = args.statusText;
22
+ this.url = args.url;
23
+ this.body = args.body;
24
+ }
25
+ }
26
+
27
+ class RockskyTimeoutError extends RockskyError {
28
+ constructor(ms) {
29
+ super(`Rocksky request timed out after ${ms}ms`);
30
+ this.name = "RockskyTimeoutError";
31
+ }
32
+ }
33
+
34
+ class RockskyAuthError extends RockskyError {
35
+ constructor(message = "Authentication required") {
36
+ super(message);
37
+ this.name = "RockskyAuthError";
38
+ }
39
+ }
40
+
41
+ // src/types.ts
42
+ var DEFAULT_BASE_URL = "https://api.rocksky.app";
43
+
44
+ // src/http.ts
45
+ function buildConfig(opts) {
46
+ const headers = {
47
+ accept: "application/json",
48
+ ...opts.userAgent ? { "user-agent": opts.userAgent } : {},
49
+ ...opts.headers ?? {}
50
+ };
51
+ return {
52
+ baseUrl: stripTrailingSlash(opts.baseUrl ?? DEFAULT_BASE_URL),
53
+ auth: opts.auth,
54
+ fetch: opts.fetch ?? globalThis.fetch.bind(globalThis),
55
+ headers,
56
+ timeoutMs: opts.timeoutMs ?? 30000,
57
+ retries: opts.retries ?? 0,
58
+ retryDelayMs: opts.retryDelayMs ?? 300
59
+ };
60
+ }
61
+ function stripTrailingSlash(url) {
62
+ return url.endsWith("/") ? url.slice(0, -1) : url;
63
+ }
64
+ async function resolveAuth(provider) {
65
+ if (provider == null)
66
+ return;
67
+ if (typeof provider === "string")
68
+ return provider;
69
+ return await provider();
70
+ }
71
+ function serializeParams(params) {
72
+ if (!params)
73
+ return "";
74
+ const usp = new URLSearchParams;
75
+ for (const [k, v] of Object.entries(params)) {
76
+ if (v == null)
77
+ continue;
78
+ if (Array.isArray(v)) {
79
+ for (const item of v) {
80
+ if (item == null)
81
+ continue;
82
+ usp.append(k, String(item));
83
+ }
84
+ } else if (typeof v === "boolean") {
85
+ usp.append(k, v ? "true" : "false");
86
+ } else {
87
+ usp.append(k, String(v));
88
+ }
89
+ }
90
+ const s = usp.toString();
91
+ return s ? `?${s}` : "";
92
+ }
93
+ async function xrpcCall(config, nsid, method, opts = {}) {
94
+ const url = `${config.baseUrl}/xrpc/${nsid}` + serializeParams(opts.params);
95
+ const timeoutMs = opts.timeoutMs ?? config.timeoutMs;
96
+ const retries = opts.retries ?? config.retries;
97
+ const headers = {
98
+ ...config.headers,
99
+ ...opts.headers ?? {}
100
+ };
101
+ const authProvider = opts.auth === undefined ? config.auth : opts.auth;
102
+ const token = await resolveAuth(authProvider);
103
+ if (token) {
104
+ headers.authorization = `Bearer ${token}`;
105
+ } else if (opts.requireAuth) {
106
+ throw new RockskyAuthError(`${nsid} requires authentication — provide an "auth" token`);
107
+ }
108
+ const init = {
109
+ method,
110
+ headers,
111
+ signal: opts.signal
112
+ };
113
+ if (method === "POST" && opts.body !== undefined) {
114
+ headers["content-type"] = "application/json";
115
+ init.body = JSON.stringify(opts.body);
116
+ }
117
+ let lastErr;
118
+ for (let attempt = 0;attempt <= retries; attempt++) {
119
+ try {
120
+ return await runOnce(config.fetch, url, init, timeoutMs);
121
+ } catch (err) {
122
+ lastErr = err;
123
+ if (!isRetryable(err) || attempt === retries)
124
+ throw err;
125
+ await sleep(config.retryDelayMs * Math.pow(2, attempt));
126
+ }
127
+ }
128
+ throw lastErr;
129
+ }
130
+ async function runOnce(fetchImpl, url, init, timeoutMs) {
131
+ const controller = new AbortController;
132
+ const upstream = init.signal;
133
+ const onAbort = () => controller.abort(upstream?.reason);
134
+ upstream?.addEventListener("abort", onAbort, { once: true });
135
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
136
+ try {
137
+ const res = await fetchImpl(url, { ...init, signal: controller.signal });
138
+ const text = await res.text();
139
+ const body = parseMaybeJson(text);
140
+ if (!res.ok) {
141
+ throw new RockskyHttpError({
142
+ status: res.status,
143
+ statusText: res.statusText,
144
+ url,
145
+ body
146
+ });
147
+ }
148
+ return body;
149
+ } catch (err) {
150
+ if (err instanceof DOMException && err.name === "AbortError") {
151
+ if (upstream?.aborted)
152
+ throw err;
153
+ throw new RockskyTimeoutError(timeoutMs);
154
+ }
155
+ throw err;
156
+ } finally {
157
+ clearTimeout(timer);
158
+ upstream?.removeEventListener("abort", onAbort);
159
+ }
160
+ }
161
+ function parseMaybeJson(text) {
162
+ if (!text)
163
+ return null;
164
+ try {
165
+ return JSON.parse(text);
166
+ } catch {
167
+ return text;
168
+ }
169
+ }
170
+ function isRetryable(err) {
171
+ if (err instanceof RockskyTimeoutError)
172
+ return true;
173
+ if (err instanceof RockskyHttpError) {
174
+ return err.status >= 500 || err.status === 429;
175
+ }
176
+ return false;
177
+ }
178
+ function sleep(ms) {
179
+ return new Promise((r) => setTimeout(r, ms));
180
+ }
181
+
182
+ // src/paginate.ts
183
+ function paginate(args) {
184
+ const pageSize = args.pageSize ?? 50;
185
+ const maxItems = args.maxItems ?? Number.POSITIVE_INFINITY;
186
+ async function* iter() {
187
+ let offset = 0;
188
+ let cursor;
189
+ let yielded = 0;
190
+ while (yielded < maxItems) {
191
+ checkAbort(args.signal);
192
+ const result = await args.fetch({ limit: pageSize, offset, cursor });
193
+ checkAbort(args.signal);
194
+ const { items, nextCursor } = normalize(result);
195
+ if (items.length === 0)
196
+ return;
197
+ for (const item of items) {
198
+ if (yielded >= maxItems)
199
+ return;
200
+ yield item;
201
+ yielded++;
202
+ }
203
+ offset += items.length;
204
+ if (nextCursor !== undefined) {
205
+ if (nextCursor === cursor || nextCursor === null)
206
+ return;
207
+ cursor = nextCursor ?? undefined;
208
+ } else if (items.length < pageSize) {
209
+ return;
210
+ }
211
+ }
212
+ }
213
+ const iterable = { [Symbol.asyncIterator]: iter };
214
+ return Object.assign(iterable, {
215
+ async toArray() {
216
+ const out = [];
217
+ for await (const item of iter())
218
+ out.push(item);
219
+ return out;
220
+ }
221
+ });
222
+ }
223
+ function normalize(result) {
224
+ if (Array.isArray(result))
225
+ return { items: result };
226
+ return { items: result.items, nextCursor: result.cursor ?? null };
227
+ }
228
+ function checkAbort(signal) {
229
+ if (signal?.aborted) {
230
+ throw signal.reason ?? new DOMException("aborted", "AbortError");
231
+ }
232
+ }
233
+
234
+ // src/realtime.ts
235
+ var RECONNECT_DEFAULTS = {
236
+ backoffMs: 500,
237
+ maxBackoffMs: 30000,
238
+ maxAttempts: Number.POSITIVE_INFINITY,
239
+ factor: 2
240
+ };
241
+
242
+ class RealtimeClient {
243
+ options;
244
+ ws;
245
+ listeners = new Map;
246
+ reconnectAttempts = 0;
247
+ pingTimer;
248
+ closed = false;
249
+ deviceId;
250
+ url;
251
+ reconnectOpts;
252
+ WsCtor;
253
+ constructor(options) {
254
+ this.options = options;
255
+ this.url = options.url ?? deriveWsUrl(options.baseUrl ?? DEFAULT_BASE_URL);
256
+ this.reconnectOpts = options.reconnect === false ? null : {
257
+ ...RECONNECT_DEFAULTS,
258
+ ...typeof options.reconnect === "object" ? options.reconnect : {}
259
+ };
260
+ const ctor = options.webSocket ?? globalThis.WebSocket;
261
+ if (!ctor) {
262
+ throw new RockskyError("No WebSocket implementation available — pass `webSocket` in options");
263
+ }
264
+ this.WsCtor = ctor;
265
+ }
266
+ get currentDeviceId() {
267
+ return this.deviceId;
268
+ }
269
+ get isOpen() {
270
+ return this.ws?.readyState === 1;
271
+ }
272
+ on(event, listener) {
273
+ const set = this.listeners.get(event) ?? new Set;
274
+ set.add(listener);
275
+ this.listeners.set(event, set);
276
+ return () => this.off(event, listener);
277
+ }
278
+ off(event, listener) {
279
+ this.listeners.get(event)?.delete(listener);
280
+ }
281
+ emit(event, payload) {
282
+ const set = this.listeners.get(event);
283
+ if (!set)
284
+ return;
285
+ for (const fn of set) {
286
+ try {
287
+ fn(payload);
288
+ } catch (err) {
289
+ const errSet = this.listeners.get("error");
290
+ errSet?.forEach((f) => f(err));
291
+ }
292
+ }
293
+ }
294
+ async connect() {
295
+ this.closed = false;
296
+ const ws = new this.WsCtor(this.url);
297
+ this.ws = ws;
298
+ await new Promise((resolve, reject) => {
299
+ const onOpen = () => {
300
+ ws.removeEventListener("open", onOpen);
301
+ ws.removeEventListener("error", onError);
302
+ resolve();
303
+ };
304
+ const onError = (err) => {
305
+ ws.removeEventListener("open", onOpen);
306
+ ws.removeEventListener("error", onError);
307
+ reject(err);
308
+ };
309
+ ws.addEventListener("open", onOpen);
310
+ ws.addEventListener("error", onError);
311
+ });
312
+ this.attachHandlers(ws);
313
+ this.reconnectAttempts = 0;
314
+ this.emit("open", undefined);
315
+ if (this.options.autoRegister !== false) {
316
+ await this.register();
317
+ }
318
+ this.startPing();
319
+ }
320
+ async register() {
321
+ const token = await resolveToken(this.options.token);
322
+ this.sendRaw({
323
+ type: "register",
324
+ clientName: this.options.clientName ?? "rocksky-sdk",
325
+ token
326
+ });
327
+ }
328
+ async sendMessage(data) {
329
+ if (!this.deviceId) {
330
+ throw new RockskyError("Cannot send message — device not registered yet (await connect() first)");
331
+ }
332
+ const token = await resolveToken(this.options.token);
333
+ this.sendRaw({
334
+ type: "message",
335
+ data,
336
+ device_id: this.deviceId,
337
+ token
338
+ });
339
+ }
340
+ async sendControl(args) {
341
+ const token = await resolveToken(this.options.token);
342
+ this.sendRaw({
343
+ type: args.type ?? "control",
344
+ target: args.target,
345
+ action: args.action,
346
+ args: args.args,
347
+ token
348
+ });
349
+ }
350
+ ping() {
351
+ if (this.ws?.readyState === 1)
352
+ this.ws.send("ping");
353
+ }
354
+ sendRaw(payload) {
355
+ if (this.ws?.readyState !== 1) {
356
+ throw new RockskyError("WebSocket is not open");
357
+ }
358
+ this.ws.send(typeof payload === "string" ? payload : JSON.stringify(payload));
359
+ }
360
+ async close(code = 1000, reason = "client closing") {
361
+ this.closed = true;
362
+ this.stopPing();
363
+ this.ws?.close(code, reason);
364
+ }
365
+ attachHandlers(ws) {
366
+ ws.addEventListener("message", (event) => {
367
+ const raw = event.data;
368
+ if (raw === "pong")
369
+ return;
370
+ let parsed;
371
+ try {
372
+ parsed = typeof raw === "string" ? JSON.parse(raw) : raw;
373
+ } catch {
374
+ this.emit("raw", raw);
375
+ return;
376
+ }
377
+ this.emit("raw", parsed);
378
+ this.dispatch(parsed);
379
+ });
380
+ ws.addEventListener("close", (event) => {
381
+ this.stopPing();
382
+ this.emit("close", event);
383
+ if (!this.closed && this.reconnectOpts)
384
+ this.scheduleReconnect();
385
+ });
386
+ ws.addEventListener("error", (err) => {
387
+ this.emit("error", err);
388
+ });
389
+ }
390
+ dispatch(msg) {
391
+ if (!msg || typeof msg !== "object")
392
+ return;
393
+ const m = msg;
394
+ if (m.status === "registered" && typeof m.deviceId === "string") {
395
+ this.deviceId = m.deviceId;
396
+ this.emit("registered", { deviceId: m.deviceId });
397
+ return;
398
+ }
399
+ if (m.type === "device_registered" && typeof m.deviceId === "string") {
400
+ this.emit("deviceRegistered", {
401
+ deviceId: m.deviceId,
402
+ clientName: String(m.clientName ?? "")
403
+ });
404
+ return;
405
+ }
406
+ if (m.type === "message" && typeof m.device_id === "string") {
407
+ this.emit("message", {
408
+ data: m.data,
409
+ device_id: m.device_id
410
+ });
411
+ return;
412
+ }
413
+ if (typeof m.action === "string") {
414
+ this.emit("control", {
415
+ type: String(m.type ?? "control"),
416
+ action: m.action,
417
+ args: m.args
418
+ });
419
+ }
420
+ }
421
+ scheduleReconnect() {
422
+ if (!this.reconnectOpts)
423
+ return;
424
+ if (this.reconnectAttempts >= this.reconnectOpts.maxAttempts)
425
+ return;
426
+ const delay = Math.min(this.reconnectOpts.backoffMs * Math.pow(this.reconnectOpts.factor, this.reconnectAttempts), this.reconnectOpts.maxBackoffMs);
427
+ this.reconnectAttempts++;
428
+ setTimeout(() => {
429
+ if (this.closed)
430
+ return;
431
+ this.connect().catch((err) => this.emit("error", err));
432
+ }, delay);
433
+ }
434
+ startPing() {
435
+ const ms = this.options.pingIntervalMs ?? 25000;
436
+ if (ms <= 0)
437
+ return;
438
+ this.pingTimer = setInterval(() => this.ping(), ms);
439
+ }
440
+ stopPing() {
441
+ if (this.pingTimer) {
442
+ clearInterval(this.pingTimer);
443
+ this.pingTimer = undefined;
444
+ }
445
+ }
446
+ }
447
+ function createRealtimeClient(opts) {
448
+ return new RealtimeClient(opts);
449
+ }
450
+
451
+ class RealtimeClientBuilder {
452
+ opts = {};
453
+ url(u) {
454
+ this.opts.url = u;
455
+ return this;
456
+ }
457
+ baseUrl(u) {
458
+ this.opts.baseUrl = u;
459
+ return this;
460
+ }
461
+ token(t) {
462
+ this.opts.token = t;
463
+ return this;
464
+ }
465
+ clientName(name) {
466
+ this.opts.clientName = name;
467
+ return this;
468
+ }
469
+ autoRegister(value) {
470
+ this.opts.autoRegister = value;
471
+ return this;
472
+ }
473
+ reconnect(value) {
474
+ this.opts.reconnect = value;
475
+ return this;
476
+ }
477
+ pingInterval(ms) {
478
+ this.opts.pingIntervalMs = ms;
479
+ return this;
480
+ }
481
+ webSocket(ctor) {
482
+ this.opts.webSocket = ctor;
483
+ return this;
484
+ }
485
+ build() {
486
+ if (!this.opts.token) {
487
+ throw new RockskyError("RealtimeClientBuilder: token() is required before build()");
488
+ }
489
+ return new RealtimeClient(this.opts);
490
+ }
491
+ }
492
+ ((RealtimeClient) => {
493
+ function builder() {
494
+ return new RealtimeClientBuilder;
495
+ }
496
+ RealtimeClient.builder = builder;
497
+ })(RealtimeClient ||= {});
498
+ function deriveWsUrl(httpBase) {
499
+ const u = new URL(httpBase);
500
+ u.protocol = u.protocol === "https:" ? "wss:" : "ws:";
501
+ u.pathname = u.pathname.replace(/\/$/, "") + "/ws";
502
+ return u.toString();
503
+ }
504
+ async function resolveToken(source) {
505
+ return typeof source === "function" ? await source() : source;
506
+ }
507
+
508
+ // src/namespaces/actor.ts
509
+ class ActorNamespace {
510
+ call;
511
+ constructor(call) {
512
+ this.call = call;
513
+ }
514
+ getProfile(params = {}, opts) {
515
+ return this.call("app.rocksky.actor.getProfile", "GET", {
516
+ params,
517
+ ...opts
518
+ });
519
+ }
520
+ getActorAlbums(params, opts) {
521
+ return this.call("app.rocksky.actor.getActorAlbums", "GET", {
522
+ params,
523
+ ...opts
524
+ });
525
+ }
526
+ getActorArtists(params, opts) {
527
+ return this.call("app.rocksky.actor.getActorArtists", "GET", {
528
+ params,
529
+ ...opts
530
+ });
531
+ }
532
+ getActorSongs(params, opts) {
533
+ return this.call("app.rocksky.actor.getActorSongs", "GET", {
534
+ params,
535
+ ...opts
536
+ });
537
+ }
538
+ getActorScrobbles(params, opts) {
539
+ return this.call("app.rocksky.actor.getActorScrobbles", "GET", {
540
+ params,
541
+ ...opts
542
+ });
543
+ }
544
+ getActorLovedSongs(params, opts) {
545
+ return this.call("app.rocksky.actor.getActorLovedSongs", "GET", {
546
+ params,
547
+ ...opts
548
+ });
549
+ }
550
+ getActorPlaylists(params, opts) {
551
+ return this.call("app.rocksky.actor.getActorPlaylists", "GET", {
552
+ params,
553
+ ...opts
554
+ });
555
+ }
556
+ getActorNeighbours(params, opts) {
557
+ return this.call("app.rocksky.actor.getActorNeighbours", "GET", {
558
+ params,
559
+ ...opts
560
+ });
561
+ }
562
+ getActorCompatibility(params, opts) {
563
+ return this.call("app.rocksky.actor.getActorCompatibility", "GET", {
564
+ params,
565
+ ...opts
566
+ });
567
+ }
568
+ }
569
+
570
+ // src/namespaces/album.ts
571
+ class AlbumNamespace {
572
+ call;
573
+ constructor(call) {
574
+ this.call = call;
575
+ }
576
+ getAlbum(params, opts) {
577
+ return this.call("app.rocksky.album.getAlbum", "GET", {
578
+ params,
579
+ ...opts
580
+ });
581
+ }
582
+ getAlbums(params = {}, opts) {
583
+ return this.call("app.rocksky.album.getAlbums", "GET", {
584
+ params,
585
+ ...opts
586
+ });
587
+ }
588
+ getAlbumTracks(params, opts) {
589
+ return this.call("app.rocksky.album.getAlbumTracks", "GET", {
590
+ params,
591
+ ...opts
592
+ });
593
+ }
594
+ }
595
+
596
+ // src/namespaces/apikey.ts
597
+ class ApikeyNamespace {
598
+ call;
599
+ constructor(call) {
600
+ this.call = call;
601
+ }
602
+ getApikeys(params = {}, opts) {
603
+ return this.call("app.rocksky.apikey.getApikeys", "GET", {
604
+ params,
605
+ requireAuth: true,
606
+ ...opts
607
+ });
608
+ }
609
+ createApikey(input, opts) {
610
+ return this.call("app.rocksky.apikey.createApikey", "POST", {
611
+ body: input,
612
+ requireAuth: true,
613
+ ...opts
614
+ });
615
+ }
616
+ updateApikey(input, opts) {
617
+ return this.call("app.rocksky.apikey.updateApikey", "POST", {
618
+ body: input,
619
+ requireAuth: true,
620
+ ...opts
621
+ });
622
+ }
623
+ removeApikey(params, opts) {
624
+ return this.call("app.rocksky.apikey.removeApikey", "POST", {
625
+ params,
626
+ requireAuth: true,
627
+ ...opts
628
+ });
629
+ }
630
+ }
631
+
632
+ // src/namespaces/artist.ts
633
+ class ArtistNamespace {
634
+ call;
635
+ constructor(call) {
636
+ this.call = call;
637
+ }
638
+ getArtist(params, opts) {
639
+ return this.call("app.rocksky.artist.getArtist", "GET", {
640
+ params,
641
+ ...opts
642
+ });
643
+ }
644
+ getArtists(params = {}, opts) {
645
+ return this.call("app.rocksky.artist.getArtists", "GET", {
646
+ params,
647
+ ...opts
648
+ });
649
+ }
650
+ getArtistAlbums(params, opts) {
651
+ return this.call("app.rocksky.artist.getArtistAlbums", "GET", {
652
+ params,
653
+ ...opts
654
+ });
655
+ }
656
+ getArtistTracks(params = {}, opts) {
657
+ return this.call("app.rocksky.artist.getArtistTracks", "GET", {
658
+ params,
659
+ ...opts
660
+ });
661
+ }
662
+ getArtistListeners(params, opts) {
663
+ return this.call("app.rocksky.artist.getArtistListeners", "GET", {
664
+ params,
665
+ ...opts
666
+ });
667
+ }
668
+ getArtistRecentListeners(params, opts) {
669
+ return this.call("app.rocksky.artist.getArtistRecentListeners", "GET", {
670
+ params,
671
+ ...opts
672
+ });
673
+ }
674
+ }
675
+
676
+ // src/namespaces/charts.ts
677
+ class ChartsNamespace {
678
+ call;
679
+ constructor(call) {
680
+ this.call = call;
681
+ }
682
+ getScrobblesChart(params = {}, opts) {
683
+ return this.call("app.rocksky.charts.getScrobblesChart", "GET", {
684
+ params,
685
+ ...opts
686
+ });
687
+ }
688
+ getTopArtists(params = {}, opts) {
689
+ return this.call("app.rocksky.charts.getTopArtists", "GET", {
690
+ params,
691
+ ...opts
692
+ });
693
+ }
694
+ getTopTracks(params = {}, opts) {
695
+ return this.call("app.rocksky.charts.getTopTracks", "GET", {
696
+ params,
697
+ ...opts
698
+ });
699
+ }
700
+ }
701
+
702
+ // src/namespaces/dropbox.ts
703
+ class DropboxNamespace {
704
+ call;
705
+ constructor(call) {
706
+ this.call = call;
707
+ }
708
+ getFiles(params = {}, opts) {
709
+ return this.call("app.rocksky.dropbox.getFiles", "GET", {
710
+ params,
711
+ requireAuth: true,
712
+ ...opts
713
+ });
714
+ }
715
+ getMetadata(params, opts) {
716
+ return this.call("app.rocksky.dropbox.getMetadata", "GET", {
717
+ params,
718
+ requireAuth: true,
719
+ ...opts
720
+ });
721
+ }
722
+ getTemporaryLink(params, opts) {
723
+ return this.call("app.rocksky.dropbox.getTemporaryLink", "GET", {
724
+ params,
725
+ requireAuth: true,
726
+ ...opts
727
+ });
728
+ }
729
+ downloadFile(params, opts) {
730
+ return this.call("app.rocksky.dropbox.downloadFile", "GET", {
731
+ params,
732
+ requireAuth: true,
733
+ ...opts
734
+ });
735
+ }
736
+ }
737
+
738
+ // src/namespaces/feed.ts
739
+ class FeedNamespace {
740
+ call;
741
+ constructor(call) {
742
+ this.call = call;
743
+ }
744
+ search(params, opts) {
745
+ return this.call("app.rocksky.feed.search", "GET", {
746
+ params,
747
+ ...opts
748
+ });
749
+ }
750
+ getFeed(params, opts) {
751
+ return this.call("app.rocksky.feed.getFeed", "GET", {
752
+ params,
753
+ ...opts
754
+ });
755
+ }
756
+ getFeedGenerators(params = {}, opts) {
757
+ return this.call("app.rocksky.feed.getFeedGenerators", "GET", {
758
+ params,
759
+ ...opts
760
+ });
761
+ }
762
+ getFeedGenerator(params, opts) {
763
+ return this.call("app.rocksky.feed.getFeedGenerator", "GET", {
764
+ params,
765
+ ...opts
766
+ });
767
+ }
768
+ describeFeedGenerator(opts) {
769
+ return this.call("app.rocksky.feed.describeFeedGenerator", "GET", {
770
+ ...opts
771
+ });
772
+ }
773
+ getFeedSkeleton(params, opts) {
774
+ return this.call("app.rocksky.feed.getFeedSkeleton", "GET", {
775
+ params,
776
+ ...opts
777
+ });
778
+ }
779
+ getRecommendations(params, opts) {
780
+ return this.call("app.rocksky.feed.getRecommendations", "GET", {
781
+ params,
782
+ ...opts
783
+ });
784
+ }
785
+ getArtistRecommendations(params, opts) {
786
+ return this.call("app.rocksky.feed.getArtistRecommendations", "GET", {
787
+ params,
788
+ ...opts
789
+ });
790
+ }
791
+ getAlbumRecommendations(params, opts) {
792
+ return this.call("app.rocksky.feed.getAlbumRecommendations", "GET", {
793
+ params,
794
+ ...opts
795
+ });
796
+ }
797
+ getStories(params = {}, opts) {
798
+ return this.call("app.rocksky.feed.getStories", "GET", {
799
+ params,
800
+ ...opts
801
+ });
802
+ }
803
+ }
804
+
805
+ // src/namespaces/googledrive.ts
806
+ class GoogleDriveNamespace {
807
+ call;
808
+ constructor(call) {
809
+ this.call = call;
810
+ }
811
+ getFile(params, opts) {
812
+ return this.call("app.rocksky.googledrive.getFile", "GET", {
813
+ params,
814
+ requireAuth: true,
815
+ ...opts
816
+ });
817
+ }
818
+ getFiles(params = {}, opts) {
819
+ return this.call("app.rocksky.googledrive.getFiles", "GET", {
820
+ params,
821
+ requireAuth: true,
822
+ ...opts
823
+ });
824
+ }
825
+ downloadFile(params, opts) {
826
+ return this.call("app.rocksky.googledrive.downloadFile", "GET", {
827
+ params,
828
+ requireAuth: true,
829
+ ...opts
830
+ });
831
+ }
832
+ }
833
+
834
+ // src/namespaces/graph.ts
835
+ class GraphNamespace {
836
+ call;
837
+ constructor(call) {
838
+ this.call = call;
839
+ }
840
+ followAccount(params, opts) {
841
+ return this.call("app.rocksky.graph.followAccount", "POST", {
842
+ params,
843
+ requireAuth: true,
844
+ ...opts
845
+ });
846
+ }
847
+ unfollowAccount(params, opts) {
848
+ return this.call("app.rocksky.graph.unfollowAccount", "POST", {
849
+ params,
850
+ requireAuth: true,
851
+ ...opts
852
+ });
853
+ }
854
+ getFollowers(params, opts) {
855
+ return this.call("app.rocksky.graph.getFollowers", "GET", {
856
+ params,
857
+ ...opts
858
+ });
859
+ }
860
+ getFollows(params, opts) {
861
+ return this.call("app.rocksky.graph.getFollows", "GET", {
862
+ params,
863
+ ...opts
864
+ });
865
+ }
866
+ getKnownFollowers(params, opts) {
867
+ return this.call("app.rocksky.graph.getKnownFollowers", "GET", {
868
+ params,
869
+ ...opts
870
+ });
871
+ }
872
+ }
873
+
874
+ // src/namespaces/like.ts
875
+ class LikeNamespace {
876
+ call;
877
+ constructor(call) {
878
+ this.call = call;
879
+ }
880
+ likeSong(input = {}, opts) {
881
+ return this.call("app.rocksky.like.likeSong", "POST", {
882
+ body: input,
883
+ requireAuth: true,
884
+ ...opts
885
+ });
886
+ }
887
+ dislikeSong(input = {}, opts) {
888
+ return this.call("app.rocksky.like.dislikeSong", "POST", {
889
+ body: input,
890
+ requireAuth: true,
891
+ ...opts
892
+ });
893
+ }
894
+ likeShout(input = {}, opts) {
895
+ return this.call("app.rocksky.like.likeShout", "POST", {
896
+ body: input,
897
+ requireAuth: true,
898
+ ...opts
899
+ });
900
+ }
901
+ dislikeShout(input = {}, opts) {
902
+ return this.call("app.rocksky.like.dislikeShout", "POST", {
903
+ body: input,
904
+ requireAuth: true,
905
+ ...opts
906
+ });
907
+ }
908
+ }
909
+
910
+ // src/namespaces/mirror.ts
911
+ class MirrorNamespace {
912
+ call;
913
+ constructor(call) {
914
+ this.call = call;
915
+ }
916
+ getMirrorSources(opts) {
917
+ return this.call("app.rocksky.mirror.getMirrorSources", "GET", {
918
+ requireAuth: true,
919
+ ...opts
920
+ });
921
+ }
922
+ putMirrorSource(input, opts) {
923
+ return this.call("app.rocksky.mirror.putMirrorSource", "POST", {
924
+ body: input,
925
+ requireAuth: true,
926
+ ...opts
927
+ });
928
+ }
929
+ }
930
+
931
+ // src/namespaces/player.ts
932
+ class PlayerNamespace {
933
+ call;
934
+ constructor(call) {
935
+ this.call = call;
936
+ }
937
+ getCurrentlyPlaying(params = {}, opts) {
938
+ return this.call("app.rocksky.player.getCurrentlyPlaying", "GET", {
939
+ params,
940
+ ...opts
941
+ });
942
+ }
943
+ getPlaybackQueue(params = {}, opts) {
944
+ return this.call("app.rocksky.player.getPlaybackQueue", "GET", {
945
+ params,
946
+ ...opts
947
+ });
948
+ }
949
+ play(params = {}, opts) {
950
+ return this.call("app.rocksky.player.play", "POST", {
951
+ params,
952
+ requireAuth: true,
953
+ ...opts
954
+ });
955
+ }
956
+ pause(params = {}, opts) {
957
+ return this.call("app.rocksky.player.pause", "POST", {
958
+ params,
959
+ requireAuth: true,
960
+ ...opts
961
+ });
962
+ }
963
+ next(params = {}, opts) {
964
+ return this.call("app.rocksky.player.next", "POST", {
965
+ params,
966
+ requireAuth: true,
967
+ ...opts
968
+ });
969
+ }
970
+ previous(params = {}, opts) {
971
+ return this.call("app.rocksky.player.previous", "POST", {
972
+ params,
973
+ requireAuth: true,
974
+ ...opts
975
+ });
976
+ }
977
+ seek(params, opts) {
978
+ return this.call("app.rocksky.player.seek", "POST", {
979
+ params,
980
+ requireAuth: true,
981
+ ...opts
982
+ });
983
+ }
984
+ playFile(params, opts) {
985
+ return this.call("app.rocksky.player.playFile", "POST", {
986
+ params,
987
+ requireAuth: true,
988
+ ...opts
989
+ });
990
+ }
991
+ playDirectory(params, opts) {
992
+ return this.call("app.rocksky.player.playDirectory", "POST", {
993
+ params,
994
+ requireAuth: true,
995
+ ...opts
996
+ });
997
+ }
998
+ addItemsToQueue(params, opts) {
999
+ return this.call("app.rocksky.player.addItemsToQueue", "POST", {
1000
+ params,
1001
+ requireAuth: true,
1002
+ ...opts
1003
+ });
1004
+ }
1005
+ addDirectoryToQueue(params, opts) {
1006
+ return this.call("app.rocksky.player.addDirectoryToQueue", "POST", {
1007
+ params,
1008
+ ...opts
1009
+ });
1010
+ }
1011
+ }
1012
+
1013
+ // src/namespaces/playlist.ts
1014
+ class PlaylistNamespace {
1015
+ call;
1016
+ constructor(call) {
1017
+ this.call = call;
1018
+ }
1019
+ getPlaylists(params = {}, opts) {
1020
+ return this.call("app.rocksky.playlist.getPlaylists", "GET", {
1021
+ params,
1022
+ ...opts
1023
+ });
1024
+ }
1025
+ getPlaylist(params, opts) {
1026
+ return this.call("app.rocksky.playlist.getPlaylist", "GET", {
1027
+ params,
1028
+ ...opts
1029
+ });
1030
+ }
1031
+ createPlaylist(params, opts) {
1032
+ return this.call("app.rocksky.playlist.createPlaylist", "POST", {
1033
+ params,
1034
+ requireAuth: true,
1035
+ ...opts
1036
+ });
1037
+ }
1038
+ removePlaylist(params, opts) {
1039
+ return this.call("app.rocksky.playlist.removePlaylist", "POST", {
1040
+ params,
1041
+ requireAuth: true,
1042
+ ...opts
1043
+ });
1044
+ }
1045
+ startPlaylist(params, opts) {
1046
+ return this.call("app.rocksky.playlist.startPlaylist", "POST", {
1047
+ params,
1048
+ requireAuth: true,
1049
+ ...opts
1050
+ });
1051
+ }
1052
+ insertDirectory(params, opts) {
1053
+ return this.call("app.rocksky.playlist.insertDirectory", "POST", {
1054
+ params,
1055
+ requireAuth: true,
1056
+ ...opts
1057
+ });
1058
+ }
1059
+ insertFiles(params, opts) {
1060
+ return this.call("app.rocksky.playlist.insertFiles", "POST", {
1061
+ params,
1062
+ requireAuth: true,
1063
+ ...opts
1064
+ });
1065
+ }
1066
+ removeTrack(params, opts) {
1067
+ return this.call("app.rocksky.playlist.removeTrack", "POST", {
1068
+ params,
1069
+ ...opts
1070
+ });
1071
+ }
1072
+ }
1073
+
1074
+ // src/namespaces/scrobble.ts
1075
+ class ScrobbleNamespace {
1076
+ call;
1077
+ constructor(call) {
1078
+ this.call = call;
1079
+ }
1080
+ createScrobble(input, opts) {
1081
+ return this.call("app.rocksky.scrobble.createScrobble", "POST", {
1082
+ body: input,
1083
+ requireAuth: true,
1084
+ ...opts
1085
+ });
1086
+ }
1087
+ getScrobble(params, opts) {
1088
+ return this.call("app.rocksky.scrobble.getScrobble", "GET", {
1089
+ params,
1090
+ ...opts
1091
+ });
1092
+ }
1093
+ getScrobbles(params = {}, opts) {
1094
+ return this.call("app.rocksky.scrobble.getScrobbles", "GET", {
1095
+ params,
1096
+ ...opts
1097
+ });
1098
+ }
1099
+ }
1100
+
1101
+ // src/namespaces/shout.ts
1102
+ class ShoutNamespace {
1103
+ call;
1104
+ constructor(call) {
1105
+ this.call = call;
1106
+ }
1107
+ createShout(input = {}, opts) {
1108
+ return this.call("app.rocksky.shout.createShout", "POST", {
1109
+ body: input,
1110
+ requireAuth: true,
1111
+ ...opts
1112
+ });
1113
+ }
1114
+ replyShout(input, opts) {
1115
+ return this.call("app.rocksky.shout.replyShout", "POST", {
1116
+ body: input,
1117
+ requireAuth: true,
1118
+ ...opts
1119
+ });
1120
+ }
1121
+ reportShout(input, opts) {
1122
+ return this.call("app.rocksky.shout.reportShout", "POST", {
1123
+ body: input,
1124
+ requireAuth: true,
1125
+ ...opts
1126
+ });
1127
+ }
1128
+ removeShout(params, opts) {
1129
+ return this.call("app.rocksky.shout.removeShout", "POST", {
1130
+ params,
1131
+ requireAuth: true,
1132
+ ...opts
1133
+ });
1134
+ }
1135
+ getShoutReplies(params, opts) {
1136
+ return this.call("app.rocksky.shout.getShoutReplies", "GET", {
1137
+ params,
1138
+ ...opts
1139
+ });
1140
+ }
1141
+ getProfileShouts(params, opts) {
1142
+ return this.call("app.rocksky.shout.getProfileShouts", "GET", {
1143
+ params,
1144
+ ...opts
1145
+ });
1146
+ }
1147
+ getTrackShouts(params, opts) {
1148
+ return this.call("app.rocksky.shout.getTrackShouts", "GET", {
1149
+ params,
1150
+ ...opts
1151
+ });
1152
+ }
1153
+ getArtistShouts(params, opts) {
1154
+ return this.call("app.rocksky.shout.getArtistShouts", "GET", {
1155
+ params,
1156
+ ...opts
1157
+ });
1158
+ }
1159
+ getAlbumShouts(params, opts) {
1160
+ return this.call("app.rocksky.shout.getAlbumShouts", "GET", {
1161
+ params,
1162
+ ...opts
1163
+ });
1164
+ }
1165
+ }
1166
+
1167
+ // src/namespaces/song.ts
1168
+ class SongNamespace {
1169
+ call;
1170
+ constructor(call) {
1171
+ this.call = call;
1172
+ }
1173
+ getSong(params, opts) {
1174
+ return this.call("app.rocksky.song.getSong", "GET", {
1175
+ params,
1176
+ ...opts
1177
+ });
1178
+ }
1179
+ getSongs(params = {}, opts) {
1180
+ return this.call("app.rocksky.song.getSongs", "GET", {
1181
+ params,
1182
+ ...opts
1183
+ });
1184
+ }
1185
+ getSongRecentListeners(params, opts) {
1186
+ return this.call("app.rocksky.song.getSongRecentListeners", "GET", {
1187
+ params,
1188
+ ...opts
1189
+ });
1190
+ }
1191
+ matchSong(params, opts) {
1192
+ return this.call("app.rocksky.song.matchSong", "GET", {
1193
+ params,
1194
+ ...opts
1195
+ });
1196
+ }
1197
+ createSong(input, opts) {
1198
+ return this.call("app.rocksky.song.createSong", "POST", {
1199
+ body: input,
1200
+ requireAuth: true,
1201
+ ...opts
1202
+ });
1203
+ }
1204
+ }
1205
+
1206
+ // src/namespaces/spotify.ts
1207
+ class SpotifyNamespace {
1208
+ call;
1209
+ constructor(call) {
1210
+ this.call = call;
1211
+ }
1212
+ getCurrentlyPlaying(params = {}, opts) {
1213
+ return this.call("app.rocksky.spotify.getCurrentlyPlaying", "GET", {
1214
+ params,
1215
+ ...opts
1216
+ });
1217
+ }
1218
+ play(opts) {
1219
+ return this.call("app.rocksky.spotify.play", "POST", {
1220
+ requireAuth: true,
1221
+ ...opts
1222
+ });
1223
+ }
1224
+ pause(opts) {
1225
+ return this.call("app.rocksky.spotify.pause", "POST", {
1226
+ requireAuth: true,
1227
+ ...opts
1228
+ });
1229
+ }
1230
+ next(opts) {
1231
+ return this.call("app.rocksky.spotify.next", "POST", {
1232
+ requireAuth: true,
1233
+ ...opts
1234
+ });
1235
+ }
1236
+ previous(opts) {
1237
+ return this.call("app.rocksky.spotify.previous", "POST", {
1238
+ requireAuth: true,
1239
+ ...opts
1240
+ });
1241
+ }
1242
+ seek(params, opts) {
1243
+ return this.call("app.rocksky.spotify.seek", "POST", {
1244
+ params,
1245
+ requireAuth: true,
1246
+ ...opts
1247
+ });
1248
+ }
1249
+ }
1250
+
1251
+ // src/namespaces/stats.ts
1252
+ class StatsNamespace {
1253
+ call;
1254
+ constructor(call) {
1255
+ this.call = call;
1256
+ }
1257
+ getStats(params, opts) {
1258
+ return this.call("app.rocksky.stats.getStats", "GET", {
1259
+ params,
1260
+ ...opts
1261
+ });
1262
+ }
1263
+ getWrapped(params, opts) {
1264
+ return this.call("app.rocksky.stats.getWrapped", "GET", {
1265
+ params,
1266
+ ...opts
1267
+ });
1268
+ }
1269
+ }
1270
+
1271
+ // src/client.ts
1272
+ class RockskyClient {
1273
+ config;
1274
+ actor;
1275
+ album;
1276
+ apikey;
1277
+ artist;
1278
+ charts;
1279
+ dropbox;
1280
+ feed;
1281
+ googledrive;
1282
+ graph;
1283
+ like;
1284
+ mirror;
1285
+ player;
1286
+ playlist;
1287
+ scrobble;
1288
+ shout;
1289
+ song;
1290
+ spotify;
1291
+ stats;
1292
+ constructor(options = {}) {
1293
+ this.config = buildConfig(options);
1294
+ const call = (nsid, method, opts) => xrpcCall(this.config, nsid, method, opts ?? {});
1295
+ this.actor = new ActorNamespace(call);
1296
+ this.album = new AlbumNamespace(call);
1297
+ this.apikey = new ApikeyNamespace(call);
1298
+ this.artist = new ArtistNamespace(call);
1299
+ this.charts = new ChartsNamespace(call);
1300
+ this.dropbox = new DropboxNamespace(call);
1301
+ this.feed = new FeedNamespace(call);
1302
+ this.googledrive = new GoogleDriveNamespace(call);
1303
+ this.graph = new GraphNamespace(call);
1304
+ this.like = new LikeNamespace(call);
1305
+ this.mirror = new MirrorNamespace(call);
1306
+ this.player = new PlayerNamespace(call);
1307
+ this.playlist = new PlaylistNamespace(call);
1308
+ this.scrobble = new ScrobbleNamespace(call);
1309
+ this.shout = new ShoutNamespace(call);
1310
+ this.song = new SongNamespace(call);
1311
+ this.spotify = new SpotifyNamespace(call);
1312
+ this.stats = new StatsNamespace(call);
1313
+ }
1314
+ withAuth(auth) {
1315
+ return new RockskyClient({
1316
+ ...this.optionsSnapshot(),
1317
+ auth
1318
+ });
1319
+ }
1320
+ withBaseUrl(baseUrl) {
1321
+ return new RockskyClient({
1322
+ ...this.optionsSnapshot(),
1323
+ baseUrl
1324
+ });
1325
+ }
1326
+ realtime(options) {
1327
+ return createRealtimeClient({
1328
+ baseUrl: this.config.baseUrl,
1329
+ ...options
1330
+ });
1331
+ }
1332
+ paginate(args) {
1333
+ return paginate(args);
1334
+ }
1335
+ xrpc(nsid, method = "GET", opts = {}) {
1336
+ return xrpcCall(this.config, nsid, method, opts);
1337
+ }
1338
+ static builder() {
1339
+ return new RockskyClientBuilder;
1340
+ }
1341
+ optionsSnapshot() {
1342
+ return {
1343
+ baseUrl: this.config.baseUrl,
1344
+ auth: this.config.auth,
1345
+ fetch: this.config.fetch,
1346
+ headers: this.config.headers,
1347
+ timeoutMs: this.config.timeoutMs,
1348
+ retries: this.config.retries,
1349
+ retryDelayMs: this.config.retryDelayMs
1350
+ };
1351
+ }
1352
+ }
1353
+
1354
+ class RockskyClientBuilder {
1355
+ opts = {};
1356
+ baseUrl(url) {
1357
+ this.opts.baseUrl = url;
1358
+ return this;
1359
+ }
1360
+ auth(auth) {
1361
+ this.opts.auth = auth;
1362
+ return this;
1363
+ }
1364
+ bearer(token) {
1365
+ this.opts.auth = token;
1366
+ return this;
1367
+ }
1368
+ fetch(impl) {
1369
+ this.opts.fetch = impl;
1370
+ return this;
1371
+ }
1372
+ header(key, value) {
1373
+ this.opts.headers = { ...this.opts.headers, [key]: value };
1374
+ return this;
1375
+ }
1376
+ headers(headers) {
1377
+ this.opts.headers = { ...this.opts.headers, ...headers };
1378
+ return this;
1379
+ }
1380
+ userAgent(ua) {
1381
+ this.opts.userAgent = ua;
1382
+ return this;
1383
+ }
1384
+ timeout(ms) {
1385
+ this.opts.timeoutMs = ms;
1386
+ return this;
1387
+ }
1388
+ retries(n) {
1389
+ this.opts.retries = n;
1390
+ return this;
1391
+ }
1392
+ retryDelay(ms) {
1393
+ this.opts.retryDelayMs = ms;
1394
+ return this;
1395
+ }
1396
+ build() {
1397
+ return new RockskyClient(this.opts);
1398
+ }
1399
+ }
1400
+ function createClient(options = {}) {
1401
+ return new RockskyClient(options);
1402
+ }
1403
+ // src/pipe.ts
1404
+ function pipe(value, ...ops) {
1405
+ let factory = typeof value === "function" ? value : () => value;
1406
+ for (const op of ops)
1407
+ factory = op(factory);
1408
+ return factory();
1409
+ }
1410
+ function map(fn) {
1411
+ return (factory) => async () => fn(await factory());
1412
+ }
1413
+ function tap(fn) {
1414
+ return (factory) => async () => {
1415
+ const a = await factory();
1416
+ await fn(a);
1417
+ return a;
1418
+ };
1419
+ }
1420
+ function withRetry(times, options = {}) {
1421
+ const delayMs = options.delayMs ?? 200;
1422
+ const factor = options.factor ?? 2;
1423
+ const shouldRetry = options.shouldRetry ?? (() => true);
1424
+ return (factory) => async () => {
1425
+ let lastErr;
1426
+ for (let attempt = 0;attempt <= times; attempt++) {
1427
+ try {
1428
+ return await factory();
1429
+ } catch (err) {
1430
+ lastErr = err;
1431
+ if (attempt === times || !shouldRetry(err, attempt))
1432
+ throw err;
1433
+ await sleep2(delayMs * Math.pow(factor, attempt));
1434
+ }
1435
+ }
1436
+ throw lastErr;
1437
+ };
1438
+ }
1439
+ function withTimeout(ms) {
1440
+ return (factory) => () => new Promise((resolve, reject) => {
1441
+ const timer = setTimeout(() => reject(new RockskyTimeoutError(ms)), ms);
1442
+ factory().then((v) => {
1443
+ clearTimeout(timer);
1444
+ resolve(v);
1445
+ }, (err) => {
1446
+ clearTimeout(timer);
1447
+ reject(err);
1448
+ });
1449
+ });
1450
+ }
1451
+ function withFallback(fallback) {
1452
+ return (factory) => async () => {
1453
+ try {
1454
+ return await factory();
1455
+ } catch (err) {
1456
+ return typeof fallback === "function" ? await fallback(err) : fallback;
1457
+ }
1458
+ };
1459
+ }
1460
+ function catchError(handler) {
1461
+ return (factory) => async () => {
1462
+ try {
1463
+ return await factory();
1464
+ } catch (err) {
1465
+ return await handler(err);
1466
+ }
1467
+ };
1468
+ }
1469
+ function sleep2(ms) {
1470
+ return new Promise((r) => setTimeout(r, ms));
1471
+ }
1472
+ export {
1473
+ withTimeout,
1474
+ withRetry,
1475
+ withFallback,
1476
+ tap,
1477
+ pipe,
1478
+ paginate,
1479
+ map,
1480
+ createRealtimeClient,
1481
+ createClient,
1482
+ catchError,
1483
+ RockskyTimeoutError,
1484
+ RockskyHttpError,
1485
+ RockskyError,
1486
+ RockskyClientBuilder,
1487
+ RockskyClient,
1488
+ RockskyAuthError,
1489
+ RealtimeClientBuilder,
1490
+ RealtimeClient,
1491
+ DEFAULT_BASE_URL
1492
+ };