@fireproof/core 0.7.3-dev.2 → 0.8.0-dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blockstore.js +6 -0
- package/dist/database.js +6 -3
- package/dist/fireproof.js +1 -0
- package/dist/loader.js +0 -4
- package/dist/prolly.js +1 -1
- package/dist/remote.js +46 -0
- package/dist/src/fireproof.d.ts +2 -2
- package/dist/src/fireproof.js +74 -69
- package/dist/src/fireproof.js.map +1 -1
- package/dist/src/fireproof.mjs +74 -69
- package/dist/src/fireproof.mjs.map +1 -1
- package/dist/storage/base.js +53 -15
- package/dist/storage/ucan.js +0 -40
- package/package.json +1 -5
- package/src/blockstore.js +4 -0
- package/src/database.js +5 -3
- package/src/fireproof.js +1 -0
- package/src/loader.js +0 -5
- package/src/prolly.js +1 -1
- package/src/storage/base.js +61 -15
- package/src/storage/ucan.js +0 -45
    
        package/dist/src/fireproof.mjs
    CHANGED
    
    | @@ -38937,10 +38937,11 @@ class Base { | |
| 38937 38937 | 
             
                }
         | 
| 38938 38938 | 
             
                cidMap.clear();
         | 
| 38939 38939 | 
             
                const blocks = {
         | 
| 38940 | 
            +
                  head: clock,
         | 
| 38940 38941 | 
             
                  lastCid: clock[0],
         | 
| 38941 38942 | 
             
                  get: cid => allBlocks.get(cid.toString())
         | 
| 38942 38943 | 
             
                };
         | 
| 38943 | 
            -
                console.log('compact', this.instanceId, this.name, blocks.lastCid.toString(), dataCids.length) | 
| 38944 | 
            +
                // console.log('compact', this.instanceId, this.name, blocks.lastCid.toString(), dataCids.length)
         | 
| 38944 38945 | 
             
                await this.parkCar(blocks, dataCids);
         | 
| 38945 38946 | 
             
              }
         | 
| 38946 38947 |  | 
| @@ -38956,11 +38957,11 @@ class Base { | |
| 38956 38957 | 
             
                  newCar = await blocksToCarBlock(innerBlockstore.lastCid, innerBlockstore);
         | 
| 38957 38958 | 
             
                }
         | 
| 38958 38959 | 
             
                // console.log('new car', newCar.cid.toString())
         | 
| 38959 | 
            -
                return await this.saveCar(newCar.cid.toString(), newCar.bytes, cids)
         | 
| 38960 | 
            +
                return await this.saveCar(newCar.cid.toString(), newCar.bytes, cids, innerBlockstore.head)
         | 
| 38960 38961 | 
             
              }
         | 
