@@ -138,7 +138,14 @@ export const selToBlock = (function () {
138138 return encodeSelToBlock ;
139139} ) ( ) ;
140140
141- export class Node {
141+ export interface Node {
142+ kind : Kind ;
143+ value : any ;
144+ lookupBySegment ( seg : PathSegment ) : Node | null ;
145+ entries ( ) : Generator < { pathSegment : PathSegment ; value : Node } , any , any > ;
146+ }
147+
148+ export class BasicNode implements Node {
142149 kind : Kind ;
143150 value : any ;
144151 constructor ( value : any ) {
@@ -152,6 +159,15 @@ export class Node {
152159 }
153160 return null ;
154161 }
162+ entries ( ) : Generator < { pathSegment : PathSegment ; value : BasicNode } , any , any > {
163+ if ( this . kind === Kind . List ) {
164+ return arrayEntries ( this . value ) ;
165+ }
166+ if ( this . kind === Kind . Map ) {
167+ return mapEntries ( this . value ) ;
168+ }
169+ throw new Error ( `Cannot call entries on ${ this . kind } kind` ) ;
170+ }
155171}
156172
157173export type SelectorNode = {
@@ -235,14 +251,21 @@ export const entriesSelector: SelectorNode = {
235251 } ,
236252} ;
237253
238- class PathSegment {
254+ export class PathSegment {
239255 value : string | number ;
240256 constructor ( value : string | number ) {
241257 this . value = value ;
242258 }
243259 toString ( ) : string {
244260 return this . value + "" ;
245261 }
262+ toIndex ( ) : number {
263+ if ( typeof this . value === "number" ) {
264+ return this . value ;
265+ } else {
266+ return parseInt ( this . value ) ;
267+ }
268+ }
246269}
247270
248271export interface Selector {
@@ -521,61 +544,26 @@ function parseLimit(node: LimitNode): RecursionLimit {
521544 }
522545}
523546
524- type IteratorState = {
525- pathSegment : PathSegment | null ;
526- value : any ;
527- } ;
528-
529- function segmentIterator ( node : any ) {
530- if ( Array . isArray ( node ) ) {
531- return arrayIterator ( node ) ;
547+ function * arrayEntries (
548+ node : Array < any >
549+ ) : Generator < { pathSegment : PathSegment ; value : BasicNode } , any , any > {
550+ for ( let i = 0 ; i < node . length ; i ++ ) {
551+ yield {
552+ pathSegment : new PathSegment ( i ) ,
553+ value : new BasicNode ( node [ i ] ) ,
554+ } ;
532555 }
533- return mapIterator ( node ) ;
534556}
535557
536- function arrayIterator ( node : Array < any > ) {
537- let i = 0 ;
538- return {
539- next ( ) : IteratorState {
540- if ( i === node . length ) {
541- return {
542- pathSegment : null ,
543- value : null ,
544- } ;
545- }
546- const index = i ++ ;
547- return {
548- pathSegment : new PathSegment ( index ) ,
549- value : node [ index ] ,
550- } ;
551- } ,
552- done ( ) : boolean {
553- return i === node . length ;
554- } ,
555- } ;
556- }
557-
558- function mapIterator ( node : { [ key : string ] : any } ) {
559- const keys = Object . keys ( node ) ;
560- let i = 0 ;
561- return {
562- next ( ) : IteratorState {
563- if ( i === keys . length ) {
564- return {
565- pathSegment : null ,
566- value : null ,
567- } ;
568- }
569- const index = i ++ ;
570- return {
571- pathSegment : new PathSegment ( keys [ index ] ) ,
572- value : node [ keys [ index ] ] ,
573- } ;
574- } ,
575- done ( ) : boolean {
576- return i === keys . length ;
577- } ,
578- } ;
558+ function * mapEntries ( node : {
559+ [ key : string ] : any ;
560+ } ) : Generator < { pathSegment : PathSegment ; value : BasicNode } , any , any > {
561+ for ( const [ k , v ] of Object . entries ( node ) ) {
562+ yield {
563+ pathSegment : new PathSegment ( k ) ,
564+ value : new BasicNode ( v ) ,
565+ } ;
566+ }
579567}
580568
581569export type NodeReifier = ( node : Node , loader : LinkLoader ) => Node ;
@@ -593,9 +581,9 @@ export function unixfsReifier(node: Node, loader: LinkLoader): Node {
593581 if ( unixfs . isDirectory ( ) ) {
594582 const dir : { [ key : string ] : Node } = { } ;
595583 for ( const link of node . value . Links ) {
596- dir [ link . Name ] = new Node ( link . Hash ) ;
584+ dir [ link . Name ] = new BasicNode ( link . Hash ) ;
597585 }
598- return new Node ( dir ) ;
586+ return new BasicNode ( dir ) ;
599587 }
600588 } catch ( e ) {
601589 return node ;
@@ -621,7 +609,7 @@ export async function* walkBlocks(
621609 const blk = await source . load ( nd . value ) ;
622610 yield blk ;
623611
624- nd = new Node ( blk . value ) ;
612+ nd = new BasicNode ( blk . value ) ;
625613 }
626614
627615 if ( sel instanceof ExploreInterpretAs ) {
@@ -660,14 +648,10 @@ export async function* walkBlocks(
660648 }
661649 } else {
662650 // visit everything
663- for ( const itr = segmentIterator ( nd . value ) ; ! itr . done ( ) ; ) {
664- let { pathSegment, value} = itr . next ( ) ;
665- if ( ! pathSegment ) {
666- continue ;
667- }
651+ for ( const { pathSegment, value} of nd . entries ( ) ) {
668652 const sNext = sel . explore ( nd . value , pathSegment ) ;
669653 if ( sNext !== null ) {
670- yield * walkBlocks ( new Node ( value ) , sNext , source ) ;
654+ yield * walkBlocks ( value , sNext , source ) ;
671655 }
672656 }
673657 }
0 commit comments