@ipld/car 4.1.5 → 5.0.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 (226) hide show
  1. package/LICENSE +4 -0
  2. package/README.md +12 -4
  3. package/dist/index.min.js +5 -0
  4. package/{types → dist/src}/api.d.ts +19 -19
  5. package/dist/src/api.d.ts.map +1 -0
  6. package/{types/lib → dist/src}/buffer-writer.d.ts +10 -10
  7. package/{types/lib → dist/src}/buffer-writer.d.ts.map +1 -1
  8. package/dist/src/coding.d.ts +41 -0
  9. package/dist/src/coding.d.ts.map +1 -0
  10. package/{types/lib → dist/src}/decoder.d.ts +3 -3
  11. package/{types/lib → dist/src}/decoder.d.ts.map +1 -1
  12. package/{types/lib → dist/src}/encoder.d.ts +2 -2
  13. package/{types/lib → dist/src}/encoder.d.ts.map +1 -1
  14. package/{types/lib → dist/src}/header-validator.d.ts +0 -0
  15. package/dist/src/header-validator.d.ts.map +1 -0
  16. package/dist/src/index-browser.d.ts +8 -0
  17. package/dist/src/index-browser.d.ts.map +1 -0
  18. package/dist/src/index.d.ts +9 -0
  19. package/dist/src/index.d.ts.map +1 -0
  20. package/{types/lib → dist/src}/indexed-reader-browser.d.ts +0 -0
  21. package/dist/src/indexed-reader-browser.d.ts.map +1 -0
  22. package/{types/lib → dist/src}/indexed-reader.d.ts +13 -13
  23. package/dist/src/indexed-reader.d.ts.map +1 -0
  24. package/{types/lib → dist/src}/indexer.d.ts +9 -9
  25. package/{types/lib → dist/src}/indexer.d.ts.map +1 -1
  26. package/{types/lib → dist/src}/iterator-channel.d.ts +0 -0
  27. package/{types/lib → dist/src}/iterator-channel.d.ts.map +1 -1
  28. package/{types/lib → dist/src}/iterator.d.ts +8 -8
  29. package/{types/lib → dist/src}/iterator.d.ts.map +1 -1
  30. package/{types/lib → dist/src}/reader-browser.d.ts +10 -10
  31. package/{types/lib → dist/src}/reader-browser.d.ts.map +1 -1
  32. package/{types/lib → dist/src}/reader.d.ts +5 -5
  33. package/{types/lib → dist/src}/reader.d.ts.map +1 -1
  34. package/{types/lib → dist/src}/writer-browser.d.ts +10 -10
  35. package/{types/lib → dist/src}/writer-browser.d.ts.map +1 -1
  36. package/{types/lib → dist/src}/writer.d.ts +4 -4
  37. package/{types/lib → dist/src}/writer.d.ts.map +1 -1
  38. package/package.json +102 -209
  39. package/{api.ts → src/api.ts} +14 -14
  40. package/{lib → src}/buffer-writer.js +5 -5
  41. package/src/coding.ts +56 -0
  42. package/{lib → src}/decoder.js +4 -4
  43. package/{lib → src}/encoder.js +1 -1
  44. package/src/header-validator.js +74 -0
  45. package/{lib → src}/header.ipldsch +0 -0
  46. package/src/index-browser.js +14 -0
  47. package/src/index.js +16 -0
  48. package/{lib → src}/indexed-reader-browser.js +0 -0
  49. package/{lib → src}/indexed-reader.js +9 -9
  50. package/{lib → src}/indexer.js +4 -4
  51. package/{lib → src}/iterator-channel.js +0 -0
  52. package/{lib → src}/iterator.js +4 -4
  53. package/{lib → src}/reader-browser.js +7 -7
  54. package/{lib → src}/reader.js +5 -5
  55. package/{lib → src}/writer-browser.js +7 -7
  56. package/{lib → src}/writer.js +3 -3
  57. package/LICENSE-APACHE +0 -13
  58. package/LICENSE-MIT +0 -7
  59. package/buffer-writer +0 -1
  60. package/car-browser.js +0 -14
  61. package/car.js +0 -16
  62. package/cjs/browser-test/common.js +0 -301
  63. package/cjs/browser-test/node-test-file-streams.js +0 -71
  64. package/cjs/browser-test/node-test-indexed-reader.js +0 -51
  65. package/cjs/browser-test/node-test-large.js +0 -135
  66. package/cjs/browser-test/node-test-raw.js +0 -68
  67. package/cjs/browser-test/node-test-updateroots.js +0 -78
  68. package/cjs/browser-test/test-buffer-writer.js +0 -330
  69. package/cjs/browser-test/test-errors.js +0 -90
  70. package/cjs/browser-test/test-indexer.js +0 -80
  71. package/cjs/browser-test/test-interface.js +0 -21
  72. package/cjs/browser-test/test-iterator.js +0 -83
  73. package/cjs/browser-test/test-reader.js +0 -278
  74. package/cjs/browser-test/test-writer.js +0 -286
  75. package/cjs/browser-test/verify-store-reader.js +0 -142
  76. package/cjs/car-browser.js +0 -18
  77. package/cjs/car.js +0 -20
  78. package/cjs/lib/buffer-writer.js +0 -164
  79. package/cjs/lib/decoder.js +0 -301
  80. package/cjs/lib/encoder.js +0 -44
  81. package/cjs/lib/header-validator.js +0 -29
  82. package/cjs/lib/indexed-reader-browser.js +0 -13
  83. package/cjs/lib/indexed-reader.js +0 -90
  84. package/cjs/lib/indexer.js +0 -41
  85. package/cjs/lib/iterator-channel.js +0 -77
  86. package/cjs/lib/iterator.js +0 -97
  87. package/cjs/lib/reader-browser.js +0 -62
  88. package/cjs/lib/reader.js +0 -38
  89. package/cjs/lib/writer-browser.js +0 -118
  90. package/cjs/lib/writer.js +0 -51
  91. package/cjs/node-test/common.js +0 -301
  92. package/cjs/node-test/node-test-file-streams.js +0 -71
  93. package/cjs/node-test/node-test-indexed-reader.js +0 -51
  94. package/cjs/node-test/node-test-large.js +0 -135
  95. package/cjs/node-test/node-test-raw.js +0 -68
  96. package/cjs/node-test/node-test-updateroots.js +0 -78
  97. package/cjs/node-test/test-buffer-writer.js +0 -330
  98. package/cjs/node-test/test-errors.js +0 -90
  99. package/cjs/node-test/test-indexer.js +0 -80
  100. package/cjs/node-test/test-interface.js +0 -21
  101. package/cjs/node-test/test-iterator.js +0 -83
  102. package/cjs/node-test/test-reader.js +0 -278
  103. package/cjs/node-test/test-writer.js +0 -286
  104. package/cjs/node-test/verify-store-reader.js +0 -142
  105. package/decoder +0 -1
  106. package/esm/browser-test/common.js +0 -274
  107. package/esm/browser-test/node-test-file-streams.js +0 -76
  108. package/esm/browser-test/node-test-indexed-reader.js +0 -53
  109. package/esm/browser-test/node-test-large.js +0 -109
  110. package/esm/browser-test/node-test-raw.js +0 -63
  111. package/esm/browser-test/node-test-updateroots.js +0 -76
  112. package/esm/browser-test/test-buffer-writer.js +0 -311
  113. package/esm/browser-test/test-errors.js +0 -91
  114. package/esm/browser-test/test-indexer.js +0 -85
  115. package/esm/browser-test/test-interface.js +0 -24
  116. package/esm/browser-test/test-iterator.js +0 -91
  117. package/esm/browser-test/test-reader.js +0 -270
  118. package/esm/browser-test/test-writer.js +0 -297
  119. package/esm/browser-test/verify-store-reader.js +0 -122
  120. package/esm/car-browser.js +0 -16
  121. package/esm/car.js +0 -18
  122. package/esm/lib/buffer-writer.js +0 -129
  123. package/esm/lib/decoder.js +0 -265
  124. package/esm/lib/encoder.js +0 -35
  125. package/esm/lib/header-validator.js +0 -23
  126. package/esm/lib/indexed-reader-browser.js +0 -6
  127. package/esm/lib/indexed-reader.js +0 -78
  128. package/esm/lib/indexer.js +0 -38
  129. package/esm/lib/iterator-channel.js +0 -71
  130. package/esm/lib/iterator.js +0 -92
  131. package/esm/lib/reader-browser.js +0 -57
  132. package/esm/lib/reader.js +0 -26
  133. package/esm/lib/writer-browser.js +0 -115
  134. package/esm/lib/writer.js +0 -42
  135. package/esm/node-test/common.js +0 -274
  136. package/esm/node-test/node-test-file-streams.js +0 -76
  137. package/esm/node-test/node-test-indexed-reader.js +0 -53
  138. package/esm/node-test/node-test-large.js +0 -109
  139. package/esm/node-test/node-test-raw.js +0 -63
  140. package/esm/node-test/node-test-updateroots.js +0 -76
  141. package/esm/node-test/test-buffer-writer.js +0 -311
  142. package/esm/node-test/test-errors.js +0 -91
  143. package/esm/node-test/test-indexer.js +0 -85
  144. package/esm/node-test/test-interface.js +0 -24
  145. package/esm/node-test/test-iterator.js +0 -91
  146. package/esm/node-test/test-reader.js +0 -270
  147. package/esm/node-test/test-writer.js +0 -297
  148. package/esm/node-test/verify-store-reader.js +0 -122
  149. package/esm/package.json +0 -9
  150. package/examples/car-to-fixture.js +0 -66
  151. package/examples/dump-car.js +0 -58
  152. package/examples/dump-index.js +0 -24
  153. package/examples/package.json +0 -27
  154. package/examples/round-trip.js +0 -45
  155. package/examples/test-examples.js +0 -115
  156. package/examples/verify-car.js +0 -87
  157. package/index.js +0 -1
  158. package/indexed-reader +0 -1
  159. package/indexer +0 -1
  160. package/iterator +0 -1
  161. package/lib/coding.ts +0 -56
  162. package/lib/header-validator.js +0 -33
  163. package/reader +0 -1
  164. package/test/_fixtures_to_js.mjs +0 -24
  165. package/test/common.js +0 -210
  166. package/test/go.car +0 -0
  167. package/test/go.carv2 +0 -0
  168. package/test/node-test-file-streams.js +0 -84
  169. package/test/node-test-indexed-reader.js +0 -45
  170. package/test/node-test-large.js +0 -112
  171. package/test/node-test-raw.js +0 -83
  172. package/test/node-test-updateroots.js +0 -89
  173. package/test/test-buffer-writer.js +0 -256
  174. package/test/test-errors.js +0 -98
  175. package/test/test-indexer.js +0 -87
  176. package/test/test-interface.js +0 -24
  177. package/test/test-iterator.js +0 -74
  178. package/test/test-reader.js +0 -245
  179. package/test/test-writer.js +0 -336
  180. package/test/verify-store-reader.js +0 -191
  181. package/tsconfig.json +0 -48
  182. package/types/api.d.ts.map +0 -1
  183. package/types/car-browser.d.ts +0 -8
  184. package/types/car-browser.d.ts.map +0 -1
  185. package/types/car.d.ts +0 -9
  186. package/types/car.d.ts.map +0 -1
  187. package/types/lib/coding.d.ts +0 -41
  188. package/types/lib/coding.d.ts.map +0 -1
  189. package/types/lib/header-validator.d.ts.map +0 -1
  190. package/types/lib/indexed-reader-browser.d.ts.map +0 -1
  191. package/types/lib/indexed-reader.d.ts.map +0 -1
  192. package/types/test/_fixtures_to_js.d.mts +0 -3
  193. package/types/test/_fixtures_to_js.d.mts.map +0 -1
  194. package/types/test/common.d.ts +0 -73
  195. package/types/test/common.d.ts.map +0 -1
  196. package/types/test/fixtures-expectations.d.ts +0 -63
  197. package/types/test/fixtures-expectations.d.ts.map +0 -1
  198. package/types/test/fixtures.d.ts +0 -3
  199. package/types/test/fixtures.d.ts.map +0 -1
  200. package/types/test/node-test-file-streams.d.ts +0 -3
  201. package/types/test/node-test-file-streams.d.ts.map +0 -1
  202. package/types/test/node-test-indexed-reader.d.ts +0 -2
  203. package/types/test/node-test-indexed-reader.d.ts.map +0 -1
  204. package/types/test/node-test-large.d.ts +0 -2
  205. package/types/test/node-test-large.d.ts.map +0 -1
  206. package/types/test/node-test-raw.d.ts +0 -2
  207. package/types/test/node-test-raw.d.ts.map +0 -1
  208. package/types/test/node-test-updateroots.d.ts +0 -2
  209. package/types/test/node-test-updateroots.d.ts.map +0 -1
  210. package/types/test/test-buffer-writer.d.ts +0 -2
  211. package/types/test/test-buffer-writer.d.ts.map +0 -1
  212. package/types/test/test-errors.d.ts +0 -2
  213. package/types/test/test-errors.d.ts.map +0 -1
  214. package/types/test/test-indexer.d.ts +0 -2
  215. package/types/test/test-indexer.d.ts.map +0 -1
  216. package/types/test/test-interface.d.ts +0 -2
  217. package/types/test/test-interface.d.ts.map +0 -1
  218. package/types/test/test-iterator.d.ts +0 -2
  219. package/types/test/test-iterator.d.ts.map +0 -1
  220. package/types/test/test-reader.d.ts +0 -2
  221. package/types/test/test-reader.d.ts.map +0 -1
  222. package/types/test/test-writer.d.ts +0 -2
  223. package/types/test/test-writer.d.ts.map +0 -1
  224. package/types/test/verify-store-reader.d.ts +0 -29
  225. package/types/test/verify-store-reader.d.ts.map +0 -1
  226. package/writer +0 -1
