@fireproof/core 0.6.4 → 0.6.6
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/README.md +4 -4
- package/dist/{src/db-index.js → db-index.js} +11 -1
- package/dist/fireproof.js +90 -0
- package/dist/import.js +29 -0
- package/dist/loader.js +23 -0
- package/dist/src/fireproof.d.ts +1 -1
- package/dist/src/fireproof.js +10 -1
- package/dist/src/fireproof.js.map +1 -1
- package/dist/src/fireproof.mjs +10 -1
- package/dist/src/fireproof.mjs.map +1 -1
- package/dist/storage/base.js +348 -0
- package/dist/storage/browser.js +61 -0
- package/dist/storage/filesystem.js +68 -0
- package/dist/storage/rest.js +58 -0
- package/dist/storage/ucan.js +0 -0
- package/package.json +1 -4
- package/src/db-index.js +10 -1
- package/dist/hooks/use-fireproof.js +0 -150
- package/dist/src/crypto-poly.js +0 -4
- package/dist/src/link.js +0 -1
- package/dist/src/loader.js +0 -131
- package/hooks/use-fireproof.js +0 -173
- /package/dist/{src/blockstore.js → blockstore.js} +0 -0
- /package/dist/{src/clock.js → clock.js} +0 -0
- /package/dist/{src/crypto.js → crypto.js} +0 -0
- /package/dist/{src/database.js → database.js} +0 -0
- /package/dist/{src/listener.js → listener.js} +0 -0
- /package/dist/{src/prolly.js → prolly.js} +0 -0
- /package/dist/{src/sha1.js → sha1.js} +0 -0
- /package/dist/{src/sync.js → sync.js} +0 -0
- /package/dist/{src/utils.js → utils.js} +0 -0
- /package/dist/{src/valet.js → valet.js} +0 -0
@@ -1,150 +0,0 @@
|
|
1
|
-
// @ts-ignore
|
2
|
-
import { useEffect, useState, useCallback, createContext } from 'react';
|
3
|
-
import { Fireproof, Index } from '@fireproof/core';
|
4
|
-
/**
|
5
|
-
@typedef {Object} FireproofCtxValue
|
6
|
-
@property {Function} addSubscriber - A function to add a subscriber with a label and function.
|
7
|
-
@property {Fireproof} database - An instance of the Fireproof class.
|
8
|
-
@property {Function} useLiveQuery - A hook to return a query result
|
9
|
-
@property {Function} useLiveDocument - A hook to return a live document
|
10
|
-
@property {boolean} ready - A boolean indicating whether the database is ready.
|
11
|
-
@param {string} label - A label for the subscriber.
|
12
|
-
@param {Function} fn - A function to be added as a subscriber.
|
13
|
-
@returns {void}
|
14
|
-
*/
|
15
|
-
export const FireproofCtx = createContext({
|
16
|
-
addSubscriber: () => { },
|
17
|
-
database: null,
|
18
|
-
ready: false
|
19
|
-
});
|
20
|
-
// const inboundSubscriberQueue = new Map()
|
21
|
-
let startedSetup = false;
|
22
|
-
let database;
|
23
|
-
const initializeDatabase = name => {
|
24
|
-
if (database)
|
25
|
-
return;
|
26
|
-
database = Fireproof.storage(name);
|
27
|
-
};
|
28
|
-
/**
|
29
|
-
@function useFireproof
|
30
|
-
React hook to initialize a Fireproof database, automatically saving and loading the clock.
|
31
|
-
You might need to import { nodePolyfills } from 'vite-plugin-node-polyfills' in your vite.config.ts
|
32
|
-
@deprecated - npm install @fireproof/react instead
|
33
|
-
@param {string} name - The path to the database file
|
34
|
-
@param {function(database): void} [defineDatabaseFn] - Synchronous function that defines the database, run this before any async calls
|
35
|
-
@param {function(database): Promise<void>} [setupDatabaseFn] - Asynchronous function that sets up the database, run this to load fixture data etc
|
36
|
-
@returns {FireproofCtxValue} { useLiveQuery, useLiveDocument, database, ready }
|
37
|
-
*/
|
38
|
-
export function useFireproof(name = 'useFireproof', defineDatabaseFn = () => { }, setupDatabaseFn = async () => { }) {
|
39
|
-
const [ready, setReady] = useState(false);
|
40
|
-
initializeDatabase(name);
|
41
|
-
/**
|
42
|
-
* @deprecated - use database.subscribe instead
|
43
|
-
*/
|
44
|
-
const addSubscriber = (label, fn) => {
|
45
|
-
// todo test that the label is not needed
|
46
|
-
return database.registerListener(fn);
|
47
|
-
// inboundSubscriberQueue.set(label, fn)
|
48
|
-
};
|
49
|
-
useEffect(() => {
|
50
|
-
const doSetup = async () => {
|
51
|
-
if (ready)
|
52
|
-
return;
|
53
|
-
if (startedSetup)
|
54
|
-
return;
|
55
|
-
startedSetup = true;
|
56
|
-
defineDatabaseFn(database); // define indexes before querying them
|
57
|
-
if (database.clock.length === 0) {
|
58
|
-
await setupDatabaseFn(database);
|
59
|
-
}
|
60
|
-
setReady(true);
|
61
|
-
};
|
62
|
-
doSetup();
|
63
|
-
}, [ready]);
|
64
|
-
function useLiveDocument(initialDoc) {
|
65
|
-
const id = initialDoc._id;
|
66
|
-
const [doc, setDoc] = useState(initialDoc);
|
67
|
-
const saveDoc = async (newDoc) => {
|
68
|
-
await database.put({ _id: id, ...newDoc });
|
69
|
-
};
|
70
|
-
const refreshDoc = useCallback(async () => {
|
71
|
-
// todo add option for mvcc checks
|
72
|
-
const got = await database.get(id).catch(() => initialDoc);
|
73
|
-
setDoc(got);
|
74
|
-
}, [id, initialDoc]);
|
75
|
-
useEffect(() => database.subscribe(change => {
|
76
|
-
if (change.find(c => c.key === id)) {
|
77
|
-
refreshDoc(); // todo use change.value
|
78
|
-
}
|
79
|
-
}), [id, refreshDoc]);
|
80
|
-
useEffect(() => {
|
81
|
-
refreshDoc();
|
82
|
-
}, []);
|
83
|
-
return [doc, saveDoc];
|
84
|
-
}
|
85
|
-
function useLiveQuery(mapFn, query = null, initialRows = []) {
|
86
|
-
const [rows, setRows] = useState({ rows: initialRows, proof: {} });
|
87
|
-
const [index, setIndex] = useState(null);
|
88
|
-
const refreshRows = useCallback(async () => {
|
89
|
-
if (!index)
|
90
|
-
return;
|
91
|
-
const got = await index.query(query || {});
|
92
|
-
setRows(got);
|
93
|
-
}, [index, JSON.stringify(query)]);
|
94
|
-
useEffect(() => {
|
95
|
-
// todo listen to index changes
|
96
|
-
return database.subscribe(() => {
|
97
|
-
refreshRows();
|
98
|
-
});
|
99
|
-
}, [refreshRows]);
|
100
|
-
useEffect(() => {
|
101
|
-
refreshRows();
|
102
|
-
}, [index]);
|
103
|
-
useEffect(() => {
|
104
|
-
const index = new Index(database, null, mapFn); // this should only be created once
|
105
|
-
setIndex(index);
|
106
|
-
}, [mapFn.toString()]);
|
107
|
-
return rows;
|
108
|
-
}
|
109
|
-
return {
|
110
|
-
addSubscriber,
|
111
|
-
useLiveQuery,
|
112
|
-
useLiveDocument,
|
113
|
-
database,
|
114
|
-
ready
|
115
|
-
};
|
116
|
-
}
|
117
|
-
// const husherMap = new Map()
|
118
|
-
// const husher = (id, workFn, ms) => {
|
119
|
-
// if (!husherMap.has(id)) {
|
120
|
-
// const start = Date.now()
|
121
|
-
// husherMap.set(
|
122
|
-
// id,
|
123
|
-
// workFn().finally(() => setTimeout(() => husherMap.delete(id), ms - (Date.now() - start)))
|
124
|
-
// )
|
125
|
-
// }
|
126
|
-
// return husherMap.get(id)
|
127
|
-
// }
|
128
|
-
// const hushed =
|
129
|
-
// (id, workFn, ms) =>
|
130
|
-
// (...args) =>
|
131
|
-
// husher(id, () => workFn(...args), ms)
|
132
|
-
// let storageSupported = false
|
133
|
-
// try {
|
134
|
-
// storageSupported = window.localStorage && true
|
135
|
-
// } catch (e) {}
|
136
|
-
// export function localGet (key) {
|
137
|
-
// if (storageSupported) {
|
138
|
-
// return localStorage && localStorage.getItem(key)
|
139
|
-
// }
|
140
|
-
// }
|
141
|
-
// function localSet (key, value) {
|
142
|
-
// if (storageSupported) {
|
143
|
-
// return localStorage && localStorage.setItem(key, value)
|
144
|
-
// }
|
145
|
-
// }
|
146
|
-
// function localRemove(key) {
|
147
|
-
// if (storageSupported) {
|
148
|
-
// return localStorage && localStorage.removeItem(key)
|
149
|
-
// }
|
150
|
-
// }
|
package/dist/src/crypto-poly.js
DELETED
package/dist/src/link.js
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
export {};
|
package/dist/src/loader.js
DELETED
@@ -1,131 +0,0 @@
|
|
1
|
-
import { readFileSync
|
2
|
-
// createReadStream
|
3
|
-
} from 'node:fs';
|
4
|
-
import { mkdir, writeFile } from 'node:fs/promises';
|
5
|
-
import { openDB } from 'idb';
|
6
|
-
import { join, dirname } from 'path';
|
7
|
-
// import { parse } from '@jsonlines/core'
|
8
|
-
// import cargoQueue from 'async/cargoQueue.js'
|
9
|
-
import { homedir } from 'os';
|
10
|
-
const defaultConfig = {
|
11
|
-
dataDir: join(homedir(), '.fireproof'),
|
12
|
-
headerKeyPrefix: 'fp.'
|
13
|
-
};
|
14
|
-
const FORCE_IDB = typeof process !== 'undefined' && !!process.env?.FORCE_IDB;
|
15
|
-
/* global localStorage */
|
16
|
-
export class Loader {
|
17
|
-
constructor(name, keyId, config = defaultConfig) {
|
18
|
-
this.name = name;
|
19
|
-
this.keyId = keyId;
|
20
|
-
this.config = config;
|
21
|
-
this.isBrowser = false;
|
22
|
-
try {
|
23
|
-
this.isBrowser = window.localStorage && true;
|
24
|
-
}
|
25
|
-
catch (e) { }
|
26
|
-
}
|
27
|
-
withDB = async (dbWorkFun) => {
|
28
|
-
if (!this.idb) {
|
29
|
-
this.idb = await openDB(`fp.${this.keyId}.${this.name}.valet`, 3, {
|
30
|
-
upgrade(db, oldVersion, newVersion, transaction) {
|
31
|
-
if (oldVersion < 1) {
|
32
|
-
db.createObjectStore('cars');
|
33
|
-
}
|
34
|
-
}
|
35
|
-
});
|
36
|
-
}
|
37
|
-
return await dbWorkFun(this.idb);
|
38
|
-
};
|
39
|
-
async writeCars(cars) {
|
40
|
-
// console.log('writeCars', this.config.dataDir, this.name, cars.map(c => c.cid.toString()))
|
41
|
-
// console.log('writeCars', cars.length)
|
42
|
-
if (FORCE_IDB || this.isBrowser) {
|
43
|
-
await this.writeCarsIDB(cars);
|
44
|
-
}
|
45
|
-
else {
|
46
|
-
const writes = [];
|
47
|
-
for (const { cid, bytes } of cars) {
|
48
|
-
const carFilename = join(this.config.dataDir, this.name, `${cid.toString()}.car`);
|
49
|
-
// console.log('writeCars', carFilename)
|
50
|
-
writes.push(writeSync(carFilename, bytes));
|
51
|
-
}
|
52
|
-
await Promise.all(writes);
|
53
|
-
}
|
54
|
-
}
|
55
|
-
async writeCarsIDB(cars) {
|
56
|
-
return await this.withDB(async (db) => {
|
57
|
-
const tx = db.transaction(['cars'], 'readwrite');
|
58
|
-
for (const { cid, bytes, replaces } of cars) {
|
59
|
-
await tx.objectStore('cars').put(bytes, cid.toString());
|
60
|
-
// todo remove old maps
|
61
|
-
if (replaces) {
|
62
|
-
await tx.objectStore('cars').delete(replaces.toString());
|
63
|
-
}
|
64
|
-
}
|
65
|
-
return await tx.done;
|
66
|
-
});
|
67
|
-
}
|
68
|
-
async readCar(carCid) {
|
69
|
-
if (FORCE_IDB || this.isBrowser) {
|
70
|
-
return await this.readCarIDB(carCid);
|
71
|
-
}
|
72
|
-
else {
|
73
|
-
const carFilename = join(this.config.dataDir, this.name, `${carCid.toString()}.car`);
|
74
|
-
const got = readFileSync(carFilename);
|
75
|
-
// console.log('readCar', carFilename, got.constructor.name)
|
76
|
-
return got;
|
77
|
-
}
|
78
|
-
}
|
79
|
-
async readCarIDB(carCid) {
|
80
|
-
return await this.withDB(async (db) => {
|
81
|
-
const tx = db.transaction(['cars'], 'readonly');
|
82
|
-
// console.log('getCarReader', carCid)
|
83
|
-
return await tx.objectStore('cars').get(carCid);
|
84
|
-
});
|
85
|
-
}
|
86
|
-
getHeader() {
|
87
|
-
if (this.isBrowser) {
|
88
|
-
return localStorage.getItem(this.config.headerKeyPrefix + this.name);
|
89
|
-
}
|
90
|
-
else {
|
91
|
-
return loadSync(this.headerFilename());
|
92
|
-
// return null
|
93
|
-
}
|
94
|
-
}
|
95
|
-
async saveHeader(stringValue) {
|
96
|
-
// console.log('saveHeader', this.isBrowser)
|
97
|
-
if (this.isBrowser) {
|
98
|
-
// console.log('localStorage!', this.config.headerKeyPrefix)
|
99
|
-
return localStorage.setItem(this.config.headerKeyPrefix + this.name, stringValue);
|
100
|
-
}
|
101
|
-
else {
|
102
|
-
// console.log('no localStorage', this.config.dataDir, this.name)
|
103
|
-
// console.log('saving clock to', this.headerFilename(), stringValue)
|
104
|
-
try {
|
105
|
-
await writeSync(this.headerFilename(), stringValue);
|
106
|
-
}
|
107
|
-
catch (error) {
|
108
|
-
console.log('error', error);
|
109
|
-
}
|
110
|
-
// console.log('saved clock to', this.headerFilename())
|
111
|
-
}
|
112
|
-
}
|
113
|
-
headerFilename() {
|
114
|
-
// console.log('headerFilename', this.config.dataDir, this.name)
|
115
|
-
return join(this.config.dataDir, this.name, 'header.json');
|
116
|
-
}
|
117
|
-
}
|
118
|
-
function loadSync(filename) {
|
119
|
-
try {
|
120
|
-
return readFileSync(filename, 'utf8').toString();
|
121
|
-
}
|
122
|
-
catch (error) {
|
123
|
-
// console.log('error', error)
|
124
|
-
return null;
|
125
|
-
}
|
126
|
-
}
|
127
|
-
async function writeSync(fullpath, stringValue) {
|
128
|
-
await mkdir(dirname(fullpath), { recursive: true });
|
129
|
-
// writeFileSync(fullpath, stringValue)
|
130
|
-
await writeFile(fullpath, stringValue);
|
131
|
-
}
|
package/hooks/use-fireproof.js
DELETED
@@ -1,173 +0,0 @@
|
|
1
|
-
// @ts-ignore
|
2
|
-
import { useEffect, useState, useCallback, createContext } from 'react'
|
3
|
-
import { Fireproof, Index } from '@fireproof/core'
|
4
|
-
|
5
|
-
/**
|
6
|
-
@typedef {Object} FireproofCtxValue
|
7
|
-
@property {Function} addSubscriber - A function to add a subscriber with a label and function.
|
8
|
-
@property {Fireproof} database - An instance of the Fireproof class.
|
9
|
-
@property {Function} useLiveQuery - A hook to return a query result
|
10
|
-
@property {Function} useLiveDocument - A hook to return a live document
|
11
|
-
@property {boolean} ready - A boolean indicating whether the database is ready.
|
12
|
-
@param {string} label - A label for the subscriber.
|
13
|
-
@param {Function} fn - A function to be added as a subscriber.
|
14
|
-
@returns {void}
|
15
|
-
*/
|
16
|
-
export const FireproofCtx = createContext({
|
17
|
-
addSubscriber: () => {},
|
18
|
-
database: null,
|
19
|
-
ready: false
|
20
|
-
})
|
21
|
-
|
22
|
-
// const inboundSubscriberQueue = new Map()
|
23
|
-
|
24
|
-
let startedSetup = false
|
25
|
-
let database
|
26
|
-
const initializeDatabase = name => {
|
27
|
-
if (database) return
|
28
|
-
database = Fireproof.storage(name)
|
29
|
-
}
|
30
|
-
|
31
|
-
/**
|
32
|
-
@function useFireproof
|
33
|
-
React hook to initialize a Fireproof database, automatically saving and loading the clock.
|
34
|
-
You might need to import { nodePolyfills } from 'vite-plugin-node-polyfills' in your vite.config.ts
|
35
|
-
@deprecated - npm install @fireproof/react instead
|
36
|
-
@param {string} name - The path to the database file
|
37
|
-
@param {function(database): void} [defineDatabaseFn] - Synchronous function that defines the database, run this before any async calls
|
38
|
-
@param {function(database): Promise<void>} [setupDatabaseFn] - Asynchronous function that sets up the database, run this to load fixture data etc
|
39
|
-
@returns {FireproofCtxValue} { useLiveQuery, useLiveDocument, database, ready }
|
40
|
-
*/
|
41
|
-
export function useFireproof (name = 'useFireproof', defineDatabaseFn = () => {}, setupDatabaseFn = async () => {}) {
|
42
|
-
const [ready, setReady] = useState(false)
|
43
|
-
initializeDatabase(name)
|
44
|
-
|
45
|
-
/**
|
46
|
-
* @deprecated - use database.subscribe instead
|
47
|
-
*/
|
48
|
-
const addSubscriber = (label, fn) => {
|
49
|
-
// todo test that the label is not needed
|
50
|
-
return database.registerListener(fn)
|
51
|
-
// inboundSubscriberQueue.set(label, fn)
|
52
|
-
}
|
53
|
-
|
54
|
-
useEffect(() => {
|
55
|
-
const doSetup = async () => {
|
56
|
-
if (ready) return
|
57
|
-
if (startedSetup) return
|
58
|
-
startedSetup = true
|
59
|
-
defineDatabaseFn(database) // define indexes before querying them
|
60
|
-
if (database.clock.length === 0) {
|
61
|
-
await setupDatabaseFn(database)
|
62
|
-
}
|
63
|
-
setReady(true)
|
64
|
-
}
|
65
|
-
doSetup()
|
66
|
-
}, [ready])
|
67
|
-
|
68
|
-
function useLiveDocument (initialDoc) {
|
69
|
-
const id = initialDoc._id
|
70
|
-
const [doc, setDoc] = useState(initialDoc)
|
71
|
-
|
72
|
-
const saveDoc = async newDoc => {
|
73
|
-
await database.put({ _id: id, ...newDoc })
|
74
|
-
}
|
75
|
-
const refreshDoc = useCallback(async () => {
|
76
|
-
// todo add option for mvcc checks
|
77
|
-
const got = await database.get(id).catch(() => initialDoc)
|
78
|
-
setDoc(got)
|
79
|
-
}, [id, initialDoc])
|
80
|
-
|
81
|
-
useEffect(
|
82
|
-
() =>
|
83
|
-
database.subscribe(change => {
|
84
|
-
if (change.find(c => c.key === id)) {
|
85
|
-
refreshDoc() // todo use change.value
|
86
|
-
}
|
87
|
-
}),
|
88
|
-
[id, refreshDoc]
|
89
|
-
)
|
90
|
-
|
91
|
-
useEffect(() => {
|
92
|
-
refreshDoc()
|
93
|
-
}, [])
|
94
|
-
|
95
|
-
return [doc, saveDoc]
|
96
|
-
}
|
97
|
-
|
98
|
-
function useLiveQuery (mapFn, query = null, initialRows = []) {
|
99
|
-
const [rows, setRows] = useState({ rows: initialRows, proof: {} })
|
100
|
-
const [index, setIndex] = useState(null)
|
101
|
-
|
102
|
-
const refreshRows = useCallback(async () => {
|
103
|
-
if (!index) return
|
104
|
-
const got = await index.query(query || {})
|
105
|
-
setRows(got)
|
106
|
-
}, [index, JSON.stringify(query)])
|
107
|
-
|
108
|
-
useEffect(
|
109
|
-
() => {
|
110
|
-
// todo listen to index changes
|
111
|
-
return database.subscribe(() => {
|
112
|
-
refreshRows()
|
113
|
-
})
|
114
|
-
},
|
115
|
-
[refreshRows]
|
116
|
-
)
|
117
|
-
|
118
|
-
useEffect(() => {
|
119
|
-
refreshRows()
|
120
|
-
}, [index])
|
121
|
-
|
122
|
-
useEffect(() => {
|
123
|
-
const index = new Index(database, null, mapFn) // this should only be created once
|
124
|
-
setIndex(index)
|
125
|
-
}, [mapFn.toString()])
|
126
|
-
|
127
|
-
return rows
|
128
|
-
}
|
129
|
-
|
130
|
-
return {
|
131
|
-
addSubscriber,
|
132
|
-
useLiveQuery,
|
133
|
-
useLiveDocument,
|
134
|
-
database,
|
135
|
-
ready
|
136
|
-
}
|
137
|
-
}
|
138
|
-
|
139
|
-
// const husherMap = new Map()
|
140
|
-
// const husher = (id, workFn, ms) => {
|
141
|
-
// if (!husherMap.has(id)) {
|
142
|
-
// const start = Date.now()
|
143
|
-
// husherMap.set(
|
144
|
-
// id,
|
145
|
-
// workFn().finally(() => setTimeout(() => husherMap.delete(id), ms - (Date.now() - start)))
|
146
|
-
// )
|
147
|
-
// }
|
148
|
-
// return husherMap.get(id)
|
149
|
-
// }
|
150
|
-
// const hushed =
|
151
|
-
// (id, workFn, ms) =>
|
152
|
-
// (...args) =>
|
153
|
-
// husher(id, () => workFn(...args), ms)
|
154
|
-
|
155
|
-
// let storageSupported = false
|
156
|
-
// try {
|
157
|
-
// storageSupported = window.localStorage && true
|
158
|
-
// } catch (e) {}
|
159
|
-
// export function localGet (key) {
|
160
|
-
// if (storageSupported) {
|
161
|
-
// return localStorage && localStorage.getItem(key)
|
162
|
-
// }
|
163
|
-
// }
|
164
|
-
// function localSet (key, value) {
|
165
|
-
// if (storageSupported) {
|
166
|
-
// return localStorage && localStorage.setItem(key, value)
|
167
|
-
// }
|
168
|
-
// }
|
169
|
-
// function localRemove(key) {
|
170
|
-
// if (storageSupported) {
|
171
|
-
// return localStorage && localStorage.removeItem(key)
|
172
|
-
// }
|
173
|
-
// }
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|