@atcute/car 2.0.3 → 2.1.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.
@@ -10,8 +10,37 @@ export declare class RepoEntry {
10
10
  get record(): unknown;
11
11
  }
12
12
  export declare function iterateAtpRepo(buf: Uint8Array): Generator<RepoEntry>;
13
+ /**
14
+ * collects entries from a CAR archive into a mapping of CID string -> actual bytes
15
+ * @param iterator a generator that yields objects with a `cid` and `bytes` property
16
+ * @returns a mapping of CID string -> actual bytes
17
+ */
18
+ export declare function collectBlock(iterator: Generator<{
19
+ cid: CID.Cid;
20
+ bytes: Uint8Array;
21
+ }>): BlockMap;
22
+ /**
23
+ * reads a block from the blockmap and validates it against the provided validation function
24
+ * @param map a mapping of CID string -> actual bytes
25
+ * @param link a CID link to read
26
+ * @param validate a validation function to validate the decoded data
27
+ * @returns the decoded and validated data
28
+ */
29
+ export declare function readBlock<T>(map: BlockMap, link: CID.CidLink, validate: (value: unknown) => value is T): T;
30
+ /** node entry object */
31
+ export interface NodeEntry {
32
+ key: string;
33
+ cid: CID.CidLink;
34
+ }
35
+ /**
36
+ * walks the entries of a Merkle Sorted Tree (MST) in a depth-first manner
37
+ * @param map a mapping of CID string -> actual bytes
38
+ * @param pointer a CID link to the root of the MST
39
+ * @returns a generator that yields the entries of the MST
40
+ */
13
41
  export declare function walkMstEntries(map: BlockMap, pointer: CID.CidLink): Generator<NodeEntry>;
14
42
  export type BlockMap = Map<string, Uint8Array>;
