@atproto/repo 0.8.12 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/LICENSE.txt +1 -1
  3. package/dist/block-map.d.ts +15 -16
  4. package/dist/block-map.d.ts.map +1 -1
  5. package/dist/block-map.js +9 -44
  6. package/dist/block-map.js.map +1 -1
  7. package/dist/car.d.ts +8 -8
  8. package/dist/car.d.ts.map +1 -1
  9. package/dist/car.js +107 -37
  10. package/dist/car.js.map +1 -1
  11. package/dist/cid-set.d.ts +8 -7
  12. package/dist/cid-set.d.ts.map +1 -1
  13. package/dist/cid-set.js +11 -4
  14. package/dist/cid-set.js.map +1 -1
  15. package/dist/data-diff.d.ts +10 -10
  16. package/dist/data-diff.d.ts.map +1 -1
  17. package/dist/data-diff.js.map +1 -1
  18. package/dist/error.d.ts +10 -10
  19. package/dist/error.d.ts.map +1 -1
  20. package/dist/error.js.map +1 -1
  21. package/dist/logger.d.ts.map +1 -1
  22. package/dist/logger.js +1 -0
  23. package/dist/logger.js.map +1 -1
  24. package/dist/mst/mst.d.ts +29 -29
  25. package/dist/mst/mst.d.ts.map +1 -1
  26. package/dist/mst/mst.js +12 -13
  27. package/dist/mst/mst.js.map +1 -1
  28. package/dist/mst/util.d.ts +2 -2
  29. package/dist/mst/util.d.ts.map +1 -1
  30. package/dist/mst/util.js +19 -40
  31. package/dist/mst/util.js.map +1 -1
  32. package/dist/parse.d.ts +6 -7
  33. package/dist/parse.d.ts.map +1 -1
  34. package/dist/parse.js +2 -3
  35. package/dist/parse.js.map +1 -1
  36. package/dist/readable-repo.d.ts +6 -7
  37. package/dist/readable-repo.d.ts.map +1 -1
  38. package/dist/readable-repo.js +0 -1
  39. package/dist/readable-repo.js.map +1 -1
  40. package/dist/repo.d.ts +4 -4
  41. package/dist/repo.d.ts.map +1 -1
  42. package/dist/repo.js +11 -10
  43. package/dist/repo.js.map +1 -1
  44. package/dist/storage/memory-blockstore.d.ts +9 -9
  45. package/dist/storage/memory-blockstore.d.ts.map +1 -1
  46. package/dist/storage/memory-blockstore.js.map +1 -1
  47. package/dist/storage/readable-blockstore.d.ts +11 -12
  48. package/dist/storage/readable-blockstore.d.ts.map +1 -1
  49. package/dist/storage/readable-blockstore.js +2 -36
  50. package/dist/storage/readable-blockstore.js.map +1 -1
  51. package/dist/storage/sync-storage.d.ts +5 -5
  52. package/dist/storage/sync-storage.d.ts.map +1 -1
  53. package/dist/storage/sync-storage.js.map +1 -1
  54. package/dist/storage/types.d.ts +25 -26
  55. package/dist/storage/types.d.ts.map +1 -1
  56. package/dist/storage/types.js +0 -1
  57. package/dist/storage/types.js.map +1 -1
  58. package/dist/sync/consumer.d.ts +3 -3
  59. package/dist/sync/consumer.d.ts.map +1 -1
  60. package/dist/sync/consumer.js +1 -1
  61. package/dist/sync/consumer.js.map +1 -1
  62. package/dist/sync/provider.d.ts +3 -3
  63. package/dist/sync/provider.d.ts.map +1 -1
  64. package/dist/sync/provider.js.map +1 -1
  65. package/dist/types.d.ts +127 -100
  66. package/dist/types.d.ts.map +1 -1
  67. package/dist/types.js +53 -13
  68. package/dist/types.js.map +1 -1
  69. package/dist/util.d.ts +8 -3
  70. package/dist/util.d.ts.map +1 -1
  71. package/dist/util.js +33 -17
  72. package/dist/util.js.map +1 -1
  73. package/package.json +6 -7
  74. package/src/block-map.ts +31 -28
  75. package/src/car.ts +124 -46
  76. package/src/cid-set.ts +16 -10
  77. package/src/data-diff.ts +10 -10
  78. package/src/error.ts +6 -6
  79. package/src/logger.ts +1 -0
  80. package/src/mst/mst.ts +24 -28
  81. package/src/mst/util.ts +24 -11
  82. package/src/parse.ts +8 -10
  83. package/src/readable-repo.ts +6 -9
  84. package/src/repo.ts +13 -12
  85. package/src/storage/memory-blockstore.ts +8 -8
  86. package/src/storage/readable-blockstore.ts +12 -15
  87. package/src/storage/sync-storage.ts +4 -4
  88. package/src/storage/types.ts +25 -27
  89. package/src/sync/consumer.ts +5 -5
  90. package/src/sync/provider.ts +10 -7
  91. package/src/types.ts +82 -43
  92. package/src/util.ts +31 -16
  93. package/tests/_keys.ts +156 -156
  94. package/tests/_util.ts +28 -14
  95. package/tests/car.test.ts +31 -13
  96. package/tests/commit-proof-fixtures.json +79 -57
  97. package/tests/commit-proofs.test.ts +3 -3
  98. package/tests/covering-proofs.test.ts +6 -6
  99. package/tests/mst.test.ts +18 -19
  100. package/tests/proofs.test.ts +8 -8
  101. package/tests/repo.test.ts +1 -1
  102. package/tests/sync.test.ts +3 -6
  103. package/bench/mst.bench.ts +0 -165
  104. package/bench/repo.bench.ts +0 -48
  105. package/tsconfig.tests.tsbuildinfo +0 -1
