@atproto/sync 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/CHANGELOG.md +12 -0
- package/LICENSE.txt +7 -0
- package/README.md +93 -0
- package/dist/events.d.ts +49 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +3 -0
- package/dist/events.js.map +1 -0
- package/dist/firehose/index.d.ts +50 -0
- package/dist/firehose/index.d.ts.map +1 -0
- package/dist/firehose/index.js +309 -0
- package/dist/firehose/index.js.map +1 -0
- package/dist/firehose/lexicons.d.ts +118 -0
- package/dist/firehose/lexicons.d.ts.map +1 -0
- package/dist/firehose/lexicons.js +265 -0
- package/dist/firehose/lexicons.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/runner/consecutive-list.d.ts +27 -0
- package/dist/runner/consecutive-list.d.ts.map +1 -0
- package/dist/runner/consecutive-list.js +68 -0
- package/dist/runner/consecutive-list.js.map +1 -0
- package/dist/runner/index.d.ts +4 -0
- package/dist/runner/index.d.ts.map +1 -0
- package/dist/runner/index.js +20 -0
- package/dist/runner/index.js.map +1 -0
- package/dist/runner/memory-runner.d.ts +24 -0
- package/dist/runner/memory-runner.d.ts.map +1 -0
- package/dist/runner/memory-runner.js +92 -0
- package/dist/runner/memory-runner.js.map +1 -0
- package/dist/runner/types.d.ts +5 -0
- package/dist/runner/types.d.ts.map +1 -0
- package/dist/runner/types.js +3 -0
- package/dist/runner/types.js.map +1 -0
- package/dist/util.d.ts +6 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +13 -0
- package/dist/util.js.map +1 -0
- package/jest.config.js +8 -0
- package/package.json +37 -0
- package/src/events.ts +61 -0
- package/src/firehose/index.ts +357 -0
- package/src/firehose/lexicons.ts +407 -0
- package/src/index.ts +3 -0
- package/src/runner/consecutive-list.ts +44 -0
- package/src/runner/index.ts +3 -0
- package/src/runner/memory-runner.ts +72 -0
- package/src/runner/types.ts +8 -0
- package/src/util.ts +10 -0
- package/tests/firehose.test.ts +180 -0
- package/tests/runner.test.ts +122 -0
- package/tsconfig.build.json +8 -0
- package/tsconfig.json +4 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# @atproto/sync
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#2752](https://github.com/bluesky-social/atproto/pull/2752) [`b15dec2f4`](https://github.com/bluesky-social/atproto/commit/b15dec2f4feb25ac91b169c83ccff1adbb5a9442) Thanks [@dholms](https://github.com/dholms)! - Introduced initial sync package for consuming firehose (com.atproto.sync.subscribeRepos)
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [[`b15dec2f4`](https://github.com/bluesky-social/atproto/commit/b15dec2f4feb25ac91b169c83ccff1adbb5a9442)]:
|
|
12
|
+
- @atproto/repo@0.5.0
|
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Dual MIT/Apache-2.0 License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022-2024 Bluesky PBC, and Contributors
|
|
4
|
+
|
|
5
|
+
Except as otherwise noted in individual files, this software is licensed under the MIT license (<http://opensource.org/licenses/MIT>), or the Apache License, Version 2.0 (<http://www.apache.org/licenses/LICENSE-2.0>).
|
|
6
|
+
|
|
7
|
+
Downstream projects and end users may chose either license individually, or both together, at their discretion. The motivation for this dual-licensing is the additional software patent assurance provided by Apache 2.0.
|
package/README.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# @atproto/sync: atproto sync tools
|
|
2
|
+
|
|
3
|
+
TypeScript library for syncing data from the [atproto](https://atproto.com) network. Currently only supports firehose (relay) subscriptions
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@atproto/sync)
|
|
6
|
+
[](https://github.com/bluesky-social/atproto/actions/workflows/repo.yaml)
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
The firehose class will spin up a websocket connection to `com.atproto.sync.subscribeRepos` on a given repo host (by default the Relay run by Bluesky).
|
|
11
|
+
|
|
12
|
+
Each event will be parsed, authenticated, and then passed on to the supplied `handleEvt` which can handle indexing.
|
|
13
|
+
|
|
14
|
+
On `Commit` events, the firehose will verify signatures and repo proofs to ensure that the event is authentic. This can be disabled with the `unauthenticatedCommits` flag. Similarly on `Identity` events, the firehose will fetch the latest DID document for the repo and do bidirectional verification on the associated handle. This can be disabled with the `unauthenticatedHandles` flag.
|
|
15
|
+
|
|
16
|
+
Events of a certain type can be excluded using the `excludeIdentity`/`excludeAccount`/`excludeCommit` flags. And repo writes can be filtered down to specific collections using `filterCollections`. By default, all events are parsed and passed through to the handler. Note that this filtered currently happens client-side, though it is likely we will introduce server-side methods for doing so in the future.
|
|
17
|
+
|
|
18
|
+
Non-fatal errors that are encountered will be passed to the required `onError` handler. In most cases, these can just be logged.
|
|
19
|
+
|
|
20
|
+
When using the firehose class, events are processed serially. Each event must be finished being handled before the next one is parsed and authenticated.
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { Firehose } from '@atproto/sync'
|
|
24
|
+
import { IdResolver } from '@atproto/identity'
|
|
25
|
+
|
|
26
|
+
const idResolver = new IdResolver()
|
|
27
|
+
const firehose = new Firehose({
|
|
28
|
+
idResolver,
|
|
29
|
+
service: 'wss://bsky.network',
|
|
30
|
+
handleEvt: async (evt) => {
|
|
31
|
+
if (evt.event === 'identity') {
|
|
32
|
+
// ...
|
|
33
|
+
} else if (evt.event === 'account') {
|
|
34
|
+
// ...
|
|
35
|
+
} else if (evt.event === 'create') {
|
|
36
|
+
// ...
|
|
37
|
+
} else if (evt.event === 'update') {
|
|
38
|
+
// ...
|
|
39
|
+
} else if (evt.event === 'delete') {
|
|
40
|
+
// ...
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
onError: (err) => {
|
|
44
|
+
console.error(err)
|
|
45
|
+
},
|
|
46
|
+
filterCollections: ['com.myexample.app'],
|
|
47
|
+
})
|
|
48
|
+
firehose.start()
|
|
49
|
+
|
|
50
|
+
// on service shutdown
|
|
51
|
+
await firehose.destroy()
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
For more robust indexing pipelines, it's recommended to use the supplied `MemoryRunner` class. This provides an in-memory partitioned queue. As events from a given repo must be processed in order, this allows events to be processed concurrently while still processing events from any given repo serially.
|
|
55
|
+
|
|
56
|
+
The `MemoryRunner` also tracks an internal cursor based on the last finished consecutive work. This ensures that no events are dropped, although it does mean that some events may occassionally be replayed (if the websocket drops and reconnects) and therefore it's recommended that any indexing logic is idempotent. An optional `setCursor` parameter may be supplied to the `MemoryRunner` which can be used to persistently store the most recently processed cursor.
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import { Firehose, MemoryRunner } from '@atproto/sync'
|
|
60
|
+
import { IdResolver } from '@atproto/identity'
|
|
61
|
+
|
|
62
|
+
const idResolver = new IdResolver()
|
|
63
|
+
const runner = new MemoryRunner({
|
|
64
|
+
setCursor: (cursor) => {
|
|
65
|
+
// persist cursor
|
|
66
|
+
},
|
|
67
|
+
})
|
|
68
|
+
const firehose = new Firehose({
|
|
69
|
+
idResolver,
|
|
70
|
+
runner,
|
|
71
|
+
service: 'wss://bsky.network',
|
|
72
|
+
handleEvt: async (evt) => {
|
|
73
|
+
// ...
|
|
74
|
+
},
|
|
75
|
+
onError: (err) => {
|
|
76
|
+
console.error(err)
|
|
77
|
+
},
|
|
78
|
+
})
|
|
79
|
+
firehose.start()
|
|
80
|
+
|
|
81
|
+
// on service shutdown
|
|
82
|
+
await firehose.destroy()
|
|
83
|
+
await runner.destroy()
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## License
|
|
87
|
+
|
|
88
|
+
This project is dual-licensed under MIT and Apache 2.0 terms:
|
|
89
|
+
|
|
90
|
+
- MIT license ([LICENSE-MIT.txt](https://github.com/bluesky-social/atproto/blob/main/LICENSE-MIT.txt) or http://opensource.org/licenses/MIT)
|
|
91
|
+
- Apache License, Version 2.0, ([LICENSE-APACHE.txt](https://github.com/bluesky-social/atproto/blob/main/LICENSE-APACHE.txt) or http://www.apache.org/licenses/LICENSE-2.0)
|
|
92
|
+
|
|
93
|
+
Downstream projects and end users may chose either license individually, or both together, at their discretion. The motivation for this dual-licensing is the additional software patent assurance provided by Apache 2.0.
|
package/dist/events.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { DidDocument } from '@atproto/identity';
|
|
2
|
+
import type { RepoRecord } from '@atproto/lexicon';
|
|
3
|
+
import { BlockMap } from '@atproto/repo';
|
|
4
|
+
import { AtUri } from '@atproto/syntax';
|
|
5
|
+
import type { CID } from 'multiformats/cid';
|
|
6
|
+
export type Event = CommitEvt | IdentityEvt | AccountEvt;
|
|
7
|
+
export type CommitMeta = {
|
|
8
|
+
seq: number;
|
|
9
|
+
time: string;
|
|
10
|
+
commit: CID;
|
|
11
|
+
blocks: BlockMap;
|
|
12
|
+
rev: string;
|
|
13
|
+
uri: AtUri;
|
|
14
|
+
did: string;
|
|
15
|
+
collection: string;
|
|
16
|
+
rkey: string;
|
|
17
|
+
};
|
|
18
|
+
export type CommitEvt = Create | Update | Delete;
|
|
19
|
+
export type Create = CommitMeta & {
|
|
20
|
+
event: 'create';
|
|
21
|
+
record: RepoRecord;
|
|
22
|
+
cid: CID;
|
|
23
|
+
};
|
|
24
|
+
export type Update = CommitMeta & {
|
|
25
|
+
event: 'update';
|
|
26
|
+
record: RepoRecord;
|
|
27
|
+
cid: CID;
|
|
28
|
+
};
|
|
29
|
+
export type Delete = CommitMeta & {
|
|
30
|
+
event: 'delete';
|
|
31
|
+
};
|
|
32
|
+
export type IdentityEvt = {
|
|
33
|
+
seq: number;
|
|
34
|
+
time: string;
|
|
35
|
+
event: 'identity';
|
|
36
|
+
did: string;
|
|
37
|
+
handle?: string;
|
|
38
|
+
didDocument?: DidDocument;
|
|
39
|
+
};
|
|
40
|
+
export type AccountEvt = {
|
|
41
|
+
seq: number;
|
|
42
|
+
time: string;
|
|
43
|
+
event: 'account';
|
|
44
|
+
did: string;
|
|
45
|
+
active: boolean;
|
|
46
|
+
status?: AccountStatus;
|
|
47
|
+
};
|
|
48
|
+
export type AccountStatus = 'takendown' | 'suspended' | 'deleted' | 'deactivated';
|
|
49
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AACvC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAE3C,MAAM,MAAM,KAAK,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,CAAA;AAExD,MAAM,MAAM,UAAU,GAAG;IACvB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,GAAG,CAAA;IACX,MAAM,EAAE,QAAQ,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,KAAK,CAAA;IACV,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;AAEhD,MAAM,MAAM,MAAM,GAAG,UAAU,GAAG;IAChC,KAAK,EAAE,QAAQ,CAAA;IACf,MAAM,EAAE,UAAU,CAAA;IAClB,GAAG,EAAE,GAAG,CAAA;CACT,CAAA;AAED,MAAM,MAAM,MAAM,GAAG,UAAU,GAAG;IAChC,KAAK,EAAE,QAAQ,CAAA;IACf,MAAM,EAAE,UAAU,CAAA;IAClB,GAAG,EAAE,GAAG,CAAA;CACT,CAAA;AAED,MAAM,MAAM,MAAM,GAAG,UAAU,GAAG;IAChC,KAAK,EAAE,QAAQ,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,UAAU,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,SAAS,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,CAAC,EAAE,aAAa,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,aAAa,GACrB,WAAW,GACX,WAAW,GACX,SAAS,GACT,aAAa,CAAA"}
|
package/dist/events.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { IdResolver } from '@atproto/identity';
|
|
2
|
+
import { type Account, type Commit, type Identity, type RepoEvent } from './lexicons';
|
|
3
|
+
import { Event, CommitEvt, AccountEvt, IdentityEvt } from '../events';
|
|
4
|
+
import { EventRunner } from '../runner';
|
|
5
|
+
export type FirehoseOptions = {
|
|
6
|
+
idResolver: IdResolver;
|
|
7
|
+
handleEvent: (evt: Event) => Awaited<void>;
|
|
8
|
+
onError: (err: Error) => void;
|
|
9
|
+
getCursor?: () => Awaited<number | undefined>;
|
|
10
|
+
runner?: EventRunner;
|
|
11
|
+
service?: string;
|
|
12
|
+
subscriptionReconnectDelay?: number;
|
|
13
|
+
unauthenticatedCommits?: boolean;
|
|
14
|
+
unauthenticatedHandles?: boolean;
|
|
15
|
+
filterCollections?: string[];
|
|
16
|
+
excludeIdentity?: boolean;
|
|
17
|
+
excludeAccount?: boolean;
|
|
18
|
+
excludeCommit?: boolean;
|
|
19
|
+
};
|
|
20
|
+
export declare class Firehose {
|
|
21
|
+
opts: FirehoseOptions;
|
|
22
|
+
private sub;
|
|
23
|
+
private abortController;
|
|
24
|
+
private destoryDefer;
|
|
25
|
+
constructor(opts: FirehoseOptions);
|
|
26
|
+
start(): any;
|
|
27
|
+
private parseEvt;
|
|
28
|
+
private processEvt;
|
|
29
|
+
destroy(): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
export declare const parseCommitAuthenticated: (idResolver: IdResolver, evt: Commit, filterCollections?: string[], forceKeyRefresh?: boolean) => Promise<CommitEvt[]>;
|
|
32
|
+
export declare const parseCommitUnauthenticated: (evt: Commit, filterCollections?: string[]) => Promise<CommitEvt[]>;
|
|
33
|
+
export declare const parseIdentity: (idResolver: IdResolver, evt: Identity, unauthenticated?: boolean) => Promise<IdentityEvt | null>;
|
|
34
|
+
export declare const parseAccount: (evt: Account) => AccountEvt | undefined;
|
|
35
|
+
export declare class FirehoseValidationError extends Error {
|
|
36
|
+
value: unknown;
|
|
37
|
+
constructor(err: unknown, value: unknown);
|
|
38
|
+
}
|
|
39
|
+
export declare class FirehoseParseError extends Error {
|
|
40
|
+
event: RepoEvent;
|
|
41
|
+
constructor(err: unknown, event: RepoEvent);
|
|
42
|
+
}
|
|
43
|
+
export declare class FirehoseSubscriptionError extends Error {
|
|
44
|
+
constructor(err: unknown);
|
|
45
|
+
}
|
|
46
|
+
export declare class FirehoseHandlerError extends Error {
|
|
47
|
+
event: Event;
|
|
48
|
+
constructor(err: unknown, event: Event);
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/firehose/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,UAAU,EAGX,MAAM,mBAAmB,CAAA;AAW1B,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,SAAS,EAMf,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,KAAK,EAEL,SAAS,EACT,UAAU,EAEV,WAAW,EACZ,MAAM,WAAW,CAAA;AAElB,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAGvC,MAAM,MAAM,eAAe,GAAG;IAC5B,UAAU,EAAE,UAAU,CAAA;IAEtB,WAAW,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1C,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAE7C,MAAM,CAAC,EAAE,WAAW,CAAA;IAEpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,0BAA0B,CAAC,EAAE,MAAM,CAAA;IAEnC,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAEhC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,CAAA;AAED,qBAAa,QAAQ;IAKA,IAAI,EAAE,eAAe;IAJxC,OAAO,CAAC,GAAG,CAAyB;IACpC,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,YAAY,CAAY;gBAEb,IAAI,EAAE,eAAe;IA6BlC,KAAK;YAiCG,QAAQ;YA6BR,UAAU;IAWlB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAI/B;AAED,eAAO,MAAM,wBAAwB,eACvB,UAAU,OACjB,MAAM,sBACS,MAAM,EAAE,gCAE3B,QAAQ,SAAS,EAAE,CAgCrB,CAAA;AAED,eAAO,MAAM,0BAA0B,QAChC,MAAM,sBACS,MAAM,EAAE,KAC3B,QAAQ,SAAS,EAAE,CAGrB,CAAA;AAyDD,eAAO,MAAM,aAAa,eACZ,UAAU,OACjB,QAAQ,gCAEZ,QAAQ,WAAW,GAAG,IAAI,CAe5B,CAAA;AAeD,eAAO,MAAM,YAAY,QAAS,OAAO,KAAG,UAAU,GAAG,SAUxD,CAAA;AAMD,qBAAa,uBAAwB,SAAQ,KAAK;IAGvC,KAAK,EAAE,OAAO;gBADrB,GAAG,EAAE,OAAO,EACL,KAAK,EAAE,OAAO;CAIxB;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAGlC,KAAK,EAAE,SAAS;gBADvB,GAAG,EAAE,OAAO,EACL,KAAK,EAAE,SAAS;CAI1B;AAED,qBAAa,yBAA0B,SAAQ,KAAK;gBACtC,GAAG,EAAE,OAAO;CAGzB;AAED,qBAAa,oBAAqB,SAAQ,KAAK;IAGpC,KAAK,EAAE,KAAK;gBADnB,GAAG,EAAE,OAAO,EACL,KAAK,EAAE,KAAK;CAItB"}
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FirehoseHandlerError = exports.FirehoseSubscriptionError = exports.FirehoseParseError = exports.FirehoseValidationError = exports.parseAccount = exports.parseIdentity = exports.parseCommitUnauthenticated = exports.parseCommitAuthenticated = exports.Firehose = void 0;
|
|
4
|
+
const common_1 = require("@atproto/common");
|
|
5
|
+
const identity_1 = require("@atproto/identity");
|
|
6
|
+
const repo_1 = require("@atproto/repo");
|
|
7
|
+
const syntax_1 = require("@atproto/syntax");
|
|
8
|
+
const xrpc_server_1 = require("@atproto/xrpc-server");
|
|
9
|
+
const lexicons_1 = require("./lexicons");
|
|
10
|
+
const util_1 = require("../util");
|
|
11
|
+
class Firehose {
|
|
12
|
+
constructor(opts) {
|
|
13
|
+
Object.defineProperty(this, "opts", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
configurable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: opts
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(this, "sub", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
configurable: true,
|
|
22
|
+
writable: true,
|
|
23
|
+
value: void 0
|
|
24
|
+
});
|
|
25
|
+
Object.defineProperty(this, "abortController", {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
configurable: true,
|
|
28
|
+
writable: true,
|
|
29
|
+
value: void 0
|
|
30
|
+
});
|
|
31
|
+
Object.defineProperty(this, "destoryDefer", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
configurable: true,
|
|
34
|
+
writable: true,
|
|
35
|
+
value: void 0
|
|
36
|
+
});
|
|
37
|
+
this.destoryDefer = (0, common_1.createDeferrable)();
|
|
38
|
+
this.abortController = new AbortController();
|
|
39
|
+
if (this.opts.getCursor && this.opts.runner) {
|
|
40
|
+
throw new Error('Must set only `getCursor` or `runner`');
|
|
41
|
+
}
|
|
42
|
+
this.sub = new xrpc_server_1.Subscription({
|
|
43
|
+
service: opts.service ?? 'wss://bsky.network',
|
|
44
|
+
method: 'com.atproto.sync.subscribeRepos',
|
|
45
|
+
signal: this.abortController.signal,
|
|
46
|
+
getParams: async () => {
|
|
47
|
+
const getCursorFn = () => this.opts.runner?.getCursor() ?? this.opts.getCursor;
|
|
48
|
+
if (!getCursorFn) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
const cursor = await getCursorFn();
|
|
52
|
+
return { cursor };
|
|
53
|
+
},
|
|
54
|
+
validate: (value) => {
|
|
55
|
+
try {
|
|
56
|
+
return (0, lexicons_1.isValidRepoEvent)(value);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
this.opts.onError(new FirehoseValidationError(err, value));
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
async start() {
|
|
65
|
+
try {
|
|
66
|
+
for await (const evt of this.sub) {
|
|
67
|
+
if (this.opts.runner) {
|
|
68
|
+
const parsed = (0, util_1.didAndSeqForEvt)(evt);
|
|
69
|
+
if (!parsed) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
this.opts.runner.trackEvent(parsed.did, parsed.seq, async () => {
|
|
73
|
+
const parsed = await this.parseEvt(evt);
|
|
74
|
+
for (const write of parsed) {
|
|
75
|
+
try {
|
|
76
|
+
await this.opts.handleEvent(write);
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
this.opts.onError(new FirehoseHandlerError(err, write));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
await this.processEvt(evt);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
if (err && err['name'] === 'AbortError') {
|
|
91
|
+
this.destoryDefer.resolve();
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
this.opts.onError(new FirehoseSubscriptionError(err));
|
|
95
|
+
await (0, common_1.wait)(this.opts.subscriptionReconnectDelay ?? 3000);
|
|
96
|
+
return this.start();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async parseEvt(evt) {
|
|
100
|
+
try {
|
|
101
|
+
if ((0, lexicons_1.isCommit)(evt) && !this.opts.excludeCommit) {
|
|
102
|
+
return this.opts.unauthenticatedCommits
|
|
103
|
+
? await (0, exports.parseCommitUnauthenticated)(evt, this.opts.filterCollections)
|
|
104
|
+
: await (0, exports.parseCommitAuthenticated)(this.opts.idResolver, evt, this.opts.filterCollections);
|
|
105
|
+
}
|
|
106
|
+
else if ((0, lexicons_1.isAccount)(evt) && !this.opts.excludeAccount) {
|
|
107
|
+
const parsed = (0, exports.parseAccount)(evt);
|
|
108
|
+
return parsed ? [parsed] : [];
|
|
109
|
+
}
|
|
110
|
+
else if ((0, lexicons_1.isIdentity)(evt) && !this.opts.excludeIdentity) {
|
|
111
|
+
const parsed = await (0, exports.parseIdentity)(this.opts.idResolver, evt, this.opts.unauthenticatedHandles);
|
|
112
|
+
return parsed ? [parsed] : [];
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
this.opts.onError(new FirehoseParseError(err, evt));
|
|
120
|
+
return [];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async processEvt(evt) {
|
|
124
|
+
const parsed = await this.parseEvt(evt);
|
|
125
|
+
for (const write of parsed) {
|
|
126
|
+
try {
|
|
127
|
+
await this.opts.handleEvent(write);
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
this.opts.onError(new FirehoseHandlerError(err, write));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async destroy() {
|
|
135
|
+
this.abortController.abort();
|
|
136
|
+
await this.destoryDefer.complete;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
exports.Firehose = Firehose;
|
|
140
|
+
const parseCommitAuthenticated = async (idResolver, evt, filterCollections, forceKeyRefresh = false) => {
|
|
141
|
+
const did = evt.repo;
|
|
142
|
+
const key = await idResolver.did.resolveAtprotoKey(did, forceKeyRefresh);
|
|
143
|
+
const claims = maybeFilterOps(evt.ops, filterCollections).map((op) => {
|
|
144
|
+
const { collection, rkey } = (0, repo_1.parseDataKey)(op.path);
|
|
145
|
+
return {
|
|
146
|
+
collection,
|
|
147
|
+
rkey,
|
|
148
|
+
cid: op.action === 'delete' ? null : op.cid,
|
|
149
|
+
};
|
|
150
|
+
});
|
|
151
|
+
const verifiedCids = {};
|
|
152
|
+
try {
|
|
153
|
+
const results = await (0, repo_1.verifyProofs)(evt.blocks, claims, did, key);
|
|
154
|
+
results.verified.forEach((op) => {
|
|
155
|
+
const path = (0, repo_1.formatDataKey)(op.collection, op.rkey);
|
|
156
|
+
verifiedCids[path] = op.cid;
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
if (err instanceof repo_1.RepoVerificationError && !forceKeyRefresh) {
|
|
161
|
+
return (0, exports.parseCommitAuthenticated)(idResolver, evt, filterCollections, true);
|
|
162
|
+
}
|
|
163
|
+
throw err;
|
|
164
|
+
}
|
|
165
|
+
const verifiedOps = evt.ops.filter((op) => {
|
|
166
|
+
if (op.action === 'delete') {
|
|
167
|
+
return verifiedCids[op.path] === null;
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
return op.cid !== null && op.cid.equals(verifiedCids[op.path]);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
return formatCommitOps(evt, verifiedOps);
|
|
174
|
+
};
|
|
175
|
+
exports.parseCommitAuthenticated = parseCommitAuthenticated;
|
|
176
|
+
const parseCommitUnauthenticated = async (evt, filterCollections) => {
|
|
177
|
+
const ops = maybeFilterOps(evt.ops, filterCollections);
|
|
178
|
+
return formatCommitOps(evt, ops);
|
|
179
|
+
};
|
|
180
|
+
exports.parseCommitUnauthenticated = parseCommitUnauthenticated;
|
|
181
|
+
const maybeFilterOps = (ops, filterCollections) => {
|
|
182
|
+
if (!filterCollections)
|
|
183
|
+
return ops;
|
|
184
|
+
return ops.filter((op) => {
|
|
185
|
+
const { collection } = (0, repo_1.parseDataKey)(op.path);
|
|
186
|
+
return filterCollections.includes(collection);
|
|
187
|
+
});
|
|
188
|
+
};
|
|
189
|
+
const formatCommitOps = async (evt, ops) => {
|
|
190
|
+
const car = await (0, repo_1.readCar)(evt.blocks);
|
|
191
|
+
const evts = [];
|
|
192
|
+
for (const op of ops) {
|
|
193
|
+
const uri = syntax_1.AtUri.make(evt.repo, op.path);
|
|
194
|
+
const meta = {
|
|
195
|
+
seq: evt.seq,
|
|
196
|
+
time: evt.time,
|
|
197
|
+
commit: evt.commit,
|
|
198
|
+
blocks: car.blocks,
|
|
199
|
+
rev: evt.rev,
|
|
200
|
+
uri,
|
|
201
|
+
did: uri.host,
|
|
202
|
+
collection: uri.collection,
|
|
203
|
+
rkey: uri.rkey,
|
|
204
|
+
};
|
|
205
|
+
if (op.action === 'create' || op.action === 'update') {
|
|
206
|
+
if (!op.cid)
|
|
207
|
+
continue;
|
|
208
|
+
const recordBytes = car.blocks.get(op.cid);
|
|
209
|
+
if (!recordBytes)
|
|
210
|
+
continue;
|
|
211
|
+
const record = (0, repo_1.cborToLexRecord)(recordBytes);
|
|
212
|
+
evts.push({
|
|
213
|
+
...meta,
|
|
214
|
+
event: op.action,
|
|
215
|
+
cid: op.cid,
|
|
216
|
+
record,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
if (op.action === 'delete') {
|
|
220
|
+
evts.push({
|
|
221
|
+
...meta,
|
|
222
|
+
event: 'delete',
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return evts;
|
|
227
|
+
};
|
|
228
|
+
const parseIdentity = async (idResolver, evt, unauthenticated = false) => {
|
|
229
|
+
const res = await idResolver.did.resolve(evt.did);
|
|
230
|
+
const handle = res && !unauthenticated
|
|
231
|
+
? await verifyHandle(idResolver, evt.did, res)
|
|
232
|
+
: undefined;
|
|
233
|
+
return {
|
|
234
|
+
event: 'identity',
|
|
235
|
+
seq: evt.seq,
|
|
236
|
+
time: evt.time,
|
|
237
|
+
did: evt.did,
|
|
238
|
+
handle,
|
|
239
|
+
didDocument: res ?? undefined,
|
|
240
|
+
};
|
|
241
|
+
};
|
|
242
|
+
exports.parseIdentity = parseIdentity;
|
|
243
|
+
const verifyHandle = async (idResolver, did, didDoc) => {
|
|
244
|
+
const { handle } = (0, identity_1.parseToAtprotoDocument)(didDoc);
|
|
245
|
+
if (!handle) {
|
|
246
|
+
return undefined;
|
|
247
|
+
}
|
|
248
|
+
const res = await idResolver.handle.resolve(handle);
|
|
249
|
+
return res === did ? handle : undefined;
|
|
250
|
+
};
|
|
251
|
+
const parseAccount = (evt) => {
|
|
252
|
+
if (evt.status && !isValidStatus(evt.status))
|
|
253
|
+
return;
|
|
254
|
+
return {
|
|
255
|
+
event: 'account',
|
|
256
|
+
seq: evt.seq,
|
|
257
|
+
time: evt.time,
|
|
258
|
+
did: evt.did,
|
|
259
|
+
active: evt.active,
|
|
260
|
+
status: evt.status,
|
|
261
|
+
};
|
|
262
|
+
};
|
|
263
|
+
exports.parseAccount = parseAccount;
|
|
264
|
+
const isValidStatus = (str) => {
|
|
265
|
+
return ['takendown', 'suspended', 'deleted', 'deactivated'].includes(str);
|
|
266
|
+
};
|
|
267
|
+
class FirehoseValidationError extends Error {
|
|
268
|
+
constructor(err, value) {
|
|
269
|
+
super('error in firehose event lexicon validation', { cause: err });
|
|
270
|
+
Object.defineProperty(this, "value", {
|
|
271
|
+
enumerable: true,
|
|
272
|
+
configurable: true,
|
|
273
|
+
writable: true,
|
|
274
|
+
value: value
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
exports.FirehoseValidationError = FirehoseValidationError;
|
|
279
|
+
class FirehoseParseError extends Error {
|
|
280
|
+
constructor(err, event) {
|
|
281
|
+
super('error in parsing and authenticating firehose event', { cause: err });
|
|
282
|
+
Object.defineProperty(this, "event", {
|
|
283
|
+
enumerable: true,
|
|
284
|
+
configurable: true,
|
|
285
|
+
writable: true,
|
|
286
|
+
value: event
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
exports.FirehoseParseError = FirehoseParseError;
|
|
291
|
+
class FirehoseSubscriptionError extends Error {
|
|
292
|
+
constructor(err) {
|
|
293
|
+
super('error on firehose subscription', { cause: err });
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
exports.FirehoseSubscriptionError = FirehoseSubscriptionError;
|
|
297
|
+
class FirehoseHandlerError extends Error {
|
|
298
|
+
constructor(err, event) {
|
|
299
|
+
super('error in firehose event handler', { cause: err });
|
|
300
|
+
Object.defineProperty(this, "event", {
|
|
301
|
+
enumerable: true,
|
|
302
|
+
configurable: true,
|
|
303
|
+
writable: true,
|
|
304
|
+
value: event
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
exports.FirehoseHandlerError = FirehoseHandlerError;
|
|
309
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/firehose/index.ts"],"names":[],"mappings":"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"}
|