@atcute/car 2.1.0 → 3.0.1

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/README.md CHANGED
@@ -7,7 +7,7 @@ library for AT Protocol.
7
7
 
8
8
  ```ts
9
9
  // read through a CAR archive
10
- const { roots, iterate } = readCar(buf);
10
+ const { header, iterate } = readCar(buf);
11
11
 
12
12
  for (const { cid, bytes } of iterate()) {
13
13
  // ...
@@ -1,12 +1,33 @@
1
1
  import * as CBOR from '@atcute/cbor';
2
2
  import * as CID from '@atcute/cid';
3
+ import { type CarEntry } from './reader.js';
4
+ export type BlockMap = Map<string, CarEntry>;
3
5
  export declare class RepoEntry {
6
+ /** The collection this record belongs to */
4
7
  readonly collection: string;
8
+ /** Record key */
5
9
  readonly rkey: string;
10
+ /** CID of this record */
6
11
  readonly cid: CID.CidLink;
7
12
  private blockmap;
8
- constructor(collection: string, rkey: string, cid: CID.CidLink, blockmap: BlockMap);
13
+ constructor(
14
+ /** The collection this record belongs to */
15
+ collection: string,
16
+ /** Record key */
17
+ rkey: string,
18
+ /** CID of this record */
19
+ cid: CID.CidLink, blockmap: BlockMap);
20
+ /**
21
+ * returns the associated CarEntry for this record
22
+ */
23
+ get carEntry(): CarEntry;
24
+ /**
25
+ * returns the raw contents of this record
26
+ */
9
27
  get bytes(): Uint8Array;
28
+ /**
29
+ * returns the decoded contents of this record
30
+ */
10
31
  get record(): unknown;
11
32
  }
12
33
  export declare function iterateAtpRepo(buf: Uint8Array): Generator<RepoEntry>;
@@ -15,10 +36,7 @@ export declare function iterateAtpRepo(buf: Uint8Array): Generator<RepoEntry>;
15
36
  * @param iterator a generator that yields objects with a `cid` and `bytes` property
16
37
  * @returns a mapping of CID string -> actual bytes
17
38
  */
18
- export declare function collectBlock(iterator: Generator<{
19
- cid: CID.Cid;
20
- bytes: Uint8Array;
21
- }>): BlockMap;
39
+ export declare function collectBlock(iterator: Generator<CarEntry>): BlockMap;
22
40
  /**
23
41
  * reads a block from the blockmap and validates it against the provided validation function
24
42
  * @param map a mapping of CID string -> actual bytes
@@ -39,7 +57,6 @@ export interface NodeEntry {
39
57
  * @returns a generator that yields the entries of the MST
40
58
  */
41
59
  export declare function walkMstEntries(map: BlockMap, pointer: CID.CidLink): Generator<NodeEntry>;
42
- export type BlockMap = Map<string, Uint8Array>;
43
60
  /** commit object */
44
61
  export interface Commit {
45
62
  version: 3;
@@ -7,24 +7,43 @@ export class RepoEntry {
7
7
  rkey;
8
8
  cid;
9
9
  blockmap;
10
- constructor(collection, rkey, cid, blockmap) {
10
+ constructor(
11
+ /** The collection this record belongs to */
12
+ collection,
13
+ /** Record key */
14
+ rkey,
15
+ /** CID of this record */
16
+ cid, blockmap) {
11
17
  this.collection = collection;
12
18
  this.rkey = rkey;
13
19
  this.cid = cid;
14
20
  this.blockmap = blockmap;
15
21
  }
16
- get bytes() {
22
+ /**
23
+ * returns the associated CarEntry for this record
24
+ */
25
+ get carEntry() {
17
26
  const cid = this.cid.$link;
18
- const bytes = this.blockmap.get(cid);
19
- assert(bytes != null, `cid not found in blockmap; cid=${cid}`);
20
- return bytes;
27
+ const entry = this.blockmap.get(cid);
28
+ assert(entry != null, `cid not found in blockmap; cid=${cid}`);
29
+ return entry;
30
+ }
31
+ /**
32
+ * returns the raw contents of this record
33
+ */
34
+ get bytes() {
35
+ return this.carEntry.bytes;
21
36
  }
37
+ /**
38
+ * returns the decoded contents of this record
39
+ */
22
40
  get record() {
23
41
  return CBOR.decode(this.bytes);
24
42
  }
25
43
  }
26
44
  export function* iterateAtpRepo(buf) {
27
- const { roots, iterate } = readCar(buf);
45
+ const { header, iterate } = readCar(buf);
46
+ const roots = header.data.roots;
28
47
  assert(roots.length === 1, `expected only 1 root in the car archive; got=${roots.length}`);
29
48
  const blockmap = collectBlock(iterate());
30
49
  assert(blockmap.size > 0, `expected at least 1 block in the archive; got=${blockmap.size}`);
@@ -41,8 +60,8 @@ export function* iterateAtpRepo(buf) {
41
60
  */
42
61
  export function collectBlock(iterator) {
43
62
  const blockmap = new Map();
44
- for (const { cid, bytes } of iterator) {
45
- blockmap.set(CID.toString(cid), bytes);
63
+ for (const entry of iterator) {
64
+ blockmap.set(CID.toString(entry.cid), entry);
46
65
  }
47
66
  return blockmap;
48
67
  }
@@ -55,9 +74,9 @@ export function collectBlock(iterator) {
55
74
  */
56
75
  export function readBlock(map, link, validate) {
57
76
  const cid = link.$link;
58
- const bytes = map.get(cid);
59
- assert(bytes != null, `cid not found in blockmap; cid=${cid}`);
60
- const data = CBOR.decode(bytes);
77
+ const entry = map.get(cid);
78
+ assert(entry != null, `cid not found in blockmap; cid=${cid}`);
79
+ const data = CBOR.decode(entry.bytes);
61
80
  assert(validate(data), `validation failed for cid=${cid}`);
62
81
  return data;
63
82
  }
@@ -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/reader.d.ts CHANGED
@@ -1,7 +1,4 @@
1
- export declare const readCar: (buffer: Uint8Array) => {
2
- roots: import("@atcute/cid").CidLink[];
3
- iterate(): Generator<{
4
- cid: import("@atcute/cid").Cid;
5
- bytes: Uint8Array;
6
- }>;
7
- };
1
+ import { type SyncCarReader } from './utilities/sync-car-reader.js';
2
+ export type { CarEntry, CarHeader, CarV1Header } from './utilities/car.js';
3
+ export type { SyncCarReader } from './utilities/sync-car-reader.js';
4
+ export declare const readCar: (buffer: Uint8Array) => SyncCarReader;
@@ -1 +1 @@
1
- {"version":3,"file":"reader.js","sourceRoot":"","sources":["../lib/reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAEjE,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,MAAkB,EAAE,EAAE;IAC7C,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACzC,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC,CAAC"}
1
+ {"version":3,"file":"reader.js","sourceRoot":"","sources":["../lib/reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,eAAe,EAAsB,MAAM,gCAAgC,CAAC;AAKrF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,MAAkB,EAAiB,EAAE;IAC5D,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACzC,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC,CAAC"}
@@ -4,3 +4,20 @@ export interface CarV1Header {
4
4
  roots: CID.CidLink[];
5
5
  }
6
6
  export declare const isCarV1Header: (value: unknown) => value is CarV1Header;
7
+ export interface CarHeader {
8
+ headerStart: number;
9
+ headerEnd: number;
10
+ data: CarV1Header;
11
+ dataStart: number;
12
+ dataEnd: number;
13
+ }
14
+ export interface CarEntry {
15
+ entryStart: number;
16
+ entryEnd: number;
17
+ cid: CID.Cid;
18
+ cidStart: number;
19
+ cidEnd: number;
20
+ bytes: Uint8Array;
21
+ bytesStart: number;
22
+ bytesEnd: number;
23
+ }
@@ -11,7 +11,7 @@ export const createUint8Reader = (buf) => {
11
11
  pos += size;
12
12
  },
13
13
  upto(size) {
14
- return buf.subarray(pos, pos + Math.min(size, buf.length - pos));
14
+ return buf.subarray(pos, pos + size);
15
15
  },
16
16
  exactly(size, seek) {
17
17
  if (size > buf.length - pos) {
@@ -1 +1 @@
1
- {"version":3,"file":"sync-byte-reader.js","sourceRoot":"","sources":["../../lib/utilities/sync-byte-reader.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,GAAe,EAAkB,EAAE;IACpE,IAAI,GAAG,GAAG,CAAC,CAAC;IAEZ,OAAO;QACN,IAAI,GAAG;YACN,OAAO,GAAG,CAAC;QACZ,CAAC;QAED,IAAI,CAAC,IAAI;YACR,IAAI,IAAI,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;gBAC7B,MAAM,IAAI,UAAU,CAAC,wBAAwB,CAAC,CAAC;YAChD,CAAC;YAED,GAAG,IAAI,IAAI,CAAC;QACb,CAAC;QACD,IAAI,CAAC,IAAI;YACR,OAAO,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,CAAC,IAAI,EAAE,IAAI;YACjB,IAAI,IAAI,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;gBAC7B,MAAM,IAAI,UAAU,CAAC,wBAAwB,CAAC,CAAC;YAChD,CAAC;YAED,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,CAAC;YAC5C,IAAI,IAAI,EAAE,CAAC;gBACV,GAAG,IAAI,IAAI,CAAC;YACb,CAAC;YAED,OAAO,KAAK,CAAC;QACd,CAAC;KACD,CAAC;AACH,CAAC,CAAC"}
1
+ {"version":3,"file":"sync-byte-reader.js","sourceRoot":"","sources":["../../lib/utilities/sync-byte-reader.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,GAAe,EAAkB,EAAE;IACpE,IAAI,GAAG,GAAG,CAAC,CAAC;IAEZ,OAAO;QACN,IAAI,GAAG;YACN,OAAO,GAAG,CAAC;QACZ,CAAC;QAED,IAAI,CAAC,IAAI;YACR,IAAI,IAAI,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;gBAC7B,MAAM,IAAI,UAAU,CAAC,wBAAwB,CAAC,CAAC;YAChD,CAAC;YAED,GAAG,IAAI,IAAI,CAAC;QACb,CAAC;QACD,IAAI,CAAC,IAAI;YACR,OAAO,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,CAAC,IAAI,EAAE,IAAI;YACjB,IAAI,IAAI,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;gBAC7B,MAAM,IAAI,UAAU,CAAC,wBAAwB,CAAC,CAAC;YAChD,CAAC;YAED,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,CAAC;YAC5C,IAAI,IAAI,EAAE,CAAC;gBACV,GAAG,IAAI,IAAI,CAAC;YACb,CAAC;YAED,OAAO,KAAK,CAAC;QACd,CAAC;KACD,CAAC;AACH,CAAC,CAAC"}
@@ -1,10 +1,7 @@
1
- import * as CBOR from '@atcute/cbor';
2
- import * as CID from '@atcute/cid';
1
+ import { type CarEntry, type CarHeader } from './car.js';
3
2
  import type { SyncByteReader } from './sync-byte-reader.js';
4
- export declare const createCarReader: (reader: SyncByteReader) => {
5
- roots: CBOR.CidLink[];
6
- iterate(): Generator<{
7
- cid: CID.Cid;
8
- bytes: Uint8Array;
9
- }>;
10
- };
3
+ export interface SyncCarReader {
4
+ header: CarHeader;
5
+ iterate(): Generator<CarEntry>;
6
+ }
7
+ export declare const createCarReader: (reader: SyncByteReader) => SyncCarReader;
@@ -12,65 +12,78 @@ const readVarint = (reader, size) => {
12
12
  return int;
13
13
  };
14
14
  const readHeader = (reader) => {
15
+ const headerStart = reader.pos;
15
16
  const length = readVarint(reader, 8);
16
17
  if (length === 0) {
17
18
  throw new RangeError(`invalid car header; length=0`);
18
19
  }
20
+ const dataStart = reader.pos;
19
21
  const rawHeader = reader.exactly(length, true);
20
- const header = CBOR.decode(rawHeader);
21
- if (!isCarV1Header(header)) {
22
+ const data = CBOR.decode(rawHeader);
23
+ if (!isCarV1Header(data)) {
22
24
  throw new TypeError(`expected a car v1 archive`);
23
25
  }
24
- return header;
26
+ const dataEnd = reader.pos;
27
+ const headerEnd = dataEnd;
28
+ return { data, headerStart, headerEnd, dataStart, dataEnd };
25
29
  };
26
30
  const readCid = (reader) => {
27
- const head = reader.upto(3 + 4);
31
+ const head = reader.exactly(4, false);
28
32
  const version = head[0];
29
33
  const codec = head[1];
30
- const digestCodec = head[2];
34
+ const digestType = head[2];
35
+ const digestSize = head[3];
31
36
  if (version !== CID.CID_VERSION) {
32
37
  throw new RangeError(`incorrect cid version (got v${version})`);
33
38
  }
34
39
  if (codec !== CID.CODEC_DCBOR && codec !== CID.CODEC_RAW) {
35
40
  throw new RangeError(`incorrect cid codec (got 0x${codec.toString(16)})`);
36
41
  }
37
- if (digestCodec !== CID.HASH_SHA256) {
38
- throw new RangeError(`incorrect cid hash type (got 0x${digestCodec.toString(16)})`);
42
+ if (digestType !== CID.HASH_SHA256) {
43
+ throw new RangeError(`incorrect cid digest type (got 0x${digestType.toString(16)})`);
39
44
  }
40
- const [digestSize, digestLebSize] = varint.decode(head, 3);
41
- const bytes = reader.exactly(3 + digestLebSize + digestSize, true);
42
- const digest = bytes.subarray(3 + digestLebSize);
45
+ if (digestSize !== 32 && digestSize !== 0) {
46
+ throw new RangeError(`incorrect cid digest size (got ${digestSize})`);
47
+ }
48
+ const bytes = reader.exactly(4 + digestSize, true);
49
+ const digest = bytes.subarray(4, 4 + digestSize);
43
50
  const cid = {
44
51
  version: version,
45
52
  codec: codec,
46
53
  digest: {
47
- codec: digestCodec,
54
+ codec: digestType,
48
55
  contents: digest,
49
56
  },
50
57
  bytes: bytes,
51
58
  };
52
59
  return cid;
53
60
  };
54
- const readBlockHeader = (reader) => {
55
- const start = reader.pos;
56
- let size = readVarint(reader, 8);
57
- if (size === 0) {
58
- throw new Error(`invalid car section; length=0`);
59
- }
60
- size += reader.pos - start;
61
- const cid = readCid(reader);
62
- const blockSize = size - (reader.pos - start);
63
- return { cid, blockSize };
64
- };
65
61
  export const createCarReader = (reader) => {
66
- const { roots } = readHeader(reader);
62
+ const header = readHeader(reader);
67
63
  return {
68
- roots,
64
+ header,
69
65
  *iterate() {
70
- while (reader.upto(8).length > 0) {
71
- const { cid, blockSize } = readBlockHeader(reader);
72
- const bytes = reader.exactly(blockSize, true);
73
- yield { cid, bytes };
66
+ while (reader.upto(8 + 36).length > 0) {
67
+ const entryStart = reader.pos;
68
+ const entrySize = readVarint(reader, 8);
69
+ const cidStart = reader.pos;
70
+ const cid = readCid(reader);
71
+ const bytesStart = reader.pos;
72
+ const bytesSize = entrySize - (bytesStart - cidStart);
73
+ const bytes = reader.exactly(bytesSize, true);
74
+ const cidEnd = bytesStart;
75
+ const bytesEnd = reader.pos;
76
+ const entryEnd = bytesEnd;
77
+ yield {
78
+ cid,
79
+ bytes,
80
+ entryStart,
81
+ entryEnd,
82
+ cidStart,
83
+ cidEnd,
84
+ bytesStart,
85
+ bytesEnd,
86
+ };
74
87
  }
75
88
  },
76
89
  };
@@ -1 +1 @@
1
- {"version":3,"file":"sync-car-reader.js","sourceRoot":"","sources":["../../lib/utilities/sync-car-reader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sync-car-reader.js","sourceRoot":"","sources":["../../lib/utilities/sync-car-reader.ts"],"names":[],"mappings":"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"}
@@ -1,34 +1,54 @@
1
1
  import * as CBOR from '@atcute/cbor';
2
2
  import * as CID from '@atcute/cid';
3
3
 
4
- import { readCar } from './reader.js';
4
+ import { readCar, type CarEntry } from './reader.js';
5
5
 
6
6
  const decoder = new TextDecoder();
7
7
 
8
+ export type BlockMap = Map<string, CarEntry>;
9
+
8
10
  export class RepoEntry {
9
11
  constructor(
12
+ /** The collection this record belongs to */
10
13
  public readonly collection: string,
14
+ /** Record key */
11
15
  public readonly rkey: string,
16
+ /** CID of this record */
12
17
  public readonly cid: CID.CidLink,
13
18
  private blockmap: BlockMap,
14
19
  ) {}
15
20
 
16
- get bytes(): Uint8Array {
21
+ /**
22
+ * returns the associated CarEntry for this record
23
+ */
24
+ get carEntry(): CarEntry {
17
25
  const cid = this.cid.$link;
18
26
 
19
- const bytes = this.blockmap.get(cid);
20
- assert(bytes != null, `cid not found in blockmap; cid=${cid}`);
27
+ const entry = this.blockmap.get(cid);
28
+ assert(entry != null, `cid not found in blockmap; cid=${cid}`);
21
29
 
22
- return bytes;
30
+ return entry;
23
31
  }
24
32
 
33
+ /**
34
+ * returns the raw contents of this record
35
+ */
36
+ get bytes(): Uint8Array {
37
+ return this.carEntry.bytes;
38
+ }
39
+
40
+ /**
41
+ * returns the decoded contents of this record
42
+ */
25
43
  get record(): unknown {
26
44
  return CBOR.decode(this.bytes);
27
45
  }
28
46
  }
29
47
 
30
48
  export function* iterateAtpRepo(buf: Uint8Array): Generator<RepoEntry> {
31
- const { roots, iterate } = readCar(buf);
49
+ const { header, iterate } = readCar(buf);
50
+ const roots = header.data.roots;
51
+
32
52
  assert(roots.length === 1, `expected only 1 root in the car archive; got=${roots.length}`);
33
53
 
34
54
  const blockmap = collectBlock(iterate());
@@ -47,10 +67,10 @@ export function* iterateAtpRepo(buf: Uint8Array): Generator<RepoEntry> {
47
67
  * @param iterator a generator that yields objects with a `cid` and `bytes` property
48
68
  * @returns a mapping of CID string -> actual bytes
49
69
  */
50
- export function collectBlock(iterator: Generator<{ cid: CID.Cid; bytes: Uint8Array }>): BlockMap {
70
+ export function collectBlock(iterator: Generator<CarEntry>): BlockMap {
51
71
  const blockmap: BlockMap = new Map();
52
- for (const { cid, bytes } of iterator) {
53
- blockmap.set(CID.toString(cid), bytes);
72
+ for (const entry of iterator) {
73
+ blockmap.set(CID.toString(entry.cid), entry);
54
74
  }
55
75
 
56
76
  return blockmap;
@@ -66,10 +86,10 @@ export function collectBlock(iterator: Generator<{ cid: CID.Cid; bytes: Uint8Arr
66
86
  export function readBlock<T>(map: BlockMap, link: CID.CidLink, validate: (value: unknown) => value is T): T {
67
87
  const cid = link.$link;
68
88
 
69
- const bytes = map.get(cid);
70
- assert(bytes != null, `cid not found in blockmap; cid=${cid}`);
89
+ const entry = map.get(cid);
90
+ assert(entry != null, `cid not found in blockmap; cid=${cid}`);
71
91
 
72
- const data = CBOR.decode(bytes);
92
+ const data = CBOR.decode(entry.bytes);
73
93
  assert(validate(data), `validation failed for cid=${cid}`);
74
94
 
75
95
  return data;
@@ -119,8 +139,6 @@ function assert(condition: boolean, message: string): asserts condition {
119
139
  }
120
140
  }
121
141
 
122
- export type BlockMap = Map<string, Uint8Array>;
123
-
124
142
  const isCidLink = (value: unknown): value is CID.CidLink => {
125
143
  if (value instanceof CID.CidLinkWrapper) {
126
144
  return true;
package/lib/reader.ts CHANGED
@@ -1,7 +1,10 @@
1
1
  import { createUint8Reader } from './utilities/sync-byte-reader.js';
2
- import { createCarReader } from './utilities/sync-car-reader.js';
2
+ import { createCarReader, type SyncCarReader } from './utilities/sync-car-reader.js';
3
3
 
4
- export const readCar = (buffer: Uint8Array) => {
4
+ export type { CarEntry, CarHeader, CarV1Header } from './utilities/car.js';
5
+ export type { SyncCarReader } from './utilities/sync-car-reader.js';
6
+
7
+ export const readCar = (buffer: Uint8Array): SyncCarReader => {
5
8
  const reader = createUint8Reader(buffer);
6
9
  return createCarReader(reader);
7
10
  };
@@ -14,3 +14,25 @@ export const isCarV1Header = (value: unknown): value is CarV1Header => {
14
14
  const { version, roots } = value as CarV1Header;
15
15
  return version === 1 && Array.isArray(roots) && roots.every((root) => root instanceof CBOR.CidLinkWrapper);
16
16
  };
17
+
18
+ export interface CarHeader {
19
+ headerStart: number;
20
+ headerEnd: number;
21
+
22
+ data: CarV1Header;
23
+ dataStart: number;
24
+ dataEnd: number;
25
+ }
26
+
27
+ export interface CarEntry {
28
+ entryStart: number;
29
+ entryEnd: number;
30
+
31
+ cid: CID.Cid;
32
+ cidStart: number;
33
+ cidEnd: number;
34
+
35
+ bytes: Uint8Array;
36
+ bytesStart: number;
37
+ bytesEnd: number;
38
+ }
@@ -21,7 +21,7 @@ export const createUint8Reader = (buf: Uint8Array): SyncByteReader => {
21
21
  pos += size;
22
22
  },
23
23
  upto(size) {
24
- return buf.subarray(pos, pos + Math.min(size, buf.length - pos));
24
+ return buf.subarray(pos, pos + size);
25
25
  },
26
26
  exactly(size, seek) {
27
27
  if (size > buf.length - pos) {
@@ -2,9 +2,14 @@ import * as CBOR from '@atcute/cbor';
2
2
  import * as CID from '@atcute/cid';
3
3
  import * as varint from '@atcute/varint';
4
4
 
5
- import { isCarV1Header, type CarV1Header } from './car.js';
5
+ import { isCarV1Header, type CarEntry, type CarHeader } from './car.js';
6
6
  import type { SyncByteReader } from './sync-byte-reader.js';
7
7
 
8
+ export interface SyncCarReader {
9
+ header: CarHeader;
10
+ iterate(): Generator<CarEntry>;
11
+ }
12
+
8
13
  const readVarint = (reader: SyncByteReader, size: number): number => {
9
14
  const buf = reader.upto(size);
10
15
  if (buf.length === 0) {
@@ -17,27 +22,34 @@ const readVarint = (reader: SyncByteReader, size: number): number => {
17
22
  return int;
18
23
  };
19
24
 
20
- const readHeader = (reader: SyncByteReader): CarV1Header => {
25
+ const readHeader = (reader: SyncByteReader): CarHeader => {
26
+ const headerStart = reader.pos;
21
27
  const length = readVarint(reader, 8);
22
28
  if (length === 0) {
23
29
  throw new RangeError(`invalid car header; length=0`);
24
30
  }
25
31
 
32
+ const dataStart = reader.pos;
26
33
  const rawHeader = reader.exactly(length, true);
27
- const header = CBOR.decode(rawHeader);
28
- if (!isCarV1Header(header)) {
34
+
35
+ const data = CBOR.decode(rawHeader);
36
+ if (!isCarV1Header(data)) {
29
37
  throw new TypeError(`expected a car v1 archive`);
30
38
  }
31
39
 
32
- return header;
40
+ const dataEnd = reader.pos;
41
+ const headerEnd = dataEnd;
42
+
43
+ return { data, headerStart, headerEnd, dataStart, dataEnd };
33
44
  };
34
45
 
35
46
  const readCid = (reader: SyncByteReader): CID.Cid => {
36
- const head = reader.upto(3 + 4);
47
+ const head = reader.exactly(4, false);
37
48
 
38
49
  const version = head[0];
39
50
  const codec = head[1];
40
- const digestCodec = head[2];
51
+ const digestType = head[2];
52
+ const digestSize = head[3];
41
53
 
42
54
  if (version !== CID.CID_VERSION) {
43
55
  throw new RangeError(`incorrect cid version (got v${version})`);
@@ -47,20 +59,22 @@ const readCid = (reader: SyncByteReader): CID.Cid => {
47
59
  throw new RangeError(`incorrect cid codec (got 0x${codec.toString(16)})`);
48
60
  }
49
61
 
50
- if (digestCodec !== CID.HASH_SHA256) {
51
- throw new RangeError(`incorrect cid hash type (got 0x${digestCodec.toString(16)})`);
62
+ if (digestType !== CID.HASH_SHA256) {
63
+ throw new RangeError(`incorrect cid digest type (got 0x${digestType.toString(16)})`);
52
64
  }
53
65
 
54
- const [digestSize, digestLebSize] = varint.decode(head, 3);
66
+ if (digestSize !== 32 && digestSize !== 0) {
67
+ throw new RangeError(`incorrect cid digest size (got ${digestSize})`);
68
+ }
55
69
 
56
- const bytes = reader.exactly(3 + digestLebSize + digestSize, true);
57
- const digest = bytes.subarray(3 + digestLebSize);
70
+ const bytes = reader.exactly(4 + digestSize, true);
71
+ const digest = bytes.subarray(4, 4 + digestSize);
58
72
 
59
73
  const cid: CID.Cid = {
60
74
  version: version,
61
75
  codec: codec,
62
76
  digest: {
63
- codec: digestCodec,
77
+ codec: digestType,
64
78
  contents: digest,
65
79
  },
66
80
  bytes: bytes,
@@ -69,33 +83,38 @@ const readCid = (reader: SyncByteReader): CID.Cid => {
69
83
  return cid;
70
84
  };
71
85
 
72
- const readBlockHeader = (reader: SyncByteReader): { cid: CID.Cid; blockSize: number } => {
73
- const start = reader.pos;
74
-
75
- let size = readVarint(reader, 8);
76
- if (size === 0) {
77
- throw new Error(`invalid car section; length=0`);
78
- }
79
-
80
- size += reader.pos - start;
81
-
82
- const cid = readCid(reader);
83
- const blockSize = size - (reader.pos - start);
84
-
85
- return { cid, blockSize };
86
- };
87
-
88
- export const createCarReader = (reader: SyncByteReader) => {
89
- const { roots } = readHeader(reader);
86
+ export const createCarReader = (reader: SyncByteReader): SyncCarReader => {
87
+ const header = readHeader(reader);
90
88
 
91
89
  return {
92
- roots,
93
- *iterate(): Generator<{ cid: CID.Cid; bytes: Uint8Array }> {
94
- while (reader.upto(8).length > 0) {
95
- const { cid, blockSize } = readBlockHeader(reader);
96
- const bytes = reader.exactly(blockSize, true);
97
-
98
- yield { cid, bytes };
90
+ header,
91
+ *iterate() {
92
+ while (reader.upto(8 + 36).length > 0) {
93
+ const entryStart = reader.pos;
94
+ const entrySize = readVarint(reader, 8);
95
+
96
+ const cidStart = reader.pos;
97
+ const cid = readCid(reader);
98
+
99
+ const bytesStart = reader.pos;
100
+ const bytesSize = entrySize - (bytesStart - cidStart);
101
+ const bytes = reader.exactly(bytesSize, true);
102
+
103
+ const cidEnd = bytesStart;
104
+ const bytesEnd = reader.pos;
105
+ const entryEnd = bytesEnd;
106
+
107
+ yield {
108
+ cid,
109
+ bytes,
110
+
111
+ entryStart,
112
+ entryEnd,
113
+ cidStart,
114
+ cidEnd,
115
+ bytesStart,
116
+ bytesEnd,
117
+ };
99
118
  }
100
119
  },
101
120
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@atcute/car",
4
- "version": "2.1.0",
4
+ "version": "3.0.1",
5
5
  "description": "lightweight DASL CAR and atproto repository decoder for AT Protocol.",
6
6
  "keywords": [
7
7
  "atproto",
@@ -28,8 +28,8 @@
28
28
  "@atcute/multibase": "^1.1.2"
29
29
  },
30
30
  "dependencies": {
31
- "@atcute/cbor": "^2.1.3",
32
- "@atcute/cid": "^2.1.0",
31
+ "@atcute/cbor": "^2.2.0",
32
+ "@atcute/cid": "^2.2.0",
33
33
  "@atcute/varint": "^1.0.2"
34
34
  },
35
35
  "scripts": {