package/src/data-diff.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { CID } from 'multiformats'
1
+ import { Cid } from '@atproto/lex-data'
2
2
  import { BlockMap } from './block-map'
3
3
  import { CidSet } from './cid-set'
4
4
  import { MST, NodeEntry, mstDiff } from './mst'
@@ -37,7 +37,7 @@ export class DataDiff {
37
37
  }
38
38
  }
39
39
 
40
- leafAdd(key: string, cid: CID) {
40
+ leafAdd(key: string, cid: Cid) {
41
41
  this.adds[key] = { key, cid }
42
42
  if (this.removedCids.has(cid)) {
43
43
  this.removedCids.delete(cid)
@@ -46,14 +46,14 @@ export class DataDiff {
46
46
  }
47
47
  }
48
48
 
49
- leafUpdate(key: string, prev: CID, cid: CID) {
49
+ leafUpdate(key: string, prev: Cid, cid: Cid) {
50
50
  if (prev.equals(cid)) return
51
51
  this.updates[key] = { key, prev, cid }
52
52
  this.removedCids.add(prev)
53
53
  this.newLeafCids.add(cid)
54
54
  }
55
55
 
56
- leafDelete(key: string, cid: CID) {
56
+ leafDelete(key: string, cid: Cid) {
57
57
  this.deletes[key] = { key, cid }
58
58
  if (this.newLeafCids.has(cid)) {
59
59
  this.newLeafCids.delete(cid)
@@ -62,7 +62,7 @@ export class DataDiff {
62
62
  }
63
63
  }
64
64
 
65
- treeAdd(cid: CID, bytes: Uint8Array) {
65
+ treeAdd(cid: Cid, bytes: Uint8Array) {
66
66
  if (this.removedCids.has(cid)) {
67
67
  this.removedCids.delete(cid)
68
68
  } else {
@@ -70,7 +70,7 @@ export class DataDiff {
70
70
  }
71
71
  }
72
72
 
73
- treeDelete(cid: CID) {
73
+ treeDelete(cid: Cid) {
74
74
  if (this.newMstBlocks.has(cid)) {
75
75
  this.newMstBlocks.delete(cid)
76
76
  } else {
@@ -102,16 +102,16 @@ export class DataDiff {
102
102
 
103
103
  export type DataAdd = {
104
104
  key: string
105
- cid: CID
105
+ cid: Cid
106
106
  }
107
107
 
108
108
  export type DataUpdate = {
109
109
  key: string
110
- prev: CID
111
- cid: CID
110
+ prev: Cid
111
+ cid: Cid
112
112
  }
113
113
 
114
114
  export type DataDelete = {
115
115
  key: string
116
- cid: CID
116
+ cid: Cid
117
117
  }
package/src/error.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { CID } from 'multiformats/cid'
1
+ import { Cid } from '@atproto/lex-data'
2
2
 
3
3
  export class MissingBlockError extends Error {
4
4
  constructor(
5
- public cid: CID,
5
+ public cid: Cid,
6
6
  def?: string,
7
7
  ) {
8
8
  let msg = `block not found: ${cid.toString()}`
@@ -16,7 +16,7 @@ export class MissingBlockError extends Error {
16
16
  export class MissingBlocksError extends Error {
17
17
  constructor(
18
18
  public context: string,
19
- public cids: CID[],
19
+ public cids: Cid[],
20
20
  ) {
21
21
  const cidStr = cids.map((c) => c.toString())
22
22
  super(`missing ${context} blocks: ${cidStr}`)
@@ -25,8 +25,8 @@ export class MissingBlocksError extends Error {
25
25
 
26
26
  export class MissingCommitBlocksError extends Error {
27
27
  constructor(
28
- public commit: CID,
29
- public cids: CID[],
28
+ public commit: Cid,
29
+ public cids: Cid[],
30
30
  ) {
31
31
  const cidStr = cids.map((c) => c.toString())
32
32
  super(`missing blocks for commit ${commit.toString()}: ${cidStr}`)
@@ -35,7 +35,7 @@ export class MissingCommitBlocksError extends Error {
35
35
 
36
36
  export class UnexpectedObjectError extends Error {
37
37
  constructor(
38
- public cid: CID,
38
+ public cid: Cid,
39
39
  public def: string,
40
40
  ) {
41
41
  super(`unexpected object at ${cid.toString()}, expected: ${def}`)
package/src/logger.ts CHANGED
@@ -1,3 +1,4 @@
1
+ // @TODO remove dependency on @atproto/common and subsystemLogger
1
2
  import { subsystemLogger } from '@atproto/common'
2
3
 
3
4
  export const logger: ReturnType<typeof subsystemLogger> =
package/src/mst/mst.ts CHANGED
@@ -1,14 +1,12 @@
1
- /* eslint-disable import/no-deprecated */
2
-
3
- import { CID } from 'multiformats'
4
1
  import { z } from 'zod'
5
- import { cidForCbor, dataToCborBlock, schema as common } from '@atproto/common'
2
+ import { cidForLex, encode } from '@atproto/lex-cbor'
3
+ import { Cid, cidForCbor } from '@atproto/lex-data'
6
4
  import { BlockMap } from '../block-map'
7
5
  import { CidSet } from '../cid-set'
8
6
  import { MissingBlockError, MissingBlocksError } from '../error'
9
7
  import * as parse from '../parse'
10
8
  import { ReadableBlockstore } from '../storage'
11
- import { CarBlock } from '../types'
9
+ import { CarBlock, schema } from '../types'
12
10
  import * as util from './util'
13
11
 
14
12
  /**
@@ -18,7 +16,7 @@ import * as util from './util'
18
16
  * Keys are laid out in alphabetic order.
19
17
  * The key insight of an MST is that each key is hashed and starting 0s are counted
20
18
  * to determine which layer it falls on (5 zeros for ~32 fanout).
21
- * This is a merkle tree, so each subtree is referred to by it's hash (CID).
19
+ * This is a merkle tree, so each subtree is referred to by it's hash (Cid).
22
20
  * When a leaf is changed, ever tree on the path to that leaf is changed as well,
23
21
  * thereby updating the root hash.
24
22
  *
@@ -44,11 +42,11 @@ import * as util from './util'
44
42
  * Then the first will be described as `prefix: 0, key: 'bsky/posts/abcdefg'`,
45
43
  * and the second will be described as `prefix: 16, key: 'hi'.`
46
44
  */
47
- const subTreePointer = z.nullable(common.cid)
45
+ const subTreePointer = z.nullable(schema.cid)
48
46
  const treeEntry = z.object({
49
47
  p: z.number(), // prefix count of ascii chars that this key shares with the prev key
50
- k: common.bytes, // the rest of the key outside the shared prefix
51
- v: common.cid, // value
48
+ k: schema.bytes, // the rest of the key outside the shared prefix
49
+ v: schema.cid, // value
52
50
  t: subTreePointer, // next subtree (to the right of leaf)
53
51
  })
54
52
  const nodeData = z.object({
@@ -72,12 +70,12 @@ export class MST {
72
70
  storage: ReadableBlockstore
73
71
  entries: NodeEntry[] | null
74
72
  layer: number | null
75
- pointer: CID
73
+ pointer: Cid
76
74
  outdatedPointer = false
77
75
 
78
76
  constructor(
79
77
  storage: ReadableBlockstore,
80
- pointer: CID,
78
+ pointer: Cid,
81
79
  entries: NodeEntry[] | null,
82
80
  layer: number | null,
83
81
  ) {
@@ -104,14 +102,14 @@ export class MST {
104
102
  ): Promise<MST> {
105
103
  const { layer = null } = opts || {}
106
104
  const entries = await util.deserializeNodeData(storage, data, opts)
107
- const pointer = await cidForCbor(data)
105
+ const pointer = await cidForLex(data)
108
106
  return new MST(storage, pointer, entries, layer)
109
107
  }
110
108
 
111
109
  // this is really a *lazy* load, doesn't actually touch storage
112
110
  static load(
113
111
  storage: ReadableBlockstore,
114
- cid: CID,
112
+ cid: Cid,
115
113
  opts?: Partial<MstOpts>,
116
114
  ): MST {
117
115
  const { layer = null } = opts || {}
@@ -147,12 +145,12 @@ export class MST {
147
145
 
148
146
  return this.entries
149
147
  }
150
- throw new Error('No entries or CID provided')
148
+ throw new Error('No entries or Cid provided')
151
149
  }
152
150
 
153
151
  // We don't hash the node on every mutation for performance reasons
154
152
  // Instead we keep track of whether the pointer is outdated and only (recursively) calculate when needed
155
- async getPointer(): Promise<CID> {
153
+ async getPointer(): Promise<Cid> {
156
154
  if (!this.outdatedPointer) return this.pointer
157
155
  const { cid } = await this.serialize()
158
156
  this.pointer = cid
@@ -160,7 +158,7 @@ export class MST {
160
158
  return this.pointer
161
159
  }
162
160
 
163
- async serialize(): Promise<{ cid: CID; bytes: Uint8Array }> {
161
+ async serialize(): Promise<{ cid: Cid; bytes: Uint8Array }> {
164
162
  let entries = await this.getEntries()
165
163
  const outdated = entries.filter(
166
164
  (e) => e.isTree() && e.outdatedPointer,
@@ -170,11 +168,9 @@ export class MST {
170
168
  entries = await this.getEntries()
171
169
  }
172
170
  const data = util.serializeNodeData(entries)
173
- const block = await dataToCborBlock(data)
174
- return {
175
- cid: block.cid,
176
- bytes: block.bytes,
177
- }
171
+ const bytes = encode(data)
172
+ const cid = await cidForCbor(bytes)
173
+ return { cid, bytes }
178
174
  }
179
175
 
180
176
  // In most cases, we get the layer of a node from a hint on creation
@@ -210,7 +206,7 @@ export class MST {
210
206
  // -------------------
211
207
 
212
208
  // Return the necessary blocks to persist the MST to repo storage
213
- async getUnstoredBlocks(): Promise<{ root: CID; blocks: BlockMap }> {
209
+ async getUnstoredBlocks(): Promise<{ root: Cid; blocks: BlockMap }> {
214
210
  const blocks = new BlockMap()
215
211
  const pointer = await this.getPointer()
216
212
  const alreadyHas = await this.storage.has(pointer)
@@ -229,7 +225,7 @@ export class MST {
229
225
 
230
226
  // Adds a new leaf for the given key/value pair
231
227
  // Throws if a leaf with that key already exists
232
- async add(key: string, value: CID, knownZeros?: number): Promise<MST> {
228
+ async add(key: string, value: Cid, knownZeros?: number): Promise<MST> {
233
229
  util.ensureValidMstKey(key)
234
230
  const keyZeros = knownZeros ?? (await util.leadingZerosOnHash(key))
235
231
  const layer = await this.getLayer()
@@ -299,7 +295,7 @@ export class MST {
299
295
  }
300
296
 
301
297
  // Gets the value at the given key
302
- async get(key: string): Promise<CID | null> {
298
+ async get(key: string): Promise<Cid | null> {
303
299
  const index = await this.findGtOrEqualLeafIndex(key)
304
300
  const found = await this.atIndex(index)
305
301
  if (found && found.isLeaf() && found.key === key) {
@@ -314,7 +310,7 @@ export class MST {
314
310
 
315
311
  // Edits the value at the given key
316
312
  // Throws if the given key does not exist
317
- async update(key: string, value: CID): Promise<MST> {
313
+ async update(key: string, value: Cid): Promise<MST> {
318
314
  util.ensureValidMstKey(key)
319
315
  const index = await this.findGtOrEqualLeafIndex(key)
320
316
  const found = await this.atIndex(index)
@@ -767,8 +763,8 @@ export class MST {
767
763
  }
768
764
  }
769
765
 
770
- async cidsForPath(key: string): Promise<CID[]> {
771
- const cids: CID[] = [await this.getPointer()]
766
+ async cidsForPath(key: string): Promise<Cid[]> {
767
+ const cids: Cid[] = [await this.getPointer()]
772
768
  const index = await this.findGtOrEqualLeafIndex(key)
773
769
  const found = await this.atIndex(index)
774
770
  if (found && found.isLeaf() && found.key === key) {
@@ -875,7 +871,7 @@ export class MST {
875
871
  export class Leaf {
876
872
  constructor(
877
873
  public key: string,
878
- public value: CID,
874
+ public value: Cid,
879
875
  ) {}
880
876
 
881
877
  isTree(): this is MST {
package/src/mst/util.ts CHANGED
@@ -1,12 +1,25 @@
1
- /* eslint-disable import/no-deprecated */
2
-
3
- import { CID } from 'multiformats'
4
- import * as uint8arrays from 'uint8arrays'
5
- import { cidForCbor } from '@atproto/common'
6
1
  import { sha256 } from '@atproto/crypto'
2
+ import { cidForLex } from '@atproto/lex-cbor'
3
+ import { Cid } from '@atproto/lex-data'
7
4
  import { ReadableBlockstore } from '../storage'
8
5
  import { Leaf, MST, MstOpts, NodeData, NodeEntry } from './mst'
9
6
 
7
+ function toAscii(bytes: Uint8Array): string {
8
+ let string = ''
9
+ for (let i = 0; i < bytes.length; i++) {
10
+ string += String.fromCharCode(bytes[i])
11
+ }
12
+ return string
13
+ }
14
+
15
+ function fromAscii(str: string): Uint8Array {
16
+ const bytes = new Uint8Array(str.length)
17
+ for (let i = 0; i < str.length; i++) {
18
+ bytes[i] = str.charCodeAt(i)
19
+ }
20
+ return bytes
21
+ }
22
+
10
23
  export const leadingZerosOnHash = async (key: string | Uint8Array) => {
11
24
  const hash = await sha256(key)
12
25
  let leadingZeros = 0
@@ -48,8 +61,8 @@ export const deserializeNodeData = async (
48
61
  }
49
62
  let lastKey = ''
50
63
  for (const entry of data.e) {
51
- const keyStr = uint8arrays.toString(entry.k, 'ascii')
52
- const key = lastKey.slice(0, entry.p) + keyStr
64
+ const keyStr = toAscii(entry.k)
65
+ const key = `${lastKey.slice(0, entry.p)}${keyStr}`
53
66
  ensureValidMstKey(key)
54
67
  entries.push(new Leaf(key, entry.v))
55
68
  lastKey = key
@@ -82,7 +95,7 @@ export const serializeNodeData = (entries: NodeEntry[]): NodeData => {
82
95
  throw new Error('Not a valid node: two subtrees next to each other')
83
96
  }
84
97
  i++
85
- let subtree: CID | null = null
98
+ let subtree: Cid | null = null
86
99
  if (next?.isTree()) {
87
100
  subtree = next.pointer
88
101
  i++
@@ -91,7 +104,7 @@ export const serializeNodeData = (entries: NodeEntry[]): NodeData => {
91
104
  const prefixLen = countPrefixLen(lastKey, leaf.key)
92
105
  data.e.push({
93
106
  p: prefixLen,
94
- k: uint8arrays.fromString(leaf.key.slice(prefixLen), 'ascii'),
107
+ k: fromAscii(leaf.key.slice(prefixLen)),
95
108
  v: leaf.value,
96
109
  t: subtree,
97
110
  })
@@ -111,9 +124,9 @@ export const countPrefixLen = (a: string, b: string): number => {
111
124
  return i
112
125
  }
113
126
 
114
- export const cidForEntries = async (entries: NodeEntry[]): Promise<CID> => {
127
+ export const cidForEntries = async (entries: NodeEntry[]): Promise<Cid> => {
115
128
  const data = serializeNodeData(entries)
116
- return cidForCbor(data)
129
+ return cidForLex(data)
117
130
  }
118
131
 
119
132
  export const isValidMstKey = (str: string): boolean => {
package/src/parse.ts CHANGED
@@ -1,16 +1,14 @@
1
- /* eslint-disable import/no-deprecated */
2
-
3
- import { CID } from 'multiformats/cid'
4
- import { cborDecode, check } from '@atproto/common'
5
- import { RepoRecord } from '@atproto/lexicon'
1
+ import { check } from '@atproto/common-web'
2
+ import { decode } from '@atproto/lex-cbor'
3
+ import { Cid, LexMap } from '@atproto/lex-data'
6
4
  import { BlockMap } from './block-map'
7
5
  import { MissingBlockError, UnexpectedObjectError } from './error'
8
6
  import { cborToLexRecord } from './util'
9
7
 
10
8
  export const getAndParseRecord = async (
11
9
  blocks: BlockMap,
12
- cid: CID,
13
- ): Promise<{ record: RepoRecord; bytes: Uint8Array }> => {
10
+ cid: Cid,
11
+ ): Promise<{ record: LexMap; bytes: Uint8Array }> => {
14
12
  const bytes = blocks.get(cid)
15
13
  if (!bytes) {
16
14
  throw new MissingBlockError(cid, 'record')
@@ -21,7 +19,7 @@ export const getAndParseRecord = async (
21
19
 
22
20
  export const getAndParseByDef = async <T>(
23
21
  blocks: BlockMap,
24
- cid: CID,
22
+ cid: Cid,
25
23
  def: check.Def<T>,
26
24
  ): Promise<{ obj: T; bytes: Uint8Array }> => {
27
25
  const bytes = blocks.get(cid)
@@ -33,10 +31,10 @@ export const getAndParseByDef = async <T>(
33
31
 
34
32
  export const parseObjByDef = <T>(
35
33
  bytes: Uint8Array,
36
- cid: CID,
34
+ cid: Cid,
37
35
  def: check.Def<T>,
38
36
  ): { obj: T; bytes: Uint8Array } => {
39
- const obj = cborDecode(bytes)
37
+ const obj = decode(bytes)
40
38
  const res = def.schema.safeParse(obj)
41
39
  if (res.success) {
42
40
  return { obj: res.data, bytes }
@@ -1,7 +1,4 @@
1
- /* eslint-disable import/no-deprecated */
2
-
3
- import { CID } from 'multiformats/cid'
4
- import { RepoRecord } from '@atproto/lexicon'
1
+ import { Cid, LexMap } from '@atproto/lex-data'
5
2
  import { MissingBlocksError } from './error'
6
3
  import log from './logger'
7
4
  import { MST } from './mst'
@@ -14,14 +11,14 @@ type Params = {
14
11
  storage: ReadableBlockstore
15
12
  data: MST
16
13
  commit: Commit
17
- cid: CID
14
+ cid: Cid
18
15
  }
19
16
 
20
17
  export class ReadableRepo {
21
18
  storage: ReadableBlockstore
22
19
  data: MST
23
20
  commit: Commit
24
- cid: CID
21
+ cid: Cid
25
22
 
26
23
  constructor(params: Params) {
27
24
  this.storage = params.storage
@@ -30,7 +27,7 @@ export class ReadableRepo {
30
27
  this.cid = params.cid
31
28
  }
32
29
 
33
- static async load(storage: ReadableBlockstore, commitCid: CID) {
30
+ static async load(storage: ReadableBlockstore, commitCid: Cid) {
34
31
  const commit = await storage.readObj(commitCid, def.versionedCommit)
35
32
  const data = await MST.load(storage, commit.data)
36
33
  log.info({ did: commit.did }, 'loaded repo for')
@@ -53,8 +50,8 @@ export class ReadableRepo {
53
50
  async *walkRecords(from?: string): AsyncIterable<{
54
51
  collection: string
55
52
  rkey: string
56
- cid: CID
57
- record: RepoRecord
53
+ cid: Cid
54
+ record: LexMap
58
55
  }> {
59
56
  for await (const leaf of this.data.walkLeavesFrom(from ?? '')) {
60
57
  const { collection, rkey } = util.parseDataKey(leaf.key)
package/src/repo.ts CHANGED
@@ -1,9 +1,7 @@
1
- /* eslint-disable import/no-deprecated */
2
-
3
- import { CID } from 'multiformats/cid'
4
- import { TID, dataToCborBlock } from '@atproto/common'
1
+ import { TID } from '@atproto/common-web'
5
2
  import * as crypto from '@atproto/crypto'
6
- import { lexToIpld } from '@atproto/lexicon'
3
+ import { encode } from '@atproto/lex-cbor'
4
+ import { Cid, cidForCbor } from '@atproto/lex-data'
7
5
  import { BlockMap } from './block-map'
8
6
  import { CidSet } from './cid-set'
9
7
  import { DataDiff } from './data-diff'
@@ -25,7 +23,7 @@ type Params = {
25
23
  storage: RepoStorage
26
24
  data: MST
27
25
  commit: Commit
28
- cid: CID
26
+ cid: Cid
29
27
  }
30
28
 
31
29
  export class Repo extends ReadableRepo {
@@ -101,7 +99,7 @@ export class Repo extends ReadableRepo {
101
99
  return Repo.createFromCommit(storage, commit)
102
100
  }
103
101
 
104
- static async load(storage: RepoStorage, cid?: CID) {
102
+ static async load(storage: RepoStorage, cid?: Cid) {
105
103
  const commitCid = cid || (await storage.getRoot())
106
104
  if (!commitCid) {
107
105
  throw new Error('No cid provided and none in storage')
@@ -171,15 +169,18 @@ export class Repo extends ReadableRepo {
171
169
  },
172
170
  keypair,
173
171
  )
174
- const commitBlock = await dataToCborBlock(lexToIpld(commit))
175
- if (!commitBlock.cid.equals(this.cid)) {
176
- newBlocks.set(commitBlock.cid, commitBlock.bytes)
177
- relevantBlocks.set(commitBlock.cid, commitBlock.bytes)
172
+
173
+ const commitBytes = encode(commit)
174
+ const commitCid = await cidForCbor(commitBytes)
175
+
176
+ if (!commitCid.equals(this.cid)) {
177
+ newBlocks.set(commitCid, commitBytes)
178
+ relevantBlocks.set(commitCid, commitBytes)
178
179
  removedCids.add(this.cid)
179
180
  }
180
181
 
181
182
  return {
182
- cid: commitBlock.cid,
183
+ cid: commitCid,
183
184
  rev,
184
185
  since: this.commit.rev,
185
186
  prev: this.cid,
@@ -1,4 +1,4 @@
1
- import { CID } from 'multiformats/cid'
1
+ import { Cid } from '@atproto/lex-data'
2
2
  import { BlockMap } from '../block-map'
3
3
  import { CommitData } from '../types'
4
4
  import { ReadableBlockstore } from './readable-blockstore'
@@ -9,7 +9,7 @@ export class MemoryBlockstore
9
9
  implements RepoStorage
10
10
  {
11
11
  blocks: BlockMap
12
- root: CID | null = null
12
+ root: Cid | null = null
13
13
  rev: string | null = null
14
14
 
15
15
  constructor(blocks?: BlockMap) {
@@ -20,23 +20,23 @@ export class MemoryBlockstore
20
20
  }
21
21
  }
22
22
 
23
- async getRoot(): Promise<CID | null> {
23
+ async getRoot(): Promise<Cid | null> {
24
24
  return this.root
25
25
  }
26
26
 
27
- async getBytes(cid: CID): Promise<Uint8Array | null> {
27
+ async getBytes(cid: Cid): Promise<Uint8Array | null> {
28
28
  return this.blocks.get(cid) || null
29
29
  }
30
30
 
31
- async has(cid: CID): Promise<boolean> {
31
+ async has(cid: Cid): Promise<boolean> {
32
32
  return this.blocks.has(cid)
33
33
  }
34
34
 
35
- async getBlocks(cids: CID[]): Promise<{ blocks: BlockMap; missing: CID[] }> {
35
+ async getBlocks(cids: Cid[]): Promise<{ blocks: BlockMap; missing: Cid[] }> {
36
36
  return this.blocks.getMany(cids)
37
37
  }
38
38
 
39
- async putBlock(cid: CID, block: Uint8Array): Promise<void> {
39
+ async putBlock(cid: Cid, block: Uint8Array): Promise<void> {
40
40
  this.blocks.set(cid, block)
41
41
  }
42
42
 
@@ -44,7 +44,7 @@ export class MemoryBlockstore
44
44
  this.blocks.addMap(blocks)
45
45
  }
46
46
 
47
- async updateRoot(cid: CID, rev: string): Promise<void> {
47
+ async updateRoot(cid: Cid, rev: string): Promise<void> {
48
48
  this.root = cid
49
49
  this.rev = rev
50
50
  }
@@ -1,29 +1,26 @@
1
- /* eslint-disable import/no-deprecated */
2
-
3
- import { CID } from 'multiformats/cid'
4
- import { check } from '@atproto/common'
5
- import { RepoRecord } from '@atproto/lexicon'
1
+ import { check } from '@atproto/common-web'
2
+ import { Cid, LexMap } from '@atproto/lex-data'
6
3
  import { BlockMap } from '../block-map'
7
4
  import { MissingBlockError } from '../error'
8
- import * as parse from '../parse'
5
+ import { parseObjByDef } from '../parse'
9
6
  import { cborToLexRecord } from '../util'
10
7
 
11
8
  export abstract class ReadableBlockstore {
12
- abstract getBytes(cid: CID): Promise<Uint8Array | null>
13
- abstract has(cid: CID): Promise<boolean>
14
- abstract getBlocks(cids: CID[]): Promise<{ blocks: BlockMap; missing: CID[] }>
9
+ abstract getBytes(cid: Cid): Promise<Uint8Array | null>
10
+ abstract has(cid: Cid): Promise<boolean>
11
+ abstract getBlocks(cids: Cid[]): Promise<{ blocks: BlockMap; missing: Cid[] }>
15
12
 
16
13
  async attemptRead<T>(
17
- cid: CID,
14
+ cid: Cid,
18
15
  def: check.Def<T>,
19
16
  ): Promise<{ obj: T; bytes: Uint8Array } | null> {
20
17
  const bytes = await this.getBytes(cid)
21
18
  if (!bytes) return null
22
- return parse.parseObjByDef(bytes, cid, def)
19
+ return parseObjByDef(bytes, cid, def)
23
20
  }
24
21
 
25
22
  async readObjAndBytes<T>(
26
- cid: CID,
23
+ cid: Cid,
27
24
  def: check.Def<T>,
28
25
  ): Promise<{ obj: T; bytes: Uint8Array }> {
29
26
  const read = await this.attemptRead(cid, def)
@@ -33,12 +30,12 @@ export abstract class ReadableBlockstore {
33
30
  return read
34
31
  }
35
32
 
36
- async readObj<T>(cid: CID, def: check.Def<T>): Promise<T> {
33
+ async readObj<T>(cid: Cid, def: check.Def<T>): Promise<T> {
37
34
  const obj = await this.readObjAndBytes(cid, def)
38
35
  return obj.obj
39
36
  }
40
37
 
41
- async attemptReadRecord(cid: CID): Promise<RepoRecord | null> {
38
+ async attemptReadRecord(cid: Cid): Promise<LexMap | null> {
42
39
  try {
43
40
  return await this.readRecord(cid)
44
41
  } catch {
@@ -46,7 +43,7 @@ export abstract class ReadableBlockstore {
46
43
  }
47
44
  }
48
45
 
49
- async readRecord(cid: CID): Promise<RepoRecord> {
46
+ async readRecord(cid: Cid): Promise<LexMap> {
50
47
  const bytes = await this.getBytes(cid)
51
48
  if (!bytes) {
52
49
  throw new MissingBlockError(cid)
@@ -1,4 +1,4 @@
1
- import { CID } from 'multiformats/cid'
1
+ import { Cid } from '@atproto/lex-data'
2
2
  import { BlockMap } from '../block-map'
3
3
  import { ReadableBlockstore } from './readable-blockstore'
4
4
 
@@ -10,13 +10,13 @@ export class SyncStorage extends ReadableBlockstore {
10
10
  super()
11
11
  }
12
12
 
13
- async getBytes(cid: CID): Promise<Uint8Array | null> {
13
+ async getBytes(cid: Cid): Promise<Uint8Array | null> {
14
14
  const got = await this.staged.getBytes(cid)
15
15
  if (got) return got
16
16
  return this.saved.getBytes(cid)
17
17
  }
18
18
 
19
- async getBlocks(cids: CID[]): Promise<{ blocks: BlockMap; missing: CID[] }> {
19
+ async getBlocks(cids: Cid[]): Promise<{ blocks: BlockMap; missing: Cid[] }> {
20
20
  const fromStaged = await this.staged.getBlocks(cids)
21
21
  const fromSaved = await this.saved.getBlocks(fromStaged.missing)
22
22
  const blocks = fromStaged.blocks
@@ -27,7 +27,7 @@ export class SyncStorage extends ReadableBlockstore {
27
27
  }
28
28
  }
29
29
 
30
- async has(cid: CID): Promise<boolean> {
30
+ async has(cid: Cid): Promise<boolean> {
31
31
  return (await this.staged.has(cid)) || (await this.saved.has(cid))
32
32
  }
33
33
  }