@atproto/bsky 0.0.152 → 0.0.153

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.
Files changed (79) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/api/app/bsky/unspecced/getPostThreadHiddenV2.js +2 -1
  3. package/dist/api/app/bsky/unspecced/getPostThreadHiddenV2.js.map +1 -1
  4. package/dist/api/com/atproto/repo/getRecord.d.ts.map +1 -1
  5. package/dist/api/com/atproto/repo/getRecord.js +1 -1
  6. package/dist/api/com/atproto/repo/getRecord.js.map +1 -1
  7. package/dist/config.d.ts +4 -0
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/config.js +10 -0
  10. package/dist/config.js.map +1 -1
  11. package/dist/data-plane/server/db/migrations/20250528T221913281Z-add-record-tags.d.ts +4 -0
  12. package/dist/data-plane/server/db/migrations/20250528T221913281Z-add-record-tags.d.ts.map +1 -0
  13. package/dist/data-plane/server/db/migrations/20250528T221913281Z-add-record-tags.js +11 -0
  14. package/dist/data-plane/server/db/migrations/20250528T221913281Z-add-record-tags.js.map +1 -0
  15. package/dist/data-plane/server/db/migrations/index.d.ts +1 -0
  16. package/dist/data-plane/server/db/migrations/index.d.ts.map +1 -1
  17. package/dist/data-plane/server/db/migrations/index.js +2 -1
  18. package/dist/data-plane/server/db/migrations/index.js.map +1 -1
  19. package/dist/data-plane/server/db/tables/record.d.ts +1 -0
  20. package/dist/data-plane/server/db/tables/record.d.ts.map +1 -1
  21. package/dist/data-plane/server/db/tables/record.js.map +1 -1
  22. package/dist/data-plane/server/routes/records.d.ts.map +1 -1
  23. package/dist/data-plane/server/routes/records.js +1 -0
  24. package/dist/data-plane/server/routes/records.js.map +1 -1
  25. package/dist/hydration/feed.d.ts +1 -0
  26. package/dist/hydration/feed.d.ts.map +1 -1
  27. package/dist/hydration/feed.js +2 -0
  28. package/dist/hydration/feed.js.map +1 -1
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +2 -0
  31. package/dist/index.js.map +1 -1
  32. package/dist/lexicon/lexicons.d.ts +10 -0
  33. package/dist/lexicon/lexicons.d.ts.map +1 -1
  34. package/dist/lexicon/lexicons.js +5 -0
  35. package/dist/lexicon/lexicons.js.map +1 -1
  36. package/dist/lexicon/types/app/bsky/unspecced/getPostThreadHiddenV2.d.ts +2 -0
  37. package/dist/lexicon/types/app/bsky/unspecced/getPostThreadHiddenV2.d.ts.map +1 -1
  38. package/dist/lexicon/types/app/bsky/unspecced/getPostThreadHiddenV2.js.map +1 -1
  39. package/dist/proto/bsky_pb.d.ts +4 -0
  40. package/dist/proto/bsky_pb.d.ts.map +1 -1
  41. package/dist/proto/bsky_pb.js +16 -0
  42. package/dist/proto/bsky_pb.js.map +1 -1
  43. package/dist/proto/bsync_connect.d.ts +19 -1
  44. package/dist/proto/bsync_connect.d.ts.map +1 -1
  45. package/dist/proto/bsync_connect.js +18 -0
  46. package/dist/proto/bsync_connect.js.map +1 -1
  47. package/dist/proto/bsync_pb.d.ts +150 -0
  48. package/dist/proto/bsync_pb.d.ts.map +1 -1
  49. package/dist/proto/bsync_pb.js +401 -1
  50. package/dist/proto/bsync_pb.js.map +1 -1
  51. package/dist/views/index.d.ts +6 -1
  52. package/dist/views/index.d.ts.map +1 -1
  53. package/dist/views/index.js +58 -22
  54. package/dist/views/index.js.map +1 -1
  55. package/dist/views/threads-v2.d.ts +4 -1
  56. package/dist/views/threads-v2.d.ts.map +1 -1
  57. package/dist/views/threads-v2.js +50 -25
  58. package/dist/views/threads-v2.js.map +1 -1
  59. package/package.json +5 -5
  60. package/proto/bsky.proto +1 -0
  61. package/src/api/app/bsky/unspecced/getPostThreadHiddenV2.ts +2 -1
  62. package/src/api/com/atproto/repo/getRecord.ts +4 -1
  63. package/src/config.ts +15 -0
  64. package/src/data-plane/server/db/migrations/20250528T221913281Z-add-record-tags.ts +9 -0
  65. package/src/data-plane/server/db/migrations/index.ts +1 -0
  66. package/src/data-plane/server/db/tables/record.ts +1 -0
  67. package/src/data-plane/server/routes/records.ts +1 -0
  68. package/src/hydration/feed.ts +3 -0
  69. package/src/index.ts +2 -0
  70. package/src/lexicon/lexicons.ts +6 -0
  71. package/src/lexicon/types/app/bsky/unspecced/getPostThreadHiddenV2.ts +2 -0
  72. package/src/proto/bsky_pb.ts +12 -0
  73. package/src/proto/bsync_connect.ts +22 -0
  74. package/src/proto/bsync_pb.ts +355 -0
  75. package/src/views/index.ts +90 -52
  76. package/src/views/threads-v2.ts +67 -37
  77. package/tests/seed/thread-v2.ts +131 -32
  78. package/tests/views/thread-v2.test.ts +139 -27
  79. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1,3 +1,4 @@
