@atproto/bsky 0.0.25 → 0.0.27
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 +14 -0
- package/buf.gen.yaml +12 -0
- package/dist/api/app/bsky/graph/getRelationships.d.ts +3 -0
- package/dist/api/app/bsky/unspecced/getTaggedSuggestions.d.ts +3 -0
- package/dist/bsync.d.ts +8 -0
- package/dist/config.d.ts +20 -0
- package/dist/context.d.ts +6 -3
- package/dist/courier.d.ts +8 -0
- package/dist/db/database-schema.d.ts +2 -1
- package/dist/db/index.js +15 -1
- package/dist/db/index.js.map +3 -3
- package/dist/db/migrations/20240124T023719200Z-tagged-suggestions.d.ts +3 -0
- package/dist/db/migrations/index.d.ts +1 -0
- package/dist/db/tables/tagged-suggestion.d.ts +9 -0
- package/dist/index.js +48246 -16828
- package/dist/index.js.map +3 -3
- package/dist/indexer/config.d.ts +8 -0
- package/dist/indexer/context.d.ts +3 -0
- package/dist/ingester/config.d.ts +8 -0
- package/dist/ingester/context.d.ts +3 -0
- package/dist/ingester/mute-subscription.d.ts +22 -0
- package/dist/lexicon/index.d.ts +4 -0
- package/dist/lexicon/lexicons.d.ts +153 -0
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts +7 -1
- package/dist/lexicon/types/app/bsky/graph/defs.d.ts +15 -0
- package/dist/lexicon/types/app/bsky/graph/getRelationships.d.ts +38 -0
- package/dist/lexicon/types/app/bsky/unspecced/getTaggedSuggestions.d.ts +39 -0
- package/dist/notifications.d.ts +27 -16
- package/dist/proto/bsync_connect.d.ts +25 -0
- package/dist/proto/bsync_pb.d.ts +90 -0
- package/dist/proto/courier_connect.d.ts +25 -0
- package/dist/proto/courier_pb.d.ts +91 -0
- package/dist/services/actor/index.d.ts +2 -2
- package/dist/services/indexing/index.d.ts +2 -2
- package/dist/services/util/post.d.ts +6 -6
- package/dist/util/retry.d.ts +2 -0
- package/package.json +15 -7
- package/proto/courier.proto +56 -0
- package/src/api/app/bsky/graph/getRelationships.ts +71 -0
- package/src/api/app/bsky/graph/muteActor.ts +32 -5
- package/src/api/app/bsky/graph/muteActorList.ts +32 -5
- package/src/api/app/bsky/graph/unmuteActor.ts +32 -5
- package/src/api/app/bsky/graph/unmuteActorList.ts +32 -5
- package/src/api/app/bsky/notification/registerPush.ts +42 -8
- package/src/api/app/bsky/unspecced/getTaggedSuggestions.ts +21 -0
- package/src/api/index.ts +4 -0
- package/src/bsync.ts +41 -0
- package/src/config.ts +79 -0
- package/src/context.ts +12 -6
- package/src/courier.ts +41 -0
- package/src/db/database-schema.ts +2 -0
- package/src/db/migrations/20240124T023719200Z-tagged-suggestions.ts +15 -0
- package/src/db/migrations/index.ts +1 -0
- package/src/db/tables/tagged-suggestion.ts +11 -0
- package/src/index.ts +26 -3
- package/src/indexer/config.ts +36 -0
- package/src/indexer/context.ts +6 -0
- package/src/indexer/index.ts +27 -3
- package/src/ingester/config.ts +34 -0
- package/src/ingester/context.ts +6 -0
- package/src/ingester/index.ts +18 -0
- package/src/ingester/mute-subscription.ts +213 -0
- package/src/lexicon/index.ts +24 -0
- package/src/lexicon/lexicons.ts +167 -0
- package/src/lexicon/types/app/bsky/actor/defs.ts +19 -0
- package/src/lexicon/types/app/bsky/graph/defs.ts +41 -0
- package/src/lexicon/types/app/bsky/graph/getRelationships.ts +53 -0
- package/src/lexicon/types/app/bsky/unspecced/getTaggedSuggestions.ts +65 -0
- package/src/notifications.ts +165 -149
- package/src/proto/bsync_connect.ts +54 -0
- package/src/proto/bsync_pb.ts +459 -0
- package/src/proto/courier_connect.ts +50 -0
- package/src/proto/courier_pb.ts +473 -0
- package/src/services/actor/index.ts +17 -2
- package/src/services/indexing/processor.ts +1 -1
- package/src/util/retry.ts +12 -0
- package/tests/notification-server.test.ts +59 -19
- package/tests/subscription/mutes.test.ts +170 -0
- package/tests/views/__snapshots__/follows.test.ts.snap +28 -0
- package/tests/views/follows.test.ts +10 -0
- package/tests/views/suggestions.test.ts +22 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import AtpAgent from '@atproto/api'
|
|
2
|
+
import { wait } from '@atproto/common'
|
|
3
|
+
import { TestNetwork, SeedClient, basicSeed, TestBsync } from '@atproto/dev-env'
|
|
4
|
+
import assert from 'assert'
|
|
5
|
+
|
|
6
|
+
describe('sync mutes', () => {
|
|
7
|
+
let network: TestNetwork
|
|
8
|
+
let bsync: TestBsync
|
|
9
|
+
let pdsAgent: AtpAgent
|
|
10
|
+
let sc: SeedClient
|
|
11
|
+
|
|
12
|
+
beforeAll(async () => {
|
|
13
|
+
assert(process.env.DB_POSTGRES_URL)
|
|
14
|
+
bsync = await TestBsync.create({
|
|
15
|
+
dbSchema: 'bsync_subscription_mutes',
|
|
16
|
+
dbUrl: process.env.DB_POSTGRES_URL,
|
|
17
|
+
})
|
|
18
|
+
network = await TestNetwork.create({
|
|
19
|
+
dbPostgresSchema: 'bsky_subscription_mutes',
|
|
20
|
+
bsky: {
|
|
21
|
+
bsyncUrl: bsync.url,
|
|
22
|
+
bsyncApiKey: [...bsync.ctx.cfg.auth.apiKeys][0],
|
|
23
|
+
bsyncHttpVersion: '1.1',
|
|
24
|
+
bsyncOnlyMutes: true,
|
|
25
|
+
ingester: {
|
|
26
|
+
bsyncUrl: bsync.url,
|
|
27
|
+
bsyncApiKey: [...bsync.ctx.cfg.auth.apiKeys][0],
|
|
28
|
+
bsyncHttpVersion: '1.1',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
})
|
|
32
|
+
pdsAgent = network.pds.getClient()
|
|
33
|
+
sc = network.getSeedClient()
|
|
34
|
+
await basicSeed(sc)
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
afterAll(async () => {
|
|
38
|
+
await network.close()
|
|
39
|
+
await bsync.close()
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('mutes and unmutes actors.', async () => {
|
|
43
|
+
await pdsAgent.api.app.bsky.graph.muteActor(
|
|
44
|
+
{ actor: sc.dids.alice },
|
|
45
|
+
{ headers: sc.getHeaders(sc.dids.bob), encoding: 'application/json' },
|
|
46
|
+
)
|
|
47
|
+
await pdsAgent.api.app.bsky.graph.muteActor(
|
|
48
|
+
{ actor: sc.dids.carol },
|
|
49
|
+
{ headers: sc.getHeaders(sc.dids.bob), encoding: 'application/json' },
|
|
50
|
+
)
|
|
51
|
+
await pdsAgent.api.app.bsky.graph.muteActor(
|
|
52
|
+
{ actor: sc.dids.dan },
|
|
53
|
+
{ headers: sc.getHeaders(sc.dids.bob), encoding: 'application/json' },
|
|
54
|
+
)
|
|
55
|
+
await processAllMuteOps(network, bsync)
|
|
56
|
+
const { data: mutes1 } = await pdsAgent.api.app.bsky.graph.getMutes(
|
|
57
|
+
{},
|
|
58
|
+
{ headers: sc.getHeaders(sc.dids.bob) },
|
|
59
|
+
)
|
|
60
|
+
expect(mutes1.mutes.map((mute) => mute.did)).toEqual([
|
|
61
|
+
sc.dids.dan,
|
|
62
|
+
sc.dids.carol,
|
|
63
|
+
sc.dids.alice,
|
|
64
|
+
])
|
|
65
|
+
await pdsAgent.api.app.bsky.graph.unmuteActor(
|
|
66
|
+
{ actor: sc.dids.carol },
|
|
67
|
+
{ headers: sc.getHeaders(sc.dids.bob), encoding: 'application/json' },
|
|
68
|
+
)
|
|
69
|
+
await processAllMuteOps(network, bsync)
|
|
70
|
+
const { data: mutes2 } = await pdsAgent.api.app.bsky.graph.getMutes(
|
|
71
|
+
{},
|
|
72
|
+
{ headers: sc.getHeaders(sc.dids.bob) },
|
|
73
|
+
)
|
|
74
|
+
expect(mutes2.mutes.map((mute) => mute.did)).toEqual([
|
|
75
|
+
sc.dids.dan,
|
|
76
|
+
sc.dids.alice,
|
|
77
|
+
])
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('mutes and unmutes lists.', async () => {
|
|
81
|
+
// create lists
|
|
82
|
+
const list1 = await pdsAgent.api.app.bsky.graph.list.create(
|
|
83
|
+
{ repo: sc.dids.bob },
|
|
84
|
+
{
|
|
85
|
+
name: 'mod list 1',
|
|
86
|
+
purpose: 'app.bsky.graph.defs#modlist',
|
|
87
|
+
createdAt: new Date().toISOString(),
|
|
88
|
+
},
|
|
89
|
+
sc.getHeaders(sc.dids.bob),
|
|
90
|
+
)
|
|
91
|
+
const list2 = await pdsAgent.api.app.bsky.graph.list.create(
|
|
92
|
+
{ repo: sc.dids.bob },
|
|
93
|
+
{
|
|
94
|
+
name: 'mod list 2',
|
|
95
|
+
purpose: 'app.bsky.graph.defs#modlist',
|
|
96
|
+
createdAt: new Date().toISOString(),
|
|
97
|
+
},
|
|
98
|
+
sc.getHeaders(sc.dids.bob),
|
|
99
|
+
)
|
|
100
|
+
const list3 = await pdsAgent.api.app.bsky.graph.list.create(
|
|
101
|
+
{ repo: sc.dids.bob },
|
|
102
|
+
{
|
|
103
|
+
name: 'mod list 3',
|
|
104
|
+
purpose: 'app.bsky.graph.defs#modlist',
|
|
105
|
+
createdAt: new Date().toISOString(),
|
|
106
|
+
},
|
|
107
|
+
sc.getHeaders(sc.dids.bob),
|
|
108
|
+
)
|
|
109
|
+
await network.processAll()
|
|
110
|
+
await pdsAgent.api.app.bsky.graph.muteActorList(
|
|
111
|
+
{ list: list1.uri },
|
|
112
|
+
{ headers: sc.getHeaders(sc.dids.bob), encoding: 'application/json' },
|
|
113
|
+
)
|
|
114
|
+
await pdsAgent.api.app.bsky.graph.muteActorList(
|
|
115
|
+
{ list: list2.uri },
|
|
116
|
+
{ headers: sc.getHeaders(sc.dids.bob), encoding: 'application/json' },
|
|
117
|
+
)
|
|
118
|
+
await pdsAgent.api.app.bsky.graph.muteActorList(
|
|
119
|
+
{ list: list3.uri },
|
|
120
|
+
{ headers: sc.getHeaders(sc.dids.bob), encoding: 'application/json' },
|
|
121
|
+
)
|
|
122
|
+
await processAllMuteOps(network, bsync)
|
|
123
|
+
const { data: listmutes1 } = await pdsAgent.api.app.bsky.graph.getListMutes(
|
|
124
|
+
{},
|
|
125
|
+
{ headers: sc.getHeaders(sc.dids.bob) },
|
|
126
|
+
)
|
|
127
|
+
expect(listmutes1.lists.map((list) => list.uri)).toEqual([
|
|
128
|
+
list3.uri,
|
|
129
|
+
list2.uri,
|
|
130
|
+
list1.uri,
|
|
131
|
+
])
|
|
132
|
+
await pdsAgent.api.app.bsky.graph.unmuteActorList(
|
|
133
|
+
{ list: list2.uri },
|
|
134
|
+
{ headers: sc.getHeaders(sc.dids.bob), encoding: 'application/json' },
|
|
135
|
+
)
|
|
136
|
+
await processAllMuteOps(network, bsync)
|
|
137
|
+
const { data: listmutes2 } = await pdsAgent.api.app.bsky.graph.getListMutes(
|
|
138
|
+
{},
|
|
139
|
+
{ headers: sc.getHeaders(sc.dids.bob) },
|
|
140
|
+
)
|
|
141
|
+
expect(listmutes2.lists.map((list) => list.uri)).toEqual([
|
|
142
|
+
list3.uri,
|
|
143
|
+
list1.uri,
|
|
144
|
+
])
|
|
145
|
+
})
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
async function processAllMuteOps(network: TestNetwork, bsync: TestBsync) {
|
|
149
|
+
const getBsyncCursor = async () => {
|
|
150
|
+
const result = await bsync.ctx.db.db
|
|
151
|
+
.selectFrom('mute_op')
|
|
152
|
+
.orderBy('id', 'desc')
|
|
153
|
+
.select('id')
|
|
154
|
+
.limit(1)
|
|
155
|
+
.executeTakeFirst()
|
|
156
|
+
return result?.id.toString() ?? null
|
|
157
|
+
}
|
|
158
|
+
assert(network.bsky.ingester.ctx.muteSubscription)
|
|
159
|
+
let total = 0
|
|
160
|
+
while (
|
|
161
|
+
(await getBsyncCursor()) !==
|
|
162
|
+
network.bsky.ingester.ctx.muteSubscription.cursor
|
|
163
|
+
) {
|
|
164
|
+
if (total > 5000) {
|
|
165
|
+
throw new Error('timeout while processing mute ops')
|
|
166
|
+
}
|
|
167
|
+
await wait(50)
|
|
168
|
+
total += 50
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -569,3 +569,31 @@ Object {
|
|
|
569
569
|
},
|
|
570
570
|
}
|
|
571
571
|
`;
|
|
572
|
+
|
|
573
|
+
exports[`pds follow views fetches relationships between users 1`] = `
|
|
574
|
+
Object {
|
|
575
|
+
"actor": "user(0)",
|
|
576
|
+
"relationships": Array [
|
|
577
|
+
Object {
|
|
578
|
+
"$type": "app.bsky.graph.defs#relationship",
|
|
579
|
+
"did": "user(1)",
|
|
580
|
+
"followedBy": "record(1)",
|
|
581
|
+
"following": "record(0)",
|
|
582
|
+
},
|
|
583
|
+
Object {
|
|
584
|
+
"$type": "app.bsky.graph.defs#relationship",
|
|
585
|
+
"did": "user(0)",
|
|
586
|
+
},
|
|
587
|
+
Object {
|
|
588
|
+
"$type": "app.bsky.graph.defs#relationship",
|
|
589
|
+
"did": "user(2)",
|
|
590
|
+
"following": "record(2)",
|
|
591
|
+
},
|
|
592
|
+
Object {
|
|
593
|
+
"$type": "app.bsky.graph.defs#notFoundActor",
|
|
594
|
+
"actor": "did:example:fake",
|
|
595
|
+
"notFound": true,
|
|
596
|
+
},
|
|
597
|
+
],
|
|
598
|
+
}
|
|
599
|
+
`;
|
|
@@ -294,4 +294,14 @@ describe('pds follow views', () => {
|
|
|
294
294
|
},
|
|
295
295
|
)
|
|
296
296
|
})
|
|
297
|
+
|
|
298
|
+
it('fetches relationships between users', async () => {
|
|
299
|
+
const res = await agent.api.app.bsky.graph.getRelationships({
|
|
300
|
+
actor: sc.dids.bob,
|
|
301
|
+
others: [sc.dids.alice, sc.dids.bob, sc.dids.carol, 'did:example:fake'],
|
|
302
|
+
})
|
|
303
|
+
expect(res.data.actor).toEqual(sc.dids.bob)
|
|
304
|
+
expect(res.data.relationships.length).toBe(4)
|
|
305
|
+
expect(forSnapshot(res.data)).toMatchSnapshot()
|
|
306
|
+
})
|
|
297
307
|
})
|
|
@@ -96,4 +96,26 @@ describe('pds user search views', () => {
|
|
|
96
96
|
authed.actors.map(stripViewer),
|
|
97
97
|
)
|
|
98
98
|
})
|
|
99
|
+
|
|
100
|
+
it('returns tagged suggestions', async () => {
|
|
101
|
+
const suggestions = [
|
|
102
|
+
{
|
|
103
|
+
tag: 'test',
|
|
104
|
+
subject: 'did:example:test',
|
|
105
|
+
subjectType: 'actor',
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
tag: 'another',
|
|
109
|
+
subject: 'at://did:example:another/app.bsky.feed.generator/my-feed',
|
|
110
|
+
subjectType: 'feed',
|
|
111
|
+
},
|
|
112
|
+
]
|
|
113
|
+
await network.bsky.ctx.db
|
|
114
|
+
.getPrimary()
|
|
115
|
+
.db.insertInto('tagged_suggestion')
|
|
116
|
+
.values(suggestions)
|
|
117
|
+
.execute()
|
|
118
|
+
const res = await agent.api.app.bsky.unspecced.getTaggedSuggestions()
|
|
119
|
+
expect(res.data.suggestions).toEqual(suggestions)
|
|
120
|
+
})
|
|
99
121
|
})
|