import { Dexie , Table } from 'dexie' ; import { Remote } from '../remote' ; import { createIndexString , NewDexie } from '../utils' ; import { Collection , CollectionConfig } from './collection' ; export class Database { readonly dexie : Dexie ; readonly remote : Remote ; private collectionMap : Map < string , Collection > = new Map ( ) ; private pendingSchemas : CollectionConfig [ ] = [ ] ; param name param collections see CollectionConfig for details on collection configuration options.
      constructor ( name , ... collections ) { this . dexie = NewDexie ( name ) ; this . remote = new Remote ( this . dexie ) ; collections . forEach ( ( collection ) => this . pendingSchemas . push ( collection ) ) ; } /**
     * Base32-encoded string representation of the db's thread id.
     */ get id ( ) : string | undefined { return this . remote . id ; } /**
     * Open the local db for reads/writes.
     */ async open ( version = 1 ) { if ( ! this . dexie . isOpen ( ) ) { let stores = [ ] ; if ( this . pendingSchemas . length ) { const specs = this . pendingSchemas . map ( ( config ) => { const indexes = [ { path : '_id' , uuid : false , auto : true } , ... ( config . indexes ?? [ ] ) , ] . map ( ( index ) => createIndexString ( index ) ) . join ( ',' ) ; return [ config . name , indexes ] ; } ) ; stores = Object . fromEntries ( specs ) ; } this . dexie . version ( version ) . stores ( stores ) ; await this . dexie . open ( ) ; for ( const collection of this . pendingSchemas ) { if ( ! this . collectionMap . has ( collection . name ) ) { const table = this . dexie . table < unknown , string > ( collection . name ) ; await table . setSchema ( collection . schema ) ; this . collectionMap . set ( collection . name , new Collection ( table ) ) ; } } this . pendingSchemas = [ ] ; } return this ; } /**
     * Close the local db to reads/writes.
     */ close ( ) { return this . dexie . close ( ) ; } /**
     * Delete the local db and its persistent storage.
     */ delete ( ) { return this . dexie . delete ( ) ; } /**
     * Get the current local db version number.
     * This is a non-ordered integer hash of the stringified input indexes.
     * It is used for uniqueness.
     */ get verno ( ) : number { return this . dexie . verno ; } param config collectionConfig ( config ) { this . pendingSchemas . push ( config ) ; return this ; } param name collection < T = unknown > ( name ) { let collection = this . collectionMap . get ( name ) ; if ( collection !== undefined ) { return collection as Collection < T > ; } const table = this . dexie . table ( name ) ; collection = new Collection < T > ( table ) ; this . collectionMap . set ( name , collection ) ; return collection as Collection < T > ; } /**
     * Returns all local collections by name.
     */ collections ( ) { const tables = this . dexie . tables . filter ( ( table ) => ! table . name . startsWith ( '_' ) ) ; for ( const table of tables ) { if ( ! this . collectionMap . has ( table . name ) ) { this . collectionMap . set ( table . name , new Collection ( table ) ) ; } } return this . collectionMap ; } }