1
+ import { sql } from 'kysely'
1
2
  import { AppBskyFeedPost } from '@atproto/api'
2
3
  import {
3
4
  RecordRef,
@@ -5,6 +6,7 @@ import {
5
6
  TestNetwork,
6
7
  TestNetworkNoAppView,
7
8
  } from '@atproto/dev-env'
9
+ import { DatabaseSchema } from '../../src/data-plane/server/db/database-schema'
8
10
  import { User, createUsers } from './util'
9
11
 
10
12
  type ReplyFn = (
@@ -15,6 +17,9 @@ type ReplyFn = (
15
17
 
16
18
  type ReplyCb = (r: ReplyFn) => Promise<void>
17
19
 
20
+ export const TAG_BUMP_DOWN = 'down'
21
+ export const TAG_HIDE = 'hide'
22
+
18
23
  const rootReplyFnBuilder = <T extends TestNetworkNoAppView>(
19
24
  sc: SeedClient<T>,
20
25
  root: RecordRef,
@@ -95,10 +100,7 @@ const createThread = async <T extends TestNetworkNoAppView>(
95
100
  return { root, replies }
96
101
  }
97
102
 
98
- export async function simple(
99
- sc: SeedClient<TestNetwork | TestNetworkNoAppView>,
100
- prefix = 'simple',
101
- ) {
103
+ export async function simple(sc: SeedClient<TestNetwork>, prefix = 'simple') {
102
104
  const users = await createUsers(sc, prefix, [
103
105
  'op',
104
106
  'alice',
@@ -126,7 +128,7 @@ export async function simple(
126
128
  }
127
129
  }
128
130
 
129
- export async function long(sc: SeedClient<TestNetwork | TestNetworkNoAppView>) {
131
+ export async function long(sc: SeedClient<TestNetwork>) {
130
132
  const users = await createUsers(sc, 'long', [
131
133
  'op',
132
134
  'alice',
@@ -187,7 +189,7 @@ export async function long(sc: SeedClient<TestNetwork | TestNetworkNoAppView>) {
187
189
  }
188
190
  }
189
191
 
190
- export async function deep(sc: SeedClient<TestNetwork | TestNetworkNoAppView>) {
192
+ export async function deep(sc: SeedClient<TestNetwork>) {
191
193
  const users = await createUsers(sc, 'deep', ['op'] as const)
192
194
  const { op } = users
193
195
 
@@ -210,9 +212,7 @@ export async function deep(sc: SeedClient<TestNetwork | TestNetworkNoAppView>) {
210
212
  }
211
213
  }
212
214
 
213
- export async function branchingFactor(
214
- sc: SeedClient<TestNetwork | TestNetworkNoAppView>,
215
- ) {
215
+ export async function branchingFactor(sc: SeedClient<TestNetwork>) {
216
216
  const users = await createUsers(sc, 'bf', ['op', 'bob'] as const)
217
217
  const { op, bob } = users
218
218
 
@@ -333,9 +333,7 @@ export async function branchingFactor(
333
333
  }
334
334
  }
335
335
 
336
- export async function annotateMoreReplies(
337
- sc: SeedClient<TestNetwork | TestNetworkNoAppView>,
338
- ) {
336
+ export async function annotateMoreReplies(sc: SeedClient<TestNetwork>) {
339
337
  const users = await createUsers(sc, 'mr', ['op', 'alice'] as const)
340
338
  const { op, alice } = users
341
339
 
@@ -392,9 +390,7 @@ export async function annotateMoreReplies(
392
390
  }
393
391
  }
394
392
 
395
- export async function annotateOP(
396
- sc: SeedClient<TestNetwork | TestNetworkNoAppView>,
397
- ) {
393
+ export async function annotateOP(sc: SeedClient<TestNetwork>) {
398
394
  const users = await createUsers(sc, 'op', ['op', 'alice', 'bob'] as const)
399
395
  const { op, alice, bob } = users
400
396
 
@@ -422,7 +418,7 @@ export async function annotateOP(
422
418
  }
423
419
  }
424
420
 
425
- export async function sort(sc: SeedClient<TestNetwork | TestNetworkNoAppView>) {
421
+ export async function sort(sc: SeedClient<TestNetwork>) {
426
422
  const users = await createUsers(sc, 'sort', [
427
423
  'op',
428
424
  'alice',
@@ -478,9 +474,7 @@ export async function sort(sc: SeedClient<TestNetwork | TestNetworkNoAppView>) {
478
474
  }
479
475
  }
480
476
 
481
- export async function bumpOpAndViewer(
482
- sc: SeedClient<TestNetwork | TestNetworkNoAppView>,
483
- ) {
477
+ export async function bumpOpAndViewer(sc: SeedClient<TestNetwork>) {
484
478
  const users = await createUsers(sc, 'bumpOV', [
485
479
  'op',
486
480
  'viewer',
@@ -566,9 +560,7 @@ export async function bumpOpAndViewer(
566
560
  }
567
561
  }
568
562
 
569
- export async function bumpGroupSorting(
570
- sc: SeedClient<TestNetwork | TestNetworkNoAppView>,
571
- ) {
563
+ export async function bumpGroupSorting(sc: SeedClient<TestNetwork>) {
572
564
  const users = await createUsers(sc, 'bumpGS', [
573
565
  'op',
574
566
  'viewer',
@@ -595,9 +587,7 @@ export async function bumpGroupSorting(
595
587
  }
596
588
  }
597
589
 
598
- export async function bumpFollows(
599
- sc: SeedClient<TestNetwork | TestNetworkNoAppView>,
600
- ) {
590
+ export async function bumpFollows(sc: SeedClient<TestNetwork>) {
601
591
  const users = await createUsers(sc, 'bumpF', [
602
592
  'op',
603
593
  'viewerF',
@@ -631,7 +621,8 @@ export async function bumpFollows(
631
621
  }
632
622
 
633
623
  export async function blockDeletionAuth(
634
- sc: SeedClient<TestNetwork | TestNetworkNoAppView>,
624
+ sc: SeedClient<TestNetwork>,
625
+ labelerDid: string,
635
626
  ) {
636
627
  const users = await createUsers(sc, 'bda', [
637
628
  'op',
@@ -675,6 +666,14 @@ export async function blockDeletionAuth(
675
666
  await sc.block(blocker.did, blocked.did)
676
667
  await sc.block(op.did, opBlocked.did)
677
668
 
669
+ const db = sc.network.bsky.db.db
670
+ await createLabel(db, {
671
+ src: labelerDid,
672
+ uri: auth.did,
673
+ cid: '',
674
+ val: '!no-unauthenticated',
675
+ })
676
+
678
677
  return {
679
678
  seedClient: sc,
680
679
  users,
@@ -683,9 +682,7 @@ export async function blockDeletionAuth(
683
682
  }
684
683
  }
685
684
 
686
- export async function mutes(
687
- sc: SeedClient<TestNetwork | TestNetworkNoAppView>,
688
- ) {
685
+ export async function mutes(sc: SeedClient<TestNetwork>) {
689
686
  const users = await createUsers(sc, 'mutes', [
690
687
  'op',
691
688
  'opMuted',
@@ -719,9 +716,7 @@ export async function mutes(
719
716
  }
720
717
  }
721
718
 
722
- export async function threadgated(
723
- sc: SeedClient<TestNetwork | TestNetworkNoAppView>,
724
- ) {
719
+ export async function threadgated(sc: SeedClient<TestNetwork>) {
725
720
  const users = await createUsers(sc, 'tg', [
726
721
  'op',
727
722
  'opMuted',
@@ -773,3 +768,107 @@ export async function threadgated(
773
768
  r,
774
769
  }
775
770
  }
771
+
772
+ export async function tags(sc: SeedClient<TestNetwork>) {
773
+ const users = await createUsers(sc, 'tags', [
774
+ 'op',
775
+ 'alice',
776
+ 'down',
777
+ 'following',
778
+ 'hide',
779
+ 'viewer',
780
+ ] as const)
781
+
782
+ const { op, alice, down, following, hide, viewer } = users
783
+
784
+ const { root, replies: r } = await createThread(sc, op, async (r) => {
785
+ await r(alice, async (r) => {
786
+ await r(alice)
787
+ await r(down)
788
+ await r(hide)
789
+ })
790
+ await r(down, async (r) => {
791
+ await r(alice)
792
+ await r(down)
793
+ await r(hide)
794
+ })
795
+ await r(hide, async (r) => {
796
+ await r(alice)
797
+ await r(down)
798
+ await r(hide)
799
+ })
800
+ await r(op)
801
+ await r(viewer)
802
+ await r(following)
803
+ })
804
+
805
+ await sc.network.processAll()
806
+
807
+ await sc.follow(viewer.did, following.did)
808
+
809
+ const db = sc.network.bsky.db.db
810
+ await createTag(db, { uri: r['1'].ref.uriStr, val: TAG_BUMP_DOWN })
811
+ await createTag(db, { uri: r['0.1'].ref.uriStr, val: TAG_BUMP_DOWN })
812
+ await createTag(db, { uri: r['1.1'].ref.uriStr, val: TAG_BUMP_DOWN })
813
+ await createTag(db, { uri: r['2.1'].ref.uriStr, val: TAG_BUMP_DOWN })
814
+
815
+ await createTag(db, { uri: r['2'].ref.uriStr, val: TAG_HIDE })
816
+ await createTag(db, { uri: r['0.2'].ref.uriStr, val: TAG_HIDE })
817
+ await createTag(db, { uri: r['1.2'].ref.uriStr, val: TAG_HIDE })
818
+ await createTag(db, { uri: r['2.2'].ref.uriStr, val: TAG_HIDE })
819
+
820
+ // Neither tag affect op, viewer.
821
+ await createTag(db, { uri: r['3'].ref.uriStr, val: TAG_BUMP_DOWN })
822
+ await createTag(db, { uri: r['4'].ref.uriStr, val: TAG_HIDE })
823
+
824
+ // Tags affect following depending on the config to prioritize following.
825
+ await createTag(db, { uri: r['5'].ref.uriStr, val: TAG_HIDE })
826
+
827
+ return {
828
+ seedClient: sc,
829
+ users,
830
+ root,
831
+ r,
832
+ }
833
+ }
834
+
835
+ const createLabel = async (
836
+ db: DatabaseSchema,
837
+ opts: {
838
+ src: string
839
+ uri: string
840
+ cid: string
841
+ val: string
842
+ exp?: string
843
+ },
844
+ ) => {
845
+ await db
846
+ .insertInto('label')
847
+ .values({
848
+ uri: opts.uri,
849
+ cid: opts.cid,
850
+ val: opts.val,
851
+ cts: new Date().toISOString(),
852
+ exp: opts.exp ?? null,
853
+ neg: false,
854
+ src: opts.src,
855
+ })
856
+ .execute()
857
+ }
858
+
859
+ const createTag = async (
860
+ db: DatabaseSchema,
861
+ opts: {
862
+ uri: string
863
+ val: string
864
+ },
865
+ ) => {
866
+ await db
867
+ .updateTable('record')
868
+ .set({
869
+ tags: sql<string[]>`${JSON.stringify([opts.val])}`,
870
+ })
871
+ .where('uri', '=', opts.uri)
872
+ .returningAll()
873
+ .execute()
874
+ }
@@ -19,6 +19,7 @@ import {
19
19
  import { ThreadItemValuePost } from '../../src/views/threads-v2'
20
20
  import { forSnapshot } from '../_util'
21
21
  import * as seeds from '../seed/thread-v2'
22
+ import { TAG_BUMP_DOWN, TAG_HIDE } from '../seed/thread-v2'
22
23
 
23
24
  type PostProps = Pick<ThreadItemPost, 'moreReplies' | 'opThread'>
24
25
  const props = (overrides: Partial<PostProps> = {}): PostProps => ({
@@ -43,12 +44,14 @@ describe('appview thread views v2', () => {
43
44
  let network: TestNetwork
44
45
  let agent: AtpAgent
45
46
  let labelerDid: string
46
- let sc: SeedClient
47
+ let sc: SeedClient<TestNetwork>
47
48
 
48
49
  beforeAll(async () => {
49
50
  network = await TestNetwork.create({
50
51
  bsky: {
51
52
  maxThreadParents: 15,
53
+ threadTagsBumpDown: new Set([TAG_BUMP_DOWN]),
54
+ threadTagsHide: new Set([TAG_HIDE]),
52
55
  },
53
56
  dbPostgresSchema: 'bsky_views_thread_v_two',
54
57
  })
@@ -1209,13 +1212,7 @@ describe('appview thread views v2', () => {
1209
1212
  let seed: Awaited<ReturnType<typeof seeds.blockDeletionAuth>>
1210
1213
 
1211
1214
  beforeAll(async () => {
1212
- seed = await seeds.blockDeletionAuth(sc)
1213
- await createLabel({
1214
- src: labelerDid,
1215
- uri: seed.users.auth.did,
1216
- cid: '',
1217
- val: '!no-unauthenticated',
1218
- })
1215
+ seed = await seeds.blockDeletionAuth(sc, labelerDid)
1219
1216
  await network.processAll()
1220
1217
  })
1221
1218
 
@@ -1964,26 +1961,141 @@ describe('appview thread views v2', () => {
1964
1961
  })
1965
1962
  })
1966
1963
 
1967
- const createLabel = async (opts: {
1968
- src?: string
1969
- uri: string
1970
- cid: string
1971
- val: string
1972
- exp?: string
1973
- }) => {
1974
- await network.bsky.db.db
1975
- .insertInto('label')
1976
- .values({
1977
- uri: opts.uri,
1978
- cid: opts.cid,
1979
- val: opts.val,
1980
- cts: new Date().toISOString(),
1981
- exp: opts.exp ?? null,
1982
- neg: false,
1983
- src: opts.src ?? labelerDid,
1964
+ describe('tags', () => {
1965
+ let seed: Awaited<ReturnType<typeof seeds.tags>>
1966
+
1967
+ beforeAll(async () => {
1968
+ seed = await seeds.tags(sc)
1969
+ await network.processAll()
1970
+ })
1971
+
1972
+ describe('when prioritizing followed users', () => {
1973
+ const prioritizeFollowedUsers = true
1974
+
1975
+ it('considers tags for bumping down and hiding', async () => {
1976
+ const { data } = await agent.app.bsky.unspecced.getPostThreadV2(
1977
+ {
1978
+ anchor: seed.root.ref.uriStr,
1979
+ sort: 'newest',
1980
+ prioritizeFollowedUsers,
1981
+ },
1982
+ {
1983
+ headers: await network.serviceHeaders(
1984
+ seed.users.viewer.did,
1985
+ ids.AppBskyUnspeccedGetPostThreadV2,
1986
+ ),
1987
+ },
1988
+ )
1989
+ const { thread: t, hasHiddenReplies } = data
1990
+
1991
+ expect(hasHiddenReplies).toBe(true)
1992
+ assertPosts(t)
1993
+ expect(t).toEqual([
1994
+ expect.objectContaining({ uri: seed.root.ref.uriStr }),
1995
+ // OP (down overridden).
1996
+ expect.objectContaining({ uri: seed.r['3'].ref.uriStr }),
1997
+ // Viewer (hide overridden).
1998
+ expect.objectContaining({ uri: seed.r['4'].ref.uriStr }),
1999
+ // Following (hide overridden).
2000
+ expect.objectContaining({ uri: seed.r['5'].ref.uriStr }),
2001
+ // Fot following.
2002
+ expect.objectContaining({ uri: seed.r['0'].ref.uriStr }),
2003
+ expect.objectContaining({ uri: seed.r['0.0'].ref.uriStr }),
2004
+ expect.objectContaining({ uri: seed.r['0.1'].ref.uriStr }),
2005
+ // Down.
2006
+ expect.objectContaining({ uri: seed.r['1'].ref.uriStr }),
2007
+ expect.objectContaining({ uri: seed.r['1.0'].ref.uriStr }),
2008
+ expect.objectContaining({ uri: seed.r['1.1'].ref.uriStr }),
2009
+ ])
2010
+ })
2011
+
2012
+ it('finds the hidden by tag', async () => {
2013
+ const { data } = await agent.app.bsky.unspecced.getPostThreadHiddenV2(
2014
+ {
2015
+ anchor: seed.root.ref.uriStr,
2016
+ prioritizeFollowedUsers,
2017
+ },
2018
+ {
2019
+ headers: await network.serviceHeaders(
2020
+ seed.users.viewer.did,
2021
+ ids.AppBskyUnspeccedGetPostThreadHiddenV2,
2022
+ ),
2023
+ },
2024
+ )
2025
+ const { thread: t } = data
2026
+
2027
+ assertHiddenPosts(t)
2028
+ expect(t).toEqual([
2029
+ // Hide.
2030
+ expect.objectContaining({ uri: seed.r['2'].ref.uriStr }),
2031
+ ])
1984
2032
  })
1985
- .execute()
1986
- }
2033
+ })
2034
+
2035
+ describe('when not prioritizing followed users', () => {
2036
+ const prioritizeFollowedUsers = false
2037
+
2038
+ it('considers tags for bumping down and hiding', async () => {
2039
+ const { data } = await agent.app.bsky.unspecced.getPostThreadV2(
2040
+ {
2041
+ anchor: seed.root.ref.uriStr,
2042
+ sort: 'newest',
2043
+ prioritizeFollowedUsers,
2044
+ },
2045
+ {
2046
+ headers: await network.serviceHeaders(
2047
+ seed.users.viewer.did,
2048
+ ids.AppBskyUnspeccedGetPostThreadV2,
2049
+ ),
2050
+ },
2051
+ )
2052
+ const { thread: t, hasHiddenReplies } = data
2053
+
2054
+ expect(hasHiddenReplies).toBe(true)
2055
+ assertPosts(t)
2056
+ expect(t).toEqual([
2057
+ expect.objectContaining({ uri: seed.root.ref.uriStr }),
2058
+ // OP (down overridden).
2059
+ expect.objectContaining({ uri: seed.r['3'].ref.uriStr }),
2060
+ // Viewer (hide overriden).
2061
+ expect.objectContaining({ uri: seed.r['4'].ref.uriStr }),
2062
+ // Following was hidden because not prioritizing.
2063
+ // Not following.
2064
+ expect.objectContaining({ uri: seed.r['0'].ref.uriStr }),
2065
+ expect.objectContaining({ uri: seed.r['0.0'].ref.uriStr }),
2066
+ expect.objectContaining({ uri: seed.r['0.1'].ref.uriStr }),
2067
+ // Down.
2068
+ expect.objectContaining({ uri: seed.r['1'].ref.uriStr }),
2069
+ expect.objectContaining({ uri: seed.r['1.0'].ref.uriStr }),
2070
+ expect.objectContaining({ uri: seed.r['1.1'].ref.uriStr }),
2071
+ ])
2072
+ })
2073
+
2074
+ it('finds the hidden by tag', async () => {
2075
+ const { data } = await agent.app.bsky.unspecced.getPostThreadHiddenV2(
2076
+ {
2077
+ anchor: seed.root.ref.uriStr,
2078
+ prioritizeFollowedUsers,
2079
+ },
2080
+ {
2081
+ headers: await network.serviceHeaders(
2082
+ seed.users.viewer.did,
2083
+ ids.AppBskyUnspeccedGetPostThreadHiddenV2,
2084
+ ),
2085
+ },
2086
+ )
2087
+ const { thread: t } = data
2088
+
2089
+ assertHiddenPosts(t)
2090
+ expect(t).toEqual([
2091
+ // Following (hide).
2092
+ expect.objectContaining({ uri: seed.r['5'].ref.uriStr }),
2093
+ // Hide.
2094
+ expect.objectContaining({ uri: seed.r['2'].ref.uriStr }),
2095
+ ])
2096
+ })
2097
+ })
2098
+ })
1987
2099
  })
1988
2100
 
1989
2101
  function assertPosts(