@atcute/tap 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 +14 -0
- package/README.md +33 -0
- package/dist/dev-index.d.ts +2 -0
- package/dist/dev-index.d.ts.map +1 -0
- package/dist/dev-index.js +21 -0
- package/dist/dev-index.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/tap-client.d.ts +14 -0
- package/dist/tap-client.d.ts.map +1 -0
- package/dist/tap-client.js +90 -0
- package/dist/tap-client.js.map +1 -0
- package/dist/tap-subscription.d.ts +15 -0
- package/dist/tap-subscription.d.ts.map +1 -0
- package/dist/tap-subscription.js +196 -0
- package/dist/tap-subscription.js.map +1 -0
- package/dist/typedefs.d.ts +74 -0
- package/dist/typedefs.d.ts.map +1 -0
- package/dist/typedefs.js +80 -0
- package/dist/typedefs.js.map +1 -0
- package/dist/types.d.ts +56 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +6 -0
- package/dist/utils.js.map +1 -0
- package/lib/dev-index.ts +24 -0
- package/lib/index.ts +5 -0
- package/lib/tap-client.ts +114 -0
- package/lib/tap-subscription.ts +267 -0
- package/lib/typedefs.ts +102 -0
- package/lib/types.ts +68 -0
- package/lib/utils.ts +6 -0
- package/package.json +44 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
BSD Zero Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Mary
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted.
|
|
7
|
+
|
|
8
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
9
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
10
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
11
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
12
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
13
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
14
|
+
PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# @atcute/tap
|
|
2
|
+
|
|
3
|
+
an atproto Tap client.
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npm install @atcute/tap
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Tap is a sync utility that connects to the relay firehose, verifies data, performs backfill, and
|
|
10
|
+
streams simple JSON events to clients over a local websocket.
|
|
11
|
+
|
|
12
|
+
## usage
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import { TapClient } from '@atcute/tap';
|
|
16
|
+
|
|
17
|
+
const tap = new TapClient({
|
|
18
|
+
url: 'http://localhost:2480',
|
|
19
|
+
// adminPassword: process.env.TAP_ADMIN_PASSWORD,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
await tap.addRepos(['did:plc:...']);
|
|
23
|
+
|
|
24
|
+
for await (const { event, ack } of tap.subscribe()) {
|
|
25
|
+
// process event idempotently
|
|
26
|
+
await ack();
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## acks
|
|
31
|
+
|
|
32
|
+
Tap’s default mode requires that clients acknowledge each event after it has been processed. if you
|
|
33
|
+
don’t call `ack()`, Tap will retry delivery later.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-index.d.ts","sourceRoot":"","sources":["../lib/dev-index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { TapClient } from './tap-client.js';
|
|
2
|
+
const tap = new TapClient({ url: 'http://localhost:2480' });
|
|
3
|
+
const subscription = tap.subscribe({
|
|
4
|
+
onConnectionOpen() {
|
|
5
|
+
console.log(`ws open`);
|
|
6
|
+
},
|
|
7
|
+
onConnectionClose() {
|
|
8
|
+
console.log(`ws close`);
|
|
9
|
+
},
|
|
10
|
+
onConnectionError(ev) {
|
|
11
|
+
console.log(`ws error`, ev);
|
|
12
|
+
},
|
|
13
|
+
onError(err) {
|
|
14
|
+
console.error('tap subscription error', err);
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
for await (const { event, ack } of subscription) {
|
|
18
|
+
console.log(event);
|
|
19
|
+
await ack();
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=dev-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-index.js","sourceRoot":"","sources":["../lib/dev-index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,EAAE,GAAG,EAAE,uBAAuB,EAAE,CAAC,CAAC;AAE5D,MAAM,YAAY,GAAG,GAAG,CAAC,SAAS,CAAC;IAClC,gBAAgB,GAAG;QAClB,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAAA,CACvB;IACD,iBAAiB,GAAG;QACnB,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAAA,CACxB;IACD,iBAAiB,CAAC,EAAE,EAAE;QACrB,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAAA,CAC5B;IACD,OAAO,CAAC,GAAG,EAAE;QACZ,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;IAAA,CAC7C;CACD,CAAC,CAAC;AAEH,IAAI,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,YAAY,EAAE,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAEnB,MAAM,GAAG,EAAE,CAAC;AACb,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,IAAI,MAAM,eAAe,CAAC;AACtC,mBAAmB,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,IAAI,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type DidDocument } from '@atcute/identity';
|
|
2
|
+
import type { Did } from '@atcute/lexicons';
|
|
3
|
+
import { TapSubscription } from './tap-subscription.js';
|
|
4
|
+
import type { RepoInfo, TapClientOptions, TapSubscribeOptions } from './types.js';
|
|
5
|
+
export declare class TapClient {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(options: TapClientOptions);
|
|
8
|
+
subscribe(options?: TapSubscribeOptions): TapSubscription;
|
|
9
|
+
addRepos(dids: Did[]): Promise<void>;
|
|
10
|
+
removeRepos(dids: Did[]): Promise<void>;
|
|
11
|
+
resolveDid(did: Did): Promise<DidDocument | null>;
|
|
12
|
+
getRepoInfo(did: Did): Promise<RepoInfo>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=tap-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tap-client.d.ts","sourceRoot":"","sources":["../lib/tap-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE1E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGlF,qBAAa,SAAS;;IAMrB,YAAY,OAAO,EAAE,gBAAgB,EAcpC;IAED,SAAS,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,eAAe,CAUxD;IAEK,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAWzC;IAEK,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAW5C;IAEK,UAAU,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAiBtD;IAEK,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAY7C;CAaD"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { defs as identityDefs } from '@atcute/identity';
|
|
2
|
+
import { TapSubscription } from './tap-subscription.js';
|
|
3
|
+
import { repoInfoSchema } from './typedefs.js';
|
|
4
|
+
import { formatAdminAuthHeader } from './utils.js';
|
|
5
|
+
export class TapClient {
|
|
6
|
+
#url;
|
|
7
|
+
#fetch;
|
|
8
|
+
#adminPassword;
|
|
9
|
+
#authHeader;
|
|
10
|
+
constructor(options) {
|
|
11
|
+
const url = typeof options.url === 'string' ? new URL(options.url) : new URL(options.url);
|
|
12
|
+
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
|
|
13
|
+
throw new Error(`invalid url protocol, expected http: or https:, got ${url.protocol}`);
|
|
14
|
+
}
|
|
15
|
+
this.#url = url;
|
|
16
|
+
this.#fetch = options.fetch ?? fetch;
|
|
17
|
+
if (options.adminPassword) {
|
|
18
|
+
this.#adminPassword = options.adminPassword;
|
|
19
|
+
this.#authHeader = formatAdminAuthHeader(options.adminPassword);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
subscribe(options) {
|
|
23
|
+
const wsUrl = new URL(this.#url);
|
|
24
|
+
wsUrl.protocol = wsUrl.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
25
|
+
wsUrl.pathname = '/channel';
|
|
26
|
+
return new TapSubscription({
|
|
27
|
+
url: wsUrl.toString(),
|
|
28
|
+
adminPassword: this.#adminPassword,
|
|
29
|
+
...options,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
async addRepos(dids) {
|
|
33
|
+
const response = await this.#fetch(new URL('/repos/add', this.#url), {
|
|
34
|
+
method: 'POST',
|
|
35
|
+
headers: this.#getHeaders(),
|
|
36
|
+
body: JSON.stringify({ dids }),
|
|
37
|
+
});
|
|
38
|
+
await response.body?.cancel();
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
throw new Error(`failed to add repos: ${response.status} ${response.statusText}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async removeRepos(dids) {
|
|
44
|
+
const response = await this.#fetch(new URL('/repos/remove', this.#url), {
|
|
45
|
+
method: 'POST',
|
|
46
|
+
headers: this.#getHeaders(),
|
|
47
|
+
body: JSON.stringify({ dids }),
|
|
48
|
+
});
|
|
49
|
+
await response.body?.cancel();
|
|
50
|
+
if (!response.ok) {
|
|
51
|
+
throw new Error(`failed to remove repos: ${response.status} ${response.statusText}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async resolveDid(did) {
|
|
55
|
+
const response = await this.#fetch(new URL(`/resolve/${did}`, this.#url), {
|
|
56
|
+
method: 'GET',
|
|
57
|
+
headers: this.#getHeaders(),
|
|
58
|
+
});
|
|
59
|
+
if (response.status === 404) {
|
|
60
|
+
await response.body?.cancel();
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
if (!response.ok) {
|
|
64
|
+
await response.body?.cancel();
|
|
65
|
+
throw new Error(`failed to resolve did: ${response.status} ${response.statusText}`);
|
|
66
|
+
}
|
|
67
|
+
return identityDefs.didDocument.parse(await response.json());
|
|
68
|
+
}
|
|
69
|
+
async getRepoInfo(did) {
|
|
70
|
+
const response = await this.#fetch(new URL(`/info/${did}`, this.#url), {
|
|
71
|
+
method: 'GET',
|
|
72
|
+
headers: this.#getHeaders(),
|
|
73
|
+
});
|
|
74
|
+
if (!response.ok) {
|
|
75
|
+
await response.body?.cancel();
|
|
76
|
+
throw new Error(`failed to get repo info: ${response.status} ${response.statusText}`);
|
|
77
|
+
}
|
|
78
|
+
return repoInfoSchema.parse(await response.json());
|
|
79
|
+
}
|
|
80
|
+
#getHeaders() {
|
|
81
|
+
const headers = {
|
|
82
|
+
'Content-Type': 'application/json',
|
|
83
|
+
};
|
|
84
|
+
if (this.#authHeader) {
|
|
85
|
+
headers['Authorization'] = this.#authHeader;
|
|
86
|
+
}
|
|
87
|
+
return headers;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=tap-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tap-client.js","sourceRoot":"","sources":["../lib/tap-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { EventIterator } from '@mary-ext/event-iterator';
|
|
2
|
+
import type { ReadonlyDeep } from 'type-fest';
|
|
3
|
+
import type { TapSubscribeOptions, TapSubscriptionMessage } from './types.js';
|
|
4
|
+
export interface TapSubscriptionOptions extends TapSubscribeOptions {
|
|
5
|
+
url: string;
|
|
6
|
+
adminPassword?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class TapSubscription {
|
|
9
|
+
#private;
|
|
10
|
+
constructor(options: TapSubscriptionOptions);
|
|
11
|
+
[Symbol.asyncIterator](): EventIterator<TapSubscriptionMessage>;
|
|
12
|
+
getOptions(): ReadonlyDeep<TapSubscriptionOptions>;
|
|
13
|
+
updateOptions(options: Partial<TapSubscriptionOptions>): void;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=tap-subscription.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tap-subscription.d.ts","sourceRoot":"","sources":["../lib/tap-subscription.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAIzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAK9C,OAAO,KAAK,EAAY,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAGxF,MAAM,WAAW,sBAAuB,SAAQ,mBAAmB;IAClE,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAWD,qBAAa,eAAe;;IAU3B,YAAY,OAAO,EAAE,sBAAsB,EAE1C;IA8JD,CAAC,MAAM,CAAC,aAAa,CAAC,0CAmBrB;IAED,UAAU,IAAI,YAAY,CAAC,sBAAsB,CAAC,CAEjD;IAED,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,sBAAsB,CAAC,GAAG,IAAI,CAQ5D;CACD"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { EventIterator } from '@mary-ext/event-iterator';
|
|
2
|
+
import { SimpleEventEmitter } from '@mary-ext/simple-event-emitter';
|
|
3
|
+
import { WebSocket as ReconnectingWebSocket } from 'partysocket';
|
|
4
|
+
import { decodeUtf8From } from '@atcute/uint8array';
|
|
5
|
+
import { flattenTapEvent, tapEventWireSchema } from './typedefs.js';
|
|
6
|
+
import { formatAdminAuthHeader } from './utils.js';
|
|
7
|
+
const PARSE_OPTIONS = { mode: 'passthrough' };
|
|
8
|
+
export class TapSubscription {
|
|
9
|
+
#listening = 0;
|
|
10
|
+
#ws;
|
|
11
|
+
#emitter = new SimpleEventEmitter();
|
|
12
|
+
#bufferedAcks = [];
|
|
13
|
+
#options;
|
|
14
|
+
#closed = false;
|
|
15
|
+
constructor(options) {
|
|
16
|
+
this.#options = options;
|
|
17
|
+
}
|
|
18
|
+
#sendAck(id) {
|
|
19
|
+
const ws = this.#ws;
|
|
20
|
+
if (ws === undefined) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
if (ws.readyState !== 1) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
ws.send(JSON.stringify({ type: 'ack', id }));
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
async #ackEvent(id) {
|
|
30
|
+
if (this.#closed) {
|
|
31
|
+
throw new Error(`tap subscription is closed`);
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
if (this.#sendAck(id)) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// fall through to buffering
|
|
40
|
+
}
|
|
41
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
42
|
+
this.#bufferedAcks.push({ id, promise, resolve, reject });
|
|
43
|
+
return await promise;
|
|
44
|
+
}
|
|
45
|
+
#flushBufferedAcks() {
|
|
46
|
+
while (this.#bufferedAcks.length > 0) {
|
|
47
|
+
const ack = this.#bufferedAcks[0];
|
|
48
|
+
if (ack === undefined) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
if (!this.#sendAck(ack.id)) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
ack.resolve(undefined);
|
|
56
|
+
this.#bufferedAcks = this.#bufferedAcks.slice(1);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
this.#options.onError?.(err);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
#create() {
|
|
65
|
+
if (this.#ws !== undefined) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const { url, adminPassword, ws: wsOptions, validateEvents = true, onConnectionClose, onConnectionError, onConnectionOpen, onError, } = this.#options;
|
|
69
|
+
const emitter = this.#emitter;
|
|
70
|
+
const authHeader = adminPassword ? formatAdminAuthHeader(adminPassword) : undefined;
|
|
71
|
+
const mergedWsOptions = authHeader !== undefined && wsOptions?.WebSocket === undefined
|
|
72
|
+
? {
|
|
73
|
+
...wsOptions,
|
|
74
|
+
WebSocket: createAuthedWebSocket(authHeader),
|
|
75
|
+
}
|
|
76
|
+
: wsOptions;
|
|
77
|
+
const ws = new ReconnectingWebSocket(() => url, null, mergedWsOptions);
|
|
78
|
+
this.#ws = ws;
|
|
79
|
+
ws.binaryType = 'arraybuffer';
|
|
80
|
+
ws.onclose = onConnectionClose ?? null;
|
|
81
|
+
ws.onerror = onConnectionError ?? null;
|
|
82
|
+
ws.onopen = (ev) => {
|
|
83
|
+
this.#flushBufferedAcks();
|
|
84
|
+
onConnectionOpen?.(ev);
|
|
85
|
+
};
|
|
86
|
+
ws.onmessage = (ev) => {
|
|
87
|
+
let raw;
|
|
88
|
+
try {
|
|
89
|
+
const data = toMessageText(ev.data);
|
|
90
|
+
raw = JSON.parse(data);
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
onError?.(new Error(`failed to parse tap message`, { cause: err }));
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
let evt;
|
|
97
|
+
if (validateEvents) {
|
|
98
|
+
const result = tapEventWireSchema.try(raw, PARSE_OPTIONS);
|
|
99
|
+
if (!result.ok) {
|
|
100
|
+
onError?.(result);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
evt = flattenTapEvent(result.value);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
try {
|
|
107
|
+
evt = flattenTapEvent(raw);
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
onError?.(err);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
let acked = false;
|
|
115
|
+
let ackPromise;
|
|
116
|
+
emitter.emit({
|
|
117
|
+
event: evt,
|
|
118
|
+
ack: () => {
|
|
119
|
+
if (!acked) {
|
|
120
|
+
acked = true;
|
|
121
|
+
ackPromise = this.#ackEvent(evt.id);
|
|
122
|
+
}
|
|
123
|
+
return ackPromise;
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
#destroy() {
|
|
129
|
+
const ws = this.#ws;
|
|
130
|
+
if (ws) {
|
|
131
|
+
ws.close();
|
|
132
|
+
this.#ws = undefined;
|
|
133
|
+
}
|
|
134
|
+
this.#closed = true;
|
|
135
|
+
if (this.#bufferedAcks.length > 0) {
|
|
136
|
+
const err = new Error(`tap subscription closed before ack was sent`);
|
|
137
|
+
for (const ack of this.#bufferedAcks) {
|
|
138
|
+
ack.reject(err);
|
|
139
|
+
}
|
|
140
|
+
this.#bufferedAcks = [];
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
[Symbol.asyncIterator]() {
|
|
144
|
+
return new EventIterator((emit) => {
|
|
145
|
+
if (this.#listening === 0) {
|
|
146
|
+
this.#closed = false;
|
|
147
|
+
this.#create();
|
|
148
|
+
}
|
|
149
|
+
this.#listening++;
|
|
150
|
+
this.#emitter.subscribe(emit);
|
|
151
|
+
return () => {
|
|
152
|
+
if (this.#listening === 1) {
|
|
153
|
+
this.#destroy();
|
|
154
|
+
}
|
|
155
|
+
this.#listening--;
|
|
156
|
+
this.#emitter.unsubscribe(emit);
|
|
157
|
+
};
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
getOptions() {
|
|
161
|
+
return this.#options;
|
|
162
|
+
}
|
|
163
|
+
updateOptions(options) {
|
|
164
|
+
this.#options = { ...this.#options, ...options };
|
|
165
|
+
if (this.#ws !== undefined) {
|
|
166
|
+
this.#destroy();
|
|
167
|
+
this.#closed = false;
|
|
168
|
+
this.#create();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const toMessageText = (data) => {
|
|
173
|
+
if (typeof data === 'string') {
|
|
174
|
+
return data;
|
|
175
|
+
}
|
|
176
|
+
if (data instanceof ArrayBuffer) {
|
|
177
|
+
return decodeUtf8From(new Uint8Array(data));
|
|
178
|
+
}
|
|
179
|
+
if (ArrayBuffer.isView(data)) {
|
|
180
|
+
return decodeUtf8From(new Uint8Array(data.buffer, data.byteOffset, data.byteLength));
|
|
181
|
+
}
|
|
182
|
+
return String(data);
|
|
183
|
+
};
|
|
184
|
+
const createAuthedWebSocket = (authorization) => {
|
|
185
|
+
const WebSocketCtor = WebSocket;
|
|
186
|
+
return class AuthedWebSocket extends WebSocketCtor {
|
|
187
|
+
constructor(url, protocols) {
|
|
188
|
+
super(url, protocols, {
|
|
189
|
+
headers: {
|
|
190
|
+
Authorization: authorization,
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
};
|
|
196
|
+
//# sourceMappingURL=tap-subscription.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tap-subscription.js","sourceRoot":"","sources":["../lib/tap-subscription.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as v from '@badrap/valita';
|
|
2
|
+
import type * as t from './types.js';
|
|
3
|
+
export declare const tapRecordEventWireSchema: v.ObjectType<{
|
|
4
|
+
id: v.Type<number>;
|
|
5
|
+
type: v.Type<"record">;
|
|
6
|
+
record: v.ObjectType<{
|
|
7
|
+
did: v.Type<`did:${string}:${string}`>;
|
|
8
|
+
rev: v.Type<string>;
|
|
9
|
+
collection: v.Type<`${string}.${string}.${string}`>;
|
|
10
|
+
rkey: v.Type<string>;
|
|
11
|
+
action: v.UnionType<[v.Type<"create">, v.Type<"update">, v.Type<"delete">]>;
|
|
12
|
+
record: v.Optional<Record<string, unknown>>;
|
|
13
|
+
cid: v.Optional<string>;
|
|
14
|
+
live: v.Type<boolean>;
|
|
15
|
+
}, undefined>;
|
|
16
|
+
}, undefined>;
|
|
17
|
+
export declare const tapIdentityEventWireSchema: v.ObjectType<{
|
|
18
|
+
id: v.Type<number>;
|
|
19
|
+
type: v.Type<"identity">;
|
|
20
|
+
identity: v.ObjectType<{
|
|
21
|
+
did: v.Type<`did:${string}:${string}`>;
|
|
22
|
+
handle: v.Type<`${string}.${string}`>;
|
|
23
|
+
is_active: v.Type<boolean>;
|
|
24
|
+
status: v.UnionType<[v.Type<"active">, v.Type<"takendown">, v.Type<"suspended">, v.Type<"deactivated">, v.Type<"deleted">]>;
|
|
25
|
+
}, undefined>;
|
|
26
|
+
}, undefined>;
|
|
27
|
+
export declare const tapEventWireSchema: v.UnionType<[v.ObjectType<{
|
|
28
|
+
id: v.Type<number>;
|
|
29
|
+
type: v.Type<"record">;
|
|
30
|
+
record: v.ObjectType<{
|
|
31
|
+
did: v.Type<`did:${string}:${string}`>;
|
|
32
|
+
rev: v.Type<string>;
|
|
33
|
+
collection: v.Type<`${string}.${string}.${string}`>;
|
|
34
|
+
rkey: v.Type<string>;
|
|
35
|
+
action: v.UnionType<[v.Type<"create">, v.Type<"update">, v.Type<"delete">]>;
|
|
36
|
+
record: v.Optional<Record<string, unknown>>;
|
|
37
|
+
cid: v.Optional<string>;
|
|
38
|
+
live: v.Type<boolean>;
|
|
39
|
+
}, undefined>;
|
|
40
|
+
}, undefined>, v.ObjectType<{
|
|
41
|
+
id: v.Type<number>;
|
|
42
|
+
type: v.Type<"identity">;
|
|
43
|
+
identity: v.ObjectType<{
|
|
44
|
+
did: v.Type<`did:${string}:${string}`>;
|
|
45
|
+
handle: v.Type<`${string}.${string}`>;
|
|
46
|
+
is_active: v.Type<boolean>;
|
|
47
|
+
status: v.UnionType<[v.Type<"active">, v.Type<"takendown">, v.Type<"suspended">, v.Type<"deactivated">, v.Type<"deleted">]>;
|
|
48
|
+
}, undefined>;
|
|
49
|
+
}, undefined>]>;
|
|
50
|
+
export declare const repoInfoSchema: v.Type<t.RepoInfo>;
|
|
51
|
+
export declare const flattenTapEvent: (wire: {
|
|
52
|
+
id: number;
|
|
53
|
+
type: "record";
|
|
54
|
+
record: {
|
|
55
|
+
did: `did:${string}:${string}`;
|
|
56
|
+
rev: string;
|
|
57
|
+
collection: `${string}.${string}.${string}`;
|
|
58
|
+
rkey: string;
|
|
59
|
+
action: "create" | "delete" | "update";
|
|
60
|
+
record?: Record<string, unknown> | undefined;
|
|
61
|
+
cid?: string | undefined;
|
|
62
|
+
live: boolean;
|
|
63
|
+
};
|
|
64
|
+
} | {
|
|
65
|
+
id: number;
|
|
66
|
+
type: "identity";
|
|
67
|
+
identity: {
|
|
68
|
+
did: `did:${string}:${string}`;
|
|
69
|
+
handle: `${string}.${string}`;
|
|
70
|
+
is_active: boolean;
|
|
71
|
+
status: "active" | "deactivated" | "deleted" | "suspended" | "takendown";
|
|
72
|
+
};
|
|
73
|
+
}) => t.TapEvent;
|
|
74
|
+
//# sourceMappingURL=typedefs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typedefs.d.ts","sourceRoot":"","sources":["../lib/typedefs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAIpC,OAAO,KAAK,KAAK,CAAC,MAAM,YAAY,CAAC;AAoCrC,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;aAInC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;aAIrC,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;eAAgE,CAAC;AAEhG,eAAO,MAAM,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAQ5C,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;gBAqC3B,CAAC"}
|
package/dist/typedefs.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import * as v from '@badrap/valita';
|
|
2
|
+
import { isDid, isHandle, isNsid, isRecordKey, isTid } from '@atcute/lexicons/syntax';
|
|
3
|
+
const didString = v.string().assert(isDid, `must be a did`);
|
|
4
|
+
const handleString = v.string().assert(isHandle, `must be a handle`);
|
|
5
|
+
const nsidString = v.string().assert(isNsid, `must be an nsid`);
|
|
6
|
+
const rkeyString = v.string().assert(isRecordKey, `must be a record key`);
|
|
7
|
+
const tidString = v.string().assert(isTid, `must be a tid`);
|
|
8
|
+
const integer = v
|
|
9
|
+
.number()
|
|
10
|
+
.assert((input) => input >= 0 && Number.isSafeInteger(input), `must be a nonnegative integer`);
|
|
11
|
+
const recordEventDataSchema = v.object({
|
|
12
|
+
did: didString,
|
|
13
|
+
rev: tidString,
|
|
14
|
+
collection: nsidString,
|
|
15
|
+
rkey: rkeyString,
|
|
16
|
+
action: v.union(v.literal('create'), v.literal('update'), v.literal('delete')),
|
|
17
|
+
record: v.record(v.unknown()).optional(),
|
|
18
|
+
cid: v.string().optional(),
|
|
19
|
+
live: v.boolean(),
|
|
20
|
+
});
|
|
21
|
+
const identityEventDataSchema = v.object({
|
|
22
|
+
did: didString,
|
|
23
|
+
handle: handleString,
|
|
24
|
+
is_active: v.boolean(),
|
|
25
|
+
status: v.union(v.literal('active'), v.literal('takendown'), v.literal('suspended'), v.literal('deactivated'), v.literal('deleted')),
|
|
26
|
+
});
|
|
27
|
+
export const tapRecordEventWireSchema = v.object({
|
|
28
|
+
id: integer,
|
|
29
|
+
type: v.literal('record'),
|
|
30
|
+
record: recordEventDataSchema,
|
|
31
|
+
});
|
|
32
|
+
export const tapIdentityEventWireSchema = v.object({
|
|
33
|
+
id: integer,
|
|
34
|
+
type: v.literal('identity'),
|
|
35
|
+
identity: identityEventDataSchema,
|
|
36
|
+
});
|
|
37
|
+
export const tapEventWireSchema = v.union(tapRecordEventWireSchema, tapIdentityEventWireSchema);
|
|
38
|
+
export const repoInfoSchema = v.object({
|
|
39
|
+
did: didString,
|
|
40
|
+
handle: handleString,
|
|
41
|
+
state: v.string(),
|
|
42
|
+
rev: tidString,
|
|
43
|
+
records: integer,
|
|
44
|
+
error: v.string().optional(),
|
|
45
|
+
retries: integer.optional(),
|
|
46
|
+
});
|
|
47
|
+
export const flattenTapEvent = (wire) => {
|
|
48
|
+
switch (wire.type) {
|
|
49
|
+
case 'identity': {
|
|
50
|
+
return {
|
|
51
|
+
id: wire.id,
|
|
52
|
+
type: 'identity',
|
|
53
|
+
did: wire.identity.did,
|
|
54
|
+
handle: wire.identity.handle,
|
|
55
|
+
isActive: wire.identity.is_active,
|
|
56
|
+
status: wire.identity.status,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
case 'record': {
|
|
60
|
+
return {
|
|
61
|
+
id: wire.id,
|
|
62
|
+
type: 'record',
|
|
63
|
+
live: wire.record.live,
|
|
64
|
+
rev: wire.record.rev,
|
|
65
|
+
did: wire.record.did,
|
|
66
|
+
collection: wire.record.collection,
|
|
67
|
+
rkey: wire.record.rkey,
|
|
68
|
+
cid: wire.record.cid,
|
|
69
|
+
action: wire.record.action,
|
|
70
|
+
record: wire.record.record,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
default: {
|
|
74
|
+
wire;
|
|
75
|
+
const obj = wire;
|
|
76
|
+
throw new Error(`unknown "${obj.type}" type`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=typedefs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typedefs.js","sourceRoot":"","sources":["../lib/typedefs.ts"],"names":[],"mappings":"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"}
|