import { assert , Item , Value , Path , MetaID } from "./exports" ; /** superclass of Block and _Array, the two kinds of containers. */ export abstract class Container < I extends Item > extends Value { /** array of items in proper order */ items : I [ ] = [ ] ; /** top-down iteration through all items */ * visit ( ) { for ( let item of this . items ) { yield * item . visit ( ) ; } } /** add an item to end */ add ( item ) { assert ( ! item . container ) ; item . container = this ; this . items . push ( item ) ; } /** unevaluate all items */ uneval ( ) { this . items . forEach ( item => item . uneval ( ) ) ; } /** make copy, bottom up, translating paths contextually */ copy ( srcPath , Path ) { let to = super . copy ( srcPath , Path ) ; this . items . forEach ( item => { assert ( item . container === this ) ; to . add ( item . copy ( srcPath , Path ) ) ; } ) ; return to ; } /** value equality */ equals ( other ) { return ( other instanceof Container && this . items . length === other . items . length && this . items . every ( ( item , i ) => item . equals ( other . items [ i ] ) ) ) ; } /** whether this value was transitively copied from another Value without any
     * updates */ isCopyOf ( ancestor ) { return ( this . items . length === ancestor . items . length && this . items . every ( ( item , i ) => { if ( item . io === 'output' ) return true ; let ancestorItem = ancestor . items [ i ] ; return ( item . id === ancestorItem . id && item . value ! . isCopyOf ( ancestorItem . value ! ) ) ; } ) ) ; } }