package/esm/car.js DELETED
@@ -1,18 +0,0 @@
1
- import { CarReader } from './lib/reader.js';
2
- import { CarIndexer } from './lib/indexer.js';
3
- import {
4
- CarBlockIterator,
5
- CarCIDIterator
6
- } from './lib/iterator.js';
7
- import { CarWriter } from './lib/writer.js';
8
- import { CarIndexedReader } from './lib/indexed-reader.js';
9
- import * as CarBufferWriter from './lib/buffer-writer.js';
10
- export {
11
- CarReader,
12
- CarIndexer,
13
- CarBlockIterator,
14
- CarCIDIterator,
15
- CarWriter,
16
- CarIndexedReader,
17
- CarBufferWriter
18
- };
@@ -1,129 +0,0 @@
1
- import varint from 'varint';
2
- import {
3
- Token,
4
- Type
5
- } from 'cborg';
6
- import { tokensToLength } from 'cborg/length';
7
- import * as CBOR from '@ipld/dag-cbor';
8
- class CarBufferWriter {
9
- constructor(bytes, headerSize) {
10
- this.bytes = bytes;
11
- this.byteOffset = headerSize;
12
- this.roots = [];
13
- this.headerSize = headerSize;
14
- }
15
- addRoot(root, options) {
16
- addRoot(this, root, options);
17
- return this;
18
- }
19
- write(block) {
20
- addBlock(this, block);
21
- return this;
22
- }
23
- close(options) {
24
- return close(this, options);
25
- }
26
- }
27
- export const addRoot = (writer, root, options = {}) => {
28
- const {
29
- resize = false
30
- } = options;
31
- const {bytes, headerSize, byteOffset, roots} = writer;
32
- writer.roots.push(root);
33
- const size = headerLength(writer);
34
- if (size > headerSize) {
35
- if (size - headerSize + byteOffset < bytes.byteLength) {
36
- if (resize) {
37
- resizeHeader(writer, size);
38
- } else {
39
- roots.pop();
40
- throw new RangeError(`Header of size ${ headerSize } has no capacity for new root ${ root }.
41
- However there is a space in the buffer and you could call addRoot(root, { resize: root }) to resize header to make a space for this root.`);
42
- }
43
- } else {
44
- roots.pop();
45
- throw new RangeError(`Buffer has no capacity for a new root ${ root }`);
46
- }
47
- }
48
- };
49
- export const blockLength = ({cid, bytes}) => {
50
- const size = cid.bytes.byteLength + bytes.byteLength;
51
- return varint.encodingLength(size) + size;
52
- };
53
- export const addBlock = (writer, {cid, bytes}) => {
54
- const byteLength = cid.bytes.byteLength + bytes.byteLength;
55
- const size = varint.encode(byteLength);
56
- if (writer.byteOffset + size.length + byteLength > writer.bytes.byteLength) {
57
- throw new RangeError('Buffer has no capacity for this block');
58
- } else {
59
- writeBytes(writer, size);
60
- writeBytes(writer, cid.bytes);
61
- writeBytes(writer, bytes);
62
- }
63
- };
64
- export const close = (writer, options = {}) => {
65
- const {
66
- resize = false
67
- } = options;
68
- const {roots, bytes, byteOffset, headerSize} = writer;
69
- const headerBytes = CBOR.encode({
70
- version: 1,
71
- roots
72
- });
73
- const varintBytes = varint.encode(headerBytes.length);
74
- const size = varintBytes.length + headerBytes.byteLength;
75
- const offset = headerSize - size;
76
- if (offset === 0) {
77
- writeHeader(writer, varintBytes, headerBytes);
78
- return bytes.subarray(0, byteOffset);
79
- } else if (resize) {
80
- resizeHeader(writer, size);
81
- writeHeader(writer, varintBytes, headerBytes);
82
- return bytes.subarray(0, writer.byteOffset);
83
- } else {
84
- throw new RangeError(`Header size was overestimated.
85
- You can use close({ resize: true }) to resize header`);
86
- }
87
- };
88
- export const resizeHeader = (writer, byteLength) => {
89
- const {bytes, headerSize} = writer;
90
- bytes.set(bytes.subarray(headerSize, writer.byteOffset), byteLength);
91
- writer.byteOffset += byteLength - headerSize;
92
- writer.headerSize = byteLength;
93
- };
94
- const writeBytes = (writer, bytes) => {
95
- writer.bytes.set(bytes, writer.byteOffset);
96
- writer.byteOffset += bytes.length;
97
- };
98
- const writeHeader = ({bytes}, varint, header) => {
99
- bytes.set(varint);
100
- bytes.set(header, varint.length);
101
- };
102
- const headerPreludeTokens = [
103
- new Token(Type.map, 2),
104
- new Token(Type.string, 'version'),
105
- new Token(Type.uint, 1),
106
- new Token(Type.string, 'roots')
107
- ];
108
- const CID_TAG = new Token(Type.tag, 42);
109
- export const calculateHeaderLength = rootLengths => {
110
- const tokens = [...headerPreludeTokens];
111
- tokens.push(new Token(Type.array, rootLengths.length));
112
- for (const rootLength of rootLengths) {
113
- tokens.push(CID_TAG);
114
- tokens.push(new Token(Type.bytes, { length: rootLength + 1 }));
115
- }
116
- const length = tokensToLength(tokens);
117
- return varint.encodingLength(length) + length;
118
- };
119
- export const headerLength = ({roots}) => calculateHeaderLength(roots.map(cid => cid.bytes.byteLength));
120
- export const estimateHeaderLength = (rootCount, rootByteLength = 36) => calculateHeaderLength(new Array(rootCount).fill(rootByteLength));
121
- export const createWriter = (buffer, options = {}) => {
122
- const {roots = [], byteOffset = 0, byteLength = buffer.byteLength, headerSize = headerLength({ roots })} = options;
123
- const bytes = new Uint8Array(buffer, byteOffset, byteLength);
124
- const writer = new CarBufferWriter(bytes, headerSize);
125
- for (const root of roots) {
126
- writer.addRoot(root);
127
- }
128
- return writer;
129
- };
@@ -1,265 +0,0 @@
1
- import varint from 'varint';
2
- import { CID } from 'multiformats/cid';
3
- import * as Digest from 'multiformats/hashes/digest';
4
- import { decode as decodeDagCbor } from '@ipld/dag-cbor';
5
- import { CarHeader as headerValidator } from './header-validator.js';
6
- const CIDV0_BYTES = {
7
- SHA2_256: 18,
8
- LENGTH: 32,
9
- DAG_PB: 112
10
- };
11
- const V2_HEADER_LENGTH = 16 + 8 + 8 + 8;
12
- async function readVarint(reader) {
13
- const bytes = await reader.upTo(8);
14
- if (!bytes.length) {
15
- throw new Error('Unexpected end of data');
16
- }
17
- const i = varint.decode(bytes);
18
- reader.seek(varint.decode.bytes);
19
- return i;
20
- }
21
- async function readV2Header(reader) {
22
- const bytes = await reader.exactly(V2_HEADER_LENGTH);
23
- const dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
24
- let offset = 0;
25
- const header = {
26
- version: 2,
27
- characteristics: [
28
- dv.getBigUint64(offset, true),
29
- dv.getBigUint64(offset += 8, true)
30
- ],
31
- dataOffset: Number(dv.getBigUint64(offset += 8, true)),
32
- dataSize: Number(dv.getBigUint64(offset += 8, true)),
33
- indexOffset: Number(dv.getBigUint64(offset += 8, true))
34
- };
35
- reader.seek(V2_HEADER_LENGTH);
36
- return header;
37
- }
38
- export async function readHeader(reader, strictVersion) {
39
- const length = await readVarint(reader);
40
- if (length === 0) {
41
- throw new Error('Invalid CAR header (zero length)');
42
- }
43
- const header = await reader.exactly(length);
44
- reader.seek(length);
45
- const block = decodeDagCbor(header);
46
- if (!headerValidator(block)) {
47
- throw new Error('Invalid CAR header format');
48
- }
49
- if (block.version !== 1 && block.version !== 2 || strictVersion !== undefined && block.version !== strictVersion) {
50
- throw new Error(`Invalid CAR version: ${ block.version }${ strictVersion !== undefined ? ` (expected ${ strictVersion })` : '' }`);
51
- }
52
- const hasRoots = Array.isArray(block.roots);
53
- if (block.version === 1 && !hasRoots || block.version === 2 && hasRoots) {
54
- throw new Error('Invalid CAR header format');
55
- }
56
- if (block.version === 1) {
57
- return block;
58
- }
59
- const v2Header = await readV2Header(reader);
60
- reader.seek(v2Header.dataOffset - reader.pos);
61
- const v1Header = await readHeader(reader, 1);
62
- return Object.assign(v1Header, v2Header);
63
- }
64
- async function readMultihash(reader) {
65
- const bytes = await reader.upTo(8);
66
- varint.decode(bytes);
67
- const codeLength = varint.decode.bytes;
68
- const length = varint.decode(bytes.subarray(varint.decode.bytes));
69
- const lengthLength = varint.decode.bytes;
70
- const mhLength = codeLength + lengthLength + length;
71
- const multihash = await reader.exactly(mhLength);
72
- reader.seek(mhLength);
73
- return multihash;
74
- }
75
- async function readCid(reader) {
76
- const first = await reader.exactly(2);
77
- if (first[0] === CIDV0_BYTES.SHA2_256 && first[1] === CIDV0_BYTES.LENGTH) {
78
- const bytes = await reader.exactly(34);
79
- reader.seek(34);
80
- const multihash = Digest.decode(bytes);
81
- return CID.create(0, CIDV0_BYTES.DAG_PB, multihash);
82
- }
83
- const version = await readVarint(reader);
84
- if (version !== 1) {
85
- throw new Error(`Unexpected CID version (${ version })`);
86
- }
87
- const codec = await readVarint(reader);
88
- const bytes = await readMultihash(reader);
89
- const multihash = Digest.decode(bytes);
90
- return CID.create(version, codec, multihash);
91
- }
92
- export async function readBlockHead(reader) {
93
- const start = reader.pos;
94
- let length = await readVarint(reader);
95
- if (length === 0) {
96
- throw new Error('Invalid CAR section (zero length)');
97
- }
98
- length += reader.pos - start;
99
- const cid = await readCid(reader);
100
- const blockLength = length - Number(reader.pos - start);
101
- return {
102
- cid,
103
- length,
104
- blockLength
105
- };
106
- }
107
- async function readBlock(reader) {
108
- const {cid, blockLength} = await readBlockHead(reader);
109
- const bytes = await reader.exactly(blockLength);
110
- reader.seek(blockLength);
111
- return {
112
- bytes,
113
- cid
114
- };
115
- }
116
- async function readBlockIndex(reader) {
117
- const offset = reader.pos;
118
- const {cid, length, blockLength} = await readBlockHead(reader);
119
- const index = {
120
- cid,
121
- length,
122
- blockLength,
123
- offset,
124
- blockOffset: reader.pos
125
- };
126
- reader.seek(index.blockLength);
127
- return index;
128
- }
129
- export function createDecoder(reader) {
130
- const headerPromise = (async () => {
131
- const header = await readHeader(reader);
132
- if (header.version === 2) {
133
- const v1length = reader.pos - header.dataOffset;
134
- reader = limitReader(reader, header.dataSize - v1length);
135
- }
136
- return header;
137
- })();
138
- return {
139
- header: () => headerPromise,
140
- async *blocks() {
141
- await headerPromise;
142
- while ((await reader.upTo(8)).length > 0) {
143
- yield await readBlock(reader);
144
- }
145
- },
146
- async *blocksIndex() {
147
- await headerPromise;
148
- while ((await reader.upTo(8)).length > 0) {
149
- yield await readBlockIndex(reader);
150
- }
151
- }
152
- };
153
- }
154
- export function bytesReader(bytes) {
155
- let pos = 0;
156
- return {
157
- async upTo(length) {
158
- return bytes.subarray(pos, pos + Math.min(length, bytes.length - pos));
159
- },
160
- async exactly(length) {
161
- if (length > bytes.length - pos) {
162
- throw new Error('Unexpected end of data');
163
- }
164
- return bytes.subarray(pos, pos + length);
165
- },
166
- seek(length) {
167
- pos += length;
168
- },
169
- get pos() {
170
- return pos;
171
- }
172
- };
173
- }
174
- export function chunkReader(readChunk) {
175
- let pos = 0;
176
- let have = 0;
177
- let offset = 0;
178
- let currentChunk = new Uint8Array(0);
179
- const read = async length => {
180
- have = currentChunk.length - offset;
181
- const bufa = [currentChunk.subarray(offset)];
182
- while (have < length) {
183
- const chunk = await readChunk();
184
- if (chunk == null) {
185
- break;
186
- }
187
- if (have < 0) {
188
- if (chunk.length > have) {
189
- bufa.push(chunk.subarray(-have));
190
- }
191
- } else {
192
- bufa.push(chunk);
193
- }
194
- have += chunk.length;
195
- }
196
- currentChunk = new Uint8Array(bufa.reduce((p, c) => p + c.length, 0));
197
- let off = 0;
198
- for (const b of bufa) {
199
- currentChunk.set(b, off);
200
- off += b.length;
201
- }
202
- offset = 0;
203
- };
204
- return {
205
- async upTo(length) {
206
- if (currentChunk.length - offset < length) {
207
- await read(length);
208
- }
209
- return currentChunk.subarray(offset, offset + Math.min(currentChunk.length - offset, length));
210
- },
211
- async exactly(length) {
212
- if (currentChunk.length - offset < length) {
213
- await read(length);
214
- }
215
- if (currentChunk.length - offset < length) {
216
- throw new Error('Unexpected end of data');
217
- }
218
- return currentChunk.subarray(offset, offset + length);
219
- },
220
- seek(length) {
221
- pos += length;
222
- offset += length;
223
- },
224
- get pos() {
225
- return pos;
226
- }
227
- };
228
- }
229
- export function asyncIterableReader(asyncIterable) {
230
- const iterator = asyncIterable[Symbol.asyncIterator]();
231
- async function readChunk() {
232
- const next = await iterator.next();
233
- if (next.done) {
234
- return null;
235
- }
236
- return next.value;
237
- }
238
- return chunkReader(readChunk);
239
- }
240
- export function limitReader(reader, byteLimit) {
241
- let bytesRead = 0;
242
- return {
243
- async upTo(length) {
244
- let bytes = await reader.upTo(length);
245
- if (bytes.length + bytesRead > byteLimit) {
246
- bytes = bytes.subarray(0, byteLimit - bytesRead);
247
- }
248
- return bytes;
249
- },
250
- async exactly(length) {
251
- const bytes = await reader.exactly(length);
252
- if (bytes.length + bytesRead > byteLimit) {
253
- throw new Error('Unexpected end of data');
254
- }
255
- return bytes;
256
- },
257
- seek(length) {
258
- bytesRead += length;
259
- reader.seek(length);
260
- },
261
- get pos() {
262
- return reader.pos;
263
- }
264
- };
265
- }
@@ -1,35 +0,0 @@
1
- import varint from 'varint';
2
- import { encode as dagCborEncode } from '@ipld/dag-cbor';
3
- export function createHeader(roots) {
4
- const headerBytes = dagCborEncode({
5
- version: 1,
6
- roots
7
- });
8
- const varintBytes = varint.encode(headerBytes.length);
9
- const header = new Uint8Array(varintBytes.length + headerBytes.length);
10
- header.set(varintBytes, 0);
11
- header.set(headerBytes, varintBytes.length);
12
- return header;
13
- }
14
- function createEncoder(writer) {
15
- return {
16
- async setRoots(roots) {
17
- const bytes = createHeader(roots);
18
- await writer.write(bytes);
19
- },
20
- async writeBlock(block) {
21
- const {cid, bytes} = block;
22
- await writer.write(new Uint8Array(varint.encode(cid.bytes.length + bytes.length)));
23
- await writer.write(cid.bytes);
24
- if (bytes.length) {
25
- await writer.write(bytes);
26
- }
27
- },
28
- async close() {
29
- await writer.end();
30
- }
31
- };
32
- }
33
- export {
34
- createEncoder
35
- };
@@ -1,23 +0,0 @@
1
- const Kinds = {
2
- Null: obj => obj === null,
3
- Int: obj => Number.isInteger(obj),
4
- Float: obj => typeof obj === 'number' && Number.isFinite(obj),
5
- String: obj => typeof obj === 'string',
6
- Bool: obj => typeof obj === 'boolean',
7
- Bytes: obj => obj instanceof Uint8Array,
8
- Link: obj => !Kinds.Null(obj) && typeof obj === 'object' && obj.asCID === obj,
9
- List: obj => Array.isArray(obj),
10
- Map: obj => !Kinds.Null(obj) && typeof obj === 'object' && obj.asCID !== obj && !Kinds.List(obj) && !Kinds.Bytes(obj)
11
- };
12
- const Types = {
13
- Int: Kinds.Int,
14
- 'CarHeader > version': obj => Types.Int(obj),
15
- 'CarHeader > roots (anon) > valueType (anon)': Kinds.Link,
16
- 'CarHeader > roots (anon)': obj => Kinds.List(obj) && Array.prototype.every.call(obj, Types['CarHeader > roots (anon) > valueType (anon)']),
17
- 'CarHeader > roots': obj => Types['CarHeader > roots (anon)'](obj),
18
- CarHeader: obj => {
19
- const keys = obj && Object.keys(obj);
20
- return Kinds.Map(obj) && ['version'].every(k => keys.includes(k)) && Object.entries(obj).every(([name, value]) => Types['CarHeader > ' + name] && Types['CarHeader > ' + name](value));
21
- }
22
- };
23
- export const CarHeader = Types.CarHeader;
@@ -1,6 +0,0 @@
1
- export class CarIndexedReader {
2
- static async fromFile() {
3
- throw new Error('Unsupported in this environment');
4
- }
5
- }
6
- export const __browser = true;
@@ -1,78 +0,0 @@
1
- import fs from 'fs';
2
- import { Readable } from 'stream';
3
- import { CID } from 'multiformats/cid';
4
- import { CarIndexer } from './indexer.js';
5
- import { CarReader as NodeCarReader } from './reader.js';
6
- export class CarIndexedReader {
7
- constructor(version, path, roots, index, order) {
8
- this._version = version;
9
- this._path = path;
10
- this._roots = roots;
11
- this._index = index;
12
- this._order = order;
13
- this._fd = null;
14
- }
15
- get version() {
16
- return this._version;
17
- }
18
- async getRoots() {
19
- return this._roots;
20
- }
21
- async has(key) {
22
- return this._index.has(key.toString());
23
- }
24
- async get(key) {
25
- const blockIndex = this._index.get(key.toString());
26
- if (!blockIndex) {
27
- return undefined;
28
- }
29
- if (!this._fd) {
30
- this._fd = await fs.promises.open(this._path, 'r');
31
- }
32
- const readIndex = {
33
- cid: key,
34
- length: 0,
35
- offset: 0,
36
- blockLength: blockIndex.blockLength,
37
- blockOffset: blockIndex.blockOffset
38
- };
39
- return NodeCarReader.readRaw(this._fd, readIndex);
40
- }
41
- async *blocks() {
42
- for (const cidStr of this._order) {
43
- const block = await this.get(CID.parse(cidStr));
44
- if (!block) {
45
- throw new Error('Unexpected internal error');
46
- }
47
- yield block;
48
- }
49
- }
50
- async *cids() {
51
- for (const cidStr of this._order) {
52
- yield CID.parse(cidStr);
53
- }
54
- }
55
- async close() {
56
- if (this._fd) {
57
- return this._fd.close();
58
- }
59
- }
60
- static async fromFile(path) {
61
- if (typeof path !== 'string') {
62
- throw new TypeError('fromFile() requires a file path string');
63
- }
64
- const iterable = await CarIndexer.fromIterable(Readable.from(fs.createReadStream(path)));
65
- const index = new Map();
66
- const order = [];
67
- for await (const {cid, blockLength, blockOffset} of iterable) {
68
- const cidStr = cid.toString();
69
- index.set(cidStr, {
70
- blockLength,
71
- blockOffset
72
- });
73
- order.push(cidStr);
74
- }
75
- return new CarIndexedReader(iterable.version, path, await iterable.getRoots(), index, order);
76
- }
77
- }
78
- export const __browser = false;
@@ -1,38 +0,0 @@
1
- import {
2
- asyncIterableReader,
3
- bytesReader,
4
- createDecoder
5
- } from './decoder.js';
6
- export class CarIndexer {
7
- constructor(version, roots, iterator) {
8
- this._version = version;
9
- this._roots = roots;
10
- this._iterator = iterator;
11
- }
12
- get version() {
13
- return this._version;
14
- }
15
- async getRoots() {
16
- return this._roots;
17
- }
18
- [Symbol.asyncIterator]() {
19
- return this._iterator;
20
- }
21
- static async fromBytes(bytes) {
22
- if (!(bytes instanceof Uint8Array)) {
23
- throw new TypeError('fromBytes() requires a Uint8Array');
24
- }
25
- return decodeIndexerComplete(bytesReader(bytes));
26
- }
27
- static async fromIterable(asyncIterable) {
28
- if (!asyncIterable || !(typeof asyncIterable[Symbol.asyncIterator] === 'function')) {
29
- throw new TypeError('fromIterable() requires an async iterable');
30
- }
31
- return decodeIndexerComplete(asyncIterableReader(asyncIterable));
32
- }
33
- }
34
- async function decodeIndexerComplete(reader) {
35
- const decoder = createDecoder(reader);
36
- const {version, roots} = await decoder.header();
37
- return new CarIndexer(version, roots, decoder.blocksIndex());
38
- }
@@ -1,71 +0,0 @@
1
- function noop() {
2
- }
3
- export function create() {
4
- const chunkQueue = [];
5
- let drainer = null;
6
- let drainerResolver = noop;
7
- let ended = false;
8
- let outWait = null;
9
- let outWaitResolver = noop;
10
- const makeDrainer = () => {
11
- if (!drainer) {
12
- drainer = new Promise(resolve => {
13
- drainerResolver = () => {
14
- drainer = null;
15
- drainerResolver = noop;
16
- resolve();
17
- };
18
- });
19
- }
20
- return drainer;
21
- };
22
- const writer = {
23
- write(chunk) {
24
- chunkQueue.push(chunk);
25
- const drainer = makeDrainer();
26
- outWaitResolver();
27
- return drainer;
28
- },
29
- async end() {
30
- ended = true;
31
- const drainer = makeDrainer();
32
- outWaitResolver();
33
- await drainer;
34
- }
35
- };
36
- const iterator = {
37
- async next() {
38
- const chunk = chunkQueue.shift();
39
- if (chunk) {
40
- if (chunkQueue.length === 0) {
41
- drainerResolver();
42
- }
43
- return {
44
- done: false,
45
- value: chunk
46
- };
47
- }
48
- if (ended) {
49
- drainerResolver();
50
- return {
51
- done: true,
52
- value: undefined
53
- };
54
- }
55
- if (!outWait) {
56
- outWait = new Promise(resolve => {
57
- outWaitResolver = () => {
58
- outWait = null;
59
- outWaitResolver = noop;
60
- return resolve(iterator.next());
61
- };
62
- });
63
- }
64
- return outWait;
65
- }
66
- };
67
- return {
68
- writer,
69
- iterator
70
- };
71
- }