| 38961 38962 |  | 
| 38962 | 
            -
              async saveCar (carCid, value, cids) {
         | 
| 38963 | 
            -
                const newValetCidCar = await this.updateCarCidMap(carCid, cids);
         | 
| 38963 | 
            +
              async saveCar (carCid, value, cids, head = null) {
         | 
| 38964 | 
            +
                const newValetCidCar = await this.updateCarCidMap(carCid, cids, head);
         | 
| 38964 38965 | 
             
                // console.log('writeCars', carCid.toString(), newValetCidCar.cid.toString())
         | 
| 38965 38966 | 
             
                const carList = [
         | 
| 38966 38967 | 
             
                  {
         | 
| @@ -38982,7 +38983,7 @@ class Base { | |
| 38982 38983 | 
             
                return newValetCidCar
         | 
| 38983 38984 | 
             
              }
         | 
| 38984 38985 |  | 
| 38985 | 
            -
              applyHeaders (headers) {
         | 
| 38986 | 
            +
              async applyHeaders (headers) {
         | 
| 38986 38987 | 
             
                // console.log('applyHeaders', headers.index)
         | 
| 38987 38988 | 
             
                this.headers = headers;
         | 
| 38988 38989 | 
             
                // console.log('before applied', this.instanceId, this.name, this.keyMaterial, this.valetRootCarCid)
         | 
| @@ -38991,6 +38992,9 @@ class Base { | |
| 38991 38992 | 
             
                    // console.log('applyHeaders', this.instanceId, this.name, header.key, header.car)
         | 
| 38992 38993 | 
             
                    header.key && this.setKeyMaterial(header.key);
         | 
| 38993 38994 | 
             
                    this.setCarCidMapCarCid(header.car);
         | 
| 38995 | 
            +
                    const { clock } = await this.readHeaderCar(header.car);
         | 
| 38996 | 
            +
                    // console.log('stored clock', this.name, branch, clock, header)
         | 
| 38997 | 
            +
                    header.clock = clock.map(c => c.toString());
         | 
| 38994 38998 | 
             
                  }
         | 
| 38995 38999 | 
             
                }
         | 
| 38996 39000 | 
             
                if (!this.valetRootCarCid) {
         | 
| @@ -39011,10 +39015,16 @@ class Base { | |
| 39011 39015 | 
             
                const headers = {};
         | 
| 39012 39016 | 
             
                for (const [branch] of Object.entries(this.config.branches)) {
         | 
| 39013 39017 | 
             
                  const got = await this.loadHeader(branch);
         | 
| 39018 | 
            +
                  // const carCid = got.car
         | 
| 39014 39019 | 
             
                  // console.log('getHeaders', this.name, branch, got)
         | 
| 39020 | 
            +
                  // if (got && got.car) {
         | 
| 39021 | 
            +
                  // const { clock } = await this.readHeaderCar(got.car)
         | 
| 39022 | 
            +
                  // console.log('stored clock', this.name, branch, clock)
         | 
| 39023 | 
            +
                  // }
         | 
| 39024 | 
            +
             | 
| 39015 39025 | 
             
                  headers[branch] = got;
         | 
| 39016 39026 | 
             
                }
         | 
| 39017 | 
            -
                this.applyHeaders(headers);
         | 
| 39027 | 
            +
                await this.applyHeaders(headers);
         | 
| 39018 39028 | 
             
                return headers
         | 
| 39019 39029 | 
             
              }
         | 
| 39020 39030 |  | 
| @@ -39022,9 +39032,14 @@ class Base { | |
| 39022 39032 | 
             
                throw new Error('not implemented')
         | 
| 39023 39033 | 
             
              }
         | 
| 39024 39034 |  | 
| 39035 | 
            +
              async getStoredClock (carCid) {
         | 
| 39036 | 
            +
             | 
| 39037 | 
            +
              }
         | 
| 39038 | 
            +
             | 
| 39025 39039 | 
             
              async saveHeader (header) {
         | 
| 39040 | 
            +
                // this.clock = header.clock
         | 
| 39026 39041 | 
             
                // for each branch, save the header
         | 
| 39027 | 
            -
                // console.log('saveHeader',  | 
| 39042 | 
            +
                // console.log('saveHeader', header.clock)
         | 
| 39028 39043 | 
             
                //  for (const branch of this.branches) {
         | 
| 39029 39044 | 
             
                //    await this.saveBranchHeader(branch)
         | 
| 39030 39045 | 
             
                //  }
         | 
| @@ -39086,8 +39101,13 @@ class Base { | |
| 39086 39101 | 
             
              async mapForIPLDHashmapCarCid (carCid) {
         | 
| 39087 39102 | 
             
                // console.log('mapForIPLDHashmapCarCid', carCid)
         | 
| 39088 39103 | 
             
                // todo why is this writeable?
         | 
| 39089 | 
            -
                const carMapReader = await this. | 
| 39090 | 
            -
             | 
| 39104 | 
            +
                const { cars, reader: carMapReader } = await this.readHeaderCar(carCid);
         | 
| 39105 | 
            +
             | 
| 39106 | 
            +
                // this.clock = clock
         | 
| 39107 | 
            +
             | 
| 39108 | 
            +
                // console.log('mapForIPLDHashmapCarCid', cars)
         | 
| 39109 | 
            +
             | 
| 39110 | 
            +
                const indexNode = await load$1(carMapReader, cars, {
         | 
| 39091 39111 | 
             
                  blockHasher: blockOpts$1.hasher,
         | 
| 39092 39112 | 
             
                  blockCodec: blockOpts$1.codec
         | 
| 39093 39113 | 
             
                });
         | 
| @@ -39099,9 +39119,21 @@ class Base { | |
| 39099 39119 | 
             
                return theCarMap
         | 
| 39100 39120 | 
             
              }
         | 
| 39101 39121 |  | 
| 39122 | 
            +
              async readHeaderCar (carCid) {
         | 
| 39123 | 
            +
                const carMapReader = await this.getWriteableCarReader(carCid);
         | 
| 39124 | 
            +
                // console.log('readHeaderCar', carCid, carMapReader)
         | 
| 39125 | 
            +
                // now when we load the root cid from the car, we get our new custom root node
         | 
| 39126 | 
            +
                const bytes = await carMapReader.get(carMapReader.root.cid);
         | 
| 39127 | 
            +
                const decoded = await decode$5({ bytes, hasher: blockOpts$1.hasher, codec: blockOpts$1.codec });
         | 
| 39128 | 
            +
                // @ts-ignore
         | 
| 39129 | 
            +
                const { fp: { cars, clock } } = decoded.value;
         | 
| 39130 | 
            +
                return { cars, clock, reader: carMapReader }
         | 
| 39131 | 
            +
              }
         | 
| 39132 | 
            +
             | 
| 39102 39133 | 
             
              async getWriteableCarReader (carCid) {
         | 
| 39103 39134 | 
             
                // console.log('getWriteableCarReader', carCid)
         | 
| 39104 39135 | 
             
                const carMapReader = await this.getCarReader(carCid);
         | 
| 39136 | 
            +
                // console.log('getWriteableCarReader', carCid, carMapReader)
         | 
| 39105 39137 | 
             
                const theseWriteableBlocks = new VMemoryBlockstore();
         | 
| 39106 39138 | 
             
                const combinedReader = {
         | 
| 39107 39139 | 
             
                  blocks: theseWriteableBlocks,
         | 
| @@ -39138,12 +39170,16 @@ class Base { | |
| 39138 39170 |  | 
| 39139 39171 | 
             
              async getCarReaderImpl (carCid) {
         | 
| 39140 39172 | 
             
                carCid = carCid.toString();
         | 
| 39173 | 
            +
                // console.log('getCarReaderImpl', carCid)
         | 
| 39141 39174 | 
             
                const carBytes = await this.readCar(carCid);
         | 
| 39142 39175 | 
             
                // console.log('getCarReader', this.constructor.name, carCid, carBytes.length)
         | 
| 39143 39176 | 
             
                const reader = await CarReader.fromBytes(carBytes);
         | 
| 39177 | 
            +
                // console.log('getCarReader', carCid, reader._header)
         | 
| 39144 39178 | 
             
                if (this.keyMaterial) {
         | 
| 39145 39179 | 
             
                  const roots = await reader.getRoots();
         | 
| 39180 | 
            +
                  // let count = 0
         | 
| 39146 39181 | 
             
                  const readerGetWithCodec = async cid => {
         | 
| 39182 | 
            +
                    // console.log('readerGetWithCodec', count++, cid)
         | 
| 39147 39183 | 
             
                    const got = await reader.get(cid);
         | 
| 39148 39184 | 
             
                    let useCodec = codec;
         | 
| 39149 39185 | 
             
                    if (cid.toString().indexOf('bafy') === 0) {
         | 
| @@ -39200,17 +39236,17 @@ class Base { | |
| 39200 39236 |  | 
| 39201 39237 | 
             
              writeCars (cars) {}
         | 
| 39202 39238 |  | 
| 39203 | 
            -
              async updateCarCidMap (carCid, cids) {
         | 
| 39239 | 
            +
              async updateCarCidMap (carCid, cids, head) {
         | 
| 39204 39240 | 
             
                // this hydrates the map if it has not been hydrated
         | 
| 39205 39241 | 
             
                const theCarMap = await this.getCidCarMap();
         | 
| 39206 39242 | 
             
                for (const cid of cids) {
         | 
| 39207 39243 | 
             
                  theCarMap.set(cid, carCid);
         | 
| 39208 39244 | 
             
                }
         | 
| 39209 39245 | 
             
                // todo can we debounce this? -- maybe put it into a queue so we can batch it
         | 
| 39210 | 
            -
                return await this.persistCarMap(theCarMap)
         | 
| 39246 | 
            +
                return await this.persistCarMap(theCarMap, head)
         | 
| 39211 39247 | 
             
              }
         | 
| 39212 39248 |  | 
| 39213 | 
            -
              async persistCarMap (theCarMap) {
         | 
| 39249 | 
            +
              async persistCarMap (theCarMap, head) {
         | 
| 39214 39250 | 
             
                const ipldLoader = await getEmptyLoader();
         | 
| 39215 39251 | 
             
                const indexNode = await create$1(ipldLoader, {
         | 
| 39216 39252 | 
             
                  bitWidth: 4,
         | 
| @@ -39223,13 +39259,21 @@ class Base { | |
| 39223 39259 | 
             
                  await indexNode.set(key, value);
         | 
| 39224 39260 | 
             
                }
         | 
| 39225 39261 |  | 
| 39262 | 
            +
                // console.log('persistCarMap', indexNode.cid, head)
         | 
| 39263 | 
            +
                const value = { fp: { cars: indexNode.cid, clock: head } };
         | 
| 39264 | 
            +
                const header = await encode$5({ value, hasher: blockOpts$1.hasher, codec: blockOpts$1.codec });
         | 
| 39265 | 
            +
                ipldLoader.blocks.put(header.cid, header.bytes);
         | 
| 39266 | 
            +
             | 
| 39226 39267 | 
             
                let newValetCidCar;
         | 
| 39227 39268 | 
             
                if (this.keyMaterial) {
         | 
| 39228 39269 | 
             
                  const cids = [...ipldLoader.blocks.blocks.keys()];
         | 
| 39229 39270 | 
             
                  // console.log('persistCarMap', cids)
         | 
| 39230 | 
            -
                   | 
| 39271 | 
            +
                  // store the clock head and a link to the indexNode.cid in a custom root?
         | 
| 39272 | 
            +
             | 
| 39273 | 
            +
                  newValetCidCar = await blocksToEncryptedCarBlock(header.cid, ipldLoader.blocks, this.keyMaterial, cids);
         | 
| 39274 | 
            +
                  // then put this carcid into the header / w3clock
         | 
| 39231 39275 | 
             
                } else {
         | 
| 39232 | 
            -
                  newValetCidCar = await blocksToCarBlock( | 
| 39276 | 
            +
                  newValetCidCar = await blocksToCarBlock(header.cid, ipldLoader.blocks);
         | 
| 39233 39277 | 
             
                }
         | 
| 39234 39278 | 
             
                return newValetCidCar
         | 
| 39235 39279 | 
             
              }
         | 
| @@ -39364,6 +39408,7 @@ const blocksFromEncryptedCarBlock = async (cid, get, keyMaterial) => { | |
| 39364 39408 | 
             
                    cache: nocache
         | 
| 39365 39409 | 
             
                    // codec: dagcbor
         | 
| 39366 39410 | 
             
                  })) {
         | 
| 39411 | 
            +
                    // console.log('decrypted', block.cid.toString())
         | 
| 39367 39412 | 
             
                    decryptedBlocks.push(block);
         | 
| 39368 39413 | 
             
                    cids.add(block.cid.toString());
         | 
| 39369 39414 | 
             
                  }
         | 
| @@ -39374,7 +39419,7 @@ const blocksFromEncryptedCarBlock = async (cid, get, keyMaterial) => { | |
| 39374 39419 | 
             
              }
         | 
| 39375 39420 | 
             
            };
         | 
| 39376 39421 |  | 
| 39377 | 
            -
            const defaultConfig$ | 
| 39422 | 
            +
            const defaultConfig$1 = {
         | 
| 39378 39423 | 
             
              headerKeyPrefix: 'fp.'
         | 
| 39379 39424 | 
             
            };
         | 
| 39380 39425 |  | 
| @@ -39382,7 +39427,7 @@ const defaultConfig$2 = { | |
| 39382 39427 |  | 
| 39383 39428 | 
             
            class Browser extends Base {
         | 
| 39384 39429 | 
             
              constructor (name, config = {}) {
         | 
| 39385 | 
            -
                super(name, Object.assign({}, defaultConfig$ | 
| 39430 | 
            +
                super(name, Object.assign({}, defaultConfig$1, config));
         | 
| 39386 39431 | 
             
              }
         | 
| 39387 39432 |  | 
| 39388 39433 | 
             
              withDB = async dbWorkFun => {
         | 
| @@ -40004,13 +40049,13 @@ var browserPonyfill = { | |
| 40004 40049 |  | 
| 40005 40050 | 
             
            var fetch = /*@__PURE__*/getDefaultExportFromCjs(browserPonyfillExports);
         | 
| 40006 40051 |  | 
| 40007 | 
            -
            const defaultConfig | 
| 40052 | 
            +
            const defaultConfig = {
         | 
| 40008 40053 | 
             
              url: 'http://localhost:4000'
         | 
| 40009 40054 | 
             
            };
         | 
| 40010 40055 |  | 
| 40011 40056 | 
             
            class Rest extends Base {
         | 
| 40012 40057 | 
             
              constructor (name, config = {}) {
         | 
| 40013 | 
            -
                super(name, Object.assign({}, defaultConfig | 
| 40058 | 
            +
                super(name, Object.assign({}, defaultConfig, config));
         | 
| 40014 40059 | 
             
                // console.log('Rest', name, config)
         | 
| 40015 40060 | 
             
              }
         | 
| 40016 40061 |  | 
| @@ -40062,49 +40107,6 @@ class Rest extends Base { | |
| 40062 40107 | 
             
              }
         | 
| 40063 40108 | 
             
            }
         | 
| 40064 40109 |  | 
| 40065 | 
            -
            const defaultConfig = {
         | 
| 40066 | 
            -
              upload: () => {},
         | 
| 40067 | 
            -
              url: (cid) => `https://${cid}.ipfs.w3s.link/`
         | 
| 40068 | 
            -
            };
         | 
| 40069 | 
            -
             | 
| 40070 | 
            -
            class UCAN extends Base {
         | 
| 40071 | 
            -
              constructor (name, config = {}) {
         | 
| 40072 | 
            -
                super(name, Object.assign({}, defaultConfig, config));
         | 
| 40073 | 
            -
              }
         | 
| 40074 | 
            -
             | 
| 40075 | 
            -
              async writeCars (cars) {
         | 
| 40076 | 
            -
                if (this.config.readonly) return
         | 
| 40077 | 
            -
                for (const { cid, bytes } of cars) {
         | 
| 40078 | 
            -
                  console.log(`write UCAN ${cid}, ${bytes.length} bytes`);
         | 
| 40079 | 
            -
                  const upCid = await this.config.upload(bytes);
         | 
| 40080 | 
            -
                  console.log(`wrote UCAN ${cid}, ${upCid}`);
         | 
| 40081 | 
            -
                  // if (!response.ok) throw new Error(`An error occurred: ${response.statusText}`)
         | 
| 40082 | 
            -
                }
         | 
| 40083 | 
            -
              }
         | 
| 40084 | 
            -
             | 
| 40085 | 
            -
              async readCar (carCid) {
         | 
| 40086 | 
            -
                const carURL = this.config.url(carCid);
         | 
| 40087 | 
            -
                const response = await fetch(carURL);
         | 
| 40088 | 
            -
                if (!response.ok) throw new Error(`An error occurred: ${response.statusText}`)
         | 
| 40089 | 
            -
                const got = await response.arrayBuffer();
         | 
| 40090 | 
            -
                return new Uint8Array(got)
         | 
| 40091 | 
            -
              }
         | 
| 40092 | 
            -
             | 
| 40093 | 
            -
              async loadHeader (branch = 'main') {
         | 
| 40094 | 
            -
                return headerMock.get(branch)
         | 
| 40095 | 
            -
              }
         | 
| 40096 | 
            -
             | 
| 40097 | 
            -
              async writeHeader (branch, header) {
         | 
| 40098 | 
            -
                if (this.config.readonly) return
         | 
| 40099 | 
            -
                const pHeader = this.prepareHeader(header);
         | 
| 40100 | 
            -
                // console.log('writeHeader rt', branch, pHeader)
         | 
| 40101 | 
            -
             | 
| 40102 | 
            -
                headerMock.set(branch, pHeader);
         | 
| 40103 | 
            -
              }
         | 
| 40104 | 
            -
            }
         | 
| 40105 | 
            -
             | 
| 40106 | 
            -
            const headerMock = new Map();
         | 
| 40107 | 
            -
             | 
| 40108 40110 | 
             
            const Loader = {
         | 
| 40109 40111 | 
             
              appropriate: (name, config = {}) => {
         | 
| 40110 40112 | 
             
                if (config.StorageClass) {
         | 
| @@ -40115,10 +40117,6 @@ const Loader = { | |
| 40115 40117 | 
             
                  return new Rest(name, config)
         | 
| 40116 40118 | 
             
                }
         | 
| 40117 40119 |  | 
| 40118 | 
            -
                if (config.type === 'ucan') {
         | 
| 40119 | 
            -
                  return new UCAN(name, config)
         | 
| 40120 | 
            -
                }
         | 
| 40121 | 
            -
             | 
| 40122 40120 | 
             
                return new Browser(name, config)
         | 
| 40123 40121 | 
             
              }
         | 
| 40124 40122 | 
             
            };
         | 
| @@ -40437,6 +40435,9 @@ const doTransaction = async (label, blockstore, doFun, doSync = true) => { | |
| 40437 40435 | 
             
              const innerBlockstore = blockstore.begin(label);
         | 
| 40438 40436 | 
             
              try {
         | 
| 40439 40437 | 
             
                const result = await doFun(innerBlockstore);
         | 
| 40438 | 
            +
                // console.log('doTransaction', label, 'result', result.head)
         | 
| 40439 | 
            +
                if (result && result.head) { innerBlockstore.head = result.head; }
         | 
| 40440 | 
            +
                // pass the latest clock head for writing to the valet
         | 
| 40440 40441 | 
             
                // @ts-ignore
         | 
| 40441 40442 | 
             
                await blockstore.commit(innerBlockstore, doSync);
         | 
| 40442 40443 | 
             
                return result
         | 
| @@ -40452,6 +40453,7 @@ const doTransaction = async (label, blockstore, doFun, doSync = true) => { | |
| 40452 40453 | 
             
            class InnerBlockstore {
         | 
| 40453 40454 | 
             
              /** @type {Map<string, Uint8Array>} */
         | 
| 40454 40455 | 
             
              blocks = new Map()
         | 
| 40456 | 
            +
              head = []
         | 
| 40455 40457 | 
             
              lastCid = null
         | 
| 40456 40458 | 
             
              label = ''
         | 
| 40457 40459 | 
             
              parentBlockstore = null
         | 
| @@ -40782,7 +40784,7 @@ async function root (inBlocks, head, doFull = false) { | |
| 40782 40784 | 
             
                    bigPut(nb);
         | 
| 40783 40785 | 
             
                  }
         | 
| 40784 40786 | 
             
                  // console.log('root root', newProllyRootNode.constructor.name, newProllyRootNode)
         | 
| 40785 | 
            -
                  return { clockCIDs, node: newProllyRootNode }
         | 
| 40787 | 
            +
                  return { clockCIDs, node: newProllyRootNode, head }
         | 
| 40786 40788 | 
             
                },
         | 
| 40787 40789 | 
             
                false
         | 
| 40788 40790 | 
             
              )
         | 
| @@ -41749,7 +41751,7 @@ class Database { | |
| 41749 41751 |  | 
| 41750 41752 | 
             
              toHeader () {
         | 
| 41751 41753 | 
             
                return {
         | 
| 41752 | 
            -
                  clock: this.clockToJSON(),
         | 
| 41754 | 
            +
                  // clock: this.clockToJSON(),
         | 
| 41753 41755 | 
             
                  name: this.name,
         | 
| 41754 41756 | 
             
                  index: {
         | 
| 41755 41757 | 
             
                    key: this.indexBlocks.valet?.primary.keyMaterial,
         | 
| @@ -41934,11 +41936,13 @@ class Database { | |
| 41934 41936 | 
             
               * @memberof Fireproof
         | 
| 41935 41937 | 
             
               * @instance
         | 
| 41936 41938 | 
             
               */
         | 
| 41937 | 
            -
              async put ({ _id, _proof, ...doc }) {
         | 
| 41939 | 
            +
              async put ({ _id, _proof, _clock, ...doc }) {
         | 
| 41938 41940 | 
             
                await this.ready;
         | 
| 41939 41941 | 
             
                const id = _id || 'f' + Math.random().toString(36).slice(2);
         | 
| 41942 | 
            +
                doc = JSON.parse(JSON.stringify(doc));
         | 
| 41943 | 
            +
                if (_clock) doc._clock = _clock;
         | 
| 41940 41944 | 
             
                await this.runValidation({ _id: id, ...doc });
         | 
| 41941 | 
            -
                return await this.putToProllyTree({ key: id, value: doc },  | 
| 41945 | 
            +
                return await this.putToProllyTree({ key: id, value: doc }, _clock)
         | 
| 41942 41946 | 
             
              }
         | 
| 41943 41947 |  | 
| 41944 41948 | 
             
              /**
         | 
| @@ -44282,6 +44286,7 @@ class Fireproof { | |
| 44282 44286 |  | 
| 44283 44287 | 
             
              static snapshot (database, clock) {
         | 
| 44284 44288 | 
             
                const definition = database.toJSON();
         | 
| 44289 | 
            +
                definition.clock = database.clockToJSON();
         | 
| 44285 44290 | 
             
                if (clock) {
         | 
| 44286 44291 | 
             
                  definition.clock = clock.map(c => parseCID(c));
         | 
| 44287 44292 | 
             
                  definition.indexes.forEach(index => {
         |