1
1
import * as API from '@ucanto/interface'
2
- import * as CARWriter from '@ipld/car/buffer-writer'
3
- import { CarReader } from '@ipld/car/reader'
2
+ import { CarBufferReader , CarBufferWriter } from '@ipld/car'
4
3
import { base32 } from 'multiformats/bases/base32'
5
4
import { UCAN , createLink } from '@ucanto/core'
6
5
import { sha256 } from 'multiformats/hashes/sha2'
@@ -33,8 +32,8 @@ class Writer {
33
32
const id = block . cid . toString ( base32 )
34
33
if ( ! this . written . has ( id ) ) {
35
34
this . blocks . push ( block )
36
- this . byteLength += CARWriter . blockLength (
37
- /** @type {CARWriter .Block } */ ( block )
35
+ this . byteLength += CarBufferWriter . blockLength (
36
+ /** @type {CarBufferWriter .Block } */ ( block )
38
37
)
39
38
this . written . add ( id )
40
39
}
@@ -46,25 +45,28 @@ class Writer {
46
45
*/
47
46
flush ( ...rootBlocks ) {
48
47
const roots = [ ]
48
+ // We reverse the roots so that the first root is the last block in the CAR
49
49
for ( const block of rootBlocks . reverse ( ) ) {
50
50
const id = block . cid . toString ( base32 )
51
51
if ( ! this . written . has ( id ) ) {
52
52
this . blocks . unshift ( block )
53
- this . byteLength += CARWriter . blockLength ( {
54
- cid : /** @type {CARWriter .CID } */ ( block . cid ) ,
53
+ this . byteLength += CarBufferWriter . blockLength ( {
54
+ cid : /** @type {CarBufferWriter .CID } */ ( block . cid ) ,
55
55
bytes : block . bytes ,
56
56
} )
57
57
this . written . add ( id )
58
58
}
59
- roots . push ( /** @type {CARWriter.CID } */ ( block . cid ) )
59
+
60
+ // We unshift here because we want to preserve the order of the roots
61
+ roots . unshift ( /** @type {CarBufferWriter.CID } */ ( block . cid ) )
60
62
}
61
63
62
- this . byteLength += CARWriter . headerLength ( { roots } )
64
+ this . byteLength += CarBufferWriter . headerLength ( { roots } )
63
65
64
66
const buffer = new ArrayBuffer ( this . byteLength )
65
- const writer = CARWriter . createWriter ( buffer , { roots } )
67
+ const writer = CarBufferWriter . createWriter ( buffer , { roots } )
66
68
67
- for ( const block of /** @type {CARWriter .Block[] } */ ( this . blocks ) ) {
69
+ for ( const block of /** @type {CarBufferWriter .Block[] } */ ( this . blocks ) ) {
68
70
writer . write ( block )
69
71
}
70
72
@@ -89,20 +91,22 @@ export const encode = ({ roots = [], blocks }) => {
89
91
90
92
/**
91
93
* @param {API.ByteView<Partial<Model>> } bytes
92
- * @returns {Promise< Model> }
94
+ * @returns {Model }
93
95
*/
94
- export const decode = async bytes => {
95
- const reader = await /** @type {any } */ ( CarReader . fromBytes ( bytes ) )
96
- /** @type {{_header: { roots: CARWriter.CID[] }, _keys: string[], _blocks: UCAN.Block[] } } */
97
- const { _header, _blocks, _keys } = reader
96
+ export const decode = bytes => {
97
+ const reader = CarBufferReader . fromBytes ( bytes )
98
98
const roots = [ ]
99
99
const blocks = new Map ( )
100
- const index = _header . roots . map ( cid => _keys . indexOf ( String ( cid ) ) )
101
100
102
- for ( const [ n , block ] of _blocks . entries ( ) ) {
103
- if ( index . includes ( n ) ) {
104
- roots . push ( /** @type {Block } */ ( block ) )
105
- } else {
101
+ for ( const root of reader . getRoots ( ) ) {
102
+ const block = reader . get ( root )
103
+ if ( block ) {
104
+ roots . push ( block )
105
+ }
106
+ }
107
+
108
+ for ( const block of reader . blocks ( ) ) {
109
+ if ( ! roots . includes ( block ) ) {
106
110
blocks . set ( block . cid . toString ( ) , block )
107
111
}
108
112
}
0 commit comments