@atproto/bsky 0.0.248 → 0.0.250
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 +38 -0
- package/dist/api/age-assurance/const.d.ts.map +1 -1
- package/dist/api/age-assurance/const.js +19 -0
- package/dist/api/age-assurance/const.js.map +1 -1
- package/dist/api/age-assurance/kws/age-verified.d.ts +20 -0
- package/dist/api/age-assurance/kws/age-verified.d.ts.map +1 -1
- package/dist/api/age-assurance/kws/age-verified.js +6 -0
- package/dist/api/age-assurance/kws/age-verified.js.map +1 -1
- package/dist/api/app/bsky/graph/muteActor.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/muteActor.js +3 -0
- package/dist/api/app/bsky/graph/muteActor.js.map +1 -1
- package/dist/api/kws/types.d.ts +33 -0
- package/dist/api/kws/types.d.ts.map +1 -1
- package/dist/api/kws/types.js +3 -0
- package/dist/api/kws/types.js.map +1 -1
- package/dist/data-plane/index.d.ts +0 -1
- package/dist/data-plane/index.d.ts.map +1 -1
- package/dist/data-plane/index.js +0 -1
- package/dist/data-plane/index.js.map +1 -1
- package/dist/data-plane/server/bsync-subscription.d.ts +47 -0
- package/dist/data-plane/server/bsync-subscription.d.ts.map +1 -0
- package/dist/data-plane/server/bsync-subscription.js +461 -0
- package/dist/data-plane/server/bsync-subscription.js.map +1 -0
- package/dist/data-plane/server/index.d.ts +1 -0
- package/dist/data-plane/server/index.d.ts.map +1 -1
- package/dist/data-plane/server/index.js +1 -0
- package/dist/data-plane/server/index.js.map +1 -1
- package/dist/lexicons/app/bsky/ageassurance/defs.defs.d.ts +4 -0
- package/dist/lexicons/app/bsky/ageassurance/defs.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/ageassurance/defs.defs.js +3 -0
- package/dist/lexicons/app/bsky/ageassurance/defs.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/defs.defs.js +1 -1
- package/dist/lexicons/chat/bsky/convo/defs.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/group/editGroup.defs.d.ts +4 -4
- package/dist/lexicons/chat/bsky/group/editGroup.defs.js +2 -2
- package/dist/lexicons/chat/bsky/group/editGroup.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/moderation/defs.defs.js +1 -1
- package/dist/lexicons/chat/bsky/moderation/defs.defs.js.map +1 -1
- package/package.json +16 -16
- package/src/api/age-assurance/const.ts +19 -0
- package/src/api/age-assurance/kws/age-verified.test.ts +98 -0
- package/src/api/age-assurance/kws/age-verified.ts +6 -0
- package/src/api/app/bsky/graph/muteActor.ts +3 -0
- package/src/api/kws/types.ts +11 -0
- package/src/api/kws/util.test.ts +50 -0
- package/src/data-plane/index.ts +0 -1
- package/src/data-plane/{bsync/index.ts → server/bsync-subscription.ts} +245 -121
- package/src/data-plane/server/index.ts +1 -0
- package/tests/data-plane/thread-mutes.test.ts +2 -0
- package/tests/stash.test.ts +6 -1
- package/tests/views/age-assurance-v2.test.ts +3 -0
- package/tests/views/age-assurance.test.ts +8 -0
- package/tests/views/bookmarks.test.ts +19 -0
- package/tests/views/drafts.test.ts +25 -2
- package/tests/views/mute-lists.test.ts +2 -0
- package/tests/views/mutes.test.ts +1 -0
- package/tests/views/notifications.test.ts +16 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/dist/data-plane/bsync/index.d.ts +0 -11
- package/dist/data-plane/bsync/index.d.ts.map +0 -1
- package/dist/data-plane/bsync/index.js +0 -376
- package/dist/data-plane/bsync/index.js.map +0 -1
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import { lexParse } from '@atproto/lex';
|
|
3
|
+
import { AtUri } from '@atproto/syntax';
|
|
4
|
+
import { authWithApiKey, createBsyncClient } from '../../bsync.js';
|
|
5
|
+
import { app } from '../../lexicons/index.js';
|
|
6
|
+
import { subLogger as log } from '../../logger.js';
|
|
7
|
+
import { Method, MuteOperation_Type, } from '../../proto/bsync_pb.js';
|
|
8
|
+
import { Namespaces } from '../../stash.js';
|
|
9
|
+
import { countAll, excluded } from './db/util.js';
|
|
10
|
+
export class BsyncSubscription {
|
|
11
|
+
constructor(opts) {
|
|
12
|
+
this.opts = opts;
|
|
13
|
+
this.pendingScans = new Set();
|
|
14
|
+
// Latest cursor processed for each stream, used to wait until caught up.
|
|
15
|
+
this.cursors = {};
|
|
16
|
+
const { config, db } = opts;
|
|
17
|
+
this.db = db;
|
|
18
|
+
this.bsyncClient = createBsyncClient({
|
|
19
|
+
baseUrl: config.bsyncUrl,
|
|
20
|
+
httpVersion: config.bsyncHttpVersion ?? '2',
|
|
21
|
+
nodeOptions: { rejectUnauthorized: !config.bsyncIgnoreBadTls },
|
|
22
|
+
interceptors: config.bsyncApiKey
|
|
23
|
+
? [authWithApiKey(config.bsyncApiKey)]
|
|
24
|
+
: [],
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
get running() {
|
|
28
|
+
return !!this.ac;
|
|
29
|
+
}
|
|
30
|
+
start() {
|
|
31
|
+
if (this.ac)
|
|
32
|
+
return;
|
|
33
|
+
this.ac = new AbortController();
|
|
34
|
+
this.scanMuteOperations();
|
|
35
|
+
this.scanNotifOperations();
|
|
36
|
+
this.scanOperations();
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Waits until the subscription has processed every operation that existed in
|
|
40
|
+
* bsync at the time `targets` was read (one cursor per stream). Returns as
|
|
41
|
+
* soon as the cursors catch up - it does not wait for the bsync long-poll
|
|
42
|
+
* timeout. Intended for tests/dev.
|
|
43
|
+
*/
|
|
44
|
+
async processAll(targets, timeout = 5000) {
|
|
45
|
+
if (!this.ac)
|
|
46
|
+
return;
|
|
47
|
+
const start = Date.now();
|
|
48
|
+
while (!this.isCaughtUp(targets)) {
|
|
49
|
+
if (Date.now() - start > timeout) {
|
|
50
|
+
throw new Error(`bsync subscription was not caught up within ${timeout}ms`);
|
|
51
|
+
}
|
|
52
|
+
await wait(5);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
isCaughtUp(targets) {
|
|
56
|
+
return (gteCursor(this.cursors.op, targets.op) &&
|
|
57
|
+
gteCursor(this.cursors.mute, targets.mute) &&
|
|
58
|
+
gteCursor(this.cursors.notif, targets.notif));
|
|
59
|
+
}
|
|
60
|
+
async destroy() {
|
|
61
|
+
// Aborting cancels any in-flight long-poll scan immediately, so we don't
|
|
62
|
+
// have to wait for the bsync long-poll timeout to elapse.
|
|
63
|
+
this.ac?.abort();
|
|
64
|
+
this.ac = undefined;
|
|
65
|
+
// Wait for the ongoing scans to unwind cleanly.
|
|
66
|
+
await Promise.all(this.pendingScans);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* starts a scanner in the background, killing it when this instance is
|
|
70
|
+
* destroyed, and storing its promise in `this.pendingScans` to allow
|
|
71
|
+
* awaiting.
|
|
72
|
+
*/
|
|
73
|
+
startScanning(scanner) {
|
|
74
|
+
if (!this.ac)
|
|
75
|
+
return;
|
|
76
|
+
const signal = this.ac.signal;
|
|
77
|
+
const scanPromise = this.runScanner(scanner, signal);
|
|
78
|
+
this.pendingScans.add(scanPromise);
|
|
79
|
+
void scanPromise
|
|
80
|
+
.catch(() => { })
|
|
81
|
+
.finally(() => {
|
|
82
|
+
this.pendingScans.delete(scanPromise);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
async runScanner(scanner, signal) {
|
|
86
|
+
let cursor;
|
|
87
|
+
while (!signal.aborted) {
|
|
88
|
+
try {
|
|
89
|
+
cursor = await scanner(cursor, signal);
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
if (signal.aborted)
|
|
93
|
+
break;
|
|
94
|
+
log.error({ err }, 'error in bsync scan');
|
|
95
|
+
// retry in a bit, but bail out early if we're shutting down
|
|
96
|
+
await wait(100, signal);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
scanMuteOperations() {
|
|
101
|
+
this.startScanning(async (cursor, signal) => {
|
|
102
|
+
const res = await this.bsyncClient.scanMuteOperations({ cursor }, { signal });
|
|
103
|
+
await this.processMuteOperations(res.operations);
|
|
104
|
+
this.cursors.mute = res.cursor;
|
|
105
|
+
return res.cursor;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
async processMuteOperations(operations) {
|
|
109
|
+
for (const op of operations) {
|
|
110
|
+
const { type, actorDid, subject } = op;
|
|
111
|
+
if (type === MuteOperation_Type.ADD) {
|
|
112
|
+
if (subject.startsWith('did:')) {
|
|
113
|
+
await this.db.db
|
|
114
|
+
.insertInto('mute')
|
|
115
|
+
.values({
|
|
116
|
+
mutedByDid: actorDid,
|
|
117
|
+
subjectDid: subject,
|
|
118
|
+
createdAt: new Date().toISOString(),
|
|
119
|
+
})
|
|
120
|
+
.onConflict((oc) => oc.doNothing())
|
|
121
|
+
.execute();
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
const uri = new AtUri(subject);
|
|
125
|
+
if (uri.collection === app.bsky.graph.list.$type) {
|
|
126
|
+
await this.db.db
|
|
127
|
+
.insertInto('list_mute')
|
|
128
|
+
.values({
|
|
129
|
+
mutedByDid: actorDid,
|
|
130
|
+
listUri: subject,
|
|
131
|
+
createdAt: new Date().toISOString(),
|
|
132
|
+
})
|
|
133
|
+
.onConflict((oc) => oc.doNothing())
|
|
134
|
+
.execute();
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
await this.db.db
|
|
138
|
+
.insertInto('thread_mute')
|
|
139
|
+
.values({
|
|
140
|
+
mutedByDid: actorDid,
|
|
141
|
+
rootUri: subject,
|
|
142
|
+
createdAt: new Date().toISOString(),
|
|
143
|
+
})
|
|
144
|
+
.onConflict((oc) => oc.doNothing())
|
|
145
|
+
.execute();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
else if (type === MuteOperation_Type.REMOVE) {
|
|
150
|
+
if (subject.startsWith('did:')) {
|
|
151
|
+
await this.db.db
|
|
152
|
+
.deleteFrom('mute')
|
|
153
|
+
.where('mutedByDid', '=', actorDid)
|
|
154
|
+
.where('subjectDid', '=', subject)
|
|
155
|
+
.execute();
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
const uri = new AtUri(subject);
|
|
159
|
+
if (uri.collection === app.bsky.graph.list.$type) {
|
|
160
|
+
await this.db.db
|
|
161
|
+
.deleteFrom('list_mute')
|
|
162
|
+
.where('mutedByDid', '=', actorDid)
|
|
163
|
+
.where('listUri', '=', subject)
|
|
164
|
+
.execute();
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
await this.db.db
|
|
168
|
+
.deleteFrom('thread_mute')
|
|
169
|
+
.where('mutedByDid', '=', actorDid)
|
|
170
|
+
.where('rootUri', '=', subject)
|
|
171
|
+
.execute();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else if (type === MuteOperation_Type.CLEAR) {
|
|
176
|
+
await this.db.db
|
|
177
|
+
.deleteFrom('mute')
|
|
178
|
+
.where('mutedByDid', '=', actorDid)
|
|
179
|
+
.execute();
|
|
180
|
+
await this.db.db
|
|
181
|
+
.deleteFrom('list_mute')
|
|
182
|
+
.where('mutedByDid', '=', actorDid)
|
|
183
|
+
.execute();
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
scanNotifOperations() {
|
|
188
|
+
this.startScanning(async (cursor, signal) => {
|
|
189
|
+
const res = await this.bsyncClient.scanNotifOperations({ cursor }, { signal });
|
|
190
|
+
await this.processNotifOperations(res.operations);
|
|
191
|
+
this.cursors.notif = res.cursor;
|
|
192
|
+
return res.cursor;
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
async processNotifOperations(operations) {
|
|
196
|
+
for (const op of operations) {
|
|
197
|
+
const { actorDid, priority } = op;
|
|
198
|
+
if (priority !== undefined) {
|
|
199
|
+
await this.db.db
|
|
200
|
+
.insertInto('actor_state')
|
|
201
|
+
.values({
|
|
202
|
+
did: actorDid,
|
|
203
|
+
priorityNotifs: priority,
|
|
204
|
+
lastSeenNotifs: new Date().toISOString(),
|
|
205
|
+
})
|
|
206
|
+
.onConflict((oc) => oc.column('did').doUpdateSet({ priorityNotifs: priority }))
|
|
207
|
+
.execute();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
scanOperations() {
|
|
212
|
+
this.startScanning(async (cursor, signal) => {
|
|
213
|
+
const res = await this.bsyncClient.scanOperations({ cursor }, { signal });
|
|
214
|
+
await this.processOperations(res.operations);
|
|
215
|
+
this.cursors.op = res.cursor;
|
|
216
|
+
return res.cursor;
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
async processOperations(operations) {
|
|
220
|
+
for (const op of operations) {
|
|
221
|
+
const { namespace } = op;
|
|
222
|
+
const now = new Date().toISOString();
|
|
223
|
+
// Index all items into private_data.
|
|
224
|
+
await handleGenericOperation(this.db, op, now);
|
|
225
|
+
// Maintain bespoke indexes for certain namespaces. A failure here must
|
|
226
|
+
// not stall the stream, so log and move on (matching bsync behavior).
|
|
227
|
+
try {
|
|
228
|
+
if (namespace ===
|
|
229
|
+
Namespaces.AppBskyNotificationDefsSubjectActivitySubscription.$type) {
|
|
230
|
+
await handleSubjectActivitySubscriptionOperation(this.db, op, now);
|
|
231
|
+
}
|
|
232
|
+
else if (namespace === Namespaces.AppBskyUnspeccedDefsAgeAssuranceEvent.$type) {
|
|
233
|
+
await handleAgeAssuranceEventOperation(this.db, op, now);
|
|
234
|
+
}
|
|
235
|
+
else if (namespace === Namespaces.AppBskyAgeassuranceDefsEvent.$type) {
|
|
236
|
+
await handleAgeAssuranceV2EventOperation(this.db, op, now);
|
|
237
|
+
}
|
|
238
|
+
else if (namespace === Namespaces.AppBskyBookmarkDefsBookmark.$type) {
|
|
239
|
+
await handleBookmarkOperation(this.db, op, now);
|
|
240
|
+
}
|
|
241
|
+
else if (namespace === Namespaces.AppBskyDraftDefsDraftWithId.$type) {
|
|
242
|
+
await handleDraftOperation(this.db, op, now);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
catch (err) {
|
|
246
|
+
log.warn({ err, namespace }, 'bsync put operation indexing failed');
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
// upsert into or remove from private_data
|
|
252
|
+
const handleGenericOperation = async (db, op, now) => {
|
|
253
|
+
const { actorDid, namespace, key, method, payload } = op;
|
|
254
|
+
if (method === Method.CREATE || method === Method.UPDATE) {
|
|
255
|
+
await db.db
|
|
256
|
+
.insertInto('private_data')
|
|
257
|
+
.values({
|
|
258
|
+
actorDid,
|
|
259
|
+
namespace,
|
|
260
|
+
key,
|
|
261
|
+
payload: Buffer.from(payload).toString('utf8'),
|
|
262
|
+
indexedAt: now,
|
|
263
|
+
updatedAt: now,
|
|
264
|
+
})
|
|
265
|
+
.onConflict((oc) => oc.columns(['actorDid', 'namespace', 'key']).doUpdateSet({
|
|
266
|
+
payload: excluded(db.db, 'payload'),
|
|
267
|
+
updatedAt: excluded(db.db, 'updatedAt'),
|
|
268
|
+
}))
|
|
269
|
+
.execute();
|
|
270
|
+
}
|
|
271
|
+
else if (method === Method.DELETE) {
|
|
272
|
+
await db.db
|
|
273
|
+
.deleteFrom('private_data')
|
|
274
|
+
.where('actorDid', '=', actorDid)
|
|
275
|
+
.where('namespace', '=', namespace)
|
|
276
|
+
.where('key', '=', key)
|
|
277
|
+
.execute();
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
assert.fail(`unexpected method ${method}`);
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
const handleSubjectActivitySubscriptionOperation = async (db, op, now) => {
|
|
284
|
+
const { actorDid, key, method, payload } = op;
|
|
285
|
+
if (method === Method.DELETE) {
|
|
286
|
+
await db.db
|
|
287
|
+
.deleteFrom('activity_subscription')
|
|
288
|
+
.where('creator', '=', actorDid)
|
|
289
|
+
.where('key', '=', key)
|
|
290
|
+
.execute();
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
const parsed = lexParse(Buffer.from(payload).toString('utf8'));
|
|
294
|
+
const { subject, activitySubscription: { post, reply }, } = parsed;
|
|
295
|
+
if (method === Method.CREATE) {
|
|
296
|
+
await db.db
|
|
297
|
+
.insertInto('activity_subscription')
|
|
298
|
+
.values({
|
|
299
|
+
creator: actorDid,
|
|
300
|
+
subjectDid: subject,
|
|
301
|
+
key,
|
|
302
|
+
indexedAt: now,
|
|
303
|
+
post,
|
|
304
|
+
reply,
|
|
305
|
+
})
|
|
306
|
+
.execute();
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
await db.db
|
|
310
|
+
.updateTable('activity_subscription')
|
|
311
|
+
.where('creator', '=', actorDid)
|
|
312
|
+
.where('key', '=', key)
|
|
313
|
+
.set({
|
|
314
|
+
indexedAt: now,
|
|
315
|
+
post,
|
|
316
|
+
reply,
|
|
317
|
+
})
|
|
318
|
+
.execute();
|
|
319
|
+
};
|
|
320
|
+
const handleAgeAssuranceEventOperation = async (db, op) => {
|
|
321
|
+
const { actorDid, method, payload } = op;
|
|
322
|
+
if (method !== Method.CREATE)
|
|
323
|
+
return;
|
|
324
|
+
const parsed = lexParse(Buffer.from(payload).toString('utf8'));
|
|
325
|
+
const { status, createdAt } = parsed;
|
|
326
|
+
const update = {
|
|
327
|
+
ageAssuranceStatus: status,
|
|
328
|
+
ageAssuranceLastInitiatedAt: status === 'pending' ? createdAt : undefined,
|
|
329
|
+
};
|
|
330
|
+
await db.db
|
|
331
|
+
.updateTable('actor')
|
|
332
|
+
.set(update)
|
|
333
|
+
.where('did', '=', actorDid)
|
|
334
|
+
.execute();
|
|
335
|
+
};
|
|
336
|
+
const handleAgeAssuranceV2EventOperation = async (db, op) => {
|
|
337
|
+
const { actorDid, method, payload } = op;
|
|
338
|
+
if (method !== Method.CREATE)
|
|
339
|
+
return;
|
|
340
|
+
const parsed = lexParse(Buffer.from(payload).toString('utf8'));
|
|
341
|
+
const { status, createdAt, access, countryCode, regionCode } = parsed;
|
|
342
|
+
const update = {
|
|
343
|
+
ageAssuranceStatus: status,
|
|
344
|
+
ageAssuranceLastInitiatedAt: status === 'pending' ? createdAt : undefined,
|
|
345
|
+
ageAssuranceAccess: access,
|
|
346
|
+
ageAssuranceCountryCode: countryCode,
|
|
347
|
+
ageAssuranceRegionCode: regionCode,
|
|
348
|
+
};
|
|
349
|
+
await db.db
|
|
350
|
+
.updateTable('actor')
|
|
351
|
+
.set(update)
|
|
352
|
+
.where('did', '=', actorDid)
|
|
353
|
+
.execute();
|
|
354
|
+
};
|
|
355
|
+
const handleBookmarkOperation = async (db, op, now) => {
|
|
356
|
+
const { actorDid, key, method, payload } = op;
|
|
357
|
+
const updateAgg = (uri, dbTxn) => {
|
|
358
|
+
return dbTxn.db
|
|
359
|
+
.insertInto('post_agg')
|
|
360
|
+
.values({
|
|
361
|
+
uri,
|
|
362
|
+
bookmarkCount: dbTxn.db
|
|
363
|
+
.selectFrom('bookmark')
|
|
364
|
+
.where('bookmark.subjectUri', '=', uri)
|
|
365
|
+
.select(countAll.as('count')),
|
|
366
|
+
})
|
|
367
|
+
.onConflict((oc) => oc
|
|
368
|
+
.column('uri')
|
|
369
|
+
.doUpdateSet({ bookmarkCount: excluded(dbTxn.db, 'bookmarkCount') }))
|
|
370
|
+
.execute();
|
|
371
|
+
};
|
|
372
|
+
if (method === Method.CREATE) {
|
|
373
|
+
const parsed = lexParse(Buffer.from(payload).toString('utf8'));
|
|
374
|
+
const { subject: { uri, cid }, } = parsed;
|
|
375
|
+
await db.transaction(async (dbTxn) => {
|
|
376
|
+
await dbTxn.db
|
|
377
|
+
.insertInto('bookmark')
|
|
378
|
+
.values({
|
|
379
|
+
creator: actorDid,
|
|
380
|
+
key,
|
|
381
|
+
indexedAt: now,
|
|
382
|
+
subjectUri: uri,
|
|
383
|
+
subjectCid: cid,
|
|
384
|
+
})
|
|
385
|
+
.execute();
|
|
386
|
+
await updateAgg(uri, dbTxn);
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
if (method === Method.DELETE) {
|
|
390
|
+
await db.transaction(async (dbTxn) => {
|
|
391
|
+
const bookmark = await dbTxn.db
|
|
392
|
+
.selectFrom('bookmark')
|
|
393
|
+
.selectAll()
|
|
394
|
+
.where('creator', '=', actorDid)
|
|
395
|
+
.where('key', '=', key)
|
|
396
|
+
.executeTakeFirst();
|
|
397
|
+
if (bookmark) {
|
|
398
|
+
await dbTxn.db
|
|
399
|
+
.deleteFrom('bookmark')
|
|
400
|
+
.where('creator', '=', actorDid)
|
|
401
|
+
.where('key', '=', key)
|
|
402
|
+
.execute();
|
|
403
|
+
await updateAgg(bookmark.subjectUri, dbTxn);
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
const handleDraftOperation = async (db, op, now) => {
|
|
409
|
+
const { actorDid, key, method, payload } = op;
|
|
410
|
+
if (method === Method.CREATE) {
|
|
411
|
+
const payloadString = Buffer.from(payload).toString('utf8');
|
|
412
|
+
await db.db
|
|
413
|
+
.insertInto('draft')
|
|
414
|
+
.values({
|
|
415
|
+
creator: actorDid,
|
|
416
|
+
key,
|
|
417
|
+
createdAt: now,
|
|
418
|
+
updatedAt: now,
|
|
419
|
+
payload: payloadString,
|
|
420
|
+
})
|
|
421
|
+
.execute();
|
|
422
|
+
}
|
|
423
|
+
if (method === Method.UPDATE) {
|
|
424
|
+
const payloadString = Buffer.from(payload).toString('utf8');
|
|
425
|
+
await db.db
|
|
426
|
+
.updateTable('draft')
|
|
427
|
+
.where('creator', '=', actorDid)
|
|
428
|
+
.where('key', '=', key)
|
|
429
|
+
.set({
|
|
430
|
+
updatedAt: now,
|
|
431
|
+
payload: payloadString,
|
|
432
|
+
})
|
|
433
|
+
.execute();
|
|
434
|
+
}
|
|
435
|
+
if (method === Method.DELETE) {
|
|
436
|
+
await db.db
|
|
437
|
+
.deleteFrom('draft')
|
|
438
|
+
.where('creator', '=', actorDid)
|
|
439
|
+
.where('key', '=', key)
|
|
440
|
+
.execute();
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
// compares numeric (bigint) cursor ids; an undefined target is always satisfied
|
|
444
|
+
const gteCursor = (current, target) => {
|
|
445
|
+
if (!target)
|
|
446
|
+
return true;
|
|
447
|
+
return BigInt(current || '0') >= BigInt(target);
|
|
448
|
+
};
|
|
449
|
+
// resolves after `ms`, or early if `signal` aborts
|
|
450
|
+
const wait = (ms, signal) => new Promise((resolve) => {
|
|
451
|
+
if (signal?.aborted)
|
|
452
|
+
return resolve();
|
|
453
|
+
const done = () => {
|
|
454
|
+
clearTimeout(timer);
|
|
455
|
+
signal?.removeEventListener('abort', done);
|
|
456
|
+
resolve();
|
|
457
|
+
};
|
|
458
|
+
const timer = setTimeout(done, ms);
|
|
459
|
+
signal?.addEventListener('abort', done, { once: true });
|
|
460
|
+
});
|
|
461
|
+
//# sourceMappingURL=bsync-subscription.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bsync-subscription.js","sourceRoot":"","sources":["../../../src/data-plane/server/bsync-subscription.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { lexParse } from '@atproto/lex'\nimport { AtUri } from '@atproto/syntax'\nimport { BsyncClient, authWithApiKey, createBsyncClient } from '../../bsync.js'\nimport { ServerConfig } from '../../config.js'\nimport { app } from '../../lexicons/index.js'\nimport { subLogger as log } from '../../logger.js'\nimport {\n Method,\n MuteOperation,\n MuteOperation_Type,\n NotifOperation,\n Operation,\n} from '../../proto/bsync_pb.js'\nimport { Namespaces } from '../../stash.js'\nimport { Database } from './db/index.js'\nimport { countAll, excluded } from './db/util.js'\n\nexport type BsyncCursors = {\n op?: string\n mute?: string\n notif?: string\n}\n\nexport class BsyncSubscription {\n private ac: AbortController | undefined\n private pendingScans = new Set<Promise<void>>()\n private bsyncClient: BsyncClient\n private db: Database\n // Latest cursor processed for each stream, used to wait until caught up.\n private cursors: BsyncCursors = {}\n\n constructor(public opts: { db: Database; config: ServerConfig }) {\n const { config, db } = opts\n\n this.db = db\n this.bsyncClient = createBsyncClient({\n baseUrl: config.bsyncUrl,\n httpVersion: config.bsyncHttpVersion ?? '2',\n nodeOptions: { rejectUnauthorized: !config.bsyncIgnoreBadTls },\n interceptors: config.bsyncApiKey\n ? [authWithApiKey(config.bsyncApiKey)]\n : [],\n })\n }\n\n get running() {\n return !!this.ac\n }\n\n start() {\n if (this.ac) return\n this.ac = new AbortController()\n this.scanMuteOperations()\n this.scanNotifOperations()\n this.scanOperations()\n }\n\n /**\n * Waits until the subscription has processed every operation that existed in\n * bsync at the time `targets` was read (one cursor per stream). Returns as\n * soon as the cursors catch up - it does not wait for the bsync long-poll\n * timeout. Intended for tests/dev.\n */\n async processAll(targets: BsyncCursors, timeout = 5000) {\n if (!this.ac) return\n const start = Date.now()\n while (!this.isCaughtUp(targets)) {\n if (Date.now() - start > timeout) {\n throw new Error(\n `bsync subscription was not caught up within ${timeout}ms`,\n )\n }\n await wait(5)\n }\n }\n\n private isCaughtUp(targets: BsyncCursors) {\n return (\n gteCursor(this.cursors.op, targets.op) &&\n gteCursor(this.cursors.mute, targets.mute) &&\n gteCursor(this.cursors.notif, targets.notif)\n )\n }\n\n async destroy() {\n // Aborting cancels any in-flight long-poll scan immediately, so we don't\n // have to wait for the bsync long-poll timeout to elapse.\n this.ac?.abort()\n this.ac = undefined\n // Wait for the ongoing scans to unwind cleanly.\n await Promise.all(this.pendingScans)\n }\n\n /**\n * starts a scanner in the background, killing it when this instance is\n * destroyed, and storing its promise in `this.pendingScans` to allow\n * awaiting.\n */\n private startScanning(\n scanner: (\n cursor: undefined | string,\n signal: AbortSignal,\n ) => Promise<string | undefined>,\n ) {\n if (!this.ac) return\n const signal = this.ac.signal\n\n const scanPromise = this.runScanner(scanner, signal)\n\n this.pendingScans.add(scanPromise)\n void scanPromise\n .catch(() => {})\n .finally(() => {\n this.pendingScans.delete(scanPromise)\n })\n }\n\n private async runScanner(\n scanner: (\n cursor: undefined | string,\n signal: AbortSignal,\n ) => Promise<string | undefined>,\n signal: AbortSignal,\n ) {\n let cursor: undefined | string\n\n while (!signal.aborted) {\n try {\n cursor = await scanner(cursor, signal)\n } catch (err) {\n if (signal.aborted) break\n\n log.error({ err }, 'error in bsync scan')\n\n // retry in a bit, but bail out early if we're shutting down\n await wait(100, signal)\n }\n }\n }\n\n private scanMuteOperations() {\n this.startScanning(async (cursor, signal) => {\n const res = await this.bsyncClient.scanMuteOperations(\n { cursor },\n { signal },\n )\n\n await this.processMuteOperations(res.operations)\n this.cursors.mute = res.cursor\n\n return res.cursor\n })\n }\n\n private async processMuteOperations(operations: MuteOperation[]) {\n for (const op of operations) {\n const { type, actorDid, subject } = op\n if (type === MuteOperation_Type.ADD) {\n if (subject.startsWith('did:')) {\n await this.db.db\n .insertInto('mute')\n .values({\n mutedByDid: actorDid,\n subjectDid: subject,\n createdAt: new Date().toISOString(),\n })\n .onConflict((oc) => oc.doNothing())\n .execute()\n } else {\n const uri = new AtUri(subject)\n if (uri.collection === app.bsky.graph.list.$type) {\n await this.db.db\n .insertInto('list_mute')\n .values({\n mutedByDid: actorDid,\n listUri: subject,\n createdAt: new Date().toISOString(),\n })\n .onConflict((oc) => oc.doNothing())\n .execute()\n } else {\n await this.db.db\n .insertInto('thread_mute')\n .values({\n mutedByDid: actorDid,\n rootUri: subject,\n createdAt: new Date().toISOString(),\n })\n .onConflict((oc) => oc.doNothing())\n .execute()\n }\n }\n } else if (type === MuteOperation_Type.REMOVE) {\n if (subject.startsWith('did:')) {\n await this.db.db\n .deleteFrom('mute')\n .where('mutedByDid', '=', actorDid)\n .where('subjectDid', '=', subject)\n .execute()\n } else {\n const uri = new AtUri(subject)\n if (uri.collection === app.bsky.graph.list.$type) {\n await this.db.db\n .deleteFrom('list_mute')\n .where('mutedByDid', '=', actorDid)\n .where('listUri', '=', subject)\n .execute()\n } else {\n await this.db.db\n .deleteFrom('thread_mute')\n .where('mutedByDid', '=', actorDid)\n .where('rootUri', '=', subject)\n .execute()\n }\n }\n } else if (type === MuteOperation_Type.CLEAR) {\n await this.db.db\n .deleteFrom('mute')\n .where('mutedByDid', '=', actorDid)\n .execute()\n await this.db.db\n .deleteFrom('list_mute')\n .where('mutedByDid', '=', actorDid)\n .execute()\n }\n }\n }\n\n private scanNotifOperations() {\n this.startScanning(async (cursor, signal) => {\n const res = await this.bsyncClient.scanNotifOperations(\n { cursor },\n { signal },\n )\n\n await this.processNotifOperations(res.operations)\n this.cursors.notif = res.cursor\n\n return res.cursor\n })\n }\n\n private async processNotifOperations(operations: NotifOperation[]) {\n for (const op of operations) {\n const { actorDid, priority } = op\n if (priority !== undefined) {\n await this.db.db\n .insertInto('actor_state')\n .values({\n did: actorDid,\n priorityNotifs: priority,\n lastSeenNotifs: new Date().toISOString(),\n })\n .onConflict((oc) =>\n oc.column('did').doUpdateSet({ priorityNotifs: priority }),\n )\n .execute()\n }\n }\n }\n\n private scanOperations() {\n this.startScanning(async (cursor, signal) => {\n const res = await this.bsyncClient.scanOperations({ cursor }, { signal })\n\n await this.processOperations(res.operations)\n this.cursors.op = res.cursor\n\n return res.cursor\n })\n }\n\n private async processOperations(operations: Operation[]) {\n for (const op of operations) {\n const { namespace } = op\n\n const now = new Date().toISOString()\n\n // Index all items into private_data.\n await handleGenericOperation(this.db, op, now)\n\n // Maintain bespoke indexes for certain namespaces. A failure here must\n // not stall the stream, so log and move on (matching bsync behavior).\n try {\n if (\n namespace ===\n Namespaces.AppBskyNotificationDefsSubjectActivitySubscription.$type\n ) {\n await handleSubjectActivitySubscriptionOperation(this.db, op, now)\n } else if (\n namespace === Namespaces.AppBskyUnspeccedDefsAgeAssuranceEvent.$type\n ) {\n await handleAgeAssuranceEventOperation(this.db, op, now)\n } else if (\n namespace === Namespaces.AppBskyAgeassuranceDefsEvent.$type\n ) {\n await handleAgeAssuranceV2EventOperation(this.db, op, now)\n } else if (namespace === Namespaces.AppBskyBookmarkDefsBookmark.$type) {\n await handleBookmarkOperation(this.db, op, now)\n } else if (namespace === Namespaces.AppBskyDraftDefsDraftWithId.$type) {\n await handleDraftOperation(this.db, op, now)\n }\n } catch (err) {\n log.warn({ err, namespace }, 'bsync put operation indexing failed')\n }\n }\n }\n}\n\ntype HandleOperation = (\n db: Database,\n op: Operation,\n now: string,\n) => Promise<void>\n\n// upsert into or remove from private_data\nconst handleGenericOperation: HandleOperation = async (\n db: Database,\n op: Operation,\n now: string,\n) => {\n const { actorDid, namespace, key, method, payload } = op\n if (method === Method.CREATE || method === Method.UPDATE) {\n await db.db\n .insertInto('private_data')\n .values({\n actorDid,\n namespace,\n key,\n payload: Buffer.from(payload).toString('utf8'),\n indexedAt: now,\n updatedAt: now,\n })\n .onConflict((oc) =>\n oc.columns(['actorDid', 'namespace', 'key']).doUpdateSet({\n payload: excluded(db.db, 'payload'),\n updatedAt: excluded(db.db, 'updatedAt'),\n }),\n )\n .execute()\n } else if (method === Method.DELETE) {\n await db.db\n .deleteFrom('private_data')\n .where('actorDid', '=', actorDid)\n .where('namespace', '=', namespace)\n .where('key', '=', key)\n .execute()\n } else {\n assert.fail(`unexpected method ${method}`)\n }\n}\n\nconst handleSubjectActivitySubscriptionOperation: HandleOperation = async (\n db: Database,\n op: Operation,\n now: string,\n) => {\n const { actorDid, key, method, payload } = op\n\n if (method === Method.DELETE) {\n await db.db\n .deleteFrom('activity_subscription')\n .where('creator', '=', actorDid)\n .where('key', '=', key)\n .execute()\n return\n }\n\n const parsed =\n lexParse<app.bsky.notification.defs.SubjectActivitySubscription>(\n Buffer.from(payload).toString('utf8'),\n )\n const {\n subject,\n activitySubscription: { post, reply },\n } = parsed\n\n if (method === Method.CREATE) {\n await db.db\n .insertInto('activity_subscription')\n .values({\n creator: actorDid,\n subjectDid: subject,\n key,\n indexedAt: now,\n post,\n reply,\n })\n .execute()\n return\n }\n\n await db.db\n .updateTable('activity_subscription')\n .where('creator', '=', actorDid)\n .where('key', '=', key)\n .set({\n indexedAt: now,\n post,\n reply,\n })\n .execute()\n}\n\nconst handleAgeAssuranceEventOperation: HandleOperation = async (\n db: Database,\n op: Operation,\n) => {\n const { actorDid, method, payload } = op\n if (method !== Method.CREATE) return\n\n const parsed = lexParse<app.bsky.unspecced.defs.AgeAssuranceEvent>(\n Buffer.from(payload).toString('utf8'),\n )\n const { status, createdAt } = parsed\n\n const update = {\n ageAssuranceStatus: status,\n ageAssuranceLastInitiatedAt: status === 'pending' ? createdAt : undefined,\n }\n\n await db.db\n .updateTable('actor')\n .set(update)\n .where('did', '=', actorDid)\n .execute()\n}\n\nconst handleAgeAssuranceV2EventOperation: HandleOperation = async (\n db: Database,\n op: Operation,\n) => {\n const { actorDid, method, payload } = op\n if (method !== Method.CREATE) return\n\n const parsed = lexParse<app.bsky.ageassurance.defs.Event>(\n Buffer.from(payload).toString('utf8'),\n )\n const { status, createdAt, access, countryCode, regionCode } = parsed\n\n const update = {\n ageAssuranceStatus: status,\n ageAssuranceLastInitiatedAt: status === 'pending' ? createdAt : undefined,\n ageAssuranceAccess: access,\n ageAssuranceCountryCode: countryCode,\n ageAssuranceRegionCode: regionCode,\n }\n\n await db.db\n .updateTable('actor')\n .set(update)\n .where('did', '=', actorDid)\n .execute()\n}\n\nconst handleBookmarkOperation: HandleOperation = async (\n db: Database,\n op: Operation,\n now: string,\n) => {\n const { actorDid, key, method, payload } = op\n\n const updateAgg = (uri: string, dbTxn: Database) => {\n return dbTxn.db\n .insertInto('post_agg')\n .values({\n uri,\n bookmarkCount: dbTxn.db\n .selectFrom('bookmark')\n .where('bookmark.subjectUri', '=', uri)\n .select(countAll.as('count')),\n })\n .onConflict((oc) =>\n oc\n .column('uri')\n .doUpdateSet({ bookmarkCount: excluded(dbTxn.db, 'bookmarkCount') }),\n )\n .execute()\n }\n\n if (method === Method.CREATE) {\n const parsed = lexParse<app.bsky.bookmark.defs.Bookmark>(\n Buffer.from(payload).toString('utf8'),\n )\n const {\n subject: { uri, cid },\n } = parsed\n\n await db.transaction(async (dbTxn) => {\n await dbTxn.db\n .insertInto('bookmark')\n .values({\n creator: actorDid,\n key,\n indexedAt: now,\n subjectUri: uri,\n subjectCid: cid,\n })\n .execute()\n\n await updateAgg(uri, dbTxn)\n })\n }\n\n if (method === Method.DELETE) {\n await db.transaction(async (dbTxn) => {\n const bookmark = await dbTxn.db\n .selectFrom('bookmark')\n .selectAll()\n .where('creator', '=', actorDid)\n .where('key', '=', key)\n .executeTakeFirst()\n\n if (bookmark) {\n await dbTxn.db\n .deleteFrom('bookmark')\n .where('creator', '=', actorDid)\n .where('key', '=', key)\n .execute()\n\n await updateAgg(bookmark.subjectUri, dbTxn)\n }\n })\n }\n}\n\nconst handleDraftOperation: HandleOperation = async (\n db: Database,\n op: Operation,\n now: string,\n) => {\n const { actorDid, key, method, payload } = op\n\n if (method === Method.CREATE) {\n const payloadString = Buffer.from(payload).toString('utf8')\n\n await db.db\n .insertInto('draft')\n .values({\n creator: actorDid,\n key,\n createdAt: now,\n updatedAt: now,\n payload: payloadString,\n })\n .execute()\n }\n\n if (method === Method.UPDATE) {\n const payloadString = Buffer.from(payload).toString('utf8')\n\n await db.db\n .updateTable('draft')\n .where('creator', '=', actorDid)\n .where('key', '=', key)\n .set({\n updatedAt: now,\n payload: payloadString,\n })\n .execute()\n }\n\n if (method === Method.DELETE) {\n await db.db\n .deleteFrom('draft')\n .where('creator', '=', actorDid)\n .where('key', '=', key)\n .execute()\n }\n}\n\n// compares numeric (bigint) cursor ids; an undefined target is always satisfied\nconst gteCursor = (current: string | undefined, target: string | undefined) => {\n if (!target) return true\n return BigInt(current || '0') >= BigInt(target)\n}\n\n// resolves after `ms`, or early if `signal` aborts\nconst wait = (ms: number, signal?: AbortSignal) =>\n new Promise<void>((resolve) => {\n if (signal?.aborted) return resolve()\n const done = () => {\n clearTimeout(timer)\n signal?.removeEventListener('abort', done)\n resolve()\n }\n const timer = setTimeout(done, ms)\n signal?.addEventListener('abort', done, { once: true })\n })\n"]}
|
|
@@ -2,6 +2,7 @@ import http from 'node:http';
|
|
|
2
2
|
import { IdResolver } from '@atproto/identity';
|
|
3
3
|
import { Database, DatabaseSchema } from './db/index.js';
|
|
4
4
|
export type { DatabaseSchema };
|
|
5
|
+
export { BsyncSubscription } from './bsync-subscription.js';
|
|
5
6
|
export { RepoSubscription } from './subscription.js';
|
|
6
7
|
export declare class DataPlaneServer {
|
|
7
8
|
server: http.Server;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/data-plane/server/index.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,WAAW,CAAA;AAK5B,OAAO,EAAE,UAAU,EAAe,MAAM,mBAAmB,CAAA;AAC3D,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAGxD,YAAY,EAAE,cAAc,EAAE,CAAA;AAE9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEpD,qBAAa,eAAe;IAIjB,MAAM,EAAE,IAAI,CAAC,MAAM;IACnB,UAAU,EAAE,UAAU;IAJ/B,OAAO,CAAC,UAAU,CAA+B;IAEjD,YACS,MAAM,EAAE,IAAI,CAAC,MAAM,EACnB,UAAU,EAAE,UAAU,EAG9B;IAED,OAAa,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,4BAS9D;IAEK,OAAO,kBAEZ;IAEK,CAAC,MAAM,CAAC,YAAY,CAAC,kBAE1B;CACF"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/data-plane/server/index.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,WAAW,CAAA;AAK5B,OAAO,EAAE,UAAU,EAAe,MAAM,mBAAmB,CAAA;AAC3D,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAGxD,YAAY,EAAE,cAAc,EAAE,CAAA;AAE9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEpD,qBAAa,eAAe;IAIjB,MAAM,EAAE,IAAI,CAAC,MAAM;IACnB,UAAU,EAAE,UAAU;IAJ/B,OAAO,CAAC,UAAU,CAA+B;IAEjD,YACS,MAAM,EAAE,IAAI,CAAC,MAAM,EACnB,UAAU,EAAE,UAAU,EAG9B;IAED,OAAa,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,4BAS9D;IAEK,OAAO,kBAEZ;IAEK,CAAC,MAAM,CAAC,YAAY,CAAC,kBAE1B;CACF"}
|
|
@@ -5,6 +5,7 @@ import express from 'express';
|
|
|
5
5
|
import httpTerminator from 'http-terminator';
|
|
6
6
|
import { IdResolver, MemoryCache } from '@atproto/identity';
|
|
7
7
|
import createRoutes from './routes/index.js';
|
|
8
|
+
export { BsyncSubscription } from './bsync-subscription.js';
|
|
8
9
|
export { RepoSubscription } from './subscription.js';
|
|
9
10
|
export class DataPlaneServer {
|
|
10
11
|
constructor(server, idResolver) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/data-plane/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;AAEhC,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAA;AACtE,OAAO,OAAO,MAAM,SAAS,CAAA;AAC7B,0CAA0C;AAC1C,OAAO,cAAc,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE3D,OAAO,YAAY,MAAM,mBAAmB,CAAA;AAI5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEpD,MAAM,OAAO,eAAe;IAG1B,YACS,MAAmB,EACnB,UAAsB;sBADtB,MAAM;0BACN,UAAU;QAEjB,IAAI,CAAC,UAAU,GAAG,cAAc,CAAC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAA;IACnE,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAY,EAAE,IAAY,EAAE,MAAe;QAC7D,MAAM,GAAG,GAAG,OAAO,EAAE,CAAA;QACrB,MAAM,QAAQ,GAAG,IAAI,WAAW,EAAE,CAAA;QAClC,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAA;QACvD,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,EAAE,UAAU,CAAC,CAAA;QAC3C,GAAG,CAAC,GAAG,CAAC,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;QAC7C,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAC/B,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;QACtC,OAAO,IAAI,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAChD,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAA;IACnC,CAAC;IAED,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;QACzB,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;IACtB,CAAC;CACF","sourcesContent":["import events from 'node:events'\nimport http from 'node:http'\nimport { expressConnectMiddleware } from '@connectrpc/connect-express'\nimport express from 'express'\n// eslint-disable-next-line import/default\nimport httpTerminator from 'http-terminator'\nimport { IdResolver, MemoryCache } from '@atproto/identity'\nimport { Database, DatabaseSchema } from './db/index.js'\nimport createRoutes from './routes/index.js'\n\nexport type { DatabaseSchema }\n\nexport { RepoSubscription } from './subscription.js'\n\nexport class DataPlaneServer {\n private terminator: httpTerminator.HttpTerminator\n\n constructor(\n public server: http.Server,\n public idResolver: IdResolver,\n ) {\n this.terminator = httpTerminator.createHttpTerminator({ server })\n }\n\n static async create(db: Database, port: number, plcUrl?: string) {\n const app = express()\n const didCache = new MemoryCache()\n const idResolver = new IdResolver({ plcUrl, didCache })\n const routes = createRoutes(db, idResolver)\n app.use(expressConnectMiddleware({ routes }))\n const server = app.listen(port)\n await events.once(server, 'listening')\n return new DataPlaneServer(server, idResolver)\n }\n\n async destroy() {\n await this.terminator.terminate()\n }\n\n async [Symbol.asyncDispose]() {\n await this.destroy()\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/data-plane/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;AAEhC,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAA;AACtE,OAAO,OAAO,MAAM,SAAS,CAAA;AAC7B,0CAA0C;AAC1C,OAAO,cAAc,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE3D,OAAO,YAAY,MAAM,mBAAmB,CAAA;AAI5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEpD,MAAM,OAAO,eAAe;IAG1B,YACS,MAAmB,EACnB,UAAsB;sBADtB,MAAM;0BACN,UAAU;QAEjB,IAAI,CAAC,UAAU,GAAG,cAAc,CAAC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAA;IACnE,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAY,EAAE,IAAY,EAAE,MAAe;QAC7D,MAAM,GAAG,GAAG,OAAO,EAAE,CAAA;QACrB,MAAM,QAAQ,GAAG,IAAI,WAAW,EAAE,CAAA;QAClC,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAA;QACvD,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,EAAE,UAAU,CAAC,CAAA;QAC3C,GAAG,CAAC,GAAG,CAAC,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;QAC7C,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAC/B,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;QACtC,OAAO,IAAI,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAChD,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAA;IACnC,CAAC;IAED,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;QACzB,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;IACtB,CAAC;CACF","sourcesContent":["import events from 'node:events'\nimport http from 'node:http'\nimport { expressConnectMiddleware } from '@connectrpc/connect-express'\nimport express from 'express'\n// eslint-disable-next-line import/default\nimport httpTerminator from 'http-terminator'\nimport { IdResolver, MemoryCache } from '@atproto/identity'\nimport { Database, DatabaseSchema } from './db/index.js'\nimport createRoutes from './routes/index.js'\n\nexport type { DatabaseSchema }\n\nexport { BsyncSubscription } from './bsync-subscription.js'\nexport { RepoSubscription } from './subscription.js'\n\nexport class DataPlaneServer {\n private terminator: httpTerminator.HttpTerminator\n\n constructor(\n public server: http.Server,\n public idResolver: IdResolver,\n ) {\n this.terminator = httpTerminator.createHttpTerminator({ server })\n }\n\n static async create(db: Database, port: number, plcUrl?: string) {\n const app = express()\n const didCache = new MemoryCache()\n const idResolver = new IdResolver({ plcUrl, didCache })\n const routes = createRoutes(db, idResolver)\n app.use(expressConnectMiddleware({ routes }))\n const server = app.listen(port)\n await events.once(server, 'listening')\n return new DataPlaneServer(server, idResolver)\n }\n\n async destroy() {\n await this.terminator.terminate()\n }\n\n async [Symbol.asyncDispose]() {\n await this.destroy()\n }\n}\n"]}
|
|
@@ -68,6 +68,10 @@ type ConfigRegion = {
|
|
|
68
68
|
* The minimum age (as a whole integer) required to use Bluesky in this region.
|
|
69
69
|
*/
|
|
70
70
|
minAccessAge: number;
|
|
71
|
+
/**
|
|
72
|
+
* Verification methods permitted in this region in addition to the third-party (KWS) flow, which is always supported. `device` permits using the native on-device age APIs (e.g. Apple Declared Age Range, Google Play Age Signals).
|
|
73
|
+
*/
|
|
74
|
+
additionalVerificationMethods?: ('device' | l.UnknownString)[];
|
|
71
75
|
/**
|
|
72
76
|
* The ordered list of Age Assurance rules that apply to this region. Rules should be applied in order, and the first matching rule determines the access level granted. The rules array should always include a default rule as the last item.
|
|
73
77
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defs.defs.d.ts","sourceRoot":"","sources":["../../../../../src/lexicons/app/bsky/ageassurance/defs.defs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAEhC,QAAA,MAAM,KAAK,+BAA+B,CAAA;AAE1C,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,4EAA4E;AAC5E,KAAK,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,aAAa,CAAA;AAEpE,YAAY,EAAE,MAAM,EAAE,CAAA;AAEtB,4EAA4E;AAC5E,QAAA,MAAM,MAAM;;EAER,CAAA;AAEJ,OAAO,EAAE,MAAM,EAAE,CAAA;AAEjB,+CAA+C;AAC/C,KAAK,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,CAAC,CAAC,aAAa,CAAA;AAE7E,YAAY,EAAE,MAAM,EAAE,CAAA;AAEtB,+CAA+C;AAC/C,QAAA,MAAM,MAAM;;EAER,CAAA;AAEJ,OAAO,EAAE,MAAM,EAAE,CAAA;AAEjB,+CAA+C;AAC/C,KAAK,KAAK,GAAG;IACX,KAAK,CAAC,EAAE,kCAAkC,CAAA;IAE1C;;OAEG;IACH,eAAe,CAAC,EAAE,CAAC,CAAC,cAAc,CAAA;IAClC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,YAAY,EAAE,KAAK,EAAE,CAAA;AAErB,+CAA+C;AAC/C,QAAA,MAAM,KAAK,oFAUV,CAAA;AAED,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,6EAA6E;AAC7E,KAAK,aAAa,GAAG;IACnB,KAAK,CAAC,EAAE,0CAA0C,CAAA;IAElD;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,CAAC,cAAc,CAAA;CACpC,CAAA;AAED,YAAY,EAAE,aAAa,EAAE,CAAA;AAE7B,6EAA6E;AAC7E,QAAA,MAAM,aAAa,4GAQlB,CAAA;AAED,OAAO,EAAE,aAAa,EAAE,CAAA;AAExB,KAAK,MAAM,GAAG;IACZ,KAAK,CAAC,EAAE,mCAAmC,CAAA;IAE3C;;OAEG;IACH,OAAO,EAAE,YAAY,EAAE,CAAA;CACxB,CAAA;AAED,YAAY,EAAE,MAAM,EAAE,CAAA;AAEtB,QAAA,MAAM,MAAM,uFAQX,CAAA;AAED,OAAO,EAAE,MAAM,EAAE,CAAA;AAEjB,6DAA6D;AAC7D,KAAK,YAAY,GAAG;IAClB,KAAK,CAAC,EAAE,yCAAyC,CAAA;IAEjD;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IAEnB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAA;IAEpB;;OAEG;IACH,KAAK,EAAE,CACH,CAAC,CAAC,MAAM,CAAC,uBAAuB,CAAC,GACjC,CAAC,CAAC,MAAM,CAAC,iCAAiC,CAAC,GAC3C,CAAC,CAAC,MAAM,CAAC,kCAAkC,CAAC,GAC5C,CAAC,CAAC,MAAM,CAAC,gCAAgC,CAAC,GAC1C,CAAC,CAAC,MAAM,CAAC,iCAAiC,CAAC,GAC3C,CAAC,CAAC,MAAM,CAAC,kCAAkC,CAAC,GAC5C,CAAC,CAAC,MAAM,CAAC,kCAAkC,CAAC,GAC5C,CAAC,CAAC,mBAAmB,CACxB,EAAE,CAAA;CACJ,CAAA;AAED,YAAY,EAAE,YAAY,EAAE,CAAA;AAE5B,6DAA6D;AAC7D,QAAA,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"defs.defs.d.ts","sourceRoot":"","sources":["../../../../../src/lexicons/app/bsky/ageassurance/defs.defs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAEhC,QAAA,MAAM,KAAK,+BAA+B,CAAA;AAE1C,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,4EAA4E;AAC5E,KAAK,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,aAAa,CAAA;AAEpE,YAAY,EAAE,MAAM,EAAE,CAAA;AAEtB,4EAA4E;AAC5E,QAAA,MAAM,MAAM;;EAER,CAAA;AAEJ,OAAO,EAAE,MAAM,EAAE,CAAA;AAEjB,+CAA+C;AAC/C,KAAK,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,CAAC,CAAC,aAAa,CAAA;AAE7E,YAAY,EAAE,MAAM,EAAE,CAAA;AAEtB,+CAA+C;AAC/C,QAAA,MAAM,MAAM;;EAER,CAAA;AAEJ,OAAO,EAAE,MAAM,EAAE,CAAA;AAEjB,+CAA+C;AAC/C,KAAK,KAAK,GAAG;IACX,KAAK,CAAC,EAAE,kCAAkC,CAAA;IAE1C;;OAEG;IACH,eAAe,CAAC,EAAE,CAAC,CAAC,cAAc,CAAA;IAClC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,YAAY,EAAE,KAAK,EAAE,CAAA;AAErB,+CAA+C;AAC/C,QAAA,MAAM,KAAK,oFAUV,CAAA;AAED,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,6EAA6E;AAC7E,KAAK,aAAa,GAAG;IACnB,KAAK,CAAC,EAAE,0CAA0C,CAAA;IAElD;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,CAAC,cAAc,CAAA;CACpC,CAAA;AAED,YAAY,EAAE,aAAa,EAAE,CAAA;AAE7B,6EAA6E;AAC7E,QAAA,MAAM,aAAa,4GAQlB,CAAA;AAED,OAAO,EAAE,aAAa,EAAE,CAAA;AAExB,KAAK,MAAM,GAAG;IACZ,KAAK,CAAC,EAAE,mCAAmC,CAAA;IAE3C;;OAEG;IACH,OAAO,EAAE,YAAY,EAAE,CAAA;CACxB,CAAA;AAED,YAAY,EAAE,MAAM,EAAE,CAAA;AAEtB,QAAA,MAAM,MAAM,uFAQX,CAAA;AAED,OAAO,EAAE,MAAM,EAAE,CAAA;AAEjB,6DAA6D;AAC7D,KAAK,YAAY,GAAG;IAClB,KAAK,CAAC,EAAE,yCAAyC,CAAA;IAEjD;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IAEnB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAA;IAEpB;;OAEG;IACH,6BAA6B,CAAC,EAAE,CAAC,QAAQ,GAAG,CAAC,CAAC,aAAa,CAAC,EAAE,CAAA;IAE9D;;OAEG;IACH,KAAK,EAAE,CACH,CAAC,CAAC,MAAM,CAAC,uBAAuB,CAAC,GACjC,CAAC,CAAC,MAAM,CAAC,iCAAiC,CAAC,GAC3C,CAAC,CAAC,MAAM,CAAC,kCAAkC,CAAC,GAC5C,CAAC,CAAC,MAAM,CAAC,gCAAgC,CAAC,GAC1C,CAAC,CAAC,MAAM,CAAC,iCAAiC,CAAC,GAC3C,CAAC,CAAC,MAAM,CAAC,kCAAkC,CAAC,GAC5C,CAAC,CAAC,MAAM,CAAC,kCAAkC,CAAC,GAC5C,CAAC,CAAC,mBAAmB,CACxB,EAAE,CAAA;CACJ,CAAA;AAED,YAAY,EAAE,YAAY,EAAE,CAAA;AAE5B,6DAA6D;AAC7D,QAAA,MAAM,YAAY,yGAyCjB,CAAA;AAED,OAAO,EAAE,YAAY,EAAE,CAAA;AAEvB,kDAAkD;AAClD,KAAK,uBAAuB,GAAG;IAC7B,KAAK,CAAC,EAAE,oDAAoD,CAAA;IAC5D,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,YAAY,EAAE,uBAAuB,EAAE,CAAA;AAEvC,kDAAkD;AAClD,QAAA,MAAM,uBAAuB,0IAO1B,CAAA;AAEH,OAAO,EAAE,uBAAuB,EAAE,CAAA;AAElC,0GAA0G;AAC1G,KAAK,iCAAiC,GAAG;IACvC,KAAK,CAAC,EAAE,8DAA8D,CAAA;IAEtE;;OAEG;IACH,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,YAAY,EAAE,iCAAiC,EAAE,CAAA;AAEjD,0GAA0G;AAC1G,QAAA,MAAM,iCAAiC,wKAQpC,CAAA;AAEH,OAAO,EAAE,iCAAiC,EAAE,CAAA;AAE5C,+FAA+F;AAC/F,KAAK,kCAAkC,GAAG;IACxC,KAAK,CAAC,EAAE,+DAA+D,CAAA;IAEvE;;OAEG;IACH,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,YAAY,EAAE,kCAAkC,EAAE,CAAA;AAElD,+FAA+F;AAC/F,QAAA,MAAM,kCAAkC,2KAQrC,CAAA;AAEH,OAAO,EAAE,kCAAkC,EAAE,CAAA;AAE7C,yGAAyG;AACzG,KAAK,gCAAgC,GAAG;IACtC,KAAK,CAAC,EAAE,6DAA6D,CAAA;IAErE;;OAEG;IACH,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,YAAY,EAAE,gCAAgC,EAAE,CAAA;AAEhD,yGAAyG;AACzG,QAAA,MAAM,gCAAgC,qKAQnC,CAAA;AAEH,OAAO,EAAE,gCAAgC,EAAE,CAAA;AAE3C,8FAA8F;AAC9F,KAAK,iCAAiC,GAAG;IACvC,KAAK,CAAC,EAAE,8DAA8D,CAAA;IAEtE;;OAEG;IACH,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,YAAY,EAAE,iCAAiC,EAAE,CAAA;AAEjD,8FAA8F;AAC9F,QAAA,MAAM,iCAAiC,wKAQpC,CAAA;AAEH,OAAO,EAAE,iCAAiC,EAAE,CAAA;AAE5C,+FAA+F;AAC/F,KAAK,kCAAkC,GAAG;IACxC,KAAK,CAAC,EAAE,+DAA+D,CAAA;IAEvE;;OAEG;IACH,IAAI,EAAE,CAAC,CAAC,cAAc,CAAA;IACtB,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,YAAY,EAAE,kCAAkC,EAAE,CAAA;AAElD,+FAA+F;AAC/F,QAAA,MAAM,kCAAkC,2KAQrC,CAAA;AAEH,OAAO,EAAE,kCAAkC,EAAE,CAAA;AAE7C,mFAAmF;AACnF,KAAK,kCAAkC,GAAG;IACxC,KAAK,CAAC,EAAE,+DAA+D,CAAA;IAEvE;;OAEG;IACH,IAAI,EAAE,CAAC,CAAC,cAAc,CAAA;IACtB,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,YAAY,EAAE,kCAAkC,EAAE,CAAA;AAElD,mFAAmF;AACnF,QAAA,MAAM,kCAAkC,2KAQrC,CAAA;AAEH,OAAO,EAAE,kCAAkC,EAAE,CAAA;AAE7C,wDAAwD;AACxD,KAAK,KAAK,GAAG;IACX,KAAK,CAAC,EAAE,kCAAkC,CAAA;IAE1C;;OAEG;IACH,SAAS,EAAE,CAAC,CAAC,cAAc,CAAA;IAE3B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,CAAC,CAAC,aAAa,CAAA;IAEvE;;OAEG;IACH,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,aAAa,CAAA;IAE9D;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IAEnB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,YAAY,EAAE,KAAK,EAAE,CAAA;AAErB,wDAAwD;AACxD,QAAA,MAAM,KAAK,oFAoBV,CAAA;AAED,OAAO,EAAE,KAAK,EAAE,CAAA"}
|
|
@@ -38,6 +38,9 @@ const configRegion = /*#__PURE__*/ l.typedObject($nsid, 'configRegion',
|
|
|
38
38
|
countryCode: /*#__PURE__*/ l.string(),
|
|
39
39
|
regionCode: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),
|
|
40
40
|
minAccessAge: /*#__PURE__*/ l.integer(),
|
|
41
|
+
additionalVerificationMethods: /*#__PURE__*/ l.optional(
|
|
42
|
+
/*#__PURE__*/ l.array(
|
|
43
|
+
/*#__PURE__*/ l.string())),
|
|
41
44
|
rules: /*#__PURE__*/ l.array(
|
|
42
45
|
/*#__PURE__*/ l.typedUnion([
|
|
43
46
|
/*#__PURE__*/ l.typedRef((() => configRegionRuleDefault)),
|