43
+ /** commit object */
15
44
  export interface Commit {
16
45
  version: 3;
17
46
  did: string;
@@ -20,7 +49,13 @@ export interface Commit {
20
49
  prev: CID.CidLink | null;
21
50
  sig: CBOR.Bytes;
22
51
  }
52
+ /**
53
+ * checks if a value is a valid commit object
54
+ * @param value the value to check
55
+ * @returns true if the value is a valid commit object, false otherwise
56
+ */
23
57
  export declare const isCommit: (value: unknown) => value is Commit;
58
+ /** mst tree entry object */
24
59
  export interface TreeEntry {
25
60
  /** count of bytes shared with previous TreeEntry in this Node (if any) */
26
61
  p: number;
@@ -31,15 +66,22 @@ export interface TreeEntry {
31
66
  /** next subtree (to the right of leaf) */
32
67
  t: CID.CidLink | null;
33
68
  }
69
+ /**
70
+ * checks if a value is a valid mst tree entry object
71
+ * @param value the value to check
72
+ * @returns true if the value is a valid mst tree entry object, false otherwise
73
+ */
34
74
  export declare const isTreeEntry: (value: unknown) => value is TreeEntry;
75
+ /** mst node object */
35
76
  export interface MstNode {
36
77
  /** link to sub-tree Node on a lower level and with all keys sorting before keys at this node */
37
78
  l: CID.CidLink | null;
38
79
  /** ordered list of TreeEntry objects */
39
80
  e: TreeEntry[];
40
81
  }
82
+ /**
83
+ * checks if a value is a valid mst node object
84
+ * @param value the value to check
85
+ * @returns true if the value is a valid mst node object, false otherwise
86
+ */
41
87
  export declare const isMstNode: (value: unknown) => value is MstNode;
42
- export interface NodeEntry {
43
- key: string;
44
- cid: CID.CidLink;
45
- }
@@ -26,19 +26,34 @@ export class RepoEntry {
26
26
  export function* iterateAtpRepo(buf) {
27
27
  const { roots, iterate } = readCar(buf);
28
28
  assert(roots.length === 1, `expected only 1 root in the car archive; got=${roots.length}`);
29
- // Collect all archive entries into a mapping of CID string -> actual bytes
30
- const blockmap = new Map();
31
- for (const entry of iterate()) {
32
- blockmap.set(CID.toString(entry.cid), entry.bytes);
33
- }
34
- // Read the head, then walk through the MST tree from there.
35
- const commit = readObject(blockmap, roots[0], isCommit);
29
+ const blockmap = collectBlock(iterate());
30
+ assert(blockmap.size > 0, `expected at least 1 block in the archive; got=${blockmap.size}`);
31
+ const commit = readBlock(blockmap, roots[0], isCommit);
36
32
  for (const { key, cid } of walkMstEntries(blockmap, commit.data)) {
37
33
  const [collection, rkey] = key.split('/');
38
34
  yield new RepoEntry(collection, rkey, cid, blockmap);
39
35
  }
40
36
  }
41
- function readObject(map, link, validate) {
37
+ /**
38
+ * collects entries from a CAR archive into a mapping of CID string -> actual bytes
39
+ * @param iterator a generator that yields objects with a `cid` and `bytes` property
40
+ * @returns a mapping of CID string -> actual bytes
41
+ */
42
+ export function collectBlock(iterator) {
43
+ const blockmap = new Map();
44
+ for (const { cid, bytes } of iterator) {
45
+ blockmap.set(CID.toString(cid), bytes);
46
+ }
47
+ return blockmap;
48
+ }
49
+ /**
50
+ * reads a block from the blockmap and validates it against the provided validation function
51
+ * @param map a mapping of CID string -> actual bytes
52
+ * @param link a CID link to read
53
+ * @param validate a validation function to validate the decoded data
54
+ * @returns the decoded and validated data
55
+ */
56
+ export function readBlock(map, link, validate) {
42
57
  const cid = link.$link;
43
58
  const bytes = map.get(cid);
44
59
  assert(bytes != null, `cid not found in blockmap; cid=${cid}`);
@@ -46,8 +61,14 @@ function readObject(map, link, validate) {
46
61
  assert(validate(data), `validation failed for cid=${cid}`);
47
62
  return data;
48
63
  }
64
+ /**
65
+ * walks the entries of a Merkle Sorted Tree (MST) in a depth-first manner
66
+ * @param map a mapping of CID string -> actual bytes
67
+ * @param pointer a CID link to the root of the MST
68
+ * @returns a generator that yields the entries of the MST
69
+ */
49
70
  export function* walkMstEntries(map, pointer) {
50
- const data = readObject(map, pointer, isMstNode);
71
+ const data = readBlock(map, pointer, isMstNode);
51
72
  const entries = data.e;
52
73
  let lastKey = '';
53
74
  if (data.l !== null) {
@@ -87,6 +108,11 @@ const isBytes = (value) => {
87
108
  }
88
109
  return '$bytes' in value && typeof value.$bytes === 'string';
89
110
  };
111
+ /**
112
+ * checks if a value is a valid commit object
113
+ * @param value the value to check
114
+ * @returns true if the value is a valid commit object, false otherwise
115
+ */
90
116
  export const isCommit = (value) => {
91
117
  if (value === null || typeof value !== 'object') {
92
118
  return false;
@@ -99,6 +125,11 @@ export const isCommit = (value) => {
99
125
  (obj.prev === null || isCidLink(obj.prev)) &&
100
126
  isBytes(obj.sig));
101
127
  };
128
+ /**
129
+ * checks if a value is a valid mst tree entry object
130
+ * @param value the value to check
131
+ * @returns true if the value is a valid mst tree entry object, false otherwise
132
+ */
102
133
  export const isTreeEntry = (value) => {
103
134
  if (value === null || typeof value !== 'object') {
104
135
  return false;
@@ -106,6 +137,11 @@ export const isTreeEntry = (value) => {
106
137
  const obj = value;
107
138
  return (typeof obj.p === 'number' && isBytes(obj.k) && isCidLink(obj.v) && (obj.t === null || isCidLink(obj.t)));
108
139
  };
140
+ /**
141
+ * checks if a value is a valid mst node object
142
+ * @param value the value to check
143
+ * @returns true if the value is a valid mst node object, false otherwise
144
+ */
109
145
  export const isMstNode = (value) => {
110
146
  if (value === null || typeof value !== 'object') {
111
147
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"atproto-repo.js","sourceRoot":"","sources":["../lib/atproto-repo.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"atproto-repo.js","sourceRoot":"","sources":["../lib/atproto-repo.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { iterateAtpRepo, type RepoEntry } from './atproto-repo.js';
2
- export { readCar } from './reader.js';
1
+ export * from './atproto-repo.js';
2
+ export * from './reader.js';
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export { iterateAtpRepo } from './atproto-repo.js';
2
- export { readCar } from './reader.js';
1
+ export * from './atproto-repo.js';
2
+ export * from './reader.js';
3
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAkB,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC"}
@@ -31,14 +31,10 @@ export function* iterateAtpRepo(buf: Uint8Array): Generator<RepoEntry> {
31
31
  const { roots, iterate } = readCar(buf);
32
32
  assert(roots.length === 1, `expected only 1 root in the car archive; got=${roots.length}`);
33
33
 
34
- // Collect all archive entries into a mapping of CID string -> actual bytes
35
- const blockmap: BlockMap = new Map();
36
- for (const entry of iterate()) {
37
- blockmap.set(CID.toString(entry.cid), entry.bytes);
38
- }
34
+ const blockmap = collectBlock(iterate());
35
+ assert(blockmap.size > 0, `expected at least 1 block in the archive; got=${blockmap.size}`);
39
36
 
40
- // Read the head, then walk through the MST tree from there.
41
- const commit = readObject(blockmap, roots[0], isCommit);
37
+ const commit = readBlock(blockmap, roots[0], isCommit);
42
38
  for (const { key, cid } of walkMstEntries(blockmap, commit.data)) {
43
39
  const [collection, rkey] = key.split('/');
44
40
 
@@ -46,7 +42,28 @@ export function* iterateAtpRepo(buf: Uint8Array): Generator<RepoEntry> {
46
42
  }
47
43
  }
48
44
 
49
- function readObject<T>(map: BlockMap, link: CID.CidLink, validate: (value: unknown) => value is T): T {
45
+ /**
46
+ * collects entries from a CAR archive into a mapping of CID string -> actual bytes
47
+ * @param iterator a generator that yields objects with a `cid` and `bytes` property
48
+ * @returns a mapping of CID string -> actual bytes
49
+ */
50
+ export function collectBlock(iterator: Generator<{ cid: CID.Cid; bytes: Uint8Array }>): BlockMap {
51
+ const blockmap: BlockMap = new Map();
52
+ for (const { cid, bytes } of iterator) {
53
+ blockmap.set(CID.toString(cid), bytes);
54
+ }
55
+
56
+ return blockmap;
57
+ }
58
+
59
+ /**
60
+ * reads a block from the blockmap and validates it against the provided validation function
61
+ * @param map a mapping of CID string -> actual bytes
62
+ * @param link a CID link to read
63
+ * @param validate a validation function to validate the decoded data
64
+ * @returns the decoded and validated data
65
+ */
66
+ export function readBlock<T>(map: BlockMap, link: CID.CidLink, validate: (value: unknown) => value is T): T {
50
67
  const cid = link.$link;
51
68
 
52
69
  const bytes = map.get(cid);
@@ -58,8 +75,20 @@ function readObject<T>(map: BlockMap, link: CID.CidLink, validate: (value: unkno
58
75
  return data;
59
76
  }
60
77
 
78
+ /** node entry object */
79
+ export interface NodeEntry {
80
+ key: string;
81
+ cid: CID.CidLink;
82
+ }
83
+
84
+ /**
85
+ * walks the entries of a Merkle Sorted Tree (MST) in a depth-first manner
86
+ * @param map a mapping of CID string -> actual bytes
87
+ * @param pointer a CID link to the root of the MST
88
+ * @returns a generator that yields the entries of the MST
89
+ */
61
90
  export function* walkMstEntries(map: BlockMap, pointer: CID.CidLink): Generator<NodeEntry> {
62
- const data = readObject(map, pointer, isMstNode);
91
+ const data = readBlock(map, pointer, isMstNode);
63
92
  const entries = data.e;
64
93
 
65
94
  let lastKey = '';
@@ -116,6 +145,7 @@ const isBytes = (value: unknown): value is CBOR.Bytes => {
116
145
  return '$bytes' in value && typeof value.$bytes === 'string';
117
146
  };
118
147
 
148
+ /** commit object */
119
149
  export interface Commit {
120
150
  version: 3;
121
151
  did: string;
@@ -125,6 +155,11 @@ export interface Commit {
125
155
  sig: CBOR.Bytes;
126
156
  }
127
157
 
158
+ /**
159
+ * checks if a value is a valid commit object
160
+ * @param value the value to check
161
+ * @returns true if the value is a valid commit object, false otherwise
162
+ */
128
163
  export const isCommit = (value: unknown): value is Commit => {
129
164
  if (value === null || typeof value !== 'object') {
130
165
  return false;
@@ -142,6 +177,7 @@ export const isCommit = (value: unknown): value is Commit => {
142
177
  );
143
178
  };
144
179
 
180
+ /** mst tree entry object */
145
181
  export interface TreeEntry {
146
182
  /** count of bytes shared with previous TreeEntry in this Node (if any) */
147
183
  p: number;
@@ -153,6 +189,11 @@ export interface TreeEntry {
153
189
  t: CID.CidLink | null;
154
190
  }
155
191
 
192
+ /**
193
+ * checks if a value is a valid mst tree entry object
194
+ * @param value the value to check
195
+ * @returns true if the value is a valid mst tree entry object, false otherwise
196
+ */
156
197
  export const isTreeEntry = (value: unknown): value is TreeEntry => {
157
198
  if (value === null || typeof value !== 'object') {
158
199
  return false;
@@ -165,6 +206,7 @@ export const isTreeEntry = (value: unknown): value is TreeEntry => {
165
206
  );
166
207
  };
167
208
 
209
+ /** mst node object */
168
210
  export interface MstNode {
169
211
  /** link to sub-tree Node on a lower level and with all keys sorting before keys at this node */
170
212
  l: CID.CidLink | null;
@@ -172,6 +214,11 @@ export interface MstNode {
172
214
  e: TreeEntry[];
173
215
  }
174
216
 
217
+ /**
218
+ * checks if a value is a valid mst node object
219
+ * @param value the value to check
220
+ * @returns true if the value is a valid mst node object, false otherwise
221
+ */
175
222
  export const isMstNode = (value: unknown): value is MstNode => {
176
223
  if (value === null || typeof value !== 'object') {
177
224
  return false;
@@ -181,8 +228,3 @@ export const isMstNode = (value: unknown): value is MstNode => {
181
228
 
182
229
  return (obj.l === null || isCidLink(obj.l)) && Array.isArray(obj.e) && obj.e.every(isTreeEntry);
183
230
  };
184
-
185
- export interface NodeEntry {
186
- key: string;
187
- cid: CID.CidLink;
188
- }
package/lib/index.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { iterateAtpRepo, type RepoEntry } from './atproto-repo.js';
2
- export { readCar } from './reader.js';
1
+ export * from './atproto-repo.js';
2
+ export * from './reader.js';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@atcute/car",
4
- "version": "2.0.3",
4
+ "version": "2.1.0",
5
5
  "description": "lightweight DASL CAR and atproto repository decoder for AT Protocol.",
6
6
  "keywords": [
7
7
  "atproto",
@@ -29,8 +29,8 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "@atcute/cbor": "^2.1.3",
32
- "@atcute/varint": "^1.0.2",
33
- "@atcute/cid": "^2.1.0"
32
+ "@atcute/cid": "^2.1.0",
33
+ "@atcute/varint": "^1.0.2"
34
34
  },
35
35
  "scripts": {
36
36
  "build": "tsc --project tsconfig.build.json",