@rocksky/sdk 0.3.0 → 0.5.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/README.md +71 -245
- package/dist/agent.d.ts +82 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/client.d.ts +165 -111
- package/dist/client.d.ts.map +1 -1
- package/dist/dedup.d.ts +38 -0
- package/dist/dedup.d.ts.map +1 -0
- package/dist/errors.d.ts +3 -23
- package/dist/errors.d.ts.map +1 -1
- package/dist/generated/types.d.ts +106 -8
- package/dist/generated/types.d.ts.map +1 -1
- package/dist/hash.d.ts +7 -0
- package/dist/hash.d.ts.map +1 -0
- package/dist/index.d.ts +17 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6956 -1267
- package/dist/jetstream.d.ts +17 -0
- package/dist/jetstream.d.ts.map +1 -0
- package/package.json +15 -11
- package/src/agent.ts +278 -0
- package/src/client.ts +393 -212
- package/src/dedup.ts +207 -0
- package/src/errors.ts +6 -43
- package/src/generated/types.ts +115 -8
- package/src/hash.ts +22 -0
- package/src/index.ts +17 -86
- package/src/jetstream.ts +122 -0
- package/src/http.ts +0 -195
- package/src/namespaces/_helpers.ts +0 -27
- package/src/namespaces/actor.ts +0 -93
- package/src/namespaces/album.ts +0 -34
- package/src/namespaces/apikey.ts +0 -50
- package/src/namespaces/artist.ts +0 -68
- package/src/namespaces/charts.ts +0 -38
- package/src/namespaces/dropbox.ts +0 -53
- package/src/namespaces/feed.ts +0 -112
- package/src/namespaces/googledrive.ts +0 -41
- package/src/namespaces/graph.ts +0 -62
- package/src/namespaces/like.ts +0 -46
- package/src/namespaces/mirror.ts +0 -27
- package/src/namespaces/player.ts +0 -125
- package/src/namespaces/playlist.ts +0 -95
- package/src/namespaces/scrobble.ts +0 -41
- package/src/namespaces/shout.ts +0 -99
- package/src/namespaces/song.ts +0 -60
- package/src/namespaces/spotify.ts +0 -56
- package/src/namespaces/stats.ts +0 -27
- package/src/paginate.ts +0 -90
- package/src/pipe.ts +0 -146
- package/src/realtime.ts +0 -408
- package/src/types.ts +0 -41
package/README.md
CHANGED
|
@@ -1,284 +1,110 @@
|
|
|
1
1
|
# @rocksky/sdk
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
- **Zero-dependency** — only uses the platform `fetch` and the standard library. Works on Bun, Node 18+, Deno, browsers, Cloudflare Workers.
|
|
3
|
+
Official TypeScript SDK for [Rocksky](https://rocksky.app) — a music scrobbling &
|
|
4
|
+
discovery platform on the AT Protocol. Built on
|
|
5
|
+
[atcute](https://github.com/mary-ext/atcute): `RockskyClient` does unauthenticated
|
|
6
|
+
AppView reads, and `Agent` logs in with an app password and writes
|
|
7
|
+
`app.rocksky.*` records to the user's PDS.
|
|
9
8
|
|
|
10
9
|
## Install
|
|
11
10
|
|
|
12
|
-
```
|
|
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 });
|
|
11
|
+
```sh
|
|
12
|
+
npm install @rocksky/sdk # or: bun add @rocksky/sdk
|
|
27
13
|
```
|
|
28
14
|
|
|
29
|
-
##
|
|
30
|
-
|
|
31
|
-
The SDK accepts a bearer token either as a string or as a (sync/async) function:
|
|
15
|
+
## Quickstart
|
|
32
16
|
|
|
33
17
|
```ts
|
|
34
|
-
import {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
18
|
+
import { RockskyClient, Agent } from "@rocksky/sdk";
|
|
19
|
+
|
|
20
|
+
// Reads — unauthenticated. new RockskyClient() uses https://api.rocksky.app.
|
|
21
|
+
const rk = new RockskyClient();
|
|
22
|
+
const stats = await rk.globalStats();
|
|
23
|
+
const top = await rk.topTracks(10, 0);
|
|
24
|
+
|
|
25
|
+
// Writes — log in with an app password (resolves the PDS automatically).
|
|
26
|
+
const agent = await Agent.login("alice.bsky.social", "app-password");
|
|
27
|
+
const uri = await agent.scrobble({
|
|
28
|
+
title: "Chaser", artist: "Calibro 35",
|
|
29
|
+
album: "Jazzploitation", albumArtist: "Calibro 35", duration: 182320,
|
|
41
30
|
});
|
|
42
31
|
```
|
|
43
32
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
## Builder
|
|
33
|
+
## API
|
|
47
34
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
.retryDelay(200)
|
|
58
|
-
.header("x-trace-id", crypto.randomUUID())
|
|
59
|
-
.build();
|
|
60
|
-
```
|
|
35
|
+
**Reads — `RockskyClient`**: the client now covers the whole `app.rocksky.*`
|
|
36
|
+
read surface. Typed methods include `profile`, `scrobbles`, `songs`, `albums`,
|
|
37
|
+
`artists`, `topTracks`, `topArtists`, `search`, `globalStats`, `lovedSongs`,
|
|
38
|
+
`catalogAlbums`, `catalogArtists`, `catalogSongs`, `albumTracks`, `artistAlbums`,
|
|
39
|
+
`artistTracks`, `scrobbleFeed`, `scrobble` (single by uri), `follows`,
|
|
40
|
+
`followers`, `knownFollowers`. Raw (`unknown`-returning) detail/long-tail
|
|
41
|
+
methods cover the rest: `album`, `artist`, `song`, `feed`, `playlists`,
|
|
42
|
+
`playlist`, `stats`, `wrapped`, `scrobblesChart`, `recommendations`,
|
|
43
|
+
`neighbours`, shouts, and more.
|
|
61
44
|
|
|
62
|
-
|
|
45
|
+
Every named method is sugar over the universal escape hatch **`rk.get(nsid,
|
|
46
|
+
params)`**, which calls ANY read query by nsid and returns `unknown`.
|
|
63
47
|
|
|
64
|
-
|
|
48
|
+
**Typed date-window charts**: `topTracksInterval(limit, offset, interval)` and
|
|
49
|
+
`topArtistsInterval(...)` take a `DateInterval` built with the `Interval`
|
|
50
|
+
factories — `Interval.allTime()`, `Interval.lastDays(n)`, `Interval.lastWeeks(n)`,
|
|
51
|
+
`Interval.lastMonths(n)`, `Interval.lastYears(n)`, `Interval.range(start, end)`.
|
|
52
|
+
`topTracks` / `topArtists` remain all-time shorthands.
|
|
65
53
|
|
|
66
54
|
```ts
|
|
67
|
-
import {
|
|
68
|
-
createClient,
|
|
69
|
-
map,
|
|
70
|
-
pipe,
|
|
71
|
-
tap,
|
|
72
|
-
withFallback,
|
|
73
|
-
withRetry,
|
|
74
|
-
withTimeout,
|
|
75
|
-
} from "@rocksky/sdk";
|
|
55
|
+
import { RockskyClient, Interval } from "@rocksky/sdk";
|
|
76
56
|
|
|
77
|
-
const
|
|
57
|
+
const rk = new RockskyClient();
|
|
58
|
+
const monthly = await rk.topTracksInterval(10, 0, Interval.lastMonths(1));
|
|
78
59
|
|
|
79
|
-
//
|
|
80
|
-
const
|
|
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
|
-
);
|
|
60
|
+
// Resolve a bare title + artist into full canonical metadata.
|
|
61
|
+
const song = await rk.matchSong("Chaser", "Calibro 35");
|
|
88
62
|
```
|
|
89
63
|
|
|
90
|
-
|
|
64
|
+
**`matchSong(title, artist, mbId?, isrc?)`**: resolves a bare title + artist into
|
|
65
|
+
full canonical metadata (album, artwork, duration, MBID, ISRC, links).
|
|
91
66
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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. |
|
|
67
|
+
**Auth-gated reads**: pass an optional bearer access token —
|
|
68
|
+
`new RockskyClient(appview, token)` — and it is sent as
|
|
69
|
+
`Authorization: Bearer <token>`.
|
|
100
70
|
|
|
101
|
-
|
|
71
|
+
**Writes — `Agent`**: two scrobble paths. `scrobble(rec)` writes full metadata
|
|
72
|
+
you already have; `scrobbleMatch(title, artist, album?, mbId?, isrc?)` resolves
|
|
73
|
+
full metadata via `matchSong` first, then writes. Plus
|
|
74
|
+
`createSong`/`createAlbum`/`createArtist`, `like`, `follow`,
|
|
75
|
+
`shout`/`replyShout`, `setNowPlaying`/`clearNowPlaying`, `delete`. Records are the
|
|
76
|
+
generated types from `./generated/types`.
|
|
102
77
|
|
|
103
|
-
|
|
104
|
-
|
|
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
|
-
```
|
|
78
|
+
**Identity hashes**: `songHash`, `albumHash`, `artistHash` — lowercase-hex
|
|
79
|
+
SHA-256, identical to the server and every other Rocksky SDK.
|
|
136
80
|
|
|
137
|
-
|
|
81
|
+
## Duplicate prevention + real-time sync
|
|
138
82
|
|
|
139
|
-
|
|
140
|
-
|
|
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:
|
|
83
|
+
An optional local index (embedded [classic-level](https://github.com/Level/classic-level)
|
|
84
|
+
LevelDB) prevents duplicate writes and stays live off the firehose:
|
|
147
85
|
|
|
148
86
|
```ts
|
|
149
|
-
|
|
150
|
-
"app.rocksky.something.notWrappedYet",
|
|
151
|
-
"GET",
|
|
152
|
-
{ params: { foo: "bar" } },
|
|
153
|
-
);
|
|
154
|
-
```
|
|
87
|
+
import { RockskyIndex } from "@rocksky/sdk";
|
|
155
88
|
|
|
156
|
-
|
|
89
|
+
const idx = new RockskyIndex("./dedup");
|
|
90
|
+
await idx.open();
|
|
91
|
+
agent.useIndex(idx);
|
|
157
92
|
|
|
158
|
-
|
|
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
|
-
}
|
|
93
|
+
const stats = await agent.syncRepo(); // backfill from the repo CAR (com.atproto.sync.getRepo)
|
|
94
|
+
agent.hydrateFromJetstream(); // keep it live from Jetstream (all 4 servers)
|
|
177
95
|
```
|
|
178
96
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
`paginate()` (and `client.paginate()`) gives you a typed async iterable over any `{ limit, offset }` or `{ cursor }` endpoint.
|
|
97
|
+
With an index attached, the write verbs skip records that already exist (return
|
|
98
|
+
the existing URI) and a same-second scrobble of the same track isn't duplicated.
|
|
182
99
|
|
|
183
|
-
|
|
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
|
-
## Types
|
|
259
|
-
|
|
260
|
-
Public model types are derived from the [Rocksky lexicons](https://tangled.org/rocksky.app/rocksky/tree/main/apps/api/lexicons) and live in `src/generated/types.ts`. They are regenerated from `apps/api/lexicons/**/*.json` by running `bun run lexgen:types` at the repo root.
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
## Development
|
|
264
|
-
|
|
265
|
-
```bash
|
|
266
|
-
bun install
|
|
267
|
-
bun test
|
|
268
|
-
bun run typecheck
|
|
269
|
-
bun run build
|
|
270
|
-
```
|
|
100
|
+
Node ≥ 22 (global `WebSocket`/`fetch`) or Bun.
|
|
271
101
|
|
|
272
|
-
|
|
102
|
+
## Example
|
|
273
103
|
|
|
274
|
-
```
|
|
275
|
-
bun run
|
|
276
|
-
bun run example:builder
|
|
277
|
-
bun run example:pipe
|
|
278
|
-
bun run example:scrobble
|
|
279
|
-
bun run example:pagination
|
|
104
|
+
```sh
|
|
105
|
+
bun run examples/native.ts
|
|
280
106
|
```
|
|
281
107
|
|
|
282
108
|
## License
|
|
283
109
|
|
|
284
|
-
|
|
110
|
+
MIT.
|
package/dist/agent.d.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { PasswordSession } from "@atcute/password-session";
|
|
2
|
+
import type { AlbumRecord, ArtistRecord, ActorTrackView, ScrobbleRecord, SongRecord } from "./generated/types.js";
|
|
3
|
+
import type { IndexStats, RockskyIndex } from "./dedup.js";
|
|
4
|
+
import { type JetstreamOptions } from "./jetstream.js";
|
|
5
|
+
/** Input for {@link Agent.scrobble} (createdAt defaults to now). */
|
|
6
|
+
export type ScrobbleInput = Omit<ScrobbleRecord, "createdAt"> & {
|
|
7
|
+
createdAt?: string;
|
|
8
|
+
};
|
|
9
|
+
/** Input for {@link Agent.createSong}. */
|
|
10
|
+
export type SongInput = Omit<SongRecord, "createdAt"> & {
|
|
11
|
+
createdAt?: string;
|
|
12
|
+
};
|
|
13
|
+
/** Input for {@link Agent.createAlbum} (`artist` is the album artist). */
|
|
14
|
+
export type AlbumInput = Omit<AlbumRecord, "createdAt"> & {
|
|
15
|
+
createdAt?: string;
|
|
16
|
+
};
|
|
17
|
+
/** Input for {@link Agent.createArtist}. */
|
|
18
|
+
export type ArtistInput = Omit<ArtistRecord, "createdAt"> & {
|
|
19
|
+
createdAt?: string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Authenticated Rocksky client: logs in with an app password and writes
|
|
23
|
+
* app.rocksky.* records to the user's PDS (via atcute). Attach a
|
|
24
|
+
* {@link RockskyIndex} with {@link Agent.useIndex} for duplicate prevention.
|
|
25
|
+
*/
|
|
26
|
+
export declare class Agent {
|
|
27
|
+
private rpc;
|
|
28
|
+
readonly did: string;
|
|
29
|
+
readonly session: PasswordSession;
|
|
30
|
+
private pds;
|
|
31
|
+
private idx?;
|
|
32
|
+
private constructor();
|
|
33
|
+
/**
|
|
34
|
+
* Resolve the account's PDS, authenticate with an app password, and return an
|
|
35
|
+
* Agent. `identifier` is a handle or DID.
|
|
36
|
+
*/
|
|
37
|
+
static login(identifier: string, password: string): Promise<Agent>;
|
|
38
|
+
/** Attach a local dedup index — write verbs then skip records that already exist. */
|
|
39
|
+
useIndex(idx: RockskyIndex): void;
|
|
40
|
+
/**
|
|
41
|
+
* Download the caller's full repository and (re)build the dedup index. Requires
|
|
42
|
+
* an attached index ({@link Agent.useIndex}). Full backfill; keep it current
|
|
43
|
+
* with {@link Agent.hydrateFromJetstream}.
|
|
44
|
+
*/
|
|
45
|
+
syncRepo(): Promise<IndexStats>;
|
|
46
|
+
/**
|
|
47
|
+
* Keep the dedup index live from the Bluesky Jetstream firehose (all four
|
|
48
|
+
* servers at once, filtered to this DID + app.rocksky.*). Resolves when the
|
|
49
|
+
* options' AbortSignal fires. Requires an attached index.
|
|
50
|
+
*/
|
|
51
|
+
hydrateFromJetstream(opts?: JetstreamOptions): Promise<void>;
|
|
52
|
+
private create;
|
|
53
|
+
private putRecord;
|
|
54
|
+
/** Delete a record by collection + rkey. */
|
|
55
|
+
delete(collection: string, rkey: string): Promise<void>;
|
|
56
|
+
/** Scrobble a play (app.rocksky.scrobble). createdAt defaults to now. */
|
|
57
|
+
scrobble(rec: ScrobbleInput): Promise<string>;
|
|
58
|
+
/** Scrobble from just a title + artist (album optional, plus optional
|
|
59
|
+
* `mbId`/`isrc` anchors): resolve full metadata via `matchSong`, then write.
|
|
60
|
+
* Matching uses the public AppView unless `appview` is given; an empty match
|
|
61
|
+
* falls back to a minimal record. */
|
|
62
|
+
scrobbleMatch(title: string, artist: string, album?: string, mbId?: string, isrc?: string, appview?: string): Promise<string>;
|
|
63
|
+
/** Create a canonical track record (app.rocksky.song). */
|
|
64
|
+
createSong(rec: SongInput): Promise<string>;
|
|
65
|
+
/** Create an album record (app.rocksky.album). `artist` is the album artist. */
|
|
66
|
+
createAlbum(rec: AlbumInput): Promise<string>;
|
|
67
|
+
/** Create an artist record (app.rocksky.artist). */
|
|
68
|
+
createArtist(rec: ArtistInput): Promise<string>;
|
|
69
|
+
/** Like a record by strong reference (uri + cid). Returns the like URI. */
|
|
70
|
+
like(uri: string, cid: string): Promise<string>;
|
|
71
|
+
/** Follow an account by DID. Returns the follow URI. */
|
|
72
|
+
follow(did: string): Promise<string>;
|
|
73
|
+
/** Post a shout on a subject. Returns the shout URI. */
|
|
74
|
+
shout(subjectUri: string, subjectCid: string, message: string): Promise<string>;
|
|
75
|
+
/** Reply to a shout, with a parent strong-ref. */
|
|
76
|
+
replyShout(subjectUri: string, subjectCid: string, parentUri: string, parentCid: string, message: string): Promise<string>;
|
|
77
|
+
/** Upsert the actor's now-playing status singleton (rkey "self"). */
|
|
78
|
+
setNowPlaying(track: ActorTrackView): Promise<string>;
|
|
79
|
+
/** Delete the actor's now-playing status singleton. */
|
|
80
|
+
clearNowPlaying(): Promise<void>;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|