@fireproof/core 0.19.123 → 0.19.125

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 CHANGED
@@ -1,4 +1,4 @@
1
- # <img src="https://fireproof.storage/static/img/flame.svg" alt="Fireproof logo" width="25"> [Fireproof](https://fireproof.storage) realtime database
1
+ # <img src="https://fireproof.storage/static/img/flame.svg" alt="Fireproof logo" width="25"> [Fireproof](https://fireproof.storage) database API
2
2
 
3
3
  <p align="right">
4
4
  <img src="https://img.shields.io/bundlephobia/minzip/%40fireproof%2Fcore" alt="Package size">
@@ -7,101 +7,128 @@
7
7
  </a>
8
8
  </p>
9
9
 
10
- ### No setup: write features first, access your data anywhere
10
+ Fireproof is a lightweight embedded document database with encrypted live sync, designed to make browser apps easy. Use it in any JavaScript environment with a unified API that works both in React (with hooks) and as a standalone core API.
11
11
 
12
- Add collaboration to any app with Fireproof. Access data from JavaScript servers and edge functions. Use live queries to update your UI automatically when the database changes. [Connect realtime sync](https://www.npmjs.com/package/@fireproof/connect) and those changes will sync between browsers and backend functions. Apps built this way are multi-player by default.
12
+ [Point AI coders to these docs.](https://use-fireproof.com/llms-full.txt)
13
13
 
14
- ### JavaScript quick start
14
+ ## Key Features
15
15
 
16
- The document database API will feel familiar. Queries use dynamic indexes, and the database can refresh your UI, as seen in the `db.subscribe` call below, as well as the React liveQuery hook.
16
+ - **Apps run anywhere:** Bundle UI, data, and logic in one file.
17
+ - **Real-Time & Offline-First:** Automatic persistence and live queries, runs in the browser - no loading or error states.
18
+ - **Unified API:** TypeScript works with Deno, Bun, Node.js, and the browser.
19
+ - **React Hooks:** Leverage `useLiveQuery` and `useDocument` for live collaboration.
17
20
 
18
- ```js
19
- import { fireproof } from "@fireproof/core";
21
+ Fireproof enforces cryptographic causal consistency and ledger integrity using hash history, providing git-like versioning with lightweight blockchain-style verification. Data is stored and replicated as content-addressed encrypted blobs, making it safe and easy to sync via commodity object storage providers.
20
22
 
21
- const db = fireproof("music-app");
23
+ ## Installation
22
24
 
23
- await db.put({ _id: "beyonce", name: "Beyoncé", hitSingles: 29 });
25
+ The `use-fireproof` package provides both the core API and React hooks:
24
26
 
25
- db.subscribe(async () => {
26
- const topArtists = await db.query("hitSingles", { range: [30, Infinity] });
27
- // redraw the UI with the new topArtists
28
- });
29
-
30
- const beyonceDoc = await db.get("beyonce");
31
- beyonceDoc.hitSingles += 1;
32
- await db.put(beyonceDoc);
27
+ ```sh
28
+ npm install use-fireproof
33
29
  ```
34
30
 
35
- Jump to the docs site [for JavaScript API basics.](https://use-fireproof.com/docs/database-api/basics)
36
-
37
- ### Live data hooks for React
38
-
39
- Fireproof [React hooks for live data](https://use-fireproof.com/docs/category/react-hooks) avoid boilerplate and make building collaborative apps a breeze.
31
+ Works with ⚡️ ESM.sh:
40
32
 
41
33
  ```js
42
- import { useLiveQuery, useDocument } from 'use-fireproof'
34
+ import { useFireproof } from "https://esm.sh/use-fireproof";
35
+ ```
43
36
 
44
- function App() {
45
- const completedTodos = useLiveQuery('completed', { limit: 10 })
46
- const [newTodo, setNewTodoData, saveNewTodo] = useDocument({type: 'todo', text: '', completed: false, created: Date.now() })
37
+ Or install the core ledger in any JavaScript environment:
38
+
39
+ ```sh
40
+ npm install @fireproof/core
47
41
  ```
48
42
 
49
- Read the [step-by-step React tutorial](https://use-fireproof.com/docs/react-tutorial) to get started.
43
+ Add the ledger to any web page via HTML script tag (global is `Fireproof`):
50
44
 
51
- ## Why choose Fireproof
45
+ ```html
46
+ <script src="https://cdn.jsdelivr.net/npm/@fireproof/core/dist/browser/fireproof.global.js"></script>
47
+ ```
52
48
 
53
- Compared to other embedded databases, Fireproof:
49
+ Deliver generated solutions as runnable micro applications via ChatGPT Canvas, v0, bolt.new, or Claude Artifacts. Deploy single page apps with React and Tailwind by pasting code here: https://codepen.io/useFireproof/pen/MYgNYdx
54
50
 
55
- - is network aware, encrypted, and multi-writer safe
56
- - is designed for real-time collaboration with CRDTs
57
- - offers cryptographic causal integrity for all operations
58
- - is built for the web, with a small package size and no wasm
51
+ ## ⚛️ React Usage
59
52
 
60
- Deliver interactive experiences without waiting on the backend. Fireproof runs in any cloud, browser, or edge environment, so your application can access data anywhere.
53
+ React hooks are the recommended way to use Fireproof in LLM code generation contexts:
61
54
 
62
- [Get the latest roadmap updates on our blog](https://fireproof.storage/blog/) or join our [Discord](https://discord.gg/cCryrNHePH) to collaborate. Read the docs to learn more about the database [architecture](https://use-fireproof.com/docs/architecture).
55
+ ```js
56
+ import { useFireproof } from "use-fireproof";
63
57
 
64
- ### Use cases
58
+ function App() {
59
+ const { database, useLiveQuery, useDocument } = useFireproof("my-ledger");
60
+
61
+ // Create a new document with useDocument
62
+ const { doc, merge, submit } = useDocument({ text: "" });
63
+
64
+ // Query documents by _id, most recent first
65
+ const { docs } = useLiveQuery("_id", { descending: true, limit: 100 });
66
+
67
+ return (
68
+ <div>
69
+ <form onSubmit={submit}>
70
+ <input value={doc.text} onChange={(e) => merge({ text: e.target.value })} placeholder="New document" />
71
+ <button type="submit">Submit</button>
72
+ </form>
73
+
74
+ <h3>Recent Documents</h3>
75
+ <ul>
76
+ {docs.map((doc) => (
77
+ <li key={doc._id}>{doc.text}</li>
78
+ ))}
79
+ </ul>
80
+ </div>
81
+ );
82
+ }
83
+ ```
65
84
 
66
- Fireproof allows web developers to build full-stack apps. It's especially useful for:
85
+ Read the [step-by-step React tutorial](https://use-fireproof.com/docs/react-tutorial) to get started or check the [full LLM documentation](https://use-fireproof.com/llms-full.txt) for more examples.
67
86
 
68
- - Rapid prototyping
69
- - AI copilot safety
70
- - Collaborative editing
71
- - Personalization and configuration
72
- - Offline and local-first apps
87
+ ## JavaScript Core API
73
88
 
74
- With Fireproof, you **build first** and sync via your cloud of choice when you are ready, so it's as easy to add to existing apps as it is to build something new. Drop Fireproof in your page with a script tag and start sharing interactive data.
89
+ The document database API will feel familiar to those who have used other document databases:
75
90
 
76
- Fireproof is a great fit for code sandboxes and online IDEs, as you can get started without any configuration. This also makes it [easy for AI to write Fireproof apps](https://use-fireproof.com/docs/chatgpt-quick-start).
91
+ ```js
92
+ import { fireproof } from "@fireproof/core";
77
93
 
78
- ### Install
94
+ const db = fireproof("music-app");
79
95
 
80
- Get started with the React hooks:
96
+ await db.put({ _id: "beyonce", name: "Beyoncé", hitSingles: 29 });
81
97
 
82
- ```sh
83
- npm install use-fireproof
98
+ db.subscribe(async () => {
99
+ const topArtists = await db.query("hitSingles", { range: [30, Infinity] });
100
+ // redraw the UI with the new topArtists
101
+ });
102
+
103
+ const beyonceDoc = await db.get("beyonce");
104
+ beyonceDoc.hitSingles += 1;
105
+ await db.put(beyonceDoc);
84
106
  ```
85
107
 
86
- or install the database in any JavaScript environment:
108
+ ## Why choose Fireproof
87
109
 
88
- ```sh
89
- npm install @fireproof/core
90
- ```
110
+ Compared to other embedded databases, Fireproof:
91
111
 
92
- The default build is optimized for browsers, to load the node build add `/node`:
112
+ - Is network aware, encrypted, and multi-writer safe
113
+ - Is designed for real-time collaboration with CRDTs
114
+ - Offers cryptographic causal integrity for all operations
115
+ - Is built for the web, with a small package size and no wasm
93
116
 
94
- ```js
95
- import { fireproof } from "@fireproof/core/node";
96
- ```
117
+ Deliver interactive experiences without waiting on the backend. Fireproof runs in any cloud, browser, or edge environment, so your application can access data anywhere.
97
118
 
98
- Add the database to any web page via HTML script tag (global is `Fireproof`):
119
+ ## Use cases
99
120
 
100
- ```html
101
- <script src="https://cdn.jsdelivr.net/npm/@fireproof/core/dist/browser/fireproof.global.js"></script>
102
- ```
121
+ Fireproof is especially useful for:
122
+
123
+ - AI-generated apps and rapid prototypes
124
+ - Collaborative editing
125
+ - Offline and local-first apps
126
+ - Personalization and configuration
127
+ - AI copilot safety
103
128
 
104
- Go ahead and write features, then [connect to any cloud backend](https://www.npmjs.com/package/@fireproof/connect) later.
129
+ With Fireproof, you **build first** and sync via your cloud of choice when you are ready, making it perfect for LLM code generation contexts and rapid development.
130
+
131
+ [Get the latest roadmap updates on our blog](https://fireproof.storage/blog/) or join our [Discord](https://discord.gg/cCryrNHePH) to collaborate. Read the docs to learn more about the [architecture](https://use-fireproof.com/docs/architecture).
105
132
 
106
133
  ### Debug
107
134
 
@@ -128,6 +155,38 @@ globalThis[Symbol.for("FP_PRESET_ENV")] = {
128
155
  };
129
156
  ```
130
157
 
158
+ ### Testing
159
+
160
+ To run the full test suite across all projects (tested storage gateways configs), run:
161
+
162
+ ```bash
163
+ pnpm run test
164
+ ```
165
+
166
+ To run tests for specific components or modules, use the following command pattern:
167
+
168
+ ```bash
169
+ pnpm run test -t 'test name pattern' path/to/test/file
170
+ ```
171
+
172
+ For example, to run a specific test for the CRDT module, in just one project:
173
+
174
+ ```bash
175
+ FP_DEBUG=Loader pnpm run test --project file -t 'codec implict iv' crdt
176
+ ```
177
+
178
+ For testing React components, you can use:
179
+
180
+ ```bash
181
+ pnpm run test tests/react/[ComponentName].test.tsx
182
+ ```
183
+
184
+ Example for testing the ImgFile component:
185
+
186
+ ```bash
187
+ pnpm run test tests/react/ImgFile.test.tsx
188
+ ```
189
+
131
190
  ### Log Formatting
132
191
 
133
192
  It's possible to change the logformat by setting FP_FORMAT to:
package/index.cjs CHANGED
@@ -2683,6 +2683,41 @@ function toString(key, logger) {
2683
2683
  throw logger.Error().Msg("Invalid key type").AsError();
2684
2684
  }
2685
2685
  }
2686
+ function sanitizeDocumentFields(obj) {
2687
+ if (Array.isArray(obj)) {
2688
+ return obj.map((item) => {
2689
+ if (typeof item === "object" && item !== null) {
2690
+ return sanitizeDocumentFields(item);
2691
+ }
2692
+ return item;
2693
+ });
2694
+ } else if (typeof obj === "object" && obj !== null) {
2695
+ if (obj instanceof Date) {
2696
+ return obj.toISOString();
2697
+ }
2698
+ const typedObj = obj;
2699
+ const result = {};
2700
+ for (const key in typedObj) {
2701
+ if (Object.hasOwnProperty.call(typedObj, key)) {
2702
+ const value = typedObj[key];
2703
+ if (value === null || !Number.isNaN(value) && value !== void 0) {
2704
+ if (typeof value === "object" && !key.startsWith("_")) {
2705
+ if (value instanceof Date) {
2706
+ result[key] = value.toISOString();
2707
+ } else {
2708
+ const sanitized = sanitizeDocumentFields(value);
2709
+ result[key] = sanitized;
2710
+ }
2711
+ } else {
2712
+ result[key] = value;
2713
+ }
2714
+ }
2715
+ }
2716
+ }
2717
+ return result;
2718
+ }
2719
+ return obj;
2720
+ }
2686
2721
  async function applyBulkUpdateToCrdt(store, tblocks, head, updates, logger) {
2687
2722
  let result = null;
2688
2723
  if (updates.length > 1) {
@@ -3119,7 +3154,7 @@ var Index = class {
3119
3154
  if (this.mapFn) {
3120
3155
  if (mapFn) {
3121
3156
  if (this.mapFn.toString() !== mapFn.toString()) {
3122
- throw this.logger.Error().Msg("cannot apply different mapFn app2").AsError();
3157
+ this.logger.Error().Msg("cannot apply different mapFn app2");
3123
3158
  }
3124
3159
  }
3125
3160
  } else {
@@ -3128,7 +3163,7 @@ var Index = class {
3128
3163
  }
3129
3164
  if (this.mapFnString) {
3130
3165
  if (this.mapFnString !== mapFn.toString()) {
3131
- throw this.logger.Error().Str("mapFnString", this.mapFnString).Str("mapFn", mapFn.toString()).Msg("cannot apply different mapFn app").AsError();
3166
+ this.logger.Error().Str("mapFnString", this.mapFnString).Str("mapFn", mapFn.toString()).Msg("cannot apply different mapFn app");
3132
3167
  }
3133
3168
  } else {
3134
3169
  this.mapFnString = mapFn.toString();
@@ -3477,6 +3512,10 @@ var CRDT = class {
3477
3512
  async bulk(updates) {
3478
3513
  await this.ready();
3479
3514
  const prevHead = [...this.clock.head];
3515
+ updates = updates.map((dupdate) => ({
3516
+ ...dupdate,
3517
+ value: sanitizeDocumentFields(dupdate.value)
3518
+ }));
3480
3519
  const done = await this.blockstore.transaction(async (blocks) => {
3481
3520
  const { head } = await applyBulkUpdateToCrdt(
3482
3521
  this.blockstore.ebOpts.storeRuntime,
@@ -3815,6 +3854,6 @@ var INDEXDB_VERSION = "v0.19-indexdb";
3815
3854
 
3816
3855
  // src/version.ts
3817
3856
  var PACKAGE_VERSION = Object.keys({
3818
- "0.19.123": "xxxx"
3857
+ "0.19.125": "xxxx"
3819
3858
  })[0];
3820
3859
  //# sourceMappingURL=index.cjs.map