@fireproof/core 0.7.3-dev.2 → 0.8.0-dev

Sign up to get free protection for your applications and to get access to all the features.
@@ -207,6 +207,11 @@ export const doTransaction = async (label, blockstore, doFun, doSync = true) =>
207
207
  const innerBlockstore = blockstore.begin(label);
208
208
  try {
209
209
  const result = await doFun(innerBlockstore);
210
+ // console.log('doTransaction', label, 'result', result.head)
211
+ if (result && result.head) {
212
+ innerBlockstore.head = result.head;
213
+ }
214
+ // pass the latest clock head for writing to the valet
210
215
  // @ts-ignore
211
216
  await blockstore.commit(innerBlockstore, doSync);
212
217
  return result;
@@ -223,6 +228,7 @@ export const doTransaction = async (label, blockstore, doFun, doSync = true) =>
223
228
  export class InnerBlockstore {
224
229
  /** @type {Map<string, Uint8Array>} */
225
230
  blocks = new Map();
231
+ head = [];
226
232
  lastCid = null;
227
233
  label = '';
228
234
  parentBlockstore = null;
package/dist/database.js CHANGED
@@ -83,7 +83,7 @@ export class Database {
83
83
  }
84
84
  toHeader() {
85
85
  return {
86
- clock: this.clockToJSON(),
86
+ // clock: this.clockToJSON(),
87
87
  name: this.name,
88
88
  index: {
89
89
  key: this.indexBlocks.valet?.primary.keyMaterial,
@@ -257,11 +257,14 @@ export class Database {
257
257
  * @memberof Fireproof
258
258
  * @instance
259
259
  */
260
- async put({ _id, _proof, ...doc }) {
260
+ async put({ _id, _proof, _clock, ...doc }) {
261
261
  await this.ready;
262
262
  const id = _id || 'f' + Math.random().toString(36).slice(2);
263
+ doc = JSON.parse(JSON.stringify(doc));
264
+ if (_clock)
265
+ doc._clock = _clock;
263
266
  await this.runValidation({ _id: id, ...doc });
264
- return await this.putToProllyTree({ key: id, value: doc }, doc._clock);
267
+ return await this.putToProllyTree({ key: id, value: doc }, _clock);
265
268
  }
266
269
  /**
267
270
  * Deletes a document from the database
package/dist/fireproof.js CHANGED
@@ -49,6 +49,7 @@ class Fireproof {
49
49
  }
50
50
  static snapshot(database, clock) {
51
51
  const definition = database.toJSON();
52
+ definition.clock = database.clockToJSON();
52
53
  if (clock) {
53
54
  definition.clock = clock.map(c => parseCID(c));
54
55
  definition.indexes.forEach(index => {
package/dist/loader.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import { Browser } from './storage/browser.js';
2
2
  import { Rest } from './storage/rest.js';
3
- import { UCAN } from './storage/ucan.js';
4
3
  export const Loader = {
5
4
  appropriate: (name, config = {}) => {
6
5
  if (config.StorageClass) {
@@ -9,9 +8,6 @@ export const Loader = {
9
8
  if (config.type === 'rest') {
10
9
  return new Rest(name, config);
11
10
  }
12
- if (config.type === 'ucan') {
13
- return new UCAN(name, config);
14
- }
15
11
  return new Browser(name, config);
16
12
  }
17
13
  };
package/dist/prolly.js CHANGED
@@ -280,7 +280,7 @@ export async function root(inBlocks, head, doFull = false) {
280
280
  bigPut(nb);
281
281
  }
282
282
  // console.log('root root', newProllyRootNode.constructor.name, newProllyRootNode)
283
- return { clockCIDs, node: newProllyRootNode };
283
+ return { clockCIDs, node: newProllyRootNode, head };
284
284
  }, false);
285
285
  // return { clockCIDs, node: newProllyRootNode }
286
286
  }
package/dist/remote.js ADDED
@@ -0,0 +1,46 @@
1
+ // when you call database.connect(email)
2
+ // it will return a promise that resolves when the user is logged in
3
+ // and sends you an email
4
+ import { create } from '@web3-storage/w3up-client';
5
+ import * as w3clock from '@web3-storage/clock/client';
6
+ import { CID } from 'multiformats';
7
+ export class Remote {
8
+ client = null;
9
+ name = 'unset';
10
+ config = {};
11
+ constructor(database, name, config) {
12
+ this.name = name;
13
+ this.config = config;
14
+ this.database = database;
15
+ }
16
+ async clock(cid) {
17
+ // const did = this.client.currentSpace()
18
+ const agent = this.client.agent();
19
+ const head = await w3clock.head({ issuer: agent, with: agent.did(), proofs: [] });
20
+ console.log('head', head, JSON.stringify(head.root.data.ocm.out));
21
+ const headCids = head.root.data.ocm.out.ok.head;
22
+ const blocks = await Promise.all([this.database.blocks.get(CID.parse(cid)),
23
+ ...headCids.map(c => this.database.blocks.get(c))]);
24
+ console.log('blocks', blocks);
25
+ const adv = await w3clock.advance({ issuer: agent, with: agent.did(), proofs: [] }, CID.parse(cid), { blocks });
26
+ console.log('adv', adv, JSON.stringify(adv.root.data.ocm.out));
27
+ return { head, adv };
28
+ }
29
+ async connect(email) {
30
+ try {
31
+ const client = await create();
32
+ await client.authorize(email);
33
+ const claims = await client.capability.access.claim();
34
+ console.log('claims', claims);
35
+ const space = await client.createSpace('fp.' + this.name);
36
+ console.log('space', space);
37
+ await client.setCurrentSpace(space.did());
38
+ await client.registerSpace(email);
39
+ this.client = client;
40
+ console.log('client', client);
41
+ }
42
+ catch (err) {
43
+ console.error('registration failed: ', err);
44
+ }
45
+ }
46
+ }
@@ -113,6 +113,7 @@ declare class InnerBlockstore {
113
113
  constructor(label: any, parentBlockstore: any);
114
114
  /** @type {Map<string, Uint8Array>} */
115
115
  blocks: Map<string, Uint8Array>;
116
+ head: any[];
116
117
  lastCid: any;
117
118
  label: string;
118
119
  parentBlockstore: any;
@@ -174,7 +175,6 @@ declare class Database {
174
175
  */
175
176
  toJSON(): any;
176
177
  toHeader(): {
177
- clock: string[];
178
178
  name: any;
179
179
  index: {
180
180
  key: any;
@@ -250,7 +250,7 @@ declare class Database {
250
250
  * @memberof Fireproof
251
251
  * @instance
252
252
  */
253
- put({ _id, _proof, ...doc }: any): Promise<{
253
+ put({ _id, _proof, _clock, ...doc }: any): Promise<{
254
254
  id: string;
255
255
  clock: CID[];
256
256
  }>;
@@ -38939,10 +38939,11 @@ class Base {
38939
38939
  }
38940
38940
  cidMap.clear();
38941
38941
  const blocks = {
38942
+ head: clock,
38942
38943
  lastCid: clock[0],
38943
38944
  get: cid => allBlocks.get(cid.toString())
38944
38945
  };
38945
- console.log('compact', this.instanceId, this.name, blocks.lastCid.toString(), dataCids.length);
38946
+ // console.log('compact', this.instanceId, this.name, blocks.lastCid.toString(), dataCids.length)
38946
38947
  await this.parkCar(blocks, dataCids);
38947
38948
  }
38948
38949
 
@@ -38958,11 +38959,11 @@ class Base {
38958
38959
  newCar = await blocksToCarBlock(innerBlockstore.lastCid, innerBlockstore);
38959
38960
  }
38960
38961
  // console.log('new car', newCar.cid.toString())
38961
- return await this.saveCar(newCar.cid.toString(), newCar.bytes, cids)
38962
+ return await this.saveCar(newCar.cid.toString(), newCar.bytes, cids, innerBlockstore.head)
38962
38963
  }
38963
38964
 
38964
- async saveCar (carCid, value, cids) {
38965
- const newValetCidCar = await this.updateCarCidMap(carCid, cids);
38965
+ async saveCar (carCid, value, cids, head = null) {
38966
+ const newValetCidCar = await this.updateCarCidMap(carCid, cids, head);
38966
38967
  // console.log('writeCars', carCid.toString(), newValetCidCar.cid.toString())
38967
38968
  const carList = [
38968
38969
  {
@@ -38984,7 +38985,7 @@ class Base {
38984
38985
  return newValetCidCar
38985
38986
  }
38986
38987
 
38987
- applyHeaders (headers) {
38988
+ async applyHeaders (headers) {
38988
38989
  // console.log('applyHeaders', headers.index)
38989
38990
  this.headers = headers;
38990
38991
  // console.log('before applied', this.instanceId, this.name, this.keyMaterial, this.valetRootCarCid)
@@ -38993,6 +38994,9 @@ class Base {
38993
38994
  // console.log('applyHeaders', this.instanceId, this.name, header.key, header.car)
38994
38995
  header.key && this.setKeyMaterial(header.key);
38995
38996
  this.setCarCidMapCarCid(header.car);
38997
+ const { clock } = await this.readHeaderCar(header.car);
38998
+ // console.log('stored clock', this.name, branch, clock, header)
38999
+ header.clock = clock.map(c => c.toString());
38996
39000
  }
38997
39001
  }
38998
39002
  if (!this.valetRootCarCid) {
@@ -39013,10 +39017,16 @@ class Base {
39013
39017
  const headers = {};
39014
39018
  for (const [branch] of Object.entries(this.config.branches)) {
39015
39019
  const got = await this.loadHeader(branch);
39020
+ // const carCid = got.car
39016
39021
  // console.log('getHeaders', this.name, branch, got)
39022
+ // if (got && got.car) {
39023
+ // const { clock } = await this.readHeaderCar(got.car)
39024
+ // console.log('stored clock', this.name, branch, clock)
39025
+ // }
39026
+
39017
39027
  headers[branch] = got;
39018
39028
  }
39019
- this.applyHeaders(headers);
39029
+ await this.applyHeaders(headers);
39020
39030
  return headers
39021
39031
  }
39022
39032
 
@@ -39024,9 +39034,14 @@ class Base {
39024
39034
  throw new Error('not implemented')
39025
39035
  }
39026
39036
 
39037
+ async getStoredClock (carCid) {
39038
+
39039
+ }
39040
+
39027
39041
  async saveHeader (header) {
39042
+ // this.clock = header.clock
39028
39043
  // for each branch, save the header
39029
- // console.log('saveHeader', this.config.branches, header)
39044
+ // console.log('saveHeader', header.clock)
39030
39045
  // for (const branch of this.branches) {
39031
39046
  // await this.saveBranchHeader(branch)
39032
39047
  // }
@@ -39088,8 +39103,13 @@ class Base {
39088
39103
  async mapForIPLDHashmapCarCid (carCid) {
39089
39104
  // console.log('mapForIPLDHashmapCarCid', carCid)
39090
39105
  // todo why is this writeable?
39091
- const carMapReader = await this.getWriteableCarReader(carCid);
39092
- const indexNode = await load$1(carMapReader, carMapReader.root.cid, {
39106
+ const { cars, reader: carMapReader } = await this.readHeaderCar(carCid);
39107
+
39108
+ // this.clock = clock
39109
+
39110
+ // console.log('mapForIPLDHashmapCarCid', cars)
39111
+
39112
+ const indexNode = await load$1(carMapReader, cars, {
39093
39113
  blockHasher: blockOpts$1.hasher,
39094
39114
  blockCodec: blockOpts$1.codec
39095
39115
  });
@@ -39101,9 +39121,21 @@ class Base {
39101
39121
  return theCarMap
39102
39122
  }
39103
39123
 
39124
+ async readHeaderCar (carCid) {
39125
+ const carMapReader = await this.getWriteableCarReader(carCid);
39126
+ // console.log('readHeaderCar', carCid, carMapReader)
39127
+ // now when we load the root cid from the car, we get our new custom root node
39128
+ const bytes = await carMapReader.get(carMapReader.root.cid);
39129
+ const decoded = await decode$5({ bytes, hasher: blockOpts$1.hasher, codec: blockOpts$1.codec });
39130
+ // @ts-ignore
39131
+ const { fp: { cars, clock } } = decoded.value;
39132
+ return { cars, clock, reader: carMapReader }
39133
+ }
39134
+
39104
39135
  async getWriteableCarReader (carCid) {
39105
39136
  // console.log('getWriteableCarReader', carCid)
39106
39137
  const carMapReader = await this.getCarReader(carCid);
39138
+ // console.log('getWriteableCarReader', carCid, carMapReader)
39107
39139
  const theseWriteableBlocks = new VMemoryBlockstore();
39108
39140
  const combinedReader = {
39109
39141
  blocks: theseWriteableBlocks,
@@ -39140,12 +39172,16 @@ class Base {
39140
39172
 
39141
39173
  async getCarReaderImpl (carCid) {
39142
39174
  carCid = carCid.toString();
39175
+ // console.log('getCarReaderImpl', carCid)
39143
39176
  const carBytes = await this.readCar(carCid);
39144
39177
  // console.log('getCarReader', this.constructor.name, carCid, carBytes.length)
39145
39178
  const reader = await CarReader.fromBytes(carBytes);
39179
+ // console.log('getCarReader', carCid, reader._header)
39146
39180
  if (this.keyMaterial) {
39147
39181
  const roots = await reader.getRoots();
39182
+ // let count = 0
39148
39183
  const readerGetWithCodec = async cid => {
39184
+ // console.log('readerGetWithCodec', count++, cid)
39149
39185
  const got = await reader.get(cid);
39150
39186
  let useCodec = codec;
39151
39187
  if (cid.toString().indexOf('bafy') === 0) {
@@ -39202,17 +39238,17 @@ class Base {
39202
39238
 
39203
39239
  writeCars (cars) {}
39204
39240
 
39205
- async updateCarCidMap (carCid, cids) {
39241
+ async updateCarCidMap (carCid, cids, head) {
39206
39242
  // this hydrates the map if it has not been hydrated
39207
39243
  const theCarMap = await this.getCidCarMap();
39208
39244
  for (const cid of cids) {
39209
39245
  theCarMap.set(cid, carCid);
39210
39246
  }
39211
39247
  // todo can we debounce this? -- maybe put it into a queue so we can batch it
39212
- return await this.persistCarMap(theCarMap)
39248
+ return await this.persistCarMap(theCarMap, head)
39213
39249
  }
39214
39250
 
39215
- async persistCarMap (theCarMap) {
39251
+ async persistCarMap (theCarMap, head) {
39216
39252
  const ipldLoader = await getEmptyLoader();
39217
39253
  const indexNode = await create$1(ipldLoader, {
39218
39254
  bitWidth: 4,
@@ -39225,13 +39261,21 @@ class Base {
39225
39261
  await indexNode.set(key, value);
39226
39262
  }
39227
39263
 
39264
+ // console.log('persistCarMap', indexNode.cid, head)
39265
+ const value = { fp: { cars: indexNode.cid, clock: head } };
39266
+ const header = await encode$5({ value, hasher: blockOpts$1.hasher, codec: blockOpts$1.codec });
39267
+ ipldLoader.blocks.put(header.cid, header.bytes);
39268
+
39228
39269
  let newValetCidCar;
39229
39270
  if (this.keyMaterial) {
39230
39271
  const cids = [...ipldLoader.blocks.blocks.keys()];
39231
39272
  // console.log('persistCarMap', cids)
39232
- newValetCidCar = await blocksToEncryptedCarBlock(indexNode.cid, ipldLoader.blocks, this.keyMaterial, cids);
39273
+ // store the clock head and a link to the indexNode.cid in a custom root?
39274
+
39275
+ newValetCidCar = await blocksToEncryptedCarBlock(header.cid, ipldLoader.blocks, this.keyMaterial, cids);
39276
+ // then put this carcid into the header / w3clock
39233
39277
  } else {
39234
- newValetCidCar = await blocksToCarBlock(indexNode.cid, ipldLoader.blocks);
39278
+ newValetCidCar = await blocksToCarBlock(header.cid, ipldLoader.blocks);
39235
39279
  }
39236
39280
  return newValetCidCar
39237
39281
  }
@@ -39366,6 +39410,7 @@ const blocksFromEncryptedCarBlock = async (cid, get, keyMaterial) => {
39366
39410
  cache: nocache
39367
39411
  // codec: dagcbor
39368
39412
  })) {
39413
+ // console.log('decrypted', block.cid.toString())
39369
39414
  decryptedBlocks.push(block);
39370
39415
  cids.add(block.cid.toString());
39371
39416
  }
@@ -39376,7 +39421,7 @@ const blocksFromEncryptedCarBlock = async (cid, get, keyMaterial) => {
39376
39421
  }
39377
39422
  };
39378
39423
 
39379
- const defaultConfig$2 = {
39424
+ const defaultConfig$1 = {
39380
39425
  headerKeyPrefix: 'fp.'
39381
39426
  };
39382
39427
 
@@ -39384,7 +39429,7 @@ const defaultConfig$2 = {
39384
39429
 
39385
39430
  class Browser extends Base {
39386
39431
  constructor (name, config = {}) {
39387
- super(name, Object.assign({}, defaultConfig$2, config));
39432
+ super(name, Object.assign({}, defaultConfig$1, config));
39388
39433
  }
39389
39434
 
39390
39435
  withDB = async dbWorkFun => {
@@ -40006,13 +40051,13 @@ var browserPonyfill = {
40006
40051
 
40007
40052
  var fetch = /*@__PURE__*/getDefaultExportFromCjs(browserPonyfillExports);
40008
40053
 
40009
- const defaultConfig$1 = {
40054
+ const defaultConfig = {
40010
40055
  url: 'http://localhost:4000'
40011
40056
  };
40012
40057
 
40013
40058
  class Rest extends Base {
40014
40059
  constructor (name, config = {}) {
40015
- super(name, Object.assign({}, defaultConfig$1, config));
40060
+ super(name, Object.assign({}, defaultConfig, config));
40016
40061
  // console.log('Rest', name, config)
40017
40062
  }
40018
40063
 
@@ -40064,49 +40109,6 @@ class Rest extends Base {
40064
40109
  }
40065
40110
  }
40066
40111
 
40067
- const defaultConfig = {
40068
- upload: () => {},
40069
- url: (cid) => `https://${cid}.ipfs.w3s.link/`
40070
- };
40071
-
40072
- class UCAN extends Base {
40073
- constructor (name, config = {}) {
40074
- super(name, Object.assign({}, defaultConfig, config));
40075
- }
40076
-
40077
- async writeCars (cars) {
40078
- if (this.config.readonly) return
40079
- for (const { cid, bytes } of cars) {
40080
- console.log(`write UCAN ${cid}, ${bytes.length} bytes`);
40081
- const upCid = await this.config.upload(bytes);
40082
- console.log(`wrote UCAN ${cid}, ${upCid}`);
40083
- // if (!response.ok) throw new Error(`An error occurred: ${response.statusText}`)
40084
- }
40085
- }
40086
-
40087
- async readCar (carCid) {
40088
- const carURL = this.config.url(carCid);
40089
- const response = await fetch(carURL);
40090
- if (!response.ok) throw new Error(`An error occurred: ${response.statusText}`)
40091
- const got = await response.arrayBuffer();
40092
- return new Uint8Array(got)
40093
- }
40094
-
40095
- async loadHeader (branch = 'main') {
40096
- return headerMock.get(branch)
40097
- }
40098
-
40099
- async writeHeader (branch, header) {
40100
- if (this.config.readonly) return
40101
- const pHeader = this.prepareHeader(header);
40102
- // console.log('writeHeader rt', branch, pHeader)
40103
-
40104
- headerMock.set(branch, pHeader);
40105
- }
40106
- }
40107
-
40108
- const headerMock = new Map();
40109
-
40110
40112
  const Loader = {
40111
40113
  appropriate: (name, config = {}) => {
40112
40114
  if (config.StorageClass) {
@@ -40117,10 +40119,6 @@ const Loader = {
40117
40119
  return new Rest(name, config)
40118
40120
  }
40119
40121
 
40120
- if (config.type === 'ucan') {
40121
- return new UCAN(name, config)
40122
- }
40123
-
40124
40122
  return new Browser(name, config)
40125
40123
  }
40126
40124
  };
@@ -40439,6 +40437,9 @@ const doTransaction = async (label, blockstore, doFun, doSync = true) => {
40439
40437
  const innerBlockstore = blockstore.begin(label);
40440
40438
  try {
40441
40439
  const result = await doFun(innerBlockstore);
40440
+ // console.log('doTransaction', label, 'result', result.head)
40441
+ if (result && result.head) { innerBlockstore.head = result.head; }
40442
+ // pass the latest clock head for writing to the valet
40442
40443
  // @ts-ignore
40443
40444
  await blockstore.commit(innerBlockstore, doSync);
40444
40445
  return result
@@ -40454,6 +40455,7 @@ const doTransaction = async (label, blockstore, doFun, doSync = true) => {
40454
40455
  class InnerBlockstore {
40455
40456
  /** @type {Map<string, Uint8Array>} */
40456
40457
  blocks = new Map()
40458
+ head = []
40457
40459
  lastCid = null
40458
40460
  label = ''
40459
40461
  parentBlockstore = null
@@ -40784,7 +40786,7 @@ async function root (inBlocks, head, doFull = false) {
40784
40786
  bigPut(nb);
40785
40787
  }
40786
40788
  // console.log('root root', newProllyRootNode.constructor.name, newProllyRootNode)
40787
- return { clockCIDs, node: newProllyRootNode }
40789
+ return { clockCIDs, node: newProllyRootNode, head }
40788
40790
  },
40789
40791
  false
40790
40792
  )
@@ -41751,7 +41753,7 @@ class Database {
41751
41753
 
41752
41754
  toHeader () {
41753
41755
  return {
41754
- clock: this.clockToJSON(),
41756
+ // clock: this.clockToJSON(),
41755
41757
  name: this.name,
41756
41758
  index: {
41757
41759
  key: this.indexBlocks.valet?.primary.keyMaterial,
@@ -41936,11 +41938,13 @@ class Database {
41936
41938
  * @memberof Fireproof
41937
41939
  * @instance
41938
41940
  */
41939
- async put ({ _id, _proof, ...doc }) {
41941
+ async put ({ _id, _proof, _clock, ...doc }) {
41940
41942
  await this.ready;
41941
41943
  const id = _id || 'f' + Math.random().toString(36).slice(2);
41944
+ doc = JSON.parse(JSON.stringify(doc));
41945
+ if (_clock) doc._clock = _clock;
41942
41946
  await this.runValidation({ _id: id, ...doc });
41943
- return await this.putToProllyTree({ key: id, value: doc }, doc._clock)
41947
+ return await this.putToProllyTree({ key: id, value: doc }, _clock)
41944
41948
  }
41945
41949
 
41946
41950
  /**
@@ -44284,6 +44288,7 @@ class Fireproof {
44284
44288
 
44285
44289
  static snapshot (database, clock) {
44286
44290
  const definition = database.toJSON();
44291
+ definition.clock = database.clockToJSON();
44287
44292
  if (clock) {
44288
44293
  definition.clock = clock.map(c => parseCID(c));
44289
44294
  definition.indexes.forEach(index => {