async traverseAndConstruct(obj, onProgress) {
    if (!obj) return
    if (typeof obj !== 'object') return obj

    // Handle arrays
    if (Array.isArray(obj) && obj.length !== 0) {
      const arr = []
      for (const element of obj) {
        if (typeof element !== 'object' && !this.options.fullyTraverseArrays) return obj

        // Dereference element if needed
        const deRef = element.referencedId
          ? await this.getObject(element.referencedId)
          : element
        if (element.referencedId && onProgress)
          onProgress({
            stage: 'construction',
            current:
              ++this.traversedReferencesCount > this.totalChildrenCount
                ? this.totalChildrenCount
                : this.traversedReferencesCount,
            total: this.totalChildrenCount
          })

        // Push the traversed object in the array
        arr.push(await this.traverseAndConstruct(deRef, onProgress))
      }

      // De-chunk
      if (arr[0]?.speckle_type?.toLowerCase().includes('datachunk')) {
        return arr.reduce((prev, curr) => prev.concat(curr.data), [])
      }

      return arr
    }

    // Handle objects
    // 1) Purge ignored props
    for (const ignoredProp of this.options.excludeProps) {
      delete obj[ignoredProp]
    }

    // 2) Iterate through obj
    for (const prop in obj) {
      if (typeof obj[prop] !== 'object' || obj[prop] === null) continue // leave alone primitive props

      if (obj[prop].referencedId) {
        obj[prop] = await this.getObject(obj[prop].referencedId)
        if (onProgress)
          onProgress({
            stage: 'construction',
            current:
              ++this.traversedReferencesCount > this.totalChildrenCount
                ? this.totalChildrenCount
                : this.traversedReferencesCount,
            total: this.totalChildrenCount
          })
      }

      obj[prop] = await this.traverseAndConstruct(obj[prop], onProgress)
    }

    return obj
  }
/**
   * Internal function used to recursively traverse an object and populate its references and dechunk any arrays.
   * @param {*} obj
   * @param {*} onProgress
   * @returns
   */
Internal function used to recursively traverse an object and populate its references and dechunk any arrays.
@param {*} obj
@param {*} onProgress
@returns
Internal function used to recursively traverse an object and populate its references and dechunk any arrays . @param { * } obj @param { * } onProgress @returns
async traverseAndConstruct(obj, onProgress) {
    if (!obj) return
    if (typeof obj !== 'object') return obj
    if (Array.isArray(obj) && obj.length !== 0) {
      const arr = []
      for (const element of obj) {
        if (typeof element !== 'object' && !this.options.fullyTraverseArrays) return obj
        const deRef = element.referencedId
          ? await this.getObject(element.referencedId)
          : element
        if (element.referencedId && onProgress)
          onProgress({
            stage: 'construction',
            current:
              ++this.traversedReferencesCount > this.totalChildrenCount
                ? this.totalChildrenCount
                : this.traversedReferencesCount,
            total: this.totalChildrenCount
          })
        arr.push(await this.traverseAndConstruct(deRef, onProgress))
      }
      if (arr[0]?.speckle_type?.toLowerCase().includes('datachunk')) {
        return arr.reduce((prev, curr) => prev.concat(curr.data), [])
      }
      return arr
    }
    for (const ignoredProp of this.options.excludeProps) {
      delete obj[ignoredProp]
    }
    for (const prop in obj) {
      if (typeof obj[prop] !== 'object' || obj[prop] === null) continue 
      if (obj[prop].referencedId) {
        obj[prop] = await this.getObject(obj[prop].referencedId)
        if (onProgress)
          onProgress({
            stage: 'construction',
            current:
              ++this.traversedReferencesCount > this.totalChildrenCount
                ? this.totalChildrenCount
                : this.traversedReferencesCount,
            total: this.totalChildrenCount
          })
      }
      obj[prop] = await this.traverseAndConstruct(obj[prop], onProgress)
    }
    return obj
  }
async traverseAndConstruct ( obj , onProgress ) { if ( ! obj ) return if ( typeof obj !== 'object' ) return obj if ( Array . isArray ( obj ) && obj . length !== 0 ) { const arr = [ ] for ( const element of obj ) { if ( typeof element !== 'object' && ! this . options . fullyTraverseArrays ) return obj const deRef = element . referencedId ? await this . getObject ( element . referencedId ) : element if ( element . referencedId && onProgress ) onProgress ( { stage : 'construction' , current : ++ this . traversedReferencesCount > this . totalChildrenCount ? this . totalChildrenCount : this . traversedReferencesCount , total : this . totalChildrenCount } ) arr . push ( await this . traverseAndConstruct ( deRef , onProgress ) ) } if ( arr [ 0 ] ?. speckle_type ?. toLowerCase ( ) . includes ( 'datachunk' ) ) { return arr . reduce ( ( prev , curr ) => prev . concat ( curr . data ) , [ ] ) } return arr } for ( const ignoredProp of this . options . excludeProps ) { delete obj [ ignoredProp ] } for ( const prop in obj ) { if ( typeof obj [ prop ] !== 'object' || obj [ prop ] === null ) continue if ( obj [ prop ] . referencedId ) { obj [ prop ] = await this . getObject ( obj [ prop ] . referencedId ) if ( onProgress ) onProgress ( { stage : 'construction' , current : ++ this . traversedReferencesCount > this . totalChildrenCount ? this . totalChildrenCount : this . traversedReferencesCount , total : this . totalChildrenCount } ) } obj [ prop ] = await this . traverseAndConstruct ( obj [ prop ] , onProgress ) } return obj }
Internal function used to recursively traverse an object and populate its references and dechunk any arrays.
Internal function used to recursively traverse an object and populate its references and dechunk any arrays .
// Handle arrays // Dereference element if needed // Push the traversed object in the array // De-chunk // Handle objects // 1) Purge ignored props // 2) Iterate through obj // leave alone primitive props