@atcute/repo 0.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/LICENSE +14 -0
- package/README.md +58 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/reader.d.ts +3 -0
- package/dist/reader.d.ts.map +1 -0
- package/dist/reader.js +67 -0
- package/dist/reader.js.map +1 -0
- package/dist/streamed-reader.d.ts +25 -0
- package/dist/streamed-reader.d.ts.map +1 -0
- package/dist/streamed-reader.js +143 -0
- package/dist/streamed-reader.js.map +1 -0
- package/dist/types.d.ts +37 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +54 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/queue.d.ts +42 -0
- package/dist/utils/queue.d.ts.map +1 -0
- package/dist/utils/queue.js +121 -0
- package/dist/utils/queue.js.map +1 -0
- package/dist/utils.d.ts +4 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +6 -0
- package/dist/utils.js.map +1 -0
- package/dist/verify.d.ts +17 -0
- package/dist/verify.d.ts.map +1 -0
- package/dist/verify.js +166 -0
- package/dist/verify.js.map +1 -0
- package/lib/index.ts +5 -0
- package/lib/reader.ts +98 -0
- package/lib/streamed-reader.ts +208 -0
- package/lib/types.ts +64 -0
- package/lib/utils/queue.ts +148 -0
- package/lib/utils.ts +7 -0
- package/lib/verify.ts +244 -0
- package/package.json +44 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
BSD Zero Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Mary
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted.
|
|
7
|
+
|
|
8
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
9
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
10
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
11
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
12
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
13
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
14
|
+
PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# @atcute/repo
|
|
2
|
+
|
|
3
|
+
read AT Protocol repository exports
|
|
4
|
+
|
|
5
|
+
## usage
|
|
6
|
+
|
|
7
|
+
### streaming usage
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { fromStream } from '@atcute/repo';
|
|
11
|
+
|
|
12
|
+
const stream = new ReadableStream({
|
|
13
|
+
/* ... */
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
await using repo = fromStream(stream);
|
|
17
|
+
|
|
18
|
+
for await (const entry of repo) {
|
|
19
|
+
entry;
|
|
20
|
+
// ^? RepoEntry { collection: 'app.bsky.feed.post', rkey: '3lprcc55bb222', ... }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
repo.missingBlocks;
|
|
24
|
+
// ^? []
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### streaming usage (for runtimes without `await using` yet)
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
const repo = fromStream(stream);
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
for await (const entry of repo) {
|
|
34
|
+
entry;
|
|
35
|
+
// ^? RepoEntry
|
|
36
|
+
}
|
|
37
|
+
} finally {
|
|
38
|
+
await repo.dispose();
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### sync usage
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
const buffer = Uint8Array.from([
|
|
46
|
+
/* ... */
|
|
47
|
+
]);
|
|
48
|
+
|
|
49
|
+
const repo = fromUint8Array(buffer);
|
|
50
|
+
|
|
51
|
+
for (const entry of repo) {
|
|
52
|
+
entry;
|
|
53
|
+
// ^? RepoEntry { collection: 'app.bsky.feed.post', rkey: '3lprcc55bb222', ... }
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
repo.missingBlocks;
|
|
57
|
+
// ^? []
|
|
58
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,cAAc,sBAAsB,CAAC;AACrC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAEA,cAAc,sBAAsB,CAAC;AACrC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
|
package/dist/reader.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../lib/reader.ts"],"names":[],"mappings":"AAQA,OAAO,EAAY,SAAS,EAAE,MAAM,YAAY,CAAC;AAYjD,wBAAiB,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,CAwBrE"}
|
package/dist/reader.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import * as CAR from '@atcute/car';
|
|
2
|
+
import * as CBOR from '@atcute/cbor';
|
|
3
|
+
import * as CID from '@atcute/cid';
|
|
4
|
+
import { isNodeData } from '@atcute/mst';
|
|
5
|
+
import { decodeUtf8From } from '@atcute/uint8array';
|
|
6
|
+
import { isCommit, RepoEntry } from './types.js';
|
|
7
|
+
import { assert } from './utils.js';
|
|
8
|
+
export function* fromUint8Array(buf) {
|
|
9
|
+
const car = CAR.fromUint8Array(buf);
|
|
10
|
+
const roots = car.roots;
|
|
11
|
+
assert(roots.length === 1, `expected only 1 root in the car archive; got=${roots.length}`);
|
|
12
|
+
const map = new Map();
|
|
13
|
+
for (const entry of car) {
|
|
14
|
+
map.set(CID.toString(entry.cid), entry);
|
|
15
|
+
}
|
|
16
|
+
// [commit, mst node, record?]
|
|
17
|
+
assert(map.size >= 2, `expected at least 2 blocks in the archive; got=${map.size}`);
|
|
18
|
+
const commit = readEntry(map, roots[0], isCommit);
|
|
19
|
+
for (const { key, cid } of walkMstEntries(map, commit.data)) {
|
|
20
|
+
const [collection, rkey] = key.split('/');
|
|
21
|
+
const carEntry = map.get(cid.$link);
|
|
22
|
+
assert(carEntry != null, `cid not found in blockmap; cid=${cid}`);
|
|
23
|
+
yield new RepoEntry(collection, rkey, cid, carEntry);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* reads a block from the blockmap and validates it against the provided validation function
|
|
28
|
+
* @internal
|
|
29
|
+
* @param map a mapping of CID string -> actual bytes
|
|
30
|
+
* @param link a CID link to read
|
|
31
|
+
* @param validate a validation function to validate the decoded data
|
|
32
|
+
* @returns the decoded and validated data
|
|
33
|
+
*/
|
|
34
|
+
export const readEntry = (map, link, validate) => {
|
|
35
|
+
const cid = link.$link;
|
|
36
|
+
const entry = map.get(cid);
|
|
37
|
+
assert(entry != null, `cid not found in blockmap; cid=${cid}`);
|
|
38
|
+
const data = CBOR.decode(entry.bytes);
|
|
39
|
+
assert(validate(data), `validation failed for cid=${cid}`);
|
|
40
|
+
return data;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* walks the entries of a Merkle Sorted Tree (MST) in a depth-first manner
|
|
44
|
+
* @internal
|
|
45
|
+
* @param map a mapping of CID string -> actual bytes
|
|
46
|
+
* @param pointer a CID link to the root of the MST
|
|
47
|
+
* @returns a generator that yields the entries of the MST
|
|
48
|
+
*/
|
|
49
|
+
export function* walkMstEntries(map, pointer) {
|
|
50
|
+
const data = readEntry(map, pointer, isNodeData);
|
|
51
|
+
const entries = data.e;
|
|
52
|
+
let lastKey = '';
|
|
53
|
+
if (data.l !== null) {
|
|
54
|
+
yield* walkMstEntries(map, data.l);
|
|
55
|
+
}
|
|
56
|
+
for (let i = 0, il = entries.length; i < il; i++) {
|
|
57
|
+
const entry = entries[i];
|
|
58
|
+
const key_str = decodeUtf8From(CBOR.fromBytes(entry.k));
|
|
59
|
+
const key = lastKey.slice(0, entry.p) + key_str;
|
|
60
|
+
lastKey = key;
|
|
61
|
+
yield { key: key, cid: entry.v };
|
|
62
|
+
if (entry.t !== null) {
|
|
63
|
+
yield* walkMstEntries(map, entry.t);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader.js","sourceRoot":"","sources":["../lib/reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { RepoEntry } from './types.js';
|
|
2
|
+
export type MissingBlockEntry = {
|
|
3
|
+
cid: string;
|
|
4
|
+
type: 'record';
|
|
5
|
+
key: string;
|
|
6
|
+
} | {
|
|
7
|
+
cid: string;
|
|
8
|
+
type: 'mst-node';
|
|
9
|
+
} | {
|
|
10
|
+
cid: string;
|
|
11
|
+
type: 'commit';
|
|
12
|
+
};
|
|
13
|
+
export interface StreamedRepoReader {
|
|
14
|
+
/**
|
|
15
|
+
* list of blocks that were referenced but not found in the repository.
|
|
16
|
+
* blocks may be reported as missing if multiple records share the same CID.
|
|
17
|
+
*/
|
|
18
|
+
readonly missingBlocks: readonly MissingBlockEntry[];
|
|
19
|
+
dispose(): Promise<void>;
|
|
20
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
21
|
+
[Symbol.asyncIterator](): AsyncIterator<RepoEntry>;
|
|
22
|
+
}
|
|
23
|
+
export declare const repoEntryTransform: () => ReadableWritablePair<RepoEntry, Uint8Array>;
|
|
24
|
+
export declare const fromStream: (stream: ReadableStream<Uint8Array>) => StreamedRepoReader;
|
|
25
|
+
//# sourceMappingURL=streamed-reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamed-reader.d.ts","sourceRoot":"","sources":["../lib/streamed-reader.ts"],"names":[],"mappings":"AAOA,OAAO,EAAY,SAAS,EAAE,MAAM,YAAY,CAAC;AAYjD,MAAM,MAAM,iBAAiB,GAC1B;IACA,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACX,GACD;IACA,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,UAAU,CAAC;CAChB,GACD;IACA,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,QAAQ,CAAC;CACd,CAAC;AAEL,MAAM,WAAW,kBAAkB;IAClC;;;OAGG;IACH,QAAQ,CAAC,aAAa,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAErD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzB,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,SAAS,CAAC,CAAC;CACnD;AAED,eAAO,MAAM,kBAAkB,QAAO,oBAAoB,CAAC,SAAS,EAAE,UAAU,CA6B/E,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,QAAQ,cAAc,CAAC,UAAU,CAAC,KAAG,kBAiI/D,CAAC"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import * as CAR from '@atcute/car';
|
|
2
|
+
import * as CBOR from '@atcute/cbor';
|
|
3
|
+
import * as CID from '@atcute/cid';
|
|
4
|
+
import { isNodeData } from '@atcute/mst';
|
|
5
|
+
import { decodeUtf8From } from '@atcute/uint8array';
|
|
6
|
+
import { isCommit, RepoEntry } from './types.js';
|
|
7
|
+
import { assert } from './utils.js';
|
|
8
|
+
import Queue from './utils/queue.js';
|
|
9
|
+
export const repoEntryTransform = () => {
|
|
10
|
+
const transform = new TransformStream();
|
|
11
|
+
let repo;
|
|
12
|
+
return {
|
|
13
|
+
readable: new ReadableStream({
|
|
14
|
+
async start(controller) {
|
|
15
|
+
repo = fromStream(transform.readable);
|
|
16
|
+
try {
|
|
17
|
+
for await (const entry of repo) {
|
|
18
|
+
controller.enqueue(entry);
|
|
19
|
+
}
|
|
20
|
+
await repo.dispose();
|
|
21
|
+
controller.close();
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
controller.error(err);
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
async cancel() {
|
|
28
|
+
if (repo !== undefined) {
|
|
29
|
+
await repo.dispose();
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
}),
|
|
33
|
+
writable: transform.writable,
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
export const fromStream = (stream) => {
|
|
37
|
+
let missingBlocks = [];
|
|
38
|
+
return {
|
|
39
|
+
get missingBlocks() {
|
|
40
|
+
return missingBlocks;
|
|
41
|
+
},
|
|
42
|
+
async dispose() {
|
|
43
|
+
// does nothing for now
|
|
44
|
+
},
|
|
45
|
+
[Symbol.asyncDispose]() {
|
|
46
|
+
return this.dispose();
|
|
47
|
+
},
|
|
48
|
+
async *[Symbol.asyncIterator]() {
|
|
49
|
+
// await using car = CarReader.fromStream(stream);
|
|
50
|
+
const car = CAR.fromStream(stream);
|
|
51
|
+
try {
|
|
52
|
+
const pending = new Map();
|
|
53
|
+
const strays = new Map();
|
|
54
|
+
const queue = new Queue();
|
|
55
|
+
const request = (cid, meta) => {
|
|
56
|
+
const entry = strays.get(cid);
|
|
57
|
+
if (entry !== undefined) {
|
|
58
|
+
strays.delete(cid);
|
|
59
|
+
queue.enqueue({ c: cid, e: entry, m: meta });
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
pending.set(cid, meta);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
{
|
|
66
|
+
const roots = await car.roots();
|
|
67
|
+
assert(roots.length === 1, `expected only 1 root in the car archive; got=${roots.length}`);
|
|
68
|
+
const rootCid = roots[0].$link;
|
|
69
|
+
request(rootCid, { t: 0 });
|
|
70
|
+
}
|
|
71
|
+
for await (const entry of car) {
|
|
72
|
+
const cid = CID.toString(entry.cid);
|
|
73
|
+
{
|
|
74
|
+
const meta = pending.get(cid);
|
|
75
|
+
if (meta !== undefined) {
|
|
76
|
+
pending.delete(cid);
|
|
77
|
+
queue.enqueue({ c: cid, e: entry, m: meta });
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
strays.set(cid, entry);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
let task;
|
|
84
|
+
while ((task = queue.dequeue())) {
|
|
85
|
+
const { c: cid, e: entry, m: meta } = task;
|
|
86
|
+
switch (meta.t) {
|
|
87
|
+
case 0: {
|
|
88
|
+
const commit = CBOR.decode(entry.bytes);
|
|
89
|
+
assert(isCommit(commit), `expected commit block; cid=${cid}`);
|
|
90
|
+
request(commit.data.$link, { t: 1 });
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
case 1: {
|
|
94
|
+
const node = CBOR.decode(entry.bytes);
|
|
95
|
+
assert(isNodeData(node), `expected mst node block; cid=${cid}`);
|
|
96
|
+
const entries = node.e;
|
|
97
|
+
const left = node.l;
|
|
98
|
+
let lastKey = '';
|
|
99
|
+
if (left !== null) {
|
|
100
|
+
request(left.$link, meta);
|
|
101
|
+
}
|
|
102
|
+
for (let i = 0, il = entries.length; i < il; i++) {
|
|
103
|
+
const entry = entries[i];
|
|
104
|
+
const next = entry.t;
|
|
105
|
+
const key_str = decodeUtf8From(CBOR.fromBytes(entry.k));
|
|
106
|
+
const key = lastKey.slice(0, entry.p) + key_str;
|
|
107
|
+
lastKey = key;
|
|
108
|
+
request(entry.v.$link, { t: 2, k: key });
|
|
109
|
+
if (next !== null) {
|
|
110
|
+
request(next.$link, { t: 1 });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
case 2: {
|
|
116
|
+
const [collection, rkey] = meta.k.split('/');
|
|
117
|
+
yield new RepoEntry(collection, rkey, CID.toCidLink(entry.cid), entry);
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
missingBlocks = Array.from(pending, ([cid, meta]) => {
|
|
124
|
+
switch (meta.t) {
|
|
125
|
+
case 0: {
|
|
126
|
+
return { cid, type: 'commit' };
|
|
127
|
+
}
|
|
128
|
+
case 1: {
|
|
129
|
+
return { cid, type: 'mst-node' };
|
|
130
|
+
}
|
|
131
|
+
case 2: {
|
|
132
|
+
return { cid, type: 'record', key: meta.k };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
finally {
|
|
138
|
+
await car.dispose();
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
};
|
|
143
|
+
//# sourceMappingURL=streamed-reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamed-reader.js","sourceRoot":"","sources":["../lib/streamed-reader.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { CarEntry } from '@atcute/car';
|
|
2
|
+
import { type Bytes } from '@atcute/cbor';
|
|
3
|
+
import { type CidLink } from '@atcute/cid';
|
|
4
|
+
export declare class RepoEntry {
|
|
5
|
+
/** the collection this record belongs to */
|
|
6
|
+
readonly collection: string;
|
|
7
|
+
/** record key */
|
|
8
|
+
readonly rkey: string;
|
|
9
|
+
/** CID of this record */
|
|
10
|
+
readonly cid: CidLink;
|
|
11
|
+
/** the associated CarEntry for this record */
|
|
12
|
+
readonly carEntry: CarEntry;
|
|
13
|
+
/**
|
|
14
|
+
* raw contents of this record
|
|
15
|
+
*/
|
|
16
|
+
get bytes(): Uint8Array;
|
|
17
|
+
/**
|
|
18
|
+
* decoded contents of this record
|
|
19
|
+
*/
|
|
20
|
+
get record(): unknown;
|
|
21
|
+
}
|
|
22
|
+
/** commit object */
|
|
23
|
+
export interface Commit {
|
|
24
|
+
version: 3;
|
|
25
|
+
did: string;
|
|
26
|
+
data: CidLink;
|
|
27
|
+
rev: string;
|
|
28
|
+
prev: CidLink | null;
|
|
29
|
+
sig: Bytes;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* checks if value is a valid commit object
|
|
33
|
+
* @param value value to check
|
|
34
|
+
* @returns true if the value is a valid commit object, false otherwise
|
|
35
|
+
*/
|
|
36
|
+
export declare const isCommit: (value: unknown) => value is Commit;
|
|
37
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAW,KAAK,KAAK,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAa,KAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtD,qBAAa,SAAS;IAGpB,4CAA4C;aAC5B,UAAU,EAAE,MAAM;IAClC,iBAAiB;aACD,IAAI,EAAE,MAAM;IAC5B,yBAAyB;aACT,GAAG,EAAE,OAAO;IAC5B,8CAA8C;aAC9B,QAAQ,EAAE,QAAQ;IAGnC;;OAEG;IACH,IAAI,KAAK,IAAI,UAAU,CAEtB;IAED;;OAEG;IACH,IAAI,MAAM,IAAI,OAAO,CAEpB;CACD;AAED,oBAAoB;AACpB,MAAM,WAAW,MAAM;IACtB,OAAO,EAAE,CAAC,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IACrB,GAAG,EAAE,KAAK,CAAC;CACX;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,MAelD,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as CBOR from '@atcute/cbor';
|
|
2
|
+
import { isBytes } from '@atcute/cbor';
|
|
3
|
+
import { isCidLink } from '@atcute/cid';
|
|
4
|
+
export class RepoEntry {
|
|
5
|
+
collection;
|
|
6
|
+
rkey;
|
|
7
|
+
cid;
|
|
8
|
+
carEntry;
|
|
9
|
+
/** @internal */
|
|
10
|
+
constructor(
|
|
11
|
+
/** the collection this record belongs to */
|
|
12
|
+
collection,
|
|
13
|
+
/** record key */
|
|
14
|
+
rkey,
|
|
15
|
+
/** CID of this record */
|
|
16
|
+
cid,
|
|
17
|
+
/** the associated CarEntry for this record */
|
|
18
|
+
carEntry) {
|
|
19
|
+
this.collection = collection;
|
|
20
|
+
this.rkey = rkey;
|
|
21
|
+
this.cid = cid;
|
|
22
|
+
this.carEntry = carEntry;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* raw contents of this record
|
|
26
|
+
*/
|
|
27
|
+
get bytes() {
|
|
28
|
+
return this.carEntry.bytes;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* decoded contents of this record
|
|
32
|
+
*/
|
|
33
|
+
get record() {
|
|
34
|
+
return CBOR.decode(this.bytes);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* checks if value is a valid commit object
|
|
39
|
+
* @param value value to check
|
|
40
|
+
* @returns true if the value is a valid commit object, false otherwise
|
|
41
|
+
*/
|
|
42
|
+
export const isCommit = (value) => {
|
|
43
|
+
if (value === null || typeof value !== 'object') {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
const obj = value;
|
|
47
|
+
return (obj.version === 3 &&
|
|
48
|
+
typeof obj.did === 'string' &&
|
|
49
|
+
isCidLink(obj.data) &&
|
|
50
|
+
typeof obj.rev === 'string' &&
|
|
51
|
+
(obj.prev === null || isCidLink(obj.prev)) &&
|
|
52
|
+
isBytes(obj.sig));
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../lib/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,cAAc,CAAC;AACrC,OAAO,EAAE,OAAO,EAAc,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,SAAS,EAAgB,MAAM,aAAa,CAAC;AAEtD,MAAM,OAAO,SAAS;IAIJ;IAEA;IAEA;IAEA;IATjB,gBAAgB;IAChB;IACC,4CAA4C;IAC5B,UAAkB;IAClC,iBAAiB;IACD,IAAY;IAC5B,yBAAyB;IACT,GAAY;IAC5B,8CAA8C;IAC9B,QAAkB;QANlB,eAAU,GAAV,UAAU,CAAQ;QAElB,SAAI,GAAJ,IAAI,CAAQ;QAEZ,QAAG,GAAH,GAAG,CAAS;QAEZ,aAAQ,GAAR,QAAQ,CAAU;IAChC,CAAC;IAEJ;;OAEG;IACH,IAAI,KAAK;QACR,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,IAAI,MAAM;QACT,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;CACD;AAYD;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAmB,EAAE;IAC3D,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACjD,OAAO,KAAK,CAAC;IACd,CAAC;IAED,MAAM,GAAG,GAAG,KAAgC,CAAC;IAE7C,OAAO,CACN,GAAG,CAAC,OAAO,KAAK,CAAC;QACjB,OAAO,GAAG,CAAC,GAAG,KAAK,QAAQ;QAC3B,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;QACnB,OAAO,GAAG,CAAC,GAAG,KAAK,QAAQ;QAC3B,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAChB,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** a queue data structure (fifo) */
|
|
2
|
+
declare class Queue<T> implements Iterable<T> {
|
|
3
|
+
#private;
|
|
4
|
+
/** size of the queue */
|
|
5
|
+
get size(): number;
|
|
6
|
+
/**
|
|
7
|
+
* clear the queue
|
|
8
|
+
*/
|
|
9
|
+
clear(): void;
|
|
10
|
+
/**
|
|
11
|
+
* adds a value to the end of the queue
|
|
12
|
+
* @param value value to add
|
|
13
|
+
* @returns the queue instance
|
|
14
|
+
*/
|
|
15
|
+
enqueue(value: T): this;
|
|
16
|
+
/**
|
|
17
|
+
* adds a value to the front of the queue
|
|
18
|
+
* @param value value to add
|
|
19
|
+
* @returns the queue instance
|
|
20
|
+
*/
|
|
21
|
+
enqueueFront(value: T): this;
|
|
22
|
+
/**
|
|
23
|
+
* removes the first value from the queue
|
|
24
|
+
* @returns first queued value, or undefined if empty
|
|
25
|
+
*/
|
|
26
|
+
dequeue(): T | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* get the first value without removing from queue
|
|
29
|
+
* @returns first queued value, or undefined if empty
|
|
30
|
+
*/
|
|
31
|
+
peek(): T | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* returns an iterator that drains all values from the queue
|
|
34
|
+
*/
|
|
35
|
+
drain(): IterableIterator<T, undefined, undefined>;
|
|
36
|
+
/**
|
|
37
|
+
* iterates over the queue without draining
|
|
38
|
+
*/
|
|
39
|
+
[Symbol.iterator](): Iterator<T, undefined, undefined>;
|
|
40
|
+
}
|
|
41
|
+
export default Queue;
|
|
42
|
+
//# sourceMappingURL=queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../lib/utils/queue.ts"],"names":[],"mappings":"AASA,oCAAoC;AACpC,cAAM,KAAK,CAAC,CAAC,CAAE,YAAW,QAAQ,CAAC,CAAC,CAAC;;IAKpC,wBAAwB;IACxB,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;;;OAIG;IACH,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI;IAevB;;;;OAIG;IACH,YAAY,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI;IAa5B;;;OAGG;IACH,OAAO,IAAI,CAAC,GAAG,SAAS;IAiBxB;;;OAGG;IACH,IAAI,IAAI,CAAC,GAAG,SAAS;IAIrB;;OAEG;IACH,KAAK,IAAI,gBAAgB,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC;IA2BlD;;OAEG;IACH,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC;CAgBtD;AAED,eAAe,KAAK,CAAC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
const createNode = (value, next) => {
|
|
2
|
+
return { value, next };
|
|
3
|
+
};
|
|
4
|
+
/** a queue data structure (fifo) */
|
|
5
|
+
class Queue {
|
|
6
|
+
#head;
|
|
7
|
+
#tail;
|
|
8
|
+
#size = 0;
|
|
9
|
+
/** size of the queue */
|
|
10
|
+
get size() {
|
|
11
|
+
return this.#size;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* clear the queue
|
|
15
|
+
*/
|
|
16
|
+
clear() {
|
|
17
|
+
this.#head = undefined;
|
|
18
|
+
this.#tail = undefined;
|
|
19
|
+
this.#size = 0;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* adds a value to the end of the queue
|
|
23
|
+
* @param value value to add
|
|
24
|
+
* @returns the queue instance
|
|
25
|
+
*/
|
|
26
|
+
enqueue(value) {
|
|
27
|
+
const tail = this.#tail;
|
|
28
|
+
const node = createNode(value, undefined);
|
|
29
|
+
if (tail !== undefined) {
|
|
30
|
+
tail.next = node;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
this.#head = node;
|
|
34
|
+
}
|
|
35
|
+
this.#tail = node;
|
|
36
|
+
this.#size++;
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* adds a value to the front of the queue
|
|
41
|
+
* @param value value to add
|
|
42
|
+
* @returns the queue instance
|
|
43
|
+
*/
|
|
44
|
+
enqueueFront(value) {
|
|
45
|
+
const head = this.#head;
|
|
46
|
+
const node = createNode(value, head);
|
|
47
|
+
if (head === undefined) {
|
|
48
|
+
this.#tail = node;
|
|
49
|
+
}
|
|
50
|
+
this.#head = node;
|
|
51
|
+
this.#size++;
|
|
52
|
+
return this;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* removes the first value from the queue
|
|
56
|
+
* @returns first queued value, or undefined if empty
|
|
57
|
+
*/
|
|
58
|
+
dequeue() {
|
|
59
|
+
const head = this.#head;
|
|
60
|
+
if (!head) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const next = head.next;
|
|
64
|
+
this.#head = next;
|
|
65
|
+
if (next === undefined) {
|
|
66
|
+
this.#tail = undefined;
|
|
67
|
+
}
|
|
68
|
+
this.#size--;
|
|
69
|
+
return head.value;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* get the first value without removing from queue
|
|
73
|
+
* @returns first queued value, or undefined if empty
|
|
74
|
+
*/
|
|
75
|
+
peek() {
|
|
76
|
+
return this.#head?.value;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* returns an iterator that drains all values from the queue
|
|
80
|
+
*/
|
|
81
|
+
drain() {
|
|
82
|
+
// deno-lint-ignore no-this-alias
|
|
83
|
+
const self = this;
|
|
84
|
+
return {
|
|
85
|
+
next() {
|
|
86
|
+
const head = self.#head;
|
|
87
|
+
if (!head) {
|
|
88
|
+
return { done: true, value: undefined };
|
|
89
|
+
}
|
|
90
|
+
const next = head.next;
|
|
91
|
+
self.#head = next;
|
|
92
|
+
if (next === undefined) {
|
|
93
|
+
self.#tail = undefined;
|
|
94
|
+
}
|
|
95
|
+
self.#size--;
|
|
96
|
+
return { done: false, value: head.value };
|
|
97
|
+
},
|
|
98
|
+
[Symbol.iterator]() {
|
|
99
|
+
return this;
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* iterates over the queue without draining
|
|
105
|
+
*/
|
|
106
|
+
[Symbol.iterator]() {
|
|
107
|
+
let current = this.#head;
|
|
108
|
+
return {
|
|
109
|
+
next() {
|
|
110
|
+
if (current === undefined) {
|
|
111
|
+
return { done: true, value: undefined };
|
|
112
|
+
}
|
|
113
|
+
const value = current.value;
|
|
114
|
+
current = current.next;
|
|
115
|
+
return { done: false, value: value };
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
export default Queue;
|
|
121
|
+
//# sourceMappingURL=queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../lib/utils/queue.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,GAAG,CAAI,KAAQ,EAAE,IAAyB,EAAW,EAAE;IACtE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACxB,CAAC,CAAC;AAEF,oCAAoC;AACpC,MAAM,KAAK;IACV,KAAK,CAAsB;IAC3B,KAAK,CAAsB;IAC3B,KAAK,GAAW,CAAC,CAAC;IAElB,wBAAwB;IACxB,IAAI,IAAI;QACP,OAAO,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,KAAK;QACJ,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACvB,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACvB,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACH,OAAO,CAAC,KAAQ;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAE1C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QAClB,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACnB,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;OAIG;IACH,YAAY,CAAC,KAAQ;QACpB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAErC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACnB,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;OAGG;IACH,OAAO;QACN,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,OAAO;QACR,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QAEvB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACxB,CAAC;QAED,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,OAAO,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IAED;;;OAGG;IACH,IAAI;QACH,OAAO,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,KAAK;QACJ,iCAAiC;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC;QAElB,OAAO;YACN,IAAI;gBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;gBACxB,IAAI,CAAC,IAAI,EAAE,CAAC;oBACX,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;gBACzC,CAAC;gBAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;gBAEvB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;gBAClB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;oBACxB,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;gBACxB,CAAC;gBAED,IAAI,CAAC,KAAK,EAAE,CAAC;gBACb,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;YAC3C,CAAC;YACD,CAAC,MAAM,CAAC,QAAQ,CAAC;gBAChB,OAAO,IAAI,CAAC;YACb,CAAC;SACD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,CAAC,MAAM,CAAC,QAAQ,CAAC;QAChB,IAAI,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC;QAEzB,OAAO;YACN,IAAI;gBACH,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC3B,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;gBACzC,CAAC;gBAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;gBAC5B,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;gBAEvB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YACtC,CAAC;SACD,CAAC;IACH,CAAC;CACD;AAED,eAAe,KAAK,CAAC"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../lib/utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM,EAAE;IACpB,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;CAKzD,CAAC"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../lib/utils.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAEf,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE;IAC1B,IAAI,CAAC,SAAS,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;AACF,CAAC,CAAC"}
|