@@ -26,14 +26,29 @@ export function toReference(buffer: ArrayBuffer): Reference {
2626 const len = buffer . byteLength ;
2727
2828 if ( len < 3 ) {
29- throw 'Buffer needs to be bigger than 3' ;
29+ throw new Error ( 'Buffer needs to be bigger than 3 bytes' ) ;
3030 }
3131
3232 const dataView = new DataView ( buffer ) ;
33- const byteWidth = dataView . getUint8 ( len - 1 ) ;
33+ const rootByteWidth = dataView . getUint8 ( len - 1 ) ;
3434 const packedType = dataView . getUint8 ( len - 2 ) ;
35- const parentWidth = fromByteWidth ( byteWidth ) ;
36- const offset = len - byteWidth - 2 ;
35+
36+ let parentWidth = fromByteWidth ( rootByteWidth ) ;
37+ let offset = len - rootByteWidth - 2 ;
38+
39+ const rootValueType = packedType >> 2 ;
40+ if (
41+ rootValueType === ValueType . VECTOR ||
42+ rootValueType === ValueType . MAP ||
43+ rootValueType === ValueType . BLOB ||
44+ rootValueType === ValueType . STRING
45+ ) {
46+ // Ensure parent width is wide enough to address the buffer
47+ let w = 1 ;
48+ while ( ( 1 << ( w * 8 ) ) <= len && w < 8 ) w <<= 1 ;
49+ parentWidth = fromByteWidth ( w ) ;
50+ offset = len - w - 2 ; // no extra hacks
51+ }
3752
3853 return new Reference ( dataView , offset , parentWidth , packedType , '/' ) ;
3954}
@@ -182,20 +197,31 @@ export class Reference {
182197 const length = this . length ( ) ;
183198 if ( Number . isInteger ( key ) && isAVector ( this . valueType ) ) {
184199 if ( key >= length || key < 0 ) {
185- throw `Key: [${ key } ] is not applicable on ${ this . path } of ${ this . valueType } length: ${ length } ` ;
200+ throw new Error ( `Key: [${ key } ] is not applicable on ${ this . path } of ${ this . valueType } length: ${ length } ` ) ;
186201 }
187202 const _indirect = indirect ( this . dataView , this . offset , this . parentWidth ) ;
188203 const elementOffset = _indirect + key * this . byteWidth ;
189- let _packedType = this . dataView . getUint8 (
190- _indirect + length * this . byteWidth + key ,
191- ) ;
204+
205+ let _packedType : ValueType ;
206+
192207 if ( isTypedVector ( this . valueType ) ) {
193- const _valueType = typedVectorElementType ( this . valueType ) ;
194- _packedType = packedType ( _valueType , BitWidth . WIDTH8 ) ;
195- } else if ( isFixedTypedVector ( this . valueType ) ) {
196- const _valueType = fixedTypedVectorElementType ( this . valueType ) ;
197- _packedType = packedType ( _valueType , BitWidth . WIDTH8 ) ;
208+ // Root typed vector: derive type instead of reading from buffer
209+ const _valueType = typedVectorElementType ( this . valueType ) ;
210+ _packedType = packedType ( _valueType , BitWidth . WIDTH8 ) ;
211+ } else if ( isFixedTypedVector ( this . valueType ) ) {
212+ const _valueType = fixedTypedVectorElementType ( this . valueType ) ;
213+ _packedType = packedType ( _valueType , BitWidth . WIDTH8 ) ;
214+ } else {
215+ // Only read packed type from buffer if it exists
216+ const typeOffset = _indirect + length * this . byteWidth + key ;
217+ if ( typeOffset < this . dataView . byteLength ) {
218+ _packedType = this . dataView . getUint8 ( typeOffset ) ;
219+ } else {
220+ // fallback for edge cases (e.g., root vectors)
221+ _packedType = this . packedType ;
222+ }
198223 }
224+
199225 return new Reference (
200226 this . dataView ,
201227 elementOffset ,
@@ -204,6 +230,7 @@ export class Reference {
204230 `${ this . path } [${ key } ]` ,
205231 ) ;
206232 }
233+
207234 if ( typeof key === 'string' ) {
208235 const index = keyIndex (
209236 key ,
@@ -226,7 +253,8 @@ export class Reference {
226253 ) ;
227254 }
228255 }
229- throw `Key [${ key } ] is not applicable on ${ this . path } of ${ this . valueType } ` ;
256+
257+ throw new Error ( `Key [${ key } ] is not applicable on ${ this . path } of ${ this . valueType } ` ) ;
230258 }
231259
232260 length ( ) : number {
0 commit comments