@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.
- package/dist/atproto-repo.d.ts +46 -4
- package/dist/atproto-repo.js +45 -9
- package/dist/atproto-repo.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/lib/atproto-repo.ts +56 -14
- package/lib/index.ts +2 -2
- package/package.json +3 -3
package/dist/atproto-repo.d.ts
CHANGED
|
@@ -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
|
-
}
|
package/dist/atproto-repo.js
CHANGED
|
@@ -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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
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 =
|
|
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;
|
package/dist/atproto-repo.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"atproto-repo.js","sourceRoot":"","sources":["../lib/atproto-repo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,cAAc,CAAC;AACrC,OAAO,KAAK,GAAG,MAAM,aAAa,CAAC;AAEnC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;AAElC,MAAM,OAAO,SAAS;IAEJ;IACA;IACA;IACR;IAJT,YACiB,UAAkB,EAClB,IAAY,EACZ,GAAgB,EACxB,QAAkB;QAHV,eAAU,GAAV,UAAU,CAAQ;QAClB,SAAI,GAAJ,IAAI,CAAQ;QACZ,QAAG,GAAH,GAAG,CAAa;QACxB,aAAQ,GAAR,QAAQ,CAAU;IACxB,CAAC;IAEJ,IAAI,KAAK;QACR,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;QAE3B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,MAAM,CAAC,KAAK,IAAI,IAAI,EAAE,kCAAkC,GAAG,EAAE,CAAC,CAAC;QAE/D,OAAO,KAAK,CAAC;IACd,CAAC;IAED,IAAI,MAAM;QACT,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;CACD;AAED,MAAM,SAAS,CAAC,CAAC,cAAc,CAAC,GAAe;IAC9C,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,gDAAgD,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAE3F,
|
|
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
|
|
2
|
-
export
|
|
1
|
+
export * from './atproto-repo.js';
|
|
2
|
+
export * from './reader.js';
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
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,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC"}
|
package/lib/atproto-repo.ts
CHANGED
|
@@ -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
|
-
|
|
35
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
2
|
-
export
|
|
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
|
|
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/
|
|
33
|
-
"@atcute/
|
|
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",
|