@atproto/bsky 0.0.277 → 0.0.279
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 +65 -0
- package/dist/api/app/bsky/actor/getSuggestions.d.ts.map +1 -1
- package/dist/api/app/bsky/actor/getSuggestions.js +5 -5
- package/dist/api/app/bsky/actor/getSuggestions.js.map +1 -1
- package/dist/api/app/bsky/actor/searchActors.d.ts.map +1 -1
- package/dist/api/app/bsky/actor/searchActors.js +3 -2
- package/dist/api/app/bsky/actor/searchActors.js.map +1 -1
- package/dist/api/app/bsky/actor/searchActorsTypeahead.d.ts.map +1 -1
- package/dist/api/app/bsky/actor/searchActorsTypeahead.js +3 -2
- package/dist/api/app/bsky/actor/searchActorsTypeahead.js.map +1 -1
- package/dist/api/app/bsky/feed/getAuthorFeed.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getAuthorFeed.js +2 -4
- package/dist/api/app/bsky/feed/getAuthorFeed.js.map +1 -1
- package/dist/api/app/bsky/feed/getFeed.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getFeed.js +10 -10
- package/dist/api/app/bsky/feed/getFeed.js.map +1 -1
- package/dist/api/app/bsky/feed/getTimeline.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getTimeline.js +2 -4
- package/dist/api/app/bsky/feed/getTimeline.js.map +1 -1
- package/dist/api/app/bsky/feed/searchPosts.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/searchPosts.js +3 -2
- package/dist/api/app/bsky/feed/searchPosts.js.map +1 -1
- package/dist/api/app/bsky/graph/getList.js +4 -1
- package/dist/api/app/bsky/graph/getList.js.map +1 -1
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js +5 -5
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js.map +1 -1
- package/dist/api/app/bsky/graph/searchStarterPacks.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/searchStarterPacks.js +3 -2
- package/dist/api/app/bsky/graph/searchStarterPacks.js.map +1 -1
- package/dist/api/app/bsky/notification/getUnreadCount.js +0 -8
- package/dist/api/app/bsky/notification/getUnreadCount.js.map +1 -1
- package/dist/api/app/bsky/notification/listNotifications.d.ts.map +1 -1
- package/dist/api/app/bsky/notification/listNotifications.js +22 -20
- package/dist/api/app/bsky/notification/listNotifications.js.map +1 -1
- package/dist/api/app/bsky/notification/updateSeen.d.ts.map +1 -1
- package/dist/api/app/bsky/notification/updateSeen.js +2 -11
- package/dist/api/app/bsky/notification/updateSeen.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js +5 -5
- package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedFeeds.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedFeeds.js +5 -4
- package/dist/api/app/bsky/unspecced/getSuggestedFeeds.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js +5 -4
- package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js +5 -4
- package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsers.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsers.js +6 -4
- package/dist/api/app/bsky/unspecced/getSuggestedUsers.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.js +4 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.js +4 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.js +4 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getTrendingTopics.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getTrendingTopics.js +3 -1
- package/dist/api/app/bsky/unspecced/getTrendingTopics.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getTrends.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getTrends.js +5 -4
- package/dist/api/app/bsky/unspecced/getTrends.js.map +1 -1
- package/dist/api/blob-dispatcher.d.ts.map +1 -1
- package/dist/api/blob-dispatcher.js +1 -0
- package/dist/api/blob-dispatcher.js.map +1 -1
- package/dist/api/util.d.ts.map +1 -1
- package/dist/api/util.js +4 -1
- package/dist/api/util.js.map +1 -1
- package/dist/bsync.d.ts.map +1 -1
- package/dist/bsync.js +18 -1
- package/dist/bsync.js.map +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +13 -1
- package/dist/config.js.map +1 -1
- package/dist/data-plane/client/index.d.ts.map +1 -1
- package/dist/data-plane/client/index.js +3 -2
- package/dist/data-plane/client/index.js.map +1 -1
- package/dist/data-plane/client/util.d.ts +0 -1
- package/dist/data-plane/client/util.d.ts.map +1 -1
- package/dist/data-plane/client/util.js +0 -45
- package/dist/data-plane/client/util.js.map +1 -1
- package/dist/data-plane/server/db/database-schema.d.ts +2 -1
- package/dist/data-plane/server/db/database-schema.d.ts.map +1 -1
- package/dist/data-plane/server/db/database-schema.js.map +1 -1
- package/dist/data-plane/server/db/migrations/20260827T200000000Z-reference-list-opt-outs.d.ts +4 -0
- package/dist/data-plane/server/db/migrations/20260827T200000000Z-reference-list-opt-outs.d.ts.map +1 -0
- package/dist/data-plane/server/db/migrations/20260827T200000000Z-reference-list-opt-outs.js +24 -0
- package/dist/data-plane/server/db/migrations/20260827T200000000Z-reference-list-opt-outs.js.map +1 -0
- package/dist/data-plane/server/db/migrations/20260904T130000000Z-remove-last-seen-priority-notifs.d.ts +4 -0
- package/dist/data-plane/server/db/migrations/20260904T130000000Z-remove-last-seen-priority-notifs.d.ts.map +1 -0
- package/dist/data-plane/server/db/migrations/20260904T130000000Z-remove-last-seen-priority-notifs.js +13 -0
- package/dist/data-plane/server/db/migrations/20260904T130000000Z-remove-last-seen-priority-notifs.js.map +1 -0
- package/dist/data-plane/server/db/migrations/index.d.ts +2 -0
- package/dist/data-plane/server/db/migrations/index.d.ts.map +1 -1
- package/dist/data-plane/server/db/migrations/index.js +2 -0
- package/dist/data-plane/server/db/migrations/index.js.map +1 -1
- package/dist/data-plane/server/db/tables/actor-state.d.ts +0 -1
- package/dist/data-plane/server/db/tables/actor-state.d.ts.map +1 -1
- package/dist/data-plane/server/db/tables/actor-state.js.map +1 -1
- package/dist/data-plane/server/db/tables/reference-list-opt-out.d.ts +15 -0
- package/dist/data-plane/server/db/tables/reference-list-opt-out.d.ts.map +1 -0
- package/dist/data-plane/server/db/tables/reference-list-opt-out.js +2 -0
- package/dist/data-plane/server/db/tables/reference-list-opt-out.js.map +1 -0
- package/dist/data-plane/server/indexing/index.d.ts +10 -0
- package/dist/data-plane/server/indexing/index.d.ts.map +1 -1
- package/dist/data-plane/server/indexing/index.js +6 -0
- package/dist/data-plane/server/indexing/index.js.map +1 -1
- package/dist/data-plane/server/indexing/plugins/reference-list-opt-out.d.ts +16 -0
- package/dist/data-plane/server/indexing/plugins/reference-list-opt-out.d.ts.map +1 -0
- package/dist/data-plane/server/indexing/plugins/reference-list-opt-out.js +73 -0
- package/dist/data-plane/server/indexing/plugins/reference-list-opt-out.js.map +1 -0
- package/dist/data-plane/server/indexing/processor.d.ts +1 -0
- package/dist/data-plane/server/indexing/processor.d.ts.map +1 -1
- package/dist/data-plane/server/indexing/processor.js +3 -0
- package/dist/data-plane/server/indexing/processor.js.map +1 -1
- package/dist/data-plane/server/routes/feeds.d.ts.map +1 -1
- package/dist/data-plane/server/routes/feeds.js +13 -0
- package/dist/data-plane/server/routes/feeds.js.map +1 -1
- package/dist/data-plane/server/routes/lists.d.ts.map +1 -1
- package/dist/data-plane/server/routes/lists.js +45 -1
- package/dist/data-plane/server/routes/lists.js.map +1 -1
- package/dist/data-plane/server/routes/notifs.d.ts.map +1 -1
- package/dist/data-plane/server/routes/notifs.js +10 -32
- package/dist/data-plane/server/routes/notifs.js.map +1 -1
- package/dist/data-plane/server/util.d.ts +4 -4
- package/dist/hydration/actor.d.ts.map +1 -1
- package/dist/hydration/actor.js +7 -4
- package/dist/hydration/actor.js.map +1 -1
- package/dist/hydration/graph.d.ts +1 -0
- package/dist/hydration/graph.d.ts.map +1 -1
- package/dist/hydration/graph.js +12 -5
- package/dist/hydration/graph.js.map +1 -1
- package/dist/hydration/hydrator.d.ts +9 -1
- package/dist/hydration/hydrator.d.ts.map +1 -1
- package/dist/hydration/hydrator.js +28 -3
- package/dist/hydration/hydrator.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -2
- package/dist/index.js.map +1 -1
- package/dist/lexicons/app/bsky/actor/defs.defs.d.ts +6 -0
- package/dist/lexicons/app/bsky/actor/defs.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/actor/defs.defs.js +2 -0
- package/dist/lexicons/app/bsky/actor/defs.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/authFullApp.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/authFullApp.defs.js +1 -0
- package/dist/lexicons/app/bsky/authFullApp.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/graph/defs.defs.d.ts +8 -0
- package/dist/lexicons/app/bsky/graph/defs.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/graph/defs.defs.js +3 -0
- package/dist/lexicons/app/bsky/graph/defs.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/graph/referencelistoptout.d.ts +3 -0
- package/dist/lexicons/app/bsky/graph/referencelistoptout.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/graph/referencelistoptout.defs.d.ts +77 -0
- package/dist/lexicons/app/bsky/graph/referencelistoptout.defs.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/graph/referencelistoptout.defs.js +27 -0
- package/dist/lexicons/app/bsky/graph/referencelistoptout.defs.js.map +1 -0
- package/dist/lexicons/app/bsky/graph/referencelistoptout.js +6 -0
- package/dist/lexicons/app/bsky/graph/referencelistoptout.js.map +1 -0
- package/dist/lexicons/app/bsky/graph.d.ts +1 -0
- package/dist/lexicons/app/bsky/graph.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/graph.js +1 -0
- package/dist/lexicons/app/bsky/graph.js.map +1 -1
- package/dist/lexicons/tools/ozone/moderation/getAccountPreferences.d.ts +3 -0
- package/dist/lexicons/tools/ozone/moderation/getAccountPreferences.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/moderation/getAccountPreferences.defs.d.ts +29 -0
- package/dist/lexicons/tools/ozone/moderation/getAccountPreferences.defs.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/moderation/getAccountPreferences.defs.js +19 -0
- package/dist/lexicons/tools/ozone/moderation/getAccountPreferences.defs.js.map +1 -0
- package/dist/lexicons/tools/ozone/moderation/getAccountPreferences.js +6 -0
- package/dist/lexicons/tools/ozone/moderation/getAccountPreferences.js.map +1 -0
- package/dist/lexicons/tools/ozone/moderation.d.ts +1 -0
- package/dist/lexicons/tools/ozone/moderation.d.ts.map +1 -1
- package/dist/lexicons/tools/ozone/moderation.js +1 -0
- package/dist/lexicons/tools/ozone/moderation.js.map +1 -1
- package/dist/logger.d.ts +1 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +1 -0
- package/dist/logger.js.map +1 -1
- package/dist/proto/bsky_connect.d.ts +10 -1
- package/dist/proto/bsky_connect.d.ts.map +1 -1
- package/dist/proto/bsky_connect.js +11 -2
- package/dist/proto/bsky_connect.js.map +1 -1
- package/dist/proto/bsky_pb.d.ts +46 -12
- package/dist/proto/bsky_pb.d.ts.map +1 -1
- package/dist/proto/bsky_pb.js +75 -15
- package/dist/proto/bsky_pb.js.map +1 -1
- package/dist/proto/bsync_connect.d.ts +10 -1
- package/dist/proto/bsync_connect.d.ts.map +1 -1
- package/dist/proto/bsync_connect.js +11 -2
- package/dist/proto/bsync_connect.js.map +1 -1
- package/dist/proto/bsync_pb.d.ts +35 -1
- package/dist/proto/bsync_pb.d.ts.map +1 -1
- package/dist/proto/bsync_pb.js +56 -1
- package/dist/proto/bsync_pb.js.map +1 -1
- package/dist/proto/courier_connect.js +1 -1
- package/dist/proto/courier_connect.js.map +1 -1
- package/dist/proto/dataplane_connect.d.ts +20 -0
- package/dist/proto/dataplane_connect.d.ts.map +1 -0
- package/dist/proto/dataplane_connect.js +24 -0
- package/dist/proto/dataplane_connect.js.map +1 -0
- package/dist/proto/dataplane_pb.d.ts +37 -0
- package/dist/proto/dataplane_pb.d.ts.map +1 -0
- package/dist/proto/dataplane_pb.js +61 -0
- package/dist/proto/dataplane_pb.js.map +1 -0
- package/dist/proto/rolodex_connect.js +1 -1
- package/dist/proto/rolodex_connect.js.map +1 -1
- package/dist/telemetry/events.d.ts +31 -0
- package/dist/telemetry/events.d.ts.map +1 -0
- package/dist/telemetry/events.js +65 -0
- package/dist/telemetry/events.js.map +1 -0
- package/dist/telemetry/rpc.d.ts +21 -0
- package/dist/telemetry/rpc.d.ts.map +1 -0
- package/dist/telemetry/rpc.js +70 -0
- package/dist/telemetry/rpc.js.map +1 -0
- package/dist/{telemetry.d.ts.map → telemetry/telemetry.d.ts.map} +1 -1
- package/dist/{telemetry.js → telemetry/telemetry.js} +1 -1
- package/dist/telemetry/telemetry.js.map +1 -0
- package/dist/telemetry/util.d.ts +14 -0
- package/dist/telemetry/util.d.ts.map +1 -0
- package/dist/telemetry/util.js +23 -0
- package/dist/telemetry/util.js.map +1 -0
- package/dist/undici.d.ts +29 -0
- package/dist/undici.d.ts.map +1 -0
- package/dist/undici.js +43 -0
- package/dist/undici.js.map +1 -0
- package/dist/util/headers.d.ts +5 -0
- package/dist/util/headers.d.ts.map +1 -0
- package/dist/util/headers.js +19 -0
- package/dist/util/headers.js.map +1 -0
- package/dist/util/uris.js +1 -1
- package/dist/util/uris.js.map +1 -1
- package/dist/views/index.d.ts +4 -2
- package/dist/views/index.d.ts.map +1 -1
- package/dist/views/index.js +24 -11
- package/dist/views/index.js.map +1 -1
- package/package.json +24 -19
- package/dist/telemetry.js.map +0 -1
- /package/dist/{telemetry.d.ts → telemetry/telemetry.d.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feeds.d.ts","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/feeds.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"feeds.d.ts","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/feeds.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAE7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;;0BAG9B,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
|
+
import { app } from '../../../lexicons/index.js';
|
|
2
3
|
import { FeedType } from '../../../proto/bsky_pb.js';
|
|
3
4
|
import { TimeCidKeyset, paginate } from '../db/pagination.js';
|
|
4
5
|
export default (db) => ({
|
|
@@ -125,11 +126,23 @@ export default (db) => ({
|
|
|
125
126
|
async getListFeed(req) {
|
|
126
127
|
const { listUri, cursor, limit } = req;
|
|
127
128
|
const { ref } = db.db.dynamic;
|
|
129
|
+
const list = await db.db
|
|
130
|
+
.selectFrom('list')
|
|
131
|
+
.where('uri', '=', listUri)
|
|
132
|
+
.select('purpose')
|
|
133
|
+
.executeTakeFirst();
|
|
128
134
|
let builder = db.db
|
|
129
135
|
.selectFrom('post')
|
|
130
136
|
.selectAll('post')
|
|
131
137
|
.innerJoin('list_item', 'list_item.subjectDid', 'post.creator')
|
|
132
138
|
.where('list_item.listUri', '=', listUri);
|
|
139
|
+
if (list?.purpose === app.bsky.graph.defs.Referencelist) {
|
|
140
|
+
builder = builder.where((eb) => eb.not(eb.exists(eb
|
|
141
|
+
.selectFrom('reference_list_opt_out')
|
|
142
|
+
.select('uri')
|
|
143
|
+
.whereRef('reference_list_opt_out.creator', '=', 'post.creator')
|
|
144
|
+
.where('reference_list_opt_out.subjectUri', '=', listUri))));
|
|
145
|
+
}
|
|
133
146
|
const keyset = new TimeCidKeyset(ref('post.sortAt'), ref('post.cid'));
|
|
134
147
|
builder = paginate(builder, {
|
|
135
148
|
limit,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feeds.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/feeds.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport type { ServiceImpl } from '@connectrpc/connect'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport { FeedType } from '../../../proto/bsky_pb.js'\nimport type { Database } from '../db/index.js'\nimport { TimeCidKeyset, paginate } from '../db/pagination.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getAuthorFeed(req) {\n const { actorDid, limit, cursor, feedType } = req\n const { ref } = db.db.dynamic\n\n // defaults to posts, reposts, and replies\n let builder = db.db\n .selectFrom('feed_item')\n .innerJoin('post', 'post.uri', 'feed_item.postUri')\n .selectAll('feed_item')\n .where('originatorDid', '=', actorDid)\n\n if (feedType === FeedType.POSTS_WITH_MEDIA) {\n builder = builder\n // only your own posts\n .where('type', '=', 'post')\n // only posts with media\n .where((eb) =>\n eb.or([\n eb.exists(\n eb\n .selectFrom('post_embed_image')\n .select('post_embed_image.postUri')\n .whereRef('post_embed_image.postUri', '=', 'feed_item.postUri'),\n ),\n eb.exists(\n eb\n .selectFrom('post_embed_gallery_image')\n .select('post_embed_gallery_image.postUri')\n .whereRef(\n 'post_embed_gallery_image.postUri',\n '=',\n 'feed_item.postUri',\n ),\n ),\n ]),\n )\n } else if (feedType === FeedType.POSTS_WITH_VIDEO) {\n builder = builder\n // only your own posts\n .where('type', '=', 'post')\n // only posts with video\n .where(({ eb, exists }) =>\n exists(\n eb\n .selectFrom('post_embed_video')\n .select('post_embed_video.postUri')\n .whereRef('post_embed_video.postUri', '=', 'feed_item.postUri'),\n ),\n )\n } else if (feedType === FeedType.POSTS_NO_REPLIES) {\n builder = builder.where((eb) =>\n eb.or([eb('post.replyParent', 'is', null), eb('type', '=', 'repost')]),\n )\n } else if (feedType === FeedType.POSTS_AND_AUTHOR_THREADS) {\n builder = builder.where((eb) =>\n eb.or([\n eb('type', '=', 'repost'),\n eb('post.replyParent', 'is', null),\n eb('post.replyRoot', 'like', `at://${actorDid}/%`),\n ]),\n )\n }\n\n const keyset = new TimeCidKeyset(\n ref('feed_item.sortAt'),\n ref('feed_item.cid'),\n )\n\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n })\n\n const page = keyset.page(await builder.execute(), limit)\n\n return {\n items: page.items.map(feedItemFromRow),\n cursor: page.cursor,\n }\n },\n\n async getTimeline(req) {\n const { actorDid, limit, cursor } = req\n const { ref } = db.db.dynamic\n\n const keyset = new TimeCidKeyset(\n ref('feed_item.sortAt'),\n ref('feed_item.cid'),\n )\n\n let followQb = db.db\n .selectFrom('feed_item')\n .innerJoin('follow', 'follow.subjectDid', 'feed_item.originatorDid')\n .where('follow.creator', '=', actorDid)\n .selectAll('feed_item')\n\n followQb = paginate(followQb, {\n limit,\n cursor,\n keyset,\n tryIndex: true,\n })\n\n let selfQb = db.db\n .selectFrom('feed_item')\n .where('feed_item.originatorDid', '=', actorDid)\n .selectAll('feed_item')\n\n selfQb = paginate(selfQb, {\n limit,\n cursor,\n keyset,\n tryIndex: true,\n })\n\n const [followRes, selfRes] = await Promise.all([\n followQb.execute(),\n selfQb.execute(),\n ])\n\n // Use own posts to fill space left by followed-account posts. When followed-account\n // posts already fill the page, still allow up to 10 own posts into the merged results.\n const selfLimit = Math.max(\n // Allow up to 10 own posts even when followed-account posts can fill the page.\n Math.min(limit, 10),\n // Allow enough own posts to fill the slots not occupied by followed-account posts.\n limit - Math.min(followRes.length, limit),\n )\n\n // The extra own post proves that another page exists, but is not part of this page.\n const selfHasMore = selfRes.length > selfLimit\n\n const selfItems = selfRes.slice(0, selfLimit)\n const feedItems = [...followRes, ...selfItems].sort((a, b) => {\n if (a.sortAt > b.sortAt) return -1\n if (a.sortAt < b.sortAt) return 1\n return a.cid > b.cid ? -1 : 1\n })\n\n const page = keyset.page(feedItems, limit)\n if (page.items.length === 0) {\n return { items: [], cursor: undefined }\n }\n const items = page.items.map(feedItemFromRow)\n\n // The combined results exceeded the requested limit.\n if (page.cursor) {\n return { items, cursor: page.cursor }\n }\n\n // Own posts exceeded their separate cap, but the combined results did not exceed the requested limit.\n if (selfHasMore) {\n const lastItem = page.items.at(-1)\n assert(lastItem)\n return { items, cursor: keyset.packFromResult(lastItem) }\n }\n\n return { items, cursor: undefined }\n },\n\n async getListFeed(req) {\n const { listUri, cursor, limit } = req\n const { ref } = db.db.dynamic\n\n let builder = db.db\n .selectFrom('post')\n .selectAll('post')\n .innerJoin('list_item', 'list_item.subjectDid', 'post.creator')\n .where('list_item.listUri', '=', listUri)\n\n const keyset = new TimeCidKeyset(ref('post.sortAt'), ref('post.cid'))\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n tryIndex: true,\n })\n const page = keyset.page(await builder.execute(), limit)\n\n return {\n items: page.items.map((item) => ({ uri: item.uri, cid: item.cid })),\n cursor: page.cursor,\n }\n },\n})\n\n// @NOTE does not support additional fields in the protos specific to author feeds\n// and timelines. at the time of writing, hydration/view implementations do not rely on them.\nconst feedItemFromRow = (row: { postUri: string; uri: string }) => {\n return {\n uri: row.postUri,\n repost: row.uri === row.postUri ? undefined : row.uri,\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"feeds.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/feeds.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport type { ServiceImpl } from '@connectrpc/connect'\nimport { app } from '../../../lexicons/index.js'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport { FeedType } from '../../../proto/bsky_pb.js'\nimport type { Database } from '../db/index.js'\nimport { TimeCidKeyset, paginate } from '../db/pagination.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getAuthorFeed(req) {\n const { actorDid, limit, cursor, feedType } = req\n const { ref } = db.db.dynamic\n\n // defaults to posts, reposts, and replies\n let builder = db.db\n .selectFrom('feed_item')\n .innerJoin('post', 'post.uri', 'feed_item.postUri')\n .selectAll('feed_item')\n .where('originatorDid', '=', actorDid)\n\n if (feedType === FeedType.POSTS_WITH_MEDIA) {\n builder = builder\n // only your own posts\n .where('type', '=', 'post')\n // only posts with media\n .where((eb) =>\n eb.or([\n eb.exists(\n eb\n .selectFrom('post_embed_image')\n .select('post_embed_image.postUri')\n .whereRef('post_embed_image.postUri', '=', 'feed_item.postUri'),\n ),\n eb.exists(\n eb\n .selectFrom('post_embed_gallery_image')\n .select('post_embed_gallery_image.postUri')\n .whereRef(\n 'post_embed_gallery_image.postUri',\n '=',\n 'feed_item.postUri',\n ),\n ),\n ]),\n )\n } else if (feedType === FeedType.POSTS_WITH_VIDEO) {\n builder = builder\n // only your own posts\n .where('type', '=', 'post')\n // only posts with video\n .where(({ eb, exists }) =>\n exists(\n eb\n .selectFrom('post_embed_video')\n .select('post_embed_video.postUri')\n .whereRef('post_embed_video.postUri', '=', 'feed_item.postUri'),\n ),\n )\n } else if (feedType === FeedType.POSTS_NO_REPLIES) {\n builder = builder.where((eb) =>\n eb.or([eb('post.replyParent', 'is', null), eb('type', '=', 'repost')]),\n )\n } else if (feedType === FeedType.POSTS_AND_AUTHOR_THREADS) {\n builder = builder.where((eb) =>\n eb.or([\n eb('type', '=', 'repost'),\n eb('post.replyParent', 'is', null),\n eb('post.replyRoot', 'like', `at://${actorDid}/%`),\n ]),\n )\n }\n\n const keyset = new TimeCidKeyset(\n ref('feed_item.sortAt'),\n ref('feed_item.cid'),\n )\n\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n })\n\n const page = keyset.page(await builder.execute(), limit)\n\n return {\n items: page.items.map(feedItemFromRow),\n cursor: page.cursor,\n }\n },\n\n async getTimeline(req) {\n const { actorDid, limit, cursor } = req\n const { ref } = db.db.dynamic\n\n const keyset = new TimeCidKeyset(\n ref('feed_item.sortAt'),\n ref('feed_item.cid'),\n )\n\n let followQb = db.db\n .selectFrom('feed_item')\n .innerJoin('follow', 'follow.subjectDid', 'feed_item.originatorDid')\n .where('follow.creator', '=', actorDid)\n .selectAll('feed_item')\n\n followQb = paginate(followQb, {\n limit,\n cursor,\n keyset,\n tryIndex: true,\n })\n\n let selfQb = db.db\n .selectFrom('feed_item')\n .where('feed_item.originatorDid', '=', actorDid)\n .selectAll('feed_item')\n\n selfQb = paginate(selfQb, {\n limit,\n cursor,\n keyset,\n tryIndex: true,\n })\n\n const [followRes, selfRes] = await Promise.all([\n followQb.execute(),\n selfQb.execute(),\n ])\n\n // Use own posts to fill space left by followed-account posts. When followed-account\n // posts already fill the page, still allow up to 10 own posts into the merged results.\n const selfLimit = Math.max(\n // Allow up to 10 own posts even when followed-account posts can fill the page.\n Math.min(limit, 10),\n // Allow enough own posts to fill the slots not occupied by followed-account posts.\n limit - Math.min(followRes.length, limit),\n )\n\n // The extra own post proves that another page exists, but is not part of this page.\n const selfHasMore = selfRes.length > selfLimit\n\n const selfItems = selfRes.slice(0, selfLimit)\n const feedItems = [...followRes, ...selfItems].sort((a, b) => {\n if (a.sortAt > b.sortAt) return -1\n if (a.sortAt < b.sortAt) return 1\n return a.cid > b.cid ? -1 : 1\n })\n\n const page = keyset.page(feedItems, limit)\n if (page.items.length === 0) {\n return { items: [], cursor: undefined }\n }\n const items = page.items.map(feedItemFromRow)\n\n // The combined results exceeded the requested limit.\n if (page.cursor) {\n return { items, cursor: page.cursor }\n }\n\n // Own posts exceeded their separate cap, but the combined results did not exceed the requested limit.\n if (selfHasMore) {\n const lastItem = page.items.at(-1)\n assert(lastItem)\n return { items, cursor: keyset.packFromResult(lastItem) }\n }\n\n return { items, cursor: undefined }\n },\n\n async getListFeed(req) {\n const { listUri, cursor, limit } = req\n const { ref } = db.db.dynamic\n const list = await db.db\n .selectFrom('list')\n .where('uri', '=', listUri)\n .select('purpose')\n .executeTakeFirst()\n\n let builder = db.db\n .selectFrom('post')\n .selectAll('post')\n .innerJoin('list_item', 'list_item.subjectDid', 'post.creator')\n .where('list_item.listUri', '=', listUri)\n\n if (list?.purpose === app.bsky.graph.defs.Referencelist) {\n builder = builder.where((eb) =>\n eb.not(\n eb.exists(\n eb\n .selectFrom('reference_list_opt_out')\n .select('uri')\n .whereRef('reference_list_opt_out.creator', '=', 'post.creator')\n .where('reference_list_opt_out.subjectUri', '=', listUri),\n ),\n ),\n )\n }\n\n const keyset = new TimeCidKeyset(ref('post.sortAt'), ref('post.cid'))\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n tryIndex: true,\n })\n const page = keyset.page(await builder.execute(), limit)\n\n return {\n items: page.items.map((item) => ({ uri: item.uri, cid: item.cid })),\n cursor: page.cursor,\n }\n },\n})\n\n// @NOTE does not support additional fields in the protos specific to author feeds\n// and timelines. at the time of writing, hydration/view implementations do not rely on them.\nconst feedItemFromRow = (row: { postUri: string; uri: string }) => {\n return {\n uri: row.postUri,\n repost: row.uri === row.postUri ? undefined : row.uri,\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lists.d.ts","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/lists.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"lists.d.ts","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/lists.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAGtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;;0BAI9B,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { keyBy } from '@atproto/common';
|
|
2
|
+
import { app } from '../../../lexicons/index.js';
|
|
2
3
|
import { TimeCidKeyset, paginate } from '../db/pagination.js';
|
|
3
4
|
import { countAll } from '../db/util.js';
|
|
4
5
|
export default (db) => ({
|
|
@@ -23,12 +24,26 @@ export default (db) => ({
|
|
|
23
24
|
};
|
|
24
25
|
},
|
|
25
26
|
async getListMembers(req) {
|
|
26
|
-
const { listUri, cursor, limit } = req;
|
|
27
|
+
const { listUri, cursor, limit, viewerDid } = req;
|
|
27
28
|
const { ref } = db.db.dynamic;
|
|
29
|
+
const list = await db.db
|
|
30
|
+
.selectFrom('list')
|
|
31
|
+
.where('uri', '=', listUri)
|
|
32
|
+
.select(['creator', 'purpose'])
|
|
33
|
+
.executeTakeFirst();
|
|
34
|
+
const isReferenceList = list?.purpose === app.bsky.graph.defs.Referencelist;
|
|
35
|
+
const isOwner = isReferenceList && list.creator === viewerDid;
|
|
28
36
|
let builder = db.db
|
|
29
37
|
.selectFrom('list_item')
|
|
30
38
|
.where('listUri', '=', listUri)
|
|
31
39
|
.selectAll();
|
|
40
|
+
if (isReferenceList && !isOwner) {
|
|
41
|
+
builder = builder.where((eb) => eb.not(eb.exists(eb
|
|
42
|
+
.selectFrom('reference_list_opt_out')
|
|
43
|
+
.select('uri')
|
|
44
|
+
.whereRef('reference_list_opt_out.creator', '=', 'list_item.subjectDid')
|
|
45
|
+
.where('reference_list_opt_out.subjectUri', '=', listUri))));
|
|
46
|
+
}
|
|
32
47
|
const keyset = new TimeCidKeyset(ref('list_item.sortAt'), ref('list_item.cid'));
|
|
33
48
|
builder = paginate(builder, {
|
|
34
49
|
limit,
|
|
@@ -37,10 +52,21 @@ export default (db) => ({
|
|
|
37
52
|
tryIndex: true,
|
|
38
53
|
});
|
|
39
54
|
const page = keyset.page(await builder.execute(), limit);
|
|
55
|
+
const optedOut = new Set();
|
|
56
|
+
if (isOwner && page.items.length > 0) {
|
|
57
|
+
const rows = await db.db
|
|
58
|
+
.selectFrom('reference_list_opt_out')
|
|
59
|
+
.where('creator', 'in', page.items.map((item) => item.subjectDid))
|
|
60
|
+
.where('subjectUri', '=', listUri)
|
|
61
|
+
.select('creator')
|
|
62
|
+
.execute();
|
|
63
|
+
rows.forEach((row) => optedOut.add(row.creator));
|
|
64
|
+
}
|
|
40
65
|
return {
|
|
41
66
|
listitems: page.items.map((item) => ({
|
|
42
67
|
uri: item.uri,
|
|
43
68
|
did: item.subjectDid,
|
|
69
|
+
subjectOptedOut: optedOut.has(item.subjectDid),
|
|
44
70
|
})),
|
|
45
71
|
cursor: page.cursor,
|
|
46
72
|
};
|
|
@@ -72,5 +98,23 @@ export default (db) => ({
|
|
|
72
98
|
count: res?.count,
|
|
73
99
|
};
|
|
74
100
|
},
|
|
101
|
+
async getReferencelistoptoutsByActorAndSubjects(req) {
|
|
102
|
+
const { actorDid, subjectUris } = req;
|
|
103
|
+
if (subjectUris.length === 0)
|
|
104
|
+
return { uris: [] };
|
|
105
|
+
const rows = await db.db
|
|
106
|
+
.selectFrom('reference_list_opt_out')
|
|
107
|
+
.innerJoin('list', 'list.uri', 'reference_list_opt_out.subjectUri')
|
|
108
|
+
.where('reference_list_opt_out.creator', '=', actorDid)
|
|
109
|
+
.where('reference_list_opt_out.subjectUri', 'in', subjectUris)
|
|
110
|
+
.where('list.purpose', '=', app.bsky.graph.defs.Referencelist)
|
|
111
|
+
.select([
|
|
112
|
+
'reference_list_opt_out.subjectUri as subjectUri',
|
|
113
|
+
'reference_list_opt_out.uri as uri',
|
|
114
|
+
])
|
|
115
|
+
.execute();
|
|
116
|
+
const bySubject = keyBy(rows, 'subjectUri');
|
|
117
|
+
return { uris: subjectUris.map((uri) => bySubject.get(uri)?.uri ?? '') };
|
|
118
|
+
},
|
|
75
119
|
});
|
|
76
120
|
//# sourceMappingURL=lists.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lists.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/lists.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"lists.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/lists.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ServiceImpl } from '@connectrpc/connect'\nimport { keyBy } from '@atproto/common'\nimport { app } from '../../../lexicons/index.js'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport type { Database } from '../db/index.js'\nimport { TimeCidKeyset, paginate } from '../db/pagination.js'\nimport { countAll } from '../db/util.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getActorLists(req) {\n const { actorDid, cursor, limit } = req\n const { ref } = db.db.dynamic\n let builder = db.db\n .selectFrom('list')\n .where('creator', '=', actorDid)\n .selectAll()\n const keyset = new TimeCidKeyset(ref('list.sortAt'), ref('list.cid'))\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n tryIndex: true,\n })\n const page = keyset.page(await builder.execute(), limit)\n return {\n listUris: page.items.map((item) => item.uri),\n cursor: page.cursor,\n }\n },\n\n async getListMembers(req) {\n const { listUri, cursor, limit, viewerDid } = req\n const { ref } = db.db.dynamic\n const list = await db.db\n .selectFrom('list')\n .where('uri', '=', listUri)\n .select(['creator', 'purpose'])\n .executeTakeFirst()\n const isReferenceList = list?.purpose === app.bsky.graph.defs.Referencelist\n const isOwner = isReferenceList && list.creator === viewerDid\n let builder = db.db\n .selectFrom('list_item')\n .where('listUri', '=', listUri)\n .selectAll()\n\n if (isReferenceList && !isOwner) {\n builder = builder.where((eb) =>\n eb.not(\n eb.exists(\n eb\n .selectFrom('reference_list_opt_out')\n .select('uri')\n .whereRef(\n 'reference_list_opt_out.creator',\n '=',\n 'list_item.subjectDid',\n )\n .where('reference_list_opt_out.subjectUri', '=', listUri),\n ),\n ),\n )\n }\n\n const keyset = new TimeCidKeyset(\n ref('list_item.sortAt'),\n ref('list_item.cid'),\n )\n\n builder = paginate(builder, {\n limit,\n cursor,\n keyset,\n tryIndex: true,\n })\n\n const page = keyset.page(await builder.execute(), limit)\n const optedOut = new Set<string>()\n if (isOwner && page.items.length > 0) {\n const rows = await db.db\n .selectFrom('reference_list_opt_out')\n .where(\n 'creator',\n 'in',\n page.items.map((item) => item.subjectDid),\n )\n .where('subjectUri', '=', listUri)\n .select('creator')\n .execute()\n rows.forEach((row) => optedOut.add(row.creator))\n }\n return {\n listitems: page.items.map((item) => ({\n uri: item.uri,\n did: item.subjectDid,\n subjectOptedOut: optedOut.has(item.subjectDid),\n })),\n cursor: page.cursor,\n }\n },\n\n async getListMembership(req) {\n const { actorDid, listUris } = req\n if (listUris.length === 0) {\n return { listitemUris: [] }\n }\n const res = await db.db\n .selectFrom('list_item')\n .where('subjectDid', '=', actorDid)\n .where('listUri', 'in', listUris)\n .selectAll()\n .execute()\n const byListUri = keyBy(res, 'listUri')\n const listitemUris = listUris.map((uri) => byListUri.get(uri)?.uri ?? '')\n return {\n listitemUris,\n }\n },\n\n async getListCount(req) {\n const res = await db.db\n .selectFrom('list_item')\n .select(countAll.as('count'))\n .where('list_item.listUri', '=', req.listUri)\n .executeTakeFirst()\n return {\n count: res?.count,\n }\n },\n\n async getReferencelistoptoutsByActorAndSubjects(req) {\n const { actorDid, subjectUris } = req\n if (subjectUris.length === 0) return { uris: [] }\n const rows = await db.db\n .selectFrom('reference_list_opt_out')\n .innerJoin('list', 'list.uri', 'reference_list_opt_out.subjectUri')\n .where('reference_list_opt_out.creator', '=', actorDid)\n .where('reference_list_opt_out.subjectUri', 'in', subjectUris)\n .where('list.purpose', '=', app.bsky.graph.defs.Referencelist)\n .select([\n 'reference_list_opt_out.subjectUri as subjectUri',\n 'reference_list_opt_out.uri as uri',\n ])\n .execute()\n const bySubject = keyBy(rows, 'subjectUri')\n return { uris: subjectUris.map((uri) => bySubject.get(uri)?.uri ?? '') }\n },\n})\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifs.d.ts","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/notifs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAItD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,4BAA4B,CAAA;AACrD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAC7D,OAAO,EAIL,uBAAuB,EACxB,MAAM,2BAA2B,CAAA;AAElC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;;0BAI9B,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"notifs.d.ts","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/notifs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAItD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,4BAA4B,CAAA;AACrD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAC7D,OAAO,EAIL,uBAAuB,EACxB,MAAM,2BAA2B,CAAA;AAElC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;;0BAI9B,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC;AA0JnE,eAAO,MAAM,oCAAoC,MAC5C,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,QACnC,MAAM,KACX,uBAoCF,CAAA"}
|
|
@@ -56,7 +56,7 @@ export default (db) => ({
|
|
|
56
56
|
};
|
|
57
57
|
},
|
|
58
58
|
async getNotificationSeen(req) {
|
|
59
|
-
const { actorDid
|
|
59
|
+
const { actorDid } = req;
|
|
60
60
|
const res = await db.db
|
|
61
61
|
.selectFrom('actor_state')
|
|
62
62
|
.where('did', '=', actorDid)
|
|
@@ -65,24 +65,19 @@ export default (db) => ({
|
|
|
65
65
|
if (!res) {
|
|
66
66
|
return {};
|
|
67
67
|
}
|
|
68
|
-
const lastSeen = priority && res.lastSeenPriorityNotifs
|
|
69
|
-
? res.lastSeenPriorityNotifs
|
|
70
|
-
: res.lastSeenNotifs;
|
|
71
68
|
return {
|
|
72
|
-
timestamp: Timestamp.fromDate(new Date(
|
|
69
|
+
timestamp: Timestamp.fromDate(new Date(res.lastSeenNotifs)),
|
|
73
70
|
};
|
|
74
71
|
},
|
|
75
72
|
async getUnreadNotificationCount(req) {
|
|
76
|
-
const { actorDid
|
|
73
|
+
const { actorDid } = req;
|
|
77
74
|
const { ref } = db.db.dynamic;
|
|
78
75
|
const lastSeenRes = await db.db
|
|
79
76
|
.selectFrom('actor_state')
|
|
80
77
|
.where('did', '=', actorDid)
|
|
81
78
|
.selectAll()
|
|
82
79
|
.executeTakeFirst();
|
|
83
|
-
const lastSeen =
|
|
84
|
-
? lastSeenRes.lastSeenPriorityNotifs
|
|
85
|
-
: lastSeenRes?.lastSeenNotifs;
|
|
80
|
+
const lastSeen = lastSeenRes?.lastSeenNotifs;
|
|
86
81
|
const result = await db.db
|
|
87
82
|
.selectFrom('notification')
|
|
88
83
|
.select(countAll.as('count'))
|
|
@@ -94,45 +89,28 @@ export default (db) => ({
|
|
|
94
89
|
// Ensure to hit notification_did_sortat_idx, handling case where lastSeenNotifs is null.
|
|
95
90
|
.where('notification.did', '=', actorDid)
|
|
96
91
|
.where('notification.sortAt', '>', lastSeen ?? '')
|
|
97
|
-
.$if(priority, (qb) => qb.where(({ exists }) => exists(db.db
|
|
98
|
-
.selectFrom('follow')
|
|
99
|
-
.select(sql `${true}`.as('val'))
|
|
100
|
-
.where('creator', '=', actorDid)
|
|
101
|
-
.whereRef('subjectDid', '=', ref('notification.author')))))
|
|
102
92
|
.executeTakeFirst();
|
|
103
93
|
return {
|
|
104
94
|
count: result?.count,
|
|
105
95
|
};
|
|
106
96
|
},
|
|
107
97
|
async updateNotificationSeen(req) {
|
|
108
|
-
const { actorDid, timestamp
|
|
98
|
+
const { actorDid, timestamp } = req;
|
|
109
99
|
if (!timestamp) {
|
|
110
100
|
return;
|
|
111
101
|
}
|
|
112
102
|
const timestampIso = timestamp.toDate().toISOString();
|
|
113
|
-
|
|
114
|
-
.updateTable('actor_state')
|
|
115
|
-
.where('did', '=', actorDid)
|
|
116
|
-
.returningAll();
|
|
117
|
-
if (priority) {
|
|
118
|
-
builder = builder.set({ lastSeenPriorityNotifs: timestampIso });
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
builder = builder.set({ lastSeenNotifs: timestampIso });
|
|
122
|
-
}
|
|
123
|
-
const updateRes = await builder.executeTakeFirst();
|
|
124
|
-
if (updateRes) {
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
103
|
+
const { ref } = db.db.dynamic;
|
|
127
104
|
await db.db
|
|
128
105
|
.insertInto('actor_state')
|
|
129
106
|
.values({
|
|
130
107
|
did: actorDid,
|
|
131
108
|
lastSeenNotifs: timestampIso,
|
|
132
|
-
priorityNotifs:
|
|
133
|
-
lastSeenPriorityNotifs: priority ? timestampIso : undefined,
|
|
109
|
+
priorityNotifs: false,
|
|
134
110
|
})
|
|
135
|
-
.onConflict((oc) => oc.
|
|
111
|
+
.onConflict((oc) => oc.column('did').doUpdateSet({
|
|
112
|
+
lastSeenNotifs: sql `greatest(${ref('actor_state.lastSeenNotifs')}, ${timestampIso})`,
|
|
113
|
+
}))
|
|
136
114
|
.executeTakeFirst();
|
|
137
115
|
},
|
|
138
116
|
async getNotificationPreferences(req) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifs.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/notifs.ts"],"names":[],"mappings":"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","sourcesContent":["import { Timestamp } from '@bufbuild/protobuf'\nimport type { ServiceImpl } from '@connectrpc/connect'\nimport { sql } from 'kysely'\nimport { keyBy } from '@atproto/common'\nimport { lexParse } from '@atproto/lex'\nimport type { app } from '../../../lexicons/index.js'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport {\n FilterableNotificationPreference,\n NotificationInclude,\n NotificationPreference,\n NotificationPreferences,\n} from '../../../proto/bsky_pb.js'\nimport { Namespaces } from '../../../stash.js'\nimport type { Database } from '../db/index.js'\nimport { IsoSortAtKey } from '../db/pagination.js'\nimport { countAll, notSoftDeletedClause } from '../db/util.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getNotifications(req) {\n const { actorDid, limit, cursor, priority } = req\n const { ref } = db.db.dynamic\n const priorityFollowQb = db.db\n .selectFrom('follow')\n .select(sql<boolean>`${true}`.as('val'))\n .where('creator', '=', actorDid)\n .whereRef('subjectDid', '=', ref('notif.author'))\n .limit(1)\n\n let builder = db.db\n .selectFrom('notification as notif')\n .where('notif.did', '=', actorDid)\n .where((eb) =>\n eb.or([\n eb('reasonSubject', 'is', null),\n eb.exists(\n db.db\n .selectFrom('record as subject')\n .selectAll()\n .whereRef('subject.uri', '=', ref('notif.reasonSubject')),\n ),\n ]),\n )\n .$if(priority, (qb) => qb.where(({ exists }) => exists(priorityFollowQb)))\n .select([\n 'notif.author as authorDid',\n 'notif.recordUri as uri',\n 'notif.recordCid as cid',\n 'notif.reason as reason',\n 'notif.reasonSubject as reasonSubject',\n 'notif.sortAt as sortAt',\n ])\n .select(priorityFollowQb.as('priority'))\n\n const key = new IsoSortAtKey(ref('notif.sortAt'))\n builder = key.paginate(builder, {\n cursor,\n limit,\n })\n\n const page = key.page(await builder.execute(), limit)\n const notifications = page.items.map((notif) => ({\n recipientDid: actorDid,\n uri: notif.uri,\n reason: notif.reason,\n reasonSubject: notif.reasonSubject ?? undefined,\n timestamp: Timestamp.fromDate(new Date(notif.sortAt)),\n priority: notif.priority ?? false,\n }))\n return {\n notifications,\n cursor: page.cursor,\n }\n },\n\n async getNotificationSeen(req) {\n const { actorDid, priority } = req\n const res = await db.db\n .selectFrom('actor_state')\n .where('did', '=', actorDid)\n .selectAll()\n .executeTakeFirst()\n if (!res) {\n return {}\n }\n const lastSeen =\n priority && res.lastSeenPriorityNotifs\n ? res.lastSeenPriorityNotifs\n : res.lastSeenNotifs\n return {\n timestamp: Timestamp.fromDate(new Date(lastSeen)),\n }\n },\n\n async getUnreadNotificationCount(req) {\n const { actorDid, priority } = req\n const { ref } = db.db.dynamic\n const lastSeenRes = await db.db\n .selectFrom('actor_state')\n .where('did', '=', actorDid)\n .selectAll()\n .executeTakeFirst()\n const lastSeen =\n priority && lastSeenRes?.lastSeenPriorityNotifs\n ? lastSeenRes.lastSeenPriorityNotifs\n : lastSeenRes?.lastSeenNotifs\n\n const result = await db.db\n .selectFrom('notification')\n .select(countAll.as('count'))\n .innerJoin('actor', 'actor.did', 'notification.did')\n .leftJoin('actor_state', 'actor_state.did', 'actor.did')\n .innerJoin('record', 'record.uri', 'notification.recordUri')\n .where(notSoftDeletedClause(ref('record')))\n .where(notSoftDeletedClause(ref('actor')))\n // Ensure to hit notification_did_sortat_idx, handling case where lastSeenNotifs is null.\n .where('notification.did', '=', actorDid)\n .where('notification.sortAt', '>', lastSeen ?? '')\n .$if(priority, (qb) =>\n qb.where(({ exists }) =>\n exists(\n db.db\n .selectFrom('follow')\n .select(sql<boolean>`${true}`.as('val'))\n .where('creator', '=', actorDid)\n .whereRef('subjectDid', '=', ref('notification.author')),\n ),\n ),\n )\n .executeTakeFirst()\n\n return {\n count: result?.count,\n }\n },\n\n async updateNotificationSeen(req) {\n const { actorDid, timestamp, priority } = req\n if (!timestamp) {\n return\n }\n const timestampIso = timestamp.toDate().toISOString()\n let builder = db.db\n .updateTable('actor_state')\n .where('did', '=', actorDid)\n .returningAll()\n if (priority) {\n builder = builder.set({ lastSeenPriorityNotifs: timestampIso })\n } else {\n builder = builder.set({ lastSeenNotifs: timestampIso })\n }\n const updateRes = await builder.executeTakeFirst()\n if (updateRes) {\n return\n }\n await db.db\n .insertInto('actor_state')\n .values({\n did: actorDid,\n lastSeenNotifs: timestampIso,\n priorityNotifs: priority,\n lastSeenPriorityNotifs: priority ? timestampIso : undefined,\n })\n .onConflict((oc) => oc.doNothing())\n .executeTakeFirst()\n },\n\n async getNotificationPreferences(req) {\n const { dids } = req\n if (dids.length === 0) {\n return { preferences: [] }\n }\n\n const res = await db.db\n .selectFrom('private_data')\n .selectAll()\n .where('actorDid', 'in', dids)\n .where(\n 'namespace',\n '=',\n Namespaces.AppBskyNotificationDefsPreferences.$type,\n )\n .where('key', '=', 'self')\n .execute()\n\n const byDid = keyBy(res, 'actorDid')\n const preferences = dids.map((did) => {\n const row = byDid.get(did)\n if (!row) {\n return {}\n }\n const p = lexParse<app.bsky.notification.defs.Preferences>(row.payload)\n return notificationPreferencesLexToProtobuf(p, row.payload)\n })\n\n return { preferences }\n },\n})\n\nexport const notificationPreferencesLexToProtobuf = (\n p: app.bsky.notification.defs.Preferences,\n json: string,\n): NotificationPreferences => {\n const lexFilterablePreferenceToProtobuf = (\n p: app.bsky.notification.defs.FilterablePreference,\n ): FilterableNotificationPreference =>\n new FilterableNotificationPreference({\n include:\n p.include === 'follows'\n ? NotificationInclude.FOLLOWS\n : NotificationInclude.ALL,\n list: { enabled: p.list ?? true },\n push: { enabled: p.push ?? true },\n })\n\n const lexPreferenceToProtobuf = (\n p: app.bsky.notification.defs.Preference,\n ): NotificationPreference =>\n new NotificationPreference({\n list: { enabled: p.list ?? true },\n push: { enabled: p.push ?? true },\n })\n\n return new NotificationPreferences({\n entry: Buffer.from(json),\n follow: lexFilterablePreferenceToProtobuf(p.follow),\n like: lexFilterablePreferenceToProtobuf(p.like),\n likeViaRepost: lexFilterablePreferenceToProtobuf(p.likeViaRepost),\n mention: lexFilterablePreferenceToProtobuf(p.mention),\n quote: lexFilterablePreferenceToProtobuf(p.quote),\n reply: lexFilterablePreferenceToProtobuf(p.reply),\n repost: lexFilterablePreferenceToProtobuf(p.repost),\n repostViaRepost: lexFilterablePreferenceToProtobuf(p.repostViaRepost),\n starterpackJoined: lexPreferenceToProtobuf(p.starterpackJoined),\n subscribedPost: lexPreferenceToProtobuf(p.subscribedPost),\n unverified: lexPreferenceToProtobuf(p.unverified),\n verified: lexPreferenceToProtobuf(p.verified),\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"notifs.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/notifs.ts"],"names":[],"mappings":"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","sourcesContent":["import { Timestamp } from '@bufbuild/protobuf'\nimport type { ServiceImpl } from '@connectrpc/connect'\nimport { sql } from 'kysely'\nimport { keyBy } from '@atproto/common'\nimport { lexParse } from '@atproto/lex'\nimport type { app } from '../../../lexicons/index.js'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport {\n FilterableNotificationPreference,\n NotificationInclude,\n NotificationPreference,\n NotificationPreferences,\n} from '../../../proto/bsky_pb.js'\nimport { Namespaces } from '../../../stash.js'\nimport type { Database } from '../db/index.js'\nimport { IsoSortAtKey } from '../db/pagination.js'\nimport { countAll, notSoftDeletedClause } from '../db/util.js'\n\nexport default (db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getNotifications(req) {\n const { actorDid, limit, cursor, priority } = req\n const { ref } = db.db.dynamic\n const priorityFollowQb = db.db\n .selectFrom('follow')\n .select(sql<boolean>`${true}`.as('val'))\n .where('creator', '=', actorDid)\n .whereRef('subjectDid', '=', ref('notif.author'))\n .limit(1)\n\n let builder = db.db\n .selectFrom('notification as notif')\n .where('notif.did', '=', actorDid)\n .where((eb) =>\n eb.or([\n eb('reasonSubject', 'is', null),\n eb.exists(\n db.db\n .selectFrom('record as subject')\n .selectAll()\n .whereRef('subject.uri', '=', ref('notif.reasonSubject')),\n ),\n ]),\n )\n .$if(priority, (qb) => qb.where(({ exists }) => exists(priorityFollowQb)))\n .select([\n 'notif.author as authorDid',\n 'notif.recordUri as uri',\n 'notif.recordCid as cid',\n 'notif.reason as reason',\n 'notif.reasonSubject as reasonSubject',\n 'notif.sortAt as sortAt',\n ])\n .select(priorityFollowQb.as('priority'))\n\n const key = new IsoSortAtKey(ref('notif.sortAt'))\n builder = key.paginate(builder, {\n cursor,\n limit,\n })\n\n const page = key.page(await builder.execute(), limit)\n const notifications = page.items.map((notif) => ({\n recipientDid: actorDid,\n uri: notif.uri,\n reason: notif.reason,\n reasonSubject: notif.reasonSubject ?? undefined,\n timestamp: Timestamp.fromDate(new Date(notif.sortAt)),\n priority: notif.priority ?? false,\n }))\n return {\n notifications,\n cursor: page.cursor,\n }\n },\n\n async getNotificationSeen(req) {\n const { actorDid } = req\n const res = await db.db\n .selectFrom('actor_state')\n .where('did', '=', actorDid)\n .selectAll()\n .executeTakeFirst()\n if (!res) {\n return {}\n }\n return {\n timestamp: Timestamp.fromDate(new Date(res.lastSeenNotifs)),\n }\n },\n\n async getUnreadNotificationCount(req) {\n const { actorDid } = req\n const { ref } = db.db.dynamic\n const lastSeenRes = await db.db\n .selectFrom('actor_state')\n .where('did', '=', actorDid)\n .selectAll()\n .executeTakeFirst()\n const lastSeen = lastSeenRes?.lastSeenNotifs\n\n const result = await db.db\n .selectFrom('notification')\n .select(countAll.as('count'))\n .innerJoin('actor', 'actor.did', 'notification.did')\n .leftJoin('actor_state', 'actor_state.did', 'actor.did')\n .innerJoin('record', 'record.uri', 'notification.recordUri')\n .where(notSoftDeletedClause(ref('record')))\n .where(notSoftDeletedClause(ref('actor')))\n // Ensure to hit notification_did_sortat_idx, handling case where lastSeenNotifs is null.\n .where('notification.did', '=', actorDid)\n .where('notification.sortAt', '>', lastSeen ?? '')\n .executeTakeFirst()\n\n return {\n count: result?.count,\n }\n },\n\n async updateNotificationSeen(req) {\n const { actorDid, timestamp } = req\n if (!timestamp) {\n return\n }\n const timestampIso = timestamp.toDate().toISOString()\n const { ref } = db.db.dynamic\n await db.db\n .insertInto('actor_state')\n .values({\n did: actorDid,\n lastSeenNotifs: timestampIso,\n priorityNotifs: false,\n })\n .onConflict((oc) =>\n oc.column('did').doUpdateSet({\n lastSeenNotifs: sql`greatest(${ref('actor_state.lastSeenNotifs')}, ${timestampIso})`,\n }),\n )\n .executeTakeFirst()\n },\n\n async getNotificationPreferences(req) {\n const { dids } = req\n if (dids.length === 0) {\n return { preferences: [] }\n }\n\n const res = await db.db\n .selectFrom('private_data')\n .selectAll()\n .where('actorDid', 'in', dids)\n .where(\n 'namespace',\n '=',\n Namespaces.AppBskyNotificationDefsPreferences.$type,\n )\n .where('key', '=', 'self')\n .execute()\n\n const byDid = keyBy(res, 'actorDid')\n const preferences = dids.map((did) => {\n const row = byDid.get(did)\n if (!row) {\n return {}\n }\n const p = lexParse<app.bsky.notification.defs.Preferences>(row.payload)\n return notificationPreferencesLexToProtobuf(p, row.payload)\n })\n\n return { preferences }\n },\n})\n\nexport const notificationPreferencesLexToProtobuf = (\n p: app.bsky.notification.defs.Preferences,\n json: string,\n): NotificationPreferences => {\n const lexFilterablePreferenceToProtobuf = (\n p: app.bsky.notification.defs.FilterablePreference,\n ): FilterableNotificationPreference =>\n new FilterableNotificationPreference({\n include:\n p.include === 'follows'\n ? NotificationInclude.FOLLOWS\n : NotificationInclude.ALL,\n list: { enabled: p.list ?? true },\n push: { enabled: p.push ?? true },\n })\n\n const lexPreferenceToProtobuf = (\n p: app.bsky.notification.defs.Preference,\n ): NotificationPreference =>\n new NotificationPreference({\n list: { enabled: p.list ?? true },\n push: { enabled: p.push ?? true },\n })\n\n return new NotificationPreferences({\n entry: Buffer.from(json),\n follow: lexFilterablePreferenceToProtobuf(p.follow),\n like: lexFilterablePreferenceToProtobuf(p.like),\n likeViaRepost: lexFilterablePreferenceToProtobuf(p.likeViaRepost),\n mention: lexFilterablePreferenceToProtobuf(p.mention),\n quote: lexFilterablePreferenceToProtobuf(p.quote),\n reply: lexFilterablePreferenceToProtobuf(p.reply),\n repost: lexFilterablePreferenceToProtobuf(p.repost),\n repostViaRepost: lexFilterablePreferenceToProtobuf(p.repostViaRepost),\n starterpackJoined: lexPreferenceToProtobuf(p.starterpackJoined),\n subscribedPost: lexPreferenceToProtobuf(p.subscribedPost),\n unverified: lexPreferenceToProtobuf(p.unverified),\n verified: lexPreferenceToProtobuf(p.verified),\n })\n}\n"]}
|
|
@@ -3,12 +3,12 @@ import type { DatabaseSchema } from './db/database-schema.js';
|
|
|
3
3
|
export declare const getDescendentsQb: (db: DatabaseSchema, opts: {
|
|
4
4
|
uri: string;
|
|
5
5
|
depth: number;
|
|
6
|
-
}) => import("kysely").QueryCreatorWithCommonTableExpression<import("./db/database-schema.js").DatabaseSchemaType, "descendent(uri, depth)", (cte: import("kysely").QueryCreator<import("./db/tables/duplicate-record.js").PartialDB & import("./db/tables/profile.js").PartialDB & import("./db/tables/profile-agg.js").PartialDB & import("./db/tables/post.js").PartialDB & import("./db/tables/post-embed.js").PartialDB & import("./db/tables/post-agg.js").PartialDB & import("./db/tables/repost.js").PartialDB & import("./db/tables/thread-gate.js").PartialDB & import("./db/tables/post-gate.js").PartialDB & import("./db/tables/feed-item.js").PartialDB & import("./db/tables/follow.js").PartialDB & import("./db/tables/like.js").PartialDB & import("./db/tables/list.js").PartialDB & import("./db/tables/list-item.js").PartialDB & import("./db/tables/list-mute.js").PartialDB & import("./db/tables/list-block.js").PartialDB & import("./db/tables/mute.js").PartialDB & import("./db/tables/actor-block.js").PartialDB & import("./db/tables/thread-mute.js").PartialDB & import("./db/tables/feed-generator.js").PartialDB & import("./db/tables/subscription.js").PartialDB & import("./db/tables/actor.js").PartialDB & import("./db/tables/actor-state.js").PartialDB & import("./db/tables/actor-sync.js").PartialDB & import("./db/tables/record.js").PartialDB & import("./db/tables/notification.js").PartialDB & import("./db/tables/notification-push-token.js").PartialDB & import("./db/tables/did-cache.js").PartialDB & import("./db/tables/label.js").PartialDB & import("./db/tables/algo.js").PartialDB & import("./db/tables/view-param.js").PartialDB & import("./db/tables/suggested-follow.js").PartialDB & import("./db/tables/suggested-feed.js").PartialDB & import("./db/tables/blob-takedown.js").PartialDB & import("./db/tables/labeler.js").PartialDB & import("./db/tables/starter-pack.js").PartialDB & import("./db/tables/tagged-suggestion.js").PartialDB & import("./db/tables/quote.js").PartialDB & import("./db/tables/verification.js").PartialDB & import("./db/tables/private-data.js").PartialDB & import("./db/tables/activity-subscription.js").PartialDB & import("./db/tables/bookmark.js").PartialDB & import("./db/tables/draft.js").PartialDB & import("./db/tables/op-thread-reply.js").PartialDB & {
|
|
6
|
+
}) => import("kysely").QueryCreatorWithCommonTableExpression<import("./db/database-schema.js").DatabaseSchemaType, "descendent(uri, depth)", (cte: import("kysely").QueryCreator<import("./db/tables/duplicate-record.js").PartialDB & import("./db/tables/profile.js").PartialDB & import("./db/tables/profile-agg.js").PartialDB & import("./db/tables/post.js").PartialDB & import("./db/tables/post-embed.js").PartialDB & import("./db/tables/post-agg.js").PartialDB & import("./db/tables/repost.js").PartialDB & import("./db/tables/thread-gate.js").PartialDB & import("./db/tables/post-gate.js").PartialDB & import("./db/tables/feed-item.js").PartialDB & import("./db/tables/follow.js").PartialDB & import("./db/tables/like.js").PartialDB & import("./db/tables/list.js").PartialDB & import("./db/tables/list-item.js").PartialDB & import("./db/tables/list-mute.js").PartialDB & import("./db/tables/list-block.js").PartialDB & import("./db/tables/mute.js").PartialDB & import("./db/tables/actor-block.js").PartialDB & import("./db/tables/thread-mute.js").PartialDB & import("./db/tables/feed-generator.js").PartialDB & import("./db/tables/subscription.js").PartialDB & import("./db/tables/actor.js").PartialDB & import("./db/tables/actor-state.js").PartialDB & import("./db/tables/actor-sync.js").PartialDB & import("./db/tables/record.js").PartialDB & import("./db/tables/reference-list-opt-out.js").PartialDB & import("./db/tables/notification.js").PartialDB & import("./db/tables/notification-push-token.js").PartialDB & import("./db/tables/did-cache.js").PartialDB & import("./db/tables/label.js").PartialDB & import("./db/tables/algo.js").PartialDB & import("./db/tables/view-param.js").PartialDB & import("./db/tables/suggested-follow.js").PartialDB & import("./db/tables/suggested-feed.js").PartialDB & import("./db/tables/blob-takedown.js").PartialDB & import("./db/tables/labeler.js").PartialDB & import("./db/tables/starter-pack.js").PartialDB & import("./db/tables/tagged-suggestion.js").PartialDB & import("./db/tables/quote.js").PartialDB & import("./db/tables/verification.js").PartialDB & import("./db/tables/private-data.js").PartialDB & import("./db/tables/activity-subscription.js").PartialDB & import("./db/tables/bookmark.js").PartialDB & import("./db/tables/draft.js").PartialDB & import("./db/tables/op-thread-reply.js").PartialDB & {
|
|
7
7
|
descendent: {
|
|
8
8
|
depth: any;
|
|
9
9
|
uri: any;
|
|
10
10
|
};
|
|
11
|
-
}>) => import("kysely").SelectQueryBuilder<import("./db/tables/duplicate-record.js").PartialDB & import("./db/tables/profile.js").PartialDB & import("./db/tables/profile-agg.js").PartialDB & import("./db/tables/post.js").PartialDB & import("./db/tables/post-embed.js").PartialDB & import("./db/tables/post-agg.js").PartialDB & import("./db/tables/repost.js").PartialDB & import("./db/tables/thread-gate.js").PartialDB & import("./db/tables/post-gate.js").PartialDB & import("./db/tables/feed-item.js").PartialDB & import("./db/tables/follow.js").PartialDB & import("./db/tables/like.js").PartialDB & import("./db/tables/list.js").PartialDB & import("./db/tables/list-item.js").PartialDB & import("./db/tables/list-mute.js").PartialDB & import("./db/tables/list-block.js").PartialDB & import("./db/tables/mute.js").PartialDB & import("./db/tables/actor-block.js").PartialDB & import("./db/tables/thread-mute.js").PartialDB & import("./db/tables/feed-generator.js").PartialDB & import("./db/tables/subscription.js").PartialDB & import("./db/tables/actor.js").PartialDB & import("./db/tables/actor-state.js").PartialDB & import("./db/tables/actor-sync.js").PartialDB & import("./db/tables/record.js").PartialDB & import("./db/tables/notification.js").PartialDB & import("./db/tables/notification-push-token.js").PartialDB & import("./db/tables/did-cache.js").PartialDB & import("./db/tables/label.js").PartialDB & import("./db/tables/algo.js").PartialDB & import("./db/tables/view-param.js").PartialDB & import("./db/tables/suggested-follow.js").PartialDB & import("./db/tables/suggested-feed.js").PartialDB & import("./db/tables/blob-takedown.js").PartialDB & import("./db/tables/labeler.js").PartialDB & import("./db/tables/starter-pack.js").PartialDB & import("./db/tables/tagged-suggestion.js").PartialDB & import("./db/tables/quote.js").PartialDB & import("./db/tables/verification.js").PartialDB & import("./db/tables/private-data.js").PartialDB & import("./db/tables/activity-subscription.js").PartialDB & import("./db/tables/bookmark.js").PartialDB & import("./db/tables/draft.js").PartialDB & import("./db/tables/op-thread-reply.js").PartialDB & {
|
|
11
|
+
}>) => import("kysely").SelectQueryBuilder<import("./db/tables/duplicate-record.js").PartialDB & import("./db/tables/profile.js").PartialDB & import("./db/tables/profile-agg.js").PartialDB & import("./db/tables/post.js").PartialDB & import("./db/tables/post-embed.js").PartialDB & import("./db/tables/post-agg.js").PartialDB & import("./db/tables/repost.js").PartialDB & import("./db/tables/thread-gate.js").PartialDB & import("./db/tables/post-gate.js").PartialDB & import("./db/tables/feed-item.js").PartialDB & import("./db/tables/follow.js").PartialDB & import("./db/tables/like.js").PartialDB & import("./db/tables/list.js").PartialDB & import("./db/tables/list-item.js").PartialDB & import("./db/tables/list-mute.js").PartialDB & import("./db/tables/list-block.js").PartialDB & import("./db/tables/mute.js").PartialDB & import("./db/tables/actor-block.js").PartialDB & import("./db/tables/thread-mute.js").PartialDB & import("./db/tables/feed-generator.js").PartialDB & import("./db/tables/subscription.js").PartialDB & import("./db/tables/actor.js").PartialDB & import("./db/tables/actor-state.js").PartialDB & import("./db/tables/actor-sync.js").PartialDB & import("./db/tables/record.js").PartialDB & import("./db/tables/reference-list-opt-out.js").PartialDB & import("./db/tables/notification.js").PartialDB & import("./db/tables/notification-push-token.js").PartialDB & import("./db/tables/did-cache.js").PartialDB & import("./db/tables/label.js").PartialDB & import("./db/tables/algo.js").PartialDB & import("./db/tables/view-param.js").PartialDB & import("./db/tables/suggested-follow.js").PartialDB & import("./db/tables/suggested-feed.js").PartialDB & import("./db/tables/blob-takedown.js").PartialDB & import("./db/tables/labeler.js").PartialDB & import("./db/tables/starter-pack.js").PartialDB & import("./db/tables/tagged-suggestion.js").PartialDB & import("./db/tables/quote.js").PartialDB & import("./db/tables/verification.js").PartialDB & import("./db/tables/private-data.js").PartialDB & import("./db/tables/activity-subscription.js").PartialDB & import("./db/tables/bookmark.js").PartialDB & import("./db/tables/draft.js").PartialDB & import("./db/tables/op-thread-reply.js").PartialDB & {
|
|
12
12
|
descendent: {
|
|
13
13
|
depth: any;
|
|
14
14
|
uri: any;
|
|
@@ -20,13 +20,13 @@ export declare const getDescendentsQb: (db: DatabaseSchema, opts: {
|
|
|
20
20
|
export declare const getAncestorsAndSelfQb: (db: DatabaseSchema, opts: {
|
|
21
21
|
uri: string;
|
|
22
22
|
parentHeight: number;
|
|
23
|
-
}) => import("kysely").QueryCreatorWithCommonTableExpression<import("./db/database-schema.js").DatabaseSchemaType, "ancestor(uri, ancestorUri, height)", (cte: import("kysely").QueryCreator<import("./db/tables/duplicate-record.js").PartialDB & import("./db/tables/profile.js").PartialDB & import("./db/tables/profile-agg.js").PartialDB & import("./db/tables/post.js").PartialDB & import("./db/tables/post-embed.js").PartialDB & import("./db/tables/post-agg.js").PartialDB & import("./db/tables/repost.js").PartialDB & import("./db/tables/thread-gate.js").PartialDB & import("./db/tables/post-gate.js").PartialDB & import("./db/tables/feed-item.js").PartialDB & import("./db/tables/follow.js").PartialDB & import("./db/tables/like.js").PartialDB & import("./db/tables/list.js").PartialDB & import("./db/tables/list-item.js").PartialDB & import("./db/tables/list-mute.js").PartialDB & import("./db/tables/list-block.js").PartialDB & import("./db/tables/mute.js").PartialDB & import("./db/tables/actor-block.js").PartialDB & import("./db/tables/thread-mute.js").PartialDB & import("./db/tables/feed-generator.js").PartialDB & import("./db/tables/subscription.js").PartialDB & import("./db/tables/actor.js").PartialDB & import("./db/tables/actor-state.js").PartialDB & import("./db/tables/actor-sync.js").PartialDB & import("./db/tables/record.js").PartialDB & import("./db/tables/notification.js").PartialDB & import("./db/tables/notification-push-token.js").PartialDB & import("./db/tables/did-cache.js").PartialDB & import("./db/tables/label.js").PartialDB & import("./db/tables/algo.js").PartialDB & import("./db/tables/view-param.js").PartialDB & import("./db/tables/suggested-follow.js").PartialDB & import("./db/tables/suggested-feed.js").PartialDB & import("./db/tables/blob-takedown.js").PartialDB & import("./db/tables/labeler.js").PartialDB & import("./db/tables/starter-pack.js").PartialDB & import("./db/tables/tagged-suggestion.js").PartialDB & import("./db/tables/quote.js").PartialDB & import("./db/tables/verification.js").PartialDB & import("./db/tables/private-data.js").PartialDB & import("./db/tables/activity-subscription.js").PartialDB & import("./db/tables/bookmark.js").PartialDB & import("./db/tables/draft.js").PartialDB & import("./db/tables/op-thread-reply.js").PartialDB & {
|
|
23
|
+
}) => import("kysely").QueryCreatorWithCommonTableExpression<import("./db/database-schema.js").DatabaseSchemaType, "ancestor(uri, ancestorUri, height)", (cte: import("kysely").QueryCreator<import("./db/tables/duplicate-record.js").PartialDB & import("./db/tables/profile.js").PartialDB & import("./db/tables/profile-agg.js").PartialDB & import("./db/tables/post.js").PartialDB & import("./db/tables/post-embed.js").PartialDB & import("./db/tables/post-agg.js").PartialDB & import("./db/tables/repost.js").PartialDB & import("./db/tables/thread-gate.js").PartialDB & import("./db/tables/post-gate.js").PartialDB & import("./db/tables/feed-item.js").PartialDB & import("./db/tables/follow.js").PartialDB & import("./db/tables/like.js").PartialDB & import("./db/tables/list.js").PartialDB & import("./db/tables/list-item.js").PartialDB & import("./db/tables/list-mute.js").PartialDB & import("./db/tables/list-block.js").PartialDB & import("./db/tables/mute.js").PartialDB & import("./db/tables/actor-block.js").PartialDB & import("./db/tables/thread-mute.js").PartialDB & import("./db/tables/feed-generator.js").PartialDB & import("./db/tables/subscription.js").PartialDB & import("./db/tables/actor.js").PartialDB & import("./db/tables/actor-state.js").PartialDB & import("./db/tables/actor-sync.js").PartialDB & import("./db/tables/record.js").PartialDB & import("./db/tables/reference-list-opt-out.js").PartialDB & import("./db/tables/notification.js").PartialDB & import("./db/tables/notification-push-token.js").PartialDB & import("./db/tables/did-cache.js").PartialDB & import("./db/tables/label.js").PartialDB & import("./db/tables/algo.js").PartialDB & import("./db/tables/view-param.js").PartialDB & import("./db/tables/suggested-follow.js").PartialDB & import("./db/tables/suggested-feed.js").PartialDB & import("./db/tables/blob-takedown.js").PartialDB & import("./db/tables/labeler.js").PartialDB & import("./db/tables/starter-pack.js").PartialDB & import("./db/tables/tagged-suggestion.js").PartialDB & import("./db/tables/quote.js").PartialDB & import("./db/tables/verification.js").PartialDB & import("./db/tables/private-data.js").PartialDB & import("./db/tables/activity-subscription.js").PartialDB & import("./db/tables/bookmark.js").PartialDB & import("./db/tables/draft.js").PartialDB & import("./db/tables/op-thread-reply.js").PartialDB & {
|
|
24
24
|
ancestor: {
|
|
25
25
|
ancestorUri: any;
|
|
26
26
|
height: any;
|
|
27
27
|
uri: any;
|
|
28
28
|
};
|
|
29
|
-
}>) => import("kysely").SelectQueryBuilder<import("./db/tables/duplicate-record.js").PartialDB & import("./db/tables/profile.js").PartialDB & import("./db/tables/profile-agg.js").PartialDB & import("./db/tables/post.js").PartialDB & import("./db/tables/post-embed.js").PartialDB & import("./db/tables/post-agg.js").PartialDB & import("./db/tables/repost.js").PartialDB & import("./db/tables/thread-gate.js").PartialDB & import("./db/tables/post-gate.js").PartialDB & import("./db/tables/feed-item.js").PartialDB & import("./db/tables/follow.js").PartialDB & import("./db/tables/like.js").PartialDB & import("./db/tables/list.js").PartialDB & import("./db/tables/list-item.js").PartialDB & import("./db/tables/list-mute.js").PartialDB & import("./db/tables/list-block.js").PartialDB & import("./db/tables/mute.js").PartialDB & import("./db/tables/actor-block.js").PartialDB & import("./db/tables/thread-mute.js").PartialDB & import("./db/tables/feed-generator.js").PartialDB & import("./db/tables/subscription.js").PartialDB & import("./db/tables/actor.js").PartialDB & import("./db/tables/actor-state.js").PartialDB & import("./db/tables/actor-sync.js").PartialDB & import("./db/tables/record.js").PartialDB & import("./db/tables/notification.js").PartialDB & import("./db/tables/notification-push-token.js").PartialDB & import("./db/tables/did-cache.js").PartialDB & import("./db/tables/label.js").PartialDB & import("./db/tables/algo.js").PartialDB & import("./db/tables/view-param.js").PartialDB & import("./db/tables/suggested-follow.js").PartialDB & import("./db/tables/suggested-feed.js").PartialDB & import("./db/tables/blob-takedown.js").PartialDB & import("./db/tables/labeler.js").PartialDB & import("./db/tables/starter-pack.js").PartialDB & import("./db/tables/tagged-suggestion.js").PartialDB & import("./db/tables/quote.js").PartialDB & import("./db/tables/verification.js").PartialDB & import("./db/tables/private-data.js").PartialDB & import("./db/tables/activity-subscription.js").PartialDB & import("./db/tables/bookmark.js").PartialDB & import("./db/tables/draft.js").PartialDB & import("./db/tables/op-thread-reply.js").PartialDB & {
|
|
29
|
+
}>) => import("kysely").SelectQueryBuilder<import("./db/tables/duplicate-record.js").PartialDB & import("./db/tables/profile.js").PartialDB & import("./db/tables/profile-agg.js").PartialDB & import("./db/tables/post.js").PartialDB & import("./db/tables/post-embed.js").PartialDB & import("./db/tables/post-agg.js").PartialDB & import("./db/tables/repost.js").PartialDB & import("./db/tables/thread-gate.js").PartialDB & import("./db/tables/post-gate.js").PartialDB & import("./db/tables/feed-item.js").PartialDB & import("./db/tables/follow.js").PartialDB & import("./db/tables/like.js").PartialDB & import("./db/tables/list.js").PartialDB & import("./db/tables/list-item.js").PartialDB & import("./db/tables/list-mute.js").PartialDB & import("./db/tables/list-block.js").PartialDB & import("./db/tables/mute.js").PartialDB & import("./db/tables/actor-block.js").PartialDB & import("./db/tables/thread-mute.js").PartialDB & import("./db/tables/feed-generator.js").PartialDB & import("./db/tables/subscription.js").PartialDB & import("./db/tables/actor.js").PartialDB & import("./db/tables/actor-state.js").PartialDB & import("./db/tables/actor-sync.js").PartialDB & import("./db/tables/record.js").PartialDB & import("./db/tables/reference-list-opt-out.js").PartialDB & import("./db/tables/notification.js").PartialDB & import("./db/tables/notification-push-token.js").PartialDB & import("./db/tables/did-cache.js").PartialDB & import("./db/tables/label.js").PartialDB & import("./db/tables/algo.js").PartialDB & import("./db/tables/view-param.js").PartialDB & import("./db/tables/suggested-follow.js").PartialDB & import("./db/tables/suggested-feed.js").PartialDB & import("./db/tables/blob-takedown.js").PartialDB & import("./db/tables/labeler.js").PartialDB & import("./db/tables/starter-pack.js").PartialDB & import("./db/tables/tagged-suggestion.js").PartialDB & import("./db/tables/quote.js").PartialDB & import("./db/tables/verification.js").PartialDB & import("./db/tables/private-data.js").PartialDB & import("./db/tables/activity-subscription.js").PartialDB & import("./db/tables/bookmark.js").PartialDB & import("./db/tables/draft.js").PartialDB & import("./db/tables/op-thread-reply.js").PartialDB & {
|
|
30
30
|
ancestor: {
|
|
31
31
|
ancestorUri: any;
|
|
32
32
|
height: any;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actor.d.ts","sourceRoot":"","sources":["../../src/hydration/actor.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,YAAY,EAIlB,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AACpE,OAAO,EAAE,GAAG,EAAa,MAAM,sBAAsB,CAAA;AACrD,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"actor.d.ts","sourceRoot":"","sources":["../../src/hydration/actor.ts"],"names":[],"mappings":"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"}
|
package/dist/hydration/actor.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { mapDefined } from '@atproto/common';
|
|
2
2
|
import { isDidIdentifier, isHandleIdentifier, normalizeHandle, } from '@atproto/syntax';
|
|
3
3
|
import { app, chat, com } from '../lexicons/index.js';
|
|
4
|
+
import { events } from '../telemetry/events.js';
|
|
4
5
|
import { HydrationMap, isActivitySubscriptionEnabled, parseDate, parseRecord, parseString, safeTakedownRef, } from './util.js';
|
|
5
6
|
export class ActorHydrator {
|
|
6
7
|
constructor(dataplane) {
|
|
@@ -257,8 +258,9 @@ export class ActorHydrator {
|
|
|
257
258
|
: undefined);
|
|
258
259
|
}
|
|
259
260
|
}
|
|
260
|
-
catch {
|
|
261
|
-
//
|
|
261
|
+
catch (err) {
|
|
262
|
+
// Fail open.
|
|
263
|
+
events.hydrationFailed({ source: 'known_followers', err });
|
|
262
264
|
}
|
|
263
265
|
return map;
|
|
264
266
|
}
|
|
@@ -288,8 +290,9 @@ export class ActorHydrator {
|
|
|
288
290
|
}
|
|
289
291
|
}
|
|
290
292
|
}
|
|
291
|
-
catch {
|
|
292
|
-
//
|
|
293
|
+
catch (err) {
|
|
294
|
+
// Fail open.
|
|
295
|
+
events.hydrationFailed({ source: 'activity_subscriptions', err });
|
|
293
296
|
}
|
|
294
297
|
return map;
|
|
295
298
|
}
|