@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.
- package/LICENSE +21 -0
- package/README.md +279 -0
- package/dist/client.d.ts +107 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/errors.d.ts +26 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/http.d.ts +28 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1492 -0
- package/dist/namespaces/_helpers.d.ts +9 -0
- package/dist/namespaces/_helpers.d.ts.map +1 -0
- package/dist/namespaces/actor.d.ts +30 -0
- package/dist/namespaces/actor.d.ts.map +1 -0
- package/dist/namespaces/album.d.ts +18 -0
- package/dist/namespaces/album.d.ts.map +1 -0
- package/dist/namespaces/apikey.d.ts +27 -0
- package/dist/namespaces/apikey.d.ts.map +1 -0
- package/dist/namespaces/artist.d.ts +31 -0
- package/dist/namespaces/artist.d.ts.map +1 -0
- package/dist/namespaces/charts.d.ts +25 -0
- package/dist/namespaces/charts.d.ts.map +1 -0
- package/dist/namespaces/dropbox.d.ts +19 -0
- package/dist/namespaces/dropbox.d.ts.map +1 -0
- package/dist/namespaces/feed.d.ts +38 -0
- package/dist/namespaces/feed.d.ts.map +1 -0
- package/dist/namespaces/googledrive.d.ts +16 -0
- package/dist/namespaces/googledrive.d.ts.map +1 -0
- package/dist/namespaces/graph.d.ts +28 -0
- package/dist/namespaces/graph.d.ts.map +1 -0
- package/dist/namespaces/like.d.ts +14 -0
- package/dist/namespaces/like.d.ts.map +1 -0
- package/dist/namespaces/mirror.d.ts +15 -0
- package/dist/namespaces/mirror.d.ts.map +1 -0
- package/dist/namespaces/player.d.ts +41 -0
- package/dist/namespaces/player.d.ts.map +1 -0
- package/dist/namespaces/playlist.d.ts +40 -0
- package/dist/namespaces/playlist.d.ts.map +1 -0
- package/dist/namespaces/scrobble.d.ts +43 -0
- package/dist/namespaces/scrobble.d.ts.map +1 -0
- package/dist/namespaces/shout.d.ts +38 -0
- package/dist/namespaces/shout.d.ts.map +1 -0
- package/dist/namespaces/song.d.ts +48 -0
- package/dist/namespaces/song.d.ts.map +1 -0
- package/dist/namespaces/spotify.d.ts +17 -0
- package/dist/namespaces/spotify.d.ts.map +1 -0
- package/dist/namespaces/stats.d.ts +14 -0
- package/dist/namespaces/stats.d.ts.map +1 -0
- package/dist/paginate.d.ts +38 -0
- package/dist/paginate.d.ts.map +1 -0
- package/dist/pipe.d.ts +36 -0
- package/dist/pipe.d.ts.map +1 -0
- package/dist/realtime.d.ts +144 -0
- package/dist/realtime.d.ts.map +1 -0
- package/dist/types.d.ts +29 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +65 -0
- package/src/client.ts +235 -0
- package/src/errors.ts +47 -0
- package/src/http.ts +195 -0
- package/src/index.ts +85 -0
- package/src/namespaces/_helpers.ts +17 -0
- package/src/namespaces/actor.ts +89 -0
- package/src/namespaces/album.ts +34 -0
- package/src/namespaces/apikey.ts +50 -0
- package/src/namespaces/artist.ts +74 -0
- package/src/namespaces/charts.ts +47 -0
- package/src/namespaces/dropbox.ts +47 -0
- package/src/namespaces/feed.ts +106 -0
- package/src/namespaces/googledrive.ts +36 -0
- package/src/namespaces/graph.ts +63 -0
- package/src/namespaces/like.ts +40 -0
- package/src/namespaces/mirror.ts +31 -0
- package/src/namespaces/player.ts +127 -0
- package/src/namespaces/playlist.ts +85 -0
- package/src/namespaces/scrobble.ts +67 -0
- package/src/namespaces/shout.ts +90 -0
- package/src/namespaces/song.ts +81 -0
- package/src/namespaces/spotify.ts +52 -0
- package/src/namespaces/stats.ts +23 -0
- package/src/paginate.ts +90 -0
- package/src/pipe.ts +146 -0
- package/src/realtime.ts +408 -0
- package/src/types.ts +41 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Tsiry Sandratraina <tsiry.sndr@rocksky.app>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
# @rocksky/sdk
|
|
2
|
+
|
|
3
|
+
A TypeScript SDK for the [Rocksky](https://rocksky.app) XRPC API.
|
|
4
|
+
|
|
5
|
+
- **Type-safe** — every endpoint and parameter is statically typed.
|
|
6
|
+
- **Builder-friendly** — fluent `RockskyClient.builder()` for ergonomic setup.
|
|
7
|
+
- **Pipe-friendly** — composable async operators (`pipe`, `withRetry`, `withTimeout`, `map`, `tap`, `withFallback`, `catchError`).
|
|
8
|
+
- **Zero-dependency** — only uses the platform `fetch` and the standard library. Works on Bun, Node 18+, Deno, browsers, Cloudflare Workers.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
bun add @rocksky/sdk
|
|
14
|
+
# or
|
|
15
|
+
npm i @rocksky/sdk
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick start
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { createClient } from "@rocksky/sdk";
|
|
22
|
+
|
|
23
|
+
const client = createClient();
|
|
24
|
+
|
|
25
|
+
const profile = await client.actor.getProfile({ did: "did:plc:7vdlgi2bflelz7mmuxoqjfcr" });
|
|
26
|
+
const topTracks = await client.charts.getTopTracks({ limit: 5 });
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Authentication
|
|
30
|
+
|
|
31
|
+
The SDK accepts a bearer token either as a string or as a (sync/async) function:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { createClient } from "@rocksky/sdk";
|
|
35
|
+
|
|
36
|
+
const client = createClient({ auth: process.env.ROCKSKY_TOKEN });
|
|
37
|
+
|
|
38
|
+
// or — refresh on every call
|
|
39
|
+
const client = createClient({
|
|
40
|
+
auth: async () => loadTokenFromKeychain(),
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Endpoints that require auth throw `RockskyAuthError` when no token is configured.
|
|
45
|
+
|
|
46
|
+
## Builder
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { RockskyClient } from "@rocksky/sdk";
|
|
50
|
+
|
|
51
|
+
const client = RockskyClient.builder()
|
|
52
|
+
.baseUrl("https://api.rocksky.app")
|
|
53
|
+
.bearer(process.env.ROCKSKY_TOKEN!)
|
|
54
|
+
.userAgent("my-app/1.0")
|
|
55
|
+
.timeout(10_000)
|
|
56
|
+
.retries(3)
|
|
57
|
+
.retryDelay(200)
|
|
58
|
+
.header("x-trace-id", crypto.randomUUID())
|
|
59
|
+
.build();
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`withAuth(token)` and `withBaseUrl(url)` return a new client without mutating the original — handy for per-request overrides.
|
|
63
|
+
|
|
64
|
+
## Pipe-style composition
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
import {
|
|
68
|
+
createClient,
|
|
69
|
+
map,
|
|
70
|
+
pipe,
|
|
71
|
+
tap,
|
|
72
|
+
withFallback,
|
|
73
|
+
withRetry,
|
|
74
|
+
withTimeout,
|
|
75
|
+
} from "@rocksky/sdk";
|
|
76
|
+
|
|
77
|
+
const client = createClient();
|
|
78
|
+
|
|
79
|
+
// Pass a thunk so withRetry can re-invoke the network call.
|
|
80
|
+
const handle = await pipe(
|
|
81
|
+
() => client.actor.getProfile({ did: "did:plc:7vdlgi2bflelz7mmuxoqjfcr" }),
|
|
82
|
+
withRetry(3, { delayMs: 200 }),
|
|
83
|
+
withTimeout(5_000),
|
|
84
|
+
tap((p) => console.log("loaded", p.handle)),
|
|
85
|
+
map((p) => p.displayName ?? p.handle),
|
|
86
|
+
withFallback("anonymous"),
|
|
87
|
+
);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
`pipe` accepts either a thunk `() => Promise<T>` (preferred — `withRetry` re-runs it) or a bare `Promise<T>` for one-shot composition.
|
|
91
|
+
|
|
92
|
+
| Operator | Description |
|
|
93
|
+
| --- | --- |
|
|
94
|
+
| `map(fn)` | Transform the resolved value. |
|
|
95
|
+
| `tap(fn)` | Run a side-effect; pass the value through. |
|
|
96
|
+
| `withRetry(n, { delayMs, factor, shouldRetry })` | Retry on rejection with exponential backoff. |
|
|
97
|
+
| `withTimeout(ms)` | Reject with `RockskyTimeoutError` if it exceeds `ms`. |
|
|
98
|
+
| `withFallback(value \| fn)` | Recover from any error with a default. |
|
|
99
|
+
| `catchError(fn)` | Map a thrown error to a value. |
|
|
100
|
+
|
|
101
|
+
## Namespaces
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
client.actor getProfile, getActorAlbums, getActorArtists, getActorSongs,
|
|
105
|
+
getActorScrobbles, getActorLovedSongs, getActorPlaylists,
|
|
106
|
+
getActorNeighbours, getActorCompatibility
|
|
107
|
+
client.album getAlbum, getAlbums, getAlbumTracks
|
|
108
|
+
client.apikey getApikeys, createApikey, updateApikey, removeApikey
|
|
109
|
+
client.artist getArtist, getArtists, getArtistAlbums, getArtistTracks,
|
|
110
|
+
getArtistListeners, getArtistRecentListeners
|
|
111
|
+
client.charts getScrobblesChart, getTopArtists, getTopTracks
|
|
112
|
+
client.dropbox getFiles, getMetadata, getTemporaryLink, downloadFile
|
|
113
|
+
client.feed search, getFeed, getFeedGenerators, getFeedGenerator,
|
|
114
|
+
describeFeedGenerator, getFeedSkeleton,
|
|
115
|
+
getRecommendations, getArtistRecommendations,
|
|
116
|
+
getAlbumRecommendations, getStories
|
|
117
|
+
client.googledrive getFile, getFiles, downloadFile
|
|
118
|
+
client.graph followAccount, unfollowAccount, getFollowers, getFollows,
|
|
119
|
+
getKnownFollowers
|
|
120
|
+
client.like likeSong, dislikeSong, likeShout, dislikeShout
|
|
121
|
+
client.mirror getMirrorSources, putMirrorSource
|
|
122
|
+
client.player getCurrentlyPlaying, getPlaybackQueue, play, pause, next,
|
|
123
|
+
previous, seek, playFile, playDirectory, addItemsToQueue,
|
|
124
|
+
addDirectoryToQueue
|
|
125
|
+
client.playlist getPlaylists, getPlaylist, createPlaylist, removePlaylist,
|
|
126
|
+
startPlaylist, insertDirectory, insertFiles, removeTrack
|
|
127
|
+
client.scrobble createScrobble, getScrobble, getScrobbles
|
|
128
|
+
client.shout createShout, replyShout, reportShout, removeShout,
|
|
129
|
+
getShoutReplies, getProfileShouts, getTrackShouts,
|
|
130
|
+
getArtistShouts, getAlbumShouts
|
|
131
|
+
client.song getSong, getSongs, getSongRecentListeners, matchSong,
|
|
132
|
+
createSong
|
|
133
|
+
client.spotify getCurrentlyPlaying, play, pause, next, previous, seek
|
|
134
|
+
client.stats getStats, getWrapped
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Every method takes a typed parameter object and returns `Promise<T>`. Pass a generic to narrow the response type:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
type Profile = { handle: string; did: string; displayName?: string };
|
|
141
|
+
const me = await client.actor.getProfile<Profile>({ did: "alice.bsky.social" });
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Escape hatch
|
|
145
|
+
|
|
146
|
+
For endpoints not yet wrapped, call `xrpc` directly:
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
const result = await client.xrpc<MyType>(
|
|
150
|
+
"app.rocksky.something.notWrappedYet",
|
|
151
|
+
"GET",
|
|
152
|
+
{ params: { foo: "bar" } },
|
|
153
|
+
);
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Error handling
|
|
157
|
+
|
|
158
|
+
The SDK throws four error classes — all extending `RockskyError`:
|
|
159
|
+
|
|
160
|
+
- `RockskyHttpError` — non-2xx response. Exposes `.status`, `.statusText`, `.url`, `.body`.
|
|
161
|
+
- `RockskyTimeoutError` — request exceeded `timeoutMs`.
|
|
162
|
+
- `RockskyAuthError` — endpoint requires auth but no token was provided.
|
|
163
|
+
- `RockskyError` — base class.
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
import { RockskyHttpError } from "@rocksky/sdk";
|
|
167
|
+
|
|
168
|
+
try {
|
|
169
|
+
await client.scrobble.getScrobble({ uri: "at://x" });
|
|
170
|
+
} catch (err) {
|
|
171
|
+
if (err instanceof RockskyHttpError && err.status === 404) {
|
|
172
|
+
console.log("not found");
|
|
173
|
+
} else {
|
|
174
|
+
throw err;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Pagination
|
|
180
|
+
|
|
181
|
+
`paginate()` (and `client.paginate()`) gives you a typed async iterable over any `{ limit, offset }` or `{ cursor }` endpoint.
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
import { createClient, paginate } from "@rocksky/sdk";
|
|
185
|
+
|
|
186
|
+
const client = createClient();
|
|
187
|
+
|
|
188
|
+
// Offset/limit — fetcher returns the items array, helper handles offset.
|
|
189
|
+
for await (const s of paginate({
|
|
190
|
+
fetch: ({ limit, offset }) =>
|
|
191
|
+
client.actor.getActorScrobbles({ did, limit, offset }).then((p) => p.scrobbles ?? []),
|
|
192
|
+
pageSize: 50,
|
|
193
|
+
maxItems: 200,
|
|
194
|
+
})) {
|
|
195
|
+
console.log(s.track.title);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Cursor-based — fetcher returns { items, cursor }.
|
|
199
|
+
const followers = await client
|
|
200
|
+
.paginate({
|
|
201
|
+
fetch: async ({ limit, cursor }) => {
|
|
202
|
+
const page = await client.graph.getFollowers({ actor, limit, cursor });
|
|
203
|
+
return { items: page.followers, cursor: page.cursor };
|
|
204
|
+
},
|
|
205
|
+
pageSize: 100,
|
|
206
|
+
})
|
|
207
|
+
.toArray();
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Options: `pageSize`, `maxItems`, `signal` (AbortSignal). The helper stops on an empty page, a short page (offset mode), or a missing cursor (cursor mode).
|
|
211
|
+
|
|
212
|
+
## Realtime (WebSocket)
|
|
213
|
+
|
|
214
|
+
The Rocksky API exposes a WebSocket endpoint at `/ws` for now-playing events and device control. The SDK ships a typed client with reconnect, ping, and a fluent builder.
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
import { RealtimeClient, createClient } from "@rocksky/sdk";
|
|
218
|
+
|
|
219
|
+
// Builder style.
|
|
220
|
+
const rt = RealtimeClient.builder()
|
|
221
|
+
.baseUrl("https://api.rocksky.app")
|
|
222
|
+
.token(process.env.ROCKSKY_TOKEN!)
|
|
223
|
+
.clientName("my-app")
|
|
224
|
+
.pingInterval(20_000)
|
|
225
|
+
.reconnect({ backoffMs: 1000, maxBackoffMs: 60_000 })
|
|
226
|
+
.build();
|
|
227
|
+
|
|
228
|
+
// Or — inherit baseUrl from a RockskyClient.
|
|
229
|
+
const client = createClient({ baseUrl: "https://api.rocksky.app" });
|
|
230
|
+
const rt2 = client.realtime({ token: process.env.ROCKSKY_TOKEN!, clientName: "my-app" });
|
|
231
|
+
|
|
232
|
+
rt.on("open", () => console.log("connected"));
|
|
233
|
+
rt.on("registered", ({ deviceId }) => console.log("device id:", deviceId));
|
|
234
|
+
rt.on("message", ({ data, device_id }) => console.log(device_id, data));
|
|
235
|
+
rt.on("control", (c) => console.log("control:", c));
|
|
236
|
+
rt.on("close", ({ code, reason }) => console.log("closed", code, reason));
|
|
237
|
+
rt.on("error", (err) => console.error(err));
|
|
238
|
+
|
|
239
|
+
await rt.connect();
|
|
240
|
+
|
|
241
|
+
// Broadcast a now-playing update to your devices.
|
|
242
|
+
await rt.sendMessage({
|
|
243
|
+
type: "track",
|
|
244
|
+
title: "Heart of Glass",
|
|
245
|
+
artist: "Blondie",
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
// Control a target device (or all of them).
|
|
249
|
+
await rt.sendControl({ action: "play", target: "device-id-123" });
|
|
250
|
+
|
|
251
|
+
await rt.close();
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Events: `open`, `close`, `error`, `registered`, `deviceRegistered`, `message`, `control`, `raw`.
|
|
255
|
+
|
|
256
|
+
For tests, pass a fake `WebSocket` constructor via `.webSocket(FakeWebSocket)`.
|
|
257
|
+
|
|
258
|
+
## Development
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
bun install
|
|
262
|
+
bun test
|
|
263
|
+
bun run typecheck
|
|
264
|
+
bun run build
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Run individual examples:
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
bun run example:quickstart
|
|
271
|
+
bun run example:builder
|
|
272
|
+
bun run example:pipe
|
|
273
|
+
bun run example:scrobble
|
|
274
|
+
bun run example:pagination
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## License
|
|
278
|
+
|
|
279
|
+
[MIT](LICENSE) © Tsiry Sandratraina.
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { type HttpClientConfig } from "./http";
|
|
2
|
+
import { type PaginateArgs } from "./paginate";
|
|
3
|
+
import { RealtimeClient, type RealtimeOptions } from "./realtime";
|
|
4
|
+
import { ActorNamespace } from "./namespaces/actor";
|
|
5
|
+
import { AlbumNamespace } from "./namespaces/album";
|
|
6
|
+
import { ApikeyNamespace } from "./namespaces/apikey";
|
|
7
|
+
import { ArtistNamespace } from "./namespaces/artist";
|
|
8
|
+
import { ChartsNamespace } from "./namespaces/charts";
|
|
9
|
+
import { DropboxNamespace } from "./namespaces/dropbox";
|
|
10
|
+
import { FeedNamespace } from "./namespaces/feed";
|
|
11
|
+
import { GoogleDriveNamespace } from "./namespaces/googledrive";
|
|
12
|
+
import { GraphNamespace } from "./namespaces/graph";
|
|
13
|
+
import { LikeNamespace } from "./namespaces/like";
|
|
14
|
+
import { MirrorNamespace } from "./namespaces/mirror";
|
|
15
|
+
import { PlayerNamespace } from "./namespaces/player";
|
|
16
|
+
import { PlaylistNamespace } from "./namespaces/playlist";
|
|
17
|
+
import { ScrobbleNamespace } from "./namespaces/scrobble";
|
|
18
|
+
import { ShoutNamespace } from "./namespaces/shout";
|
|
19
|
+
import { SongNamespace } from "./namespaces/song";
|
|
20
|
+
import { SpotifyNamespace } from "./namespaces/spotify";
|
|
21
|
+
import { StatsNamespace } from "./namespaces/stats";
|
|
22
|
+
import type { AuthProvider, ClientOptions, FetchLike, RequestOptions } from "./types";
|
|
23
|
+
export declare class RockskyClient {
|
|
24
|
+
readonly config: HttpClientConfig;
|
|
25
|
+
readonly actor: ActorNamespace;
|
|
26
|
+
readonly album: AlbumNamespace;
|
|
27
|
+
readonly apikey: ApikeyNamespace;
|
|
28
|
+
readonly artist: ArtistNamespace;
|
|
29
|
+
readonly charts: ChartsNamespace;
|
|
30
|
+
readonly dropbox: DropboxNamespace;
|
|
31
|
+
readonly feed: FeedNamespace;
|
|
32
|
+
readonly googledrive: GoogleDriveNamespace;
|
|
33
|
+
readonly graph: GraphNamespace;
|
|
34
|
+
readonly like: LikeNamespace;
|
|
35
|
+
readonly mirror: MirrorNamespace;
|
|
36
|
+
readonly player: PlayerNamespace;
|
|
37
|
+
readonly playlist: PlaylistNamespace;
|
|
38
|
+
readonly scrobble: ScrobbleNamespace;
|
|
39
|
+
readonly shout: ShoutNamespace;
|
|
40
|
+
readonly song: SongNamespace;
|
|
41
|
+
readonly spotify: SpotifyNamespace;
|
|
42
|
+
readonly stats: StatsNamespace;
|
|
43
|
+
constructor(options?: ClientOptions);
|
|
44
|
+
/** Build a one-off authenticated copy without mutating this client. */
|
|
45
|
+
withAuth(auth: AuthProvider): RockskyClient;
|
|
46
|
+
/** Build a copy with an overridden base URL. */
|
|
47
|
+
withBaseUrl(baseUrl: string): RockskyClient;
|
|
48
|
+
/**
|
|
49
|
+
* Open a realtime WebSocket connection to /ws.
|
|
50
|
+
*
|
|
51
|
+
* const rt = client.realtime({ token, clientName: "my-app" });
|
|
52
|
+
* rt.on("message", m => console.log(m));
|
|
53
|
+
* await rt.connect();
|
|
54
|
+
*
|
|
55
|
+
* Defaults `baseUrl` to this client's base URL. Override anything by
|
|
56
|
+
* passing the option, or use `RealtimeClient.builder()` for full control.
|
|
57
|
+
*/
|
|
58
|
+
realtime(options: Omit<RealtimeOptions, "baseUrl"> & Partial<Pick<RealtimeOptions, "baseUrl">>): RealtimeClient;
|
|
59
|
+
/**
|
|
60
|
+
* Page through any limit/offset or cursor-based endpoint as an async iterable.
|
|
61
|
+
*
|
|
62
|
+
* for await (const s of client.paginate({
|
|
63
|
+
* fetch: ({ limit, offset }) =>
|
|
64
|
+
* client.actor.getActorScrobbles({ did, limit, offset }),
|
|
65
|
+
* pageSize: 50,
|
|
66
|
+
* })) { ... }
|
|
67
|
+
*/
|
|
68
|
+
paginate<T>(args: PaginateArgs<T>): AsyncIterable<T> & {
|
|
69
|
+
toArray(): Promise<T[]>;
|
|
70
|
+
};
|
|
71
|
+
/** Direct escape hatch — call any XRPC endpoint by NSID. */
|
|
72
|
+
xrpc<T = unknown>(nsid: string, method?: "GET" | "POST", opts?: {
|
|
73
|
+
params?: Record<string, unknown>;
|
|
74
|
+
body?: unknown;
|
|
75
|
+
requireAuth?: boolean;
|
|
76
|
+
} & RequestOptions): Promise<T>;
|
|
77
|
+
static builder(): RockskyClientBuilder;
|
|
78
|
+
private optionsSnapshot;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Fluent builder.
|
|
82
|
+
*
|
|
83
|
+
* const client = RockskyClient.builder()
|
|
84
|
+
* .baseUrl("https://api.rocksky.app")
|
|
85
|
+
* .auth(() => loadToken())
|
|
86
|
+
* .timeout(10_000)
|
|
87
|
+
* .retries(3)
|
|
88
|
+
* .userAgent("my-app/1.0")
|
|
89
|
+
* .build();
|
|
90
|
+
*/
|
|
91
|
+
export declare class RockskyClientBuilder {
|
|
92
|
+
private readonly opts;
|
|
93
|
+
baseUrl(url: string): this;
|
|
94
|
+
auth(auth: AuthProvider): this;
|
|
95
|
+
bearer(token: string): this;
|
|
96
|
+
fetch(impl: FetchLike): this;
|
|
97
|
+
header(key: string, value: string): this;
|
|
98
|
+
headers(headers: Record<string, string>): this;
|
|
99
|
+
userAgent(ua: string): this;
|
|
100
|
+
timeout(ms: number): this;
|
|
101
|
+
retries(n: number): this;
|
|
102
|
+
retryDelay(ms: number): this;
|
|
103
|
+
build(): RockskyClient;
|
|
104
|
+
}
|
|
105
|
+
/** Convenience factory — equivalent to `new RockskyClient(options)`. */
|
|
106
|
+
export declare function createClient(options?: ClientOptions): RockskyClient;
|
|
107
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare class RockskyError extends Error {
|
|
2
|
+
readonly cause?: unknown;
|
|
3
|
+
constructor(message: string, options?: {
|
|
4
|
+
cause?: unknown;
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
export declare class RockskyHttpError extends RockskyError {
|
|
8
|
+
readonly status: number;
|
|
9
|
+
readonly statusText: string;
|
|
10
|
+
readonly url: string;
|
|
11
|
+
readonly body: unknown;
|
|
12
|
+
constructor(args: {
|
|
13
|
+
status: number;
|
|
14
|
+
statusText: string;
|
|
15
|
+
url: string;
|
|
16
|
+
body: unknown;
|
|
17
|
+
message?: string;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
export declare class RockskyTimeoutError extends RockskyError {
|
|
21
|
+
constructor(ms: number);
|
|
22
|
+
}
|
|
23
|
+
export declare class RockskyAuthError extends RockskyError {
|
|
24
|
+
constructor(message?: string);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;gBACb,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAK3D;AAED,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;gBAEX,IAAI,EAAE;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,OAAO,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB;CAWF;AAED,qBAAa,mBAAoB,SAAQ,YAAY;gBACvC,EAAE,EAAE,MAAM;CAIvB;AAED,qBAAa,gBAAiB,SAAQ,YAAY;gBACpC,OAAO,SAA4B;CAIhD"}
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type AuthProvider, type FetchLike, type RequestOptions } from "./types";
|
|
2
|
+
export type XrpcCallOptions = RequestOptions & {
|
|
3
|
+
params?: Record<string, unknown>;
|
|
4
|
+
body?: unknown;
|
|
5
|
+
requireAuth?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export type HttpClientConfig = {
|
|
8
|
+
baseUrl: string;
|
|
9
|
+
auth?: AuthProvider;
|
|
10
|
+
fetch: FetchLike;
|
|
11
|
+
headers: Record<string, string>;
|
|
12
|
+
timeoutMs: number;
|
|
13
|
+
retries: number;
|
|
14
|
+
retryDelayMs: number;
|
|
15
|
+
};
|
|
16
|
+
export declare function buildConfig(opts: {
|
|
17
|
+
baseUrl?: string;
|
|
18
|
+
auth?: AuthProvider;
|
|
19
|
+
fetch?: FetchLike;
|
|
20
|
+
headers?: Record<string, string>;
|
|
21
|
+
timeoutMs?: number;
|
|
22
|
+
retries?: number;
|
|
23
|
+
retryDelayMs?: number;
|
|
24
|
+
userAgent?: string;
|
|
25
|
+
}): HttpClientConfig;
|
|
26
|
+
export declare function serializeParams(params: Record<string, unknown> | undefined): string;
|
|
27
|
+
export declare function xrpcCall<T>(config: HttpClientConfig, nsid: string, method: "GET" | "POST", opts?: XrpcCallOptions): Promise<T>;
|
|
28
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,SAAS,EACd,KAAK,cAAc,EACpB,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,gBAAgB,CAenB;AAcD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC1C,MAAM,CAkBR;AAED,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,KAAK,GAAG,MAAM,EACtB,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,CAAC,CAAC,CA4CZ"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export { RockskyClient, RockskyClientBuilder, createClient, } from "./client";
|
|
2
|
+
export { RockskyError, RockskyHttpError, RockskyTimeoutError, RockskyAuthError, } from "./errors";
|
|
3
|
+
export { pipe, map, tap, withRetry, withTimeout, withFallback, catchError, type Op, } from "./pipe";
|
|
4
|
+
export { DEFAULT_BASE_URL, type AuthProvider, type ClientOptions, type FetchLike, type Json, type Pagination, type RequestOptions, } from "./types";
|
|
5
|
+
export { paginate, type PageOpts, type PageResult, type PaginateArgs, } from "./paginate";
|
|
6
|
+
export { RealtimeClient, RealtimeClientBuilder, createRealtimeClient, type RealtimeOptions, type RealtimeEvent, type RealtimeEventMap, type ReconnectOptions, type WebSocketCtor, type WebSocketLike, } from "./realtime";
|
|
7
|
+
export type { GetProfileParams, ActorPagedParams, ActorRangeParams, } from "./namespaces/actor";
|
|
8
|
+
export type { CreateScrobbleInput, GetScrobblesParams, } from "./namespaces/scrobble";
|
|
9
|
+
export type { GetSongParams, GetSongsParams, MatchSongParams, CreateSongInput, } from "./namespaces/song";
|
|
10
|
+
export type { GetAlbumsParams } from "./namespaces/album";
|
|
11
|
+
export type { GetArtistsParams, ArtistListenersParams, GetArtistTracksParams, } from "./namespaces/artist";
|
|
12
|
+
export type { ListApikeysParams, CreateApikeyInput, UpdateApikeyInput, } from "./namespaces/apikey";
|
|
13
|
+
export type { ScrobblesChartParams, TopChartParams, } from "./namespaces/charts";
|
|
14
|
+
export type { FollowListParams, KnownFollowersParams, } from "./namespaces/graph";
|
|
15
|
+
export type { RecommendParams } from "./namespaces/feed";
|
|
16
|
+
export type { LikeInput } from "./namespaces/like";
|
|
17
|
+
export type { PutMirrorSourceInput } from "./namespaces/mirror";
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,YAAY,GACb,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,IAAI,EACJ,GAAG,EACH,GAAG,EACH,SAAS,EACT,WAAW,EACX,YAAY,EACZ,UAAU,EACV,KAAK,EAAE,GACR,MAAM,QAAQ,CAAC;AAChB,OAAO,EACL,gBAAgB,EAChB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,IAAI,EACT,KAAK,UAAU,EACf,KAAK,cAAc,GACpB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,QAAQ,EACR,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,aAAa,EACb,cAAc,EACd,eAAe,EACf,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,YAAY,EACV,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,oBAAoB,EACpB,cAAc,GACf,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC"}
|