@atcute/car 5.1.0 → 5.1.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/dist/index.d.ts +4 -4
- package/dist/reader.d.ts +2 -2
- package/dist/reader.d.ts.map +1 -1
- package/dist/reader.js +73 -77
- package/dist/reader.js.map +1 -1
- package/dist/streamed-reader.d.ts +1 -1
- package/dist/writer.d.ts +1 -1
- package/lib/index.ts +4 -4
- package/lib/reader.ts +84 -100
- package/lib/streamed-reader.ts +1 -1
- package/lib/writer.ts +1 -1
- package/package.json +17 -16
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export * from './reader.
|
|
2
|
-
export * from './streamed-reader.
|
|
3
|
-
export * from './writer.
|
|
4
|
-
export * from './types.
|
|
1
|
+
export * from './reader.ts';
|
|
2
|
+
export * from './streamed-reader.ts';
|
|
3
|
+
export * from './writer.ts';
|
|
4
|
+
export * from './types.ts';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/reader.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { CidLink } from '@atcute/cid';
|
|
2
|
-
import { type CarEntry, type CarHeader } from './types.
|
|
2
|
+
import { type CarEntry, type CarHeader } from './types.ts';
|
|
3
3
|
export interface SyncCarReader {
|
|
4
4
|
readonly header: CarHeader;
|
|
5
5
|
readonly roots: CidLink[];
|
|
6
6
|
/** @deprecated do for..of on the reader directly */
|
|
7
|
-
iterate():
|
|
7
|
+
iterate(): IterableIterator<CarEntry>;
|
|
8
8
|
[Symbol.iterator](): Iterator<CarEntry>;
|
|
9
9
|
}
|
|
10
10
|
export declare const fromUint8Array: (buffer: Uint8Array<ArrayBufferLike>) => SyncCarReader;
|
package/dist/reader.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../lib/reader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,EAAiB,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../lib/reader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,EAAiB,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAE1E,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;IAE1B,oDAAoD;IACpD,OAAO,IAAI,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC;CACxC;AAED,eAAO,MAAM,cAAc,wDAiE1B,CAAC"}
|
package/dist/reader.js
CHANGED
|
@@ -3,94 +3,87 @@ import * as CID from '@atcute/cid';
|
|
|
3
3
|
import * as varint from '@atcute/varint';
|
|
4
4
|
import { isCarV1Header } from './types.js';
|
|
5
5
|
export const fromUint8Array = (buffer) => {
|
|
6
|
-
const
|
|
7
|
-
|
|
6
|
+
const { header, nextOffset: headerOffset } = readHeader(buffer, 0);
|
|
7
|
+
let pos = headerOffset;
|
|
8
8
|
return {
|
|
9
9
|
header,
|
|
10
10
|
roots: header.data.roots,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
cid,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
bytesEnd
|
|
32
|
-
|
|
33
|
-
|
|
11
|
+
iterate() {
|
|
12
|
+
return {
|
|
13
|
+
next() {
|
|
14
|
+
if (pos >= buffer.length) {
|
|
15
|
+
return {
|
|
16
|
+
done: true,
|
|
17
|
+
value: undefined,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const entryStart = pos;
|
|
21
|
+
const { value: entryLength, nextOffset: lengthOffset } = varint.decode(buffer, pos, 8);
|
|
22
|
+
pos = lengthOffset;
|
|
23
|
+
const cidStart = pos;
|
|
24
|
+
const { cid, nextOffset: cidOffset } = readCid(buffer, pos);
|
|
25
|
+
pos = cidOffset;
|
|
26
|
+
const bytesStart = pos;
|
|
27
|
+
const bytesSize = entryLength - (bytesStart - cidStart);
|
|
28
|
+
if (bytesSize < 0 || bytesStart + bytesSize > buffer.length) {
|
|
29
|
+
throw new RangeError('unexpected end of data');
|
|
30
|
+
}
|
|
31
|
+
const bytesEnd = bytesStart + bytesSize;
|
|
32
|
+
const bytes = buffer.subarray(bytesStart, bytesEnd);
|
|
33
|
+
pos = bytesEnd;
|
|
34
|
+
const cidEnd = bytesStart;
|
|
35
|
+
const entryEnd = bytesEnd;
|
|
36
|
+
return {
|
|
37
|
+
done: false,
|
|
38
|
+
value: {
|
|
39
|
+
cid,
|
|
40
|
+
bytes,
|
|
41
|
+
entryStart,
|
|
42
|
+
entryEnd,
|
|
43
|
+
cidStart,
|
|
44
|
+
cidEnd,
|
|
45
|
+
bytesStart,
|
|
46
|
+
bytesEnd,
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
[Symbol.iterator]() {
|
|
51
|
+
return this;
|
|
52
|
+
},
|
|
53
|
+
};
|
|
34
54
|
},
|
|
35
55
|
[Symbol.iterator]() {
|
|
36
56
|
return this.iterate();
|
|
37
57
|
},
|
|
38
58
|
};
|
|
39
59
|
};
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
get pos() {
|
|
44
|
-
return pos;
|
|
45
|
-
},
|
|
46
|
-
seek(size) {
|
|
47
|
-
if (size > buf.length - pos) {
|
|
48
|
-
throw new RangeError('unexpected end of data');
|
|
49
|
-
}
|
|
50
|
-
pos += size;
|
|
51
|
-
},
|
|
52
|
-
upto(size) {
|
|
53
|
-
return buf.subarray(pos, pos + size);
|
|
54
|
-
},
|
|
55
|
-
exactly(size, seek) {
|
|
56
|
-
if (size > buf.length - pos) {
|
|
57
|
-
throw new RangeError('unexpected end of data');
|
|
58
|
-
}
|
|
59
|
-
const slice = buf.subarray(pos, pos + size);
|
|
60
|
-
if (seek) {
|
|
61
|
-
pos += size;
|
|
62
|
-
}
|
|
63
|
-
return slice;
|
|
64
|
-
},
|
|
65
|
-
};
|
|
66
|
-
};
|
|
67
|
-
const readVarint = (reader, size) => {
|
|
68
|
-
const buf = reader.upto(size);
|
|
69
|
-
if (buf.length === 0) {
|
|
70
|
-
throw new RangeError(`unexpected end of data`);
|
|
71
|
-
}
|
|
72
|
-
const [int, read] = varint.decode(buf);
|
|
73
|
-
reader.seek(read);
|
|
74
|
-
return int;
|
|
75
|
-
};
|
|
76
|
-
const readHeader = (reader) => {
|
|
77
|
-
const headerStart = reader.pos;
|
|
78
|
-
const length = readVarint(reader, 8);
|
|
60
|
+
const readHeader = (source, offset) => {
|
|
61
|
+
const headerStart = offset;
|
|
62
|
+
const { value: length, nextOffset: lengthOffset } = varint.decode(source, offset, 8);
|
|
79
63
|
if (length === 0) {
|
|
80
64
|
throw new RangeError(`invalid car header; length=0`);
|
|
81
65
|
}
|
|
82
|
-
const dataStart =
|
|
83
|
-
const
|
|
84
|
-
|
|
66
|
+
const dataStart = lengthOffset;
|
|
67
|
+
const dataEnd = dataStart + length;
|
|
68
|
+
if (dataEnd > source.length) {
|
|
69
|
+
throw new RangeError('unexpected end of data');
|
|
70
|
+
}
|
|
71
|
+
const data = CBOR.decode(source.subarray(dataStart, dataEnd));
|
|
85
72
|
if (!isCarV1Header(data)) {
|
|
86
73
|
throw new TypeError(`expected a car v1 archive`);
|
|
87
74
|
}
|
|
88
|
-
const dataEnd = reader.pos;
|
|
89
75
|
const headerEnd = dataEnd;
|
|
90
|
-
return {
|
|
76
|
+
return {
|
|
77
|
+
header: { data, headerStart, headerEnd, dataStart, dataEnd },
|
|
78
|
+
nextOffset: dataEnd,
|
|
79
|
+
};
|
|
91
80
|
};
|
|
92
|
-
const readCid = (
|
|
93
|
-
const
|
|
81
|
+
const readCid = (source, offset) => {
|
|
82
|
+
const cidEnd = offset + 36;
|
|
83
|
+
if (cidEnd > source.length) {
|
|
84
|
+
throw new RangeError('unexpected end of data');
|
|
85
|
+
}
|
|
86
|
+
const bytes = source.subarray(offset, cidEnd);
|
|
94
87
|
const version = bytes[0];
|
|
95
88
|
const codec = bytes[1];
|
|
96
89
|
const digestType = bytes[2];
|
|
@@ -108,13 +101,16 @@ const readCid = (reader) => {
|
|
|
108
101
|
throw new RangeError(`incorrect cid digest size (got ${digestSize})`);
|
|
109
102
|
}
|
|
110
103
|
return {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
104
|
+
cid: {
|
|
105
|
+
version: version,
|
|
106
|
+
codec: codec,
|
|
107
|
+
digest: {
|
|
108
|
+
codec: digestType,
|
|
109
|
+
contents: bytes.subarray(4, 36),
|
|
110
|
+
},
|
|
111
|
+
bytes: bytes,
|
|
116
112
|
},
|
|
117
|
-
|
|
113
|
+
nextOffset: cidEnd,
|
|
118
114
|
};
|
|
119
115
|
};
|
|
120
116
|
//# sourceMappingURL=reader.js.map
|
package/dist/reader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reader.js","sourceRoot":"","sources":["../lib/reader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,cAAc,CAAC;AAErC,OAAO,KAAK,GAAG,MAAM,aAAa,CAAC;AACnC,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAEzC,OAAO,EAAE,aAAa,EAAiC,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"reader.js","sourceRoot":"","sources":["../lib/reader.ts"],"names":[],"mappings":"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"}
|
package/dist/writer.d.ts
CHANGED
package/lib/index.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// implements github:darobin/dasl.ing@cc66c35 (2025-10-20)
|
|
2
2
|
|
|
3
|
-
export * from './reader.
|
|
4
|
-
export * from './streamed-reader.
|
|
3
|
+
export * from './reader.ts';
|
|
4
|
+
export * from './streamed-reader.ts';
|
|
5
5
|
|
|
6
|
-
export * from './writer.
|
|
6
|
+
export * from './writer.ts';
|
|
7
7
|
|
|
8
|
-
export * from './types.
|
|
8
|
+
export * from './types.ts';
|
package/lib/reader.ts
CHANGED
|
@@ -3,60 +3,76 @@ import type { CidLink } from '@atcute/cid';
|
|
|
3
3
|
import * as CID from '@atcute/cid';
|
|
4
4
|
import * as varint from '@atcute/varint';
|
|
5
5
|
|
|
6
|
-
import { isCarV1Header, type CarEntry, type CarHeader } from './types.
|
|
7
|
-
|
|
8
|
-
interface SyncByteReader {
|
|
9
|
-
readonly pos: number;
|
|
10
|
-
upto(size: number): Uint8Array;
|
|
11
|
-
exactly(size: number, seek: boolean): Uint8Array;
|
|
12
|
-
seek(size: number): void;
|
|
13
|
-
}
|
|
6
|
+
import { isCarV1Header, type CarEntry, type CarHeader } from './types.ts';
|
|
14
7
|
|
|
15
8
|
export interface SyncCarReader {
|
|
16
9
|
readonly header: CarHeader;
|
|
17
10
|
readonly roots: CidLink[];
|
|
18
11
|
|
|
19
12
|
/** @deprecated do for..of on the reader directly */
|
|
20
|
-
iterate():
|
|
13
|
+
iterate(): IterableIterator<CarEntry>;
|
|
21
14
|
[Symbol.iterator](): Iterator<CarEntry>;
|
|
22
15
|
}
|
|
23
16
|
|
|
24
17
|
export const fromUint8Array = (buffer: Uint8Array): SyncCarReader => {
|
|
25
|
-
const
|
|
26
|
-
|
|
18
|
+
const { header, nextOffset: headerOffset } = readHeader(buffer, 0);
|
|
19
|
+
let pos = headerOffset;
|
|
27
20
|
|
|
28
21
|
return {
|
|
29
22
|
header,
|
|
30
23
|
roots: header.data.roots,
|
|
31
24
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
bytesStart
|
|
57
|
-
bytesEnd
|
|
58
|
-
|
|
59
|
-
|
|
25
|
+
iterate(): IterableIterator<CarEntry> {
|
|
26
|
+
return {
|
|
27
|
+
next(): IteratorResult<CarEntry> {
|
|
28
|
+
if (pos >= buffer.length) {
|
|
29
|
+
return {
|
|
30
|
+
done: true,
|
|
31
|
+
value: undefined,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const entryStart = pos;
|
|
36
|
+
const { value: entryLength, nextOffset: lengthOffset } = varint.decode(buffer, pos, 8);
|
|
37
|
+
pos = lengthOffset;
|
|
38
|
+
|
|
39
|
+
const cidStart = pos;
|
|
40
|
+
const { cid, nextOffset: cidOffset } = readCid(buffer, pos);
|
|
41
|
+
pos = cidOffset;
|
|
42
|
+
|
|
43
|
+
const bytesStart = pos;
|
|
44
|
+
const bytesSize = entryLength - (bytesStart - cidStart);
|
|
45
|
+
if (bytesSize < 0 || bytesStart + bytesSize > buffer.length) {
|
|
46
|
+
throw new RangeError('unexpected end of data');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const bytesEnd = bytesStart + bytesSize;
|
|
50
|
+
const bytes = buffer.subarray(bytesStart, bytesEnd);
|
|
51
|
+
pos = bytesEnd;
|
|
52
|
+
|
|
53
|
+
const cidEnd = bytesStart;
|
|
54
|
+
const entryEnd = bytesEnd;
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
done: false,
|
|
58
|
+
value: {
|
|
59
|
+
cid,
|
|
60
|
+
bytes,
|
|
61
|
+
|
|
62
|
+
entryStart,
|
|
63
|
+
entryEnd,
|
|
64
|
+
cidStart,
|
|
65
|
+
cidEnd,
|
|
66
|
+
bytesStart,
|
|
67
|
+
bytesEnd,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
[Symbol.iterator]() {
|
|
73
|
+
return this;
|
|
74
|
+
},
|
|
75
|
+
};
|
|
60
76
|
},
|
|
61
77
|
|
|
62
78
|
[Symbol.iterator](): Iterator<CarEntry> {
|
|
@@ -65,74 +81,39 @@ export const fromUint8Array = (buffer: Uint8Array): SyncCarReader => {
|
|
|
65
81
|
};
|
|
66
82
|
};
|
|
67
83
|
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
return {
|
|
72
|
-
get pos() {
|
|
73
|
-
return pos;
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
seek(size) {
|
|
77
|
-
if (size > buf.length - pos) {
|
|
78
|
-
throw new RangeError('unexpected end of data');
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
pos += size;
|
|
82
|
-
},
|
|
83
|
-
upto(size) {
|
|
84
|
-
return buf.subarray(pos, pos + size);
|
|
85
|
-
},
|
|
86
|
-
exactly(size, seek) {
|
|
87
|
-
if (size > buf.length - pos) {
|
|
88
|
-
throw new RangeError('unexpected end of data');
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const slice = buf.subarray(pos, pos + size);
|
|
92
|
-
if (seek) {
|
|
93
|
-
pos += size;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return slice;
|
|
97
|
-
},
|
|
98
|
-
};
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
const readVarint = (reader: SyncByteReader, size: number): number => {
|
|
102
|
-
const buf = reader.upto(size);
|
|
103
|
-
if (buf.length === 0) {
|
|
104
|
-
throw new RangeError(`unexpected end of data`);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const [int, read] = varint.decode(buf);
|
|
108
|
-
reader.seek(read);
|
|
109
|
-
|
|
110
|
-
return int;
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
const readHeader = (reader: SyncByteReader): CarHeader => {
|
|
114
|
-
const headerStart = reader.pos;
|
|
115
|
-
const length = readVarint(reader, 8);
|
|
84
|
+
const readHeader = (source: Uint8Array, offset: number): { header: CarHeader; nextOffset: number } => {
|
|
85
|
+
const headerStart = offset;
|
|
86
|
+
const { value: length, nextOffset: lengthOffset } = varint.decode(source, offset, 8);
|
|
116
87
|
if (length === 0) {
|
|
117
88
|
throw new RangeError(`invalid car header; length=0`);
|
|
118
89
|
}
|
|
119
90
|
|
|
120
|
-
const dataStart =
|
|
121
|
-
const
|
|
91
|
+
const dataStart = lengthOffset;
|
|
92
|
+
const dataEnd = dataStart + length;
|
|
93
|
+
if (dataEnd > source.length) {
|
|
94
|
+
throw new RangeError('unexpected end of data');
|
|
95
|
+
}
|
|
122
96
|
|
|
123
|
-
const data = CBOR.decode(
|
|
97
|
+
const data = CBOR.decode(source.subarray(dataStart, dataEnd));
|
|
124
98
|
if (!isCarV1Header(data)) {
|
|
125
99
|
throw new TypeError(`expected a car v1 archive`);
|
|
126
100
|
}
|
|
127
101
|
|
|
128
|
-
const dataEnd = reader.pos;
|
|
129
102
|
const headerEnd = dataEnd;
|
|
130
103
|
|
|
131
|
-
return {
|
|
104
|
+
return {
|
|
105
|
+
header: { data, headerStart, headerEnd, dataStart, dataEnd },
|
|
106
|
+
nextOffset: dataEnd,
|
|
107
|
+
};
|
|
132
108
|
};
|
|
133
109
|
|
|
134
|
-
const readCid = (
|
|
135
|
-
const
|
|
110
|
+
const readCid = (source: Uint8Array, offset: number): { cid: CID.Cid; nextOffset: number } => {
|
|
111
|
+
const cidEnd = offset + 36;
|
|
112
|
+
if (cidEnd > source.length) {
|
|
113
|
+
throw new RangeError('unexpected end of data');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const bytes = source.subarray(offset, cidEnd);
|
|
136
117
|
|
|
137
118
|
const version = bytes[0];
|
|
138
119
|
const codec = bytes[1];
|
|
@@ -156,12 +137,15 @@ const readCid = (reader: SyncByteReader): CID.Cid => {
|
|
|
156
137
|
}
|
|
157
138
|
|
|
158
139
|
return {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
140
|
+
cid: {
|
|
141
|
+
version: version,
|
|
142
|
+
codec: codec,
|
|
143
|
+
digest: {
|
|
144
|
+
codec: digestType,
|
|
145
|
+
contents: bytes.subarray(4, 36),
|
|
146
|
+
},
|
|
147
|
+
bytes: bytes,
|
|
164
148
|
},
|
|
165
|
-
|
|
149
|
+
nextOffset: cidEnd,
|
|
166
150
|
};
|
|
167
151
|
};
|
package/lib/streamed-reader.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as CBOR from '@atcute/cbor';
|
|
|
2
2
|
import type { Cid, CidLink } from '@atcute/cid';
|
|
3
3
|
import * as CID from '@atcute/cid';
|
|
4
4
|
|
|
5
|
-
import { isCarV1Header, type CarEntry, type CarHeader } from './types.
|
|
5
|
+
import { isCarV1Header, type CarEntry, type CarHeader } from './types.ts';
|
|
6
6
|
|
|
7
7
|
export interface StreamedCarReader {
|
|
8
8
|
header(): Promise<CarHeader>;
|
package/lib/writer.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { CidLink } from '@atcute/cid';
|
|
|
3
3
|
import { allocUnsafe } from '@atcute/uint8array';
|
|
4
4
|
import * as varint from '@atcute/varint';
|
|
5
5
|
|
|
6
|
-
import type { CarBlock } from './types.
|
|
6
|
+
import type { CarBlock } from './types.ts';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* encodes a number as an unsigned varint (variable-length integer)
|
package/package.json
CHANGED
|
@@ -1,41 +1,42 @@
|
|
|
1
1
|
{
|
|
2
|
-
"type": "module",
|
|
3
2
|
"name": "@atcute/car",
|
|
4
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.1",
|
|
5
4
|
"description": "lightweight DASL CAR (content-addressable archives) codec for AT Protocol.",
|
|
6
5
|
"keywords": [
|
|
7
6
|
"atproto",
|
|
8
|
-
"
|
|
9
|
-
"
|
|
7
|
+
"car",
|
|
8
|
+
"dasl"
|
|
10
9
|
],
|
|
11
10
|
"license": "0BSD",
|
|
12
11
|
"repository": {
|
|
13
12
|
"url": "https://github.com/mary-ext/atcute",
|
|
14
13
|
"directory": "packages/utilities/car"
|
|
15
14
|
},
|
|
16
|
-
"publishConfig": {
|
|
17
|
-
"access": "public"
|
|
18
|
-
},
|
|
19
15
|
"files": [
|
|
20
16
|
"dist/",
|
|
21
17
|
"lib/",
|
|
22
18
|
"!lib/**/*.bench.ts",
|
|
23
19
|
"!lib/**/*.test.ts"
|
|
24
20
|
],
|
|
21
|
+
"type": "module",
|
|
22
|
+
"sideEffects": false,
|
|
25
23
|
"exports": {
|
|
26
24
|
".": "./dist/index.js"
|
|
27
25
|
},
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
"@vitest/coverage-v8": "^4.0.16",
|
|
31
|
-
"vitest": "^4.0.16",
|
|
32
|
-
"@atcute/multibase": "^1.1.6"
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
33
28
|
},
|
|
34
29
|
"dependencies": {
|
|
35
|
-
"@atcute/cbor": "^2.3.
|
|
36
|
-
"@atcute/cid": "^2.4.
|
|
37
|
-
"@atcute/
|
|
38
|
-
"@atcute/
|
|
30
|
+
"@atcute/cbor": "^2.3.2",
|
|
31
|
+
"@atcute/cid": "^2.4.1",
|
|
32
|
+
"@atcute/uint8array": "^1.1.1",
|
|
33
|
+
"@atcute/varint": "^2.0.0"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/node": "^25.2.3",
|
|
37
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
38
|
+
"vitest": "^4.0.18",
|
|
39
|
+
"@atcute/multibase": "^1.1.8"
|
|
39
40
|
},
|
|
40
41
|
"scripts": {
|
|
41
42
|
"build": "tsgo --project tsconfig.build.json",
|