@fireproof/core 0.19.0-dev-publish → 0.19.0-dev-use-fix

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. package/{chunk-EVSZA26U.js → chunk-AZVWSRER.js} +2 -2
  2. package/{chunk-UCMXU3DH.js → chunk-NZNG6TQT.js} +103 -1
  3. package/chunk-NZNG6TQT.js.map +1 -0
  4. package/{chunk-5X6APJDY.js → chunk-ZHO4NMWL.js} +2 -2
  5. package/index.cjs +122 -92
  6. package/index.cjs.map +1 -1
  7. package/index.d.cts +21 -1
  8. package/index.d.ts +21 -1
  9. package/index.js +41 -122
  10. package/index.js.map +1 -1
  11. package/metafile-cjs.json +1 -1
  12. package/metafile-esm.json +1 -1
  13. package/package.json +1 -1
  14. package/{sqlite-data-store-RIH56645.js → sqlite-data-store-3ST7XOLX.js} +3 -3
  15. package/{sqlite-meta-store-6347MWOR.js → sqlite-meta-store-QOIMCSJ7.js} +3 -3
  16. package/{sqlite-wal-store-G5YGK77N.js → sqlite-wal-store-JFBQPOYT.js} +3 -3
  17. package/{store-file-D472VFCS.js → store-file-CSS5THFH.js} +2 -2
  18. package/{store-indexdb-FRX5PTKR.js → store-indexdb-DR4HELVP.js} +3 -3
  19. package/{store-sql-MDSU23Y7.js → store-sql-BG6SMGQJ.js} +5 -5
  20. package/tests/blockstore/loader.test.ts +265 -0
  21. package/tests/blockstore/store.test.ts +164 -0
  22. package/tests/blockstore/transaction.test.ts +121 -0
  23. package/tests/fireproof/config.test.ts +212 -0
  24. package/tests/fireproof/crdt.test.ts +434 -0
  25. package/tests/fireproof/database.test.ts +466 -0
  26. package/tests/fireproof/fireproof.test.ts +602 -0
  27. package/tests/fireproof/hello.test.ts +54 -0
  28. package/tests/fireproof/indexer.test.ts +389 -0
  29. package/tests/helpers.ts +81 -0
  30. package/tests/react/useFireproof.test.tsx +19 -0
  31. package/tests/www/gallery.html +132 -0
  32. package/tests/www/iife.html +42 -0
  33. package/tests/www/todo-aws.html +232 -0
  34. package/tests/www/todo-ipfs.html +213 -0
  35. package/tests/www/todo-local.html +214 -0
  36. package/tests/www/todo-netlify.html +227 -0
  37. package/tests/www/todo.html +236 -0
  38. package/chunk-UCMXU3DH.js.map +0 -1
  39. /package/{chunk-EVSZA26U.js.map → chunk-AZVWSRER.js.map} +0 -0
  40. /package/{chunk-5X6APJDY.js.map → chunk-ZHO4NMWL.js.map} +0 -0
  41. /package/{sqlite-data-store-RIH56645.js.map → sqlite-data-store-3ST7XOLX.js.map} +0 -0
  42. /package/{sqlite-meta-store-6347MWOR.js.map → sqlite-meta-store-QOIMCSJ7.js.map} +0 -0
  43. /package/{sqlite-wal-store-G5YGK77N.js.map → sqlite-wal-store-JFBQPOYT.js.map} +0 -0
  44. /package/{store-file-D472VFCS.js.map → store-file-CSS5THFH.js.map} +0 -0
  45. /package/{store-indexdb-FRX5PTKR.js.map → store-indexdb-DR4HELVP.js.map} +0 -0
  46. /package/{store-sql-MDSU23Y7.js.map → store-sql-BG6SMGQJ.js.map} +0 -0
@@ -0,0 +1,227 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Fireproof Test</title>
7
+ <script src="./fireproof.iife.js"></script>
8
+ <script src="./connect-netlify.iife.js"></script>
9
+ <script type="text/javascript">
10
+ function todoApp() {
11
+ const actorTag = Math.random().toString(36).substring(2, 7);
12
+ const { fireproof, index } = Fireproof;
13
+ const { connect } = FireproofConnect;
14
+
15
+ let dbName;
16
+ let db;
17
+ let cx;
18
+
19
+ let dbUnsubscribe = false;
20
+
21
+ function setupDb(name, newDb, newConn) {
22
+ const input = document.querySelector("#todo");
23
+ input.disabled = true;
24
+
25
+ if (dbUnsubscribe) {
26
+ dbUnsubscribe();
27
+ }
28
+ if (newDb) {
29
+ // console.log('new db', newDb, newConn)
30
+ name = newDb.name;
31
+ dbName = newDb.name;
32
+ db = newDb;
33
+ cx = newConn;
34
+ const input = document.querySelector("#list");
35
+ input.value = dbName;
36
+ } else {
37
+ dbName = name;
38
+ db = fireproof(name);
39
+ cx = connect.netlify(db);
40
+ cx.ready.then(async () => {
41
+ const span = document.querySelector("#cxInfo");
42
+ span.innerText = `📡 ${cx.name}`;
43
+ });
44
+ }
45
+
46
+ window.db = db;
47
+ window.cx = cx;
48
+
49
+ db.changes([], { limit: 1 }).then((changes) => {
50
+ if (changes.clock.length > 0) {
51
+ input.disabled = false;
52
+ } else {
53
+ cx.ready.then(async () => {
54
+ input.disabled = false;
55
+ });
56
+ }
57
+ });
58
+
59
+ dbUnsubscribe = db.subscribe(redraw);
60
+ return db;
61
+ }
62
+
63
+ let doing;
64
+ const redraw = async () => {
65
+ if (doing) {
66
+ return doing;
67
+ }
68
+ doing = doRedraw().finally(() => (doing = null));
69
+ return doing;
70
+ };
71
+ window.redraw = redraw;
72
+
73
+ let compactor = "🚗";
74
+ function drawInfo() {
75
+ document.querySelector("#carLog").innerText =
76
+ ` ⏰ ${db._crdt.clock.head.length} ${compactor} ${cx.loader.carLog.length} 📩 ${cx.taskManager.queue.length}`;
77
+ }
78
+ const doRedraw = async () => {
79
+ drawInfo();
80
+ const result = await db.allDocs();
81
+ drawInfo();
82
+ document.querySelector("ul").innerHTML = "";
83
+ for (const row of result.rows) {
84
+ // const doc = await db.get(row.id);
85
+ const doc = row.value;
86
+ const checkbox = document.createElement("input");
87
+ checkbox.setAttribute("type", "checkbox");
88
+ if (doc.completed) {
89
+ checkbox.setAttribute("checked", true);
90
+ }
91
+ checkbox.onchange = async (e) => {
92
+ e.target.indeterminate = true;
93
+ const clicks = doc.clicks || 0;
94
+ doc.clicks = clicks + 1;
95
+ doc.completed = !doc.completed;
96
+ await db.put(doc);
97
+ };
98
+ const textSpan = document.createElement("span");
99
+ textSpan.innerText = `${doc.actor}:${doc.clicks || 0} ${doc.task}`;
100
+ const li = document.createElement("li");
101
+ li.appendChild(checkbox);
102
+ li.appendChild(textSpan);
103
+ document.querySelector("ul").appendChild(li);
104
+ }
105
+ };
106
+
107
+ async function initialize() {
108
+ ps = new URLSearchParams(location.search);
109
+ const listQ = ps.get("list");
110
+ setupDb(listQ || "my-list");
111
+ const input = document.querySelector("#list");
112
+ input.value = dbName;
113
+ redraw();
114
+ }
115
+
116
+ async function openDashboard(e) {
117
+ db.openDashboard();
118
+ }
119
+ window.openDashboard = openDashboard;
120
+
121
+ async function changeList(e) {
122
+ e.preventDefault();
123
+ const input = document.querySelector("#list");
124
+ dbName = input.value;
125
+ history.pushState(null, "", location.pathname + "?list=" + encodeURIComponent(dbName));
126
+ setupDb(dbName);
127
+ redraw();
128
+ }
129
+ window.changeList = changeList;
130
+
131
+ async function createTodoClick(e) {
132
+ e.preventDefault();
133
+ const input = document.querySelector("#todo");
134
+ input.disabled = true;
135
+ const ok = await db.put({ actor: actorTag, created: Date.now(), task: input.value, completed: false });
136
+ input.disabled = false;
137
+ input.value = "";
138
+ }
139
+ window.createTodoClick = createTodoClick;
140
+
141
+ let worker;
142
+ async function startWorker() {
143
+ const button = document.querySelector("#robot");
144
+ button.innerText = "🦾";
145
+ const dcs = await db.allDocs();
146
+ console.log("start worker", dcs.rows.length);
147
+ // worker = setInterval(async () => {
148
+ // dcs.rows.map((r) => db.put({ ...r.value, clicks: (r.value.clicks || 0) + 1, completed: Math.random() > 0.5 }))
149
+ // }, 5000)
150
+ goWorker(dcs);
151
+ }
152
+ const goWorker = (dcs) => {
153
+ worker = setTimeout(
154
+ async () => {
155
+ await Promise.all(
156
+ dcs.rows.slice(0, 5).map((r) => {
157
+ r.value.clicks = r.value.clicks || 0;
158
+ r.value.clicks += 1;
159
+ r.value.completed = Math.random() > 0.5;
160
+ db.put({ ...r.value });
161
+ }),
162
+ );
163
+ goWorker(dcs);
164
+ },
165
+ Math.floor(Math.random() * 5000) + 5000,
166
+ );
167
+ };
168
+
169
+ const stopWorker = () => {
170
+ const button = document.querySelector("#robot");
171
+ button.innerText = "🤖";
172
+ console.log("stop worker");
173
+ clearTimeout(worker);
174
+ };
175
+ const toggleWorker = (e) => {
176
+ e.preventDefault();
177
+ if (worker) {
178
+ stopWorker();
179
+ } else {
180
+ startWorker(e);
181
+ }
182
+ };
183
+ window.toggleWorker = toggleWorker;
184
+
185
+ async function doCompact(e) {
186
+ e.preventDefault();
187
+ compactor = "🚕";
188
+ drawInfo();
189
+ await db.compact();
190
+ drawInfo();
191
+ compactor = "🚗";
192
+ }
193
+ window.doCompact = doCompact;
194
+
195
+ window.onload = initialize;
196
+ window.db = db;
197
+ }
198
+
199
+ todoApp();
200
+ </script>
201
+ </head>
202
+
203
+ <body>
204
+ <h1>Fireproof Todos</h1>
205
+ List:
206
+ <input title="Change list" type="text" name="list" id="list" />
207
+ <button onclick="changeList(event)">Change List</button>
208
+
209
+ <p>
210
+ Fireproof stores data locally and encrypts it before sending it to the cloud. This demo uses web3.storage, but you can easily
211
+ run Fireproof on S3 or another provider.
212
+ <a href="https://use-fireproof.com/">Learn more in the Fireproof developer docs.</a>
213
+ </p>
214
+
215
+ <button onclick="openDashboard(event)">🔥 Import to Dashboard</button>
216
+ <button id="robot" onclick="toggleWorker(event)">🤖</button>
217
+ <br />
218
+ <span id="carLog" onclick="doCompact(event)"></span>
219
+ <br />
220
+ <span id="cxInfo"></span>
221
+
222
+ <h3>Todos</h3>
223
+ <input title="Create a todo" type="text" name="todo" id="todo" />
224
+ <button onclick="createTodoClick(event)">Create Todo</button>
225
+ <ul></ul>
226
+ </body>
227
+ </html>
@@ -0,0 +1,236 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Fireproof Test</title>
7
+ <script src="./fireproof.iife.js"></script>
8
+ <script src="./connect-partykit.iife.js"></script>
9
+ <script type="text/javascript">
10
+ function todoApp() {
11
+ const actorTag = Math.random().toString(36).substring(2, 7);
12
+ const { fireproof, index } = Fireproof;
13
+ const { connect } = FireproofConnect;
14
+
15
+ // console.log('connect', connect)
16
+
17
+ let dbName;
18
+ let db;
19
+ let cx;
20
+
21
+ let dbUnsubscribe = false;
22
+
23
+ function setupDb(name, newDb, newConn) {
24
+ const input = document.querySelector("#todo");
25
+ input.disabled = true;
26
+
27
+ if (dbUnsubscribe) {
28
+ dbUnsubscribe();
29
+ }
30
+ if (newDb) {
31
+ // console.log('new db', newDb, newConn)
32
+ name = newDb.name;
33
+ dbName = newDb.name;
34
+ db = newDb;
35
+ cx = newConn;
36
+ const input = document.querySelector("#list");
37
+ input.value = dbName;
38
+ } else {
39
+ dbName = name;
40
+ db = fireproof(name, { autoCompact: 100, threshold: 50000 });
41
+ cx = connect.partykitRest(db);
42
+ cx.ready.then(async () => {
43
+ const span = document.querySelector("#cxInfo");
44
+ span.innerText = `📡 ${cx.party.id}`;
45
+ });
46
+ }
47
+
48
+ window.db = db;
49
+ window.cx = cx;
50
+
51
+ db.changes([], { limit: 1 }).then((changes) => {
52
+ if (changes.clock.length > 0) {
53
+ input.disabled = false;
54
+ } else {
55
+ cx.ready.then(async () => {
56
+ input.disabled = false;
57
+ });
58
+ }
59
+ });
60
+
61
+ dbUnsubscribe = db.subscribe(redraw);
62
+ return db;
63
+ }
64
+
65
+ let doing;
66
+ const redraw = async () => {
67
+ if (doing) {
68
+ return doing;
69
+ }
70
+ doing = doRedraw().finally(() => (doing = null));
71
+ return doing;
72
+ };
73
+ window.redraw = redraw;
74
+
75
+ let compactor = "🚗";
76
+ function drawInfo() {
77
+ document.querySelector("#carLog").innerText =
78
+ ` ⏰ ${db._crdt.clock.head.length} ${compactor} ${cx.loader.carLog.length} 📩 ${cx.loader.remoteWAL.walState.operations.length}`;
79
+ }
80
+ const doRedraw = async () => {
81
+ drawInfo();
82
+ const result = await db.allDocs().catch((e) => {
83
+ console.error(
84
+ "allDocs error",
85
+ e,
86
+ ` ⏰ ${db._crdt.clock.head.length} ${compactor} ${cx.loader.carLog.length} 📩 ${cx.loader.remoteWAL.walState.operations.length}`,
87
+ );
88
+ return { rows: [] };
89
+ });
90
+ drawInfo();
91
+ document.querySelector("ul").innerHTML = "";
92
+ for (const row of result.rows) {
93
+ // const doc = await db.get(row.id);
94
+ const doc = row.value;
95
+ const checkbox = document.createElement("input");
96
+ checkbox.setAttribute("type", "checkbox");
97
+ if (doc.completed) {
98
+ checkbox.setAttribute("checked", true);
99
+ }
100
+ checkbox.onchange = async (e) => {
101
+ e.target.indeterminate = true;
102
+ const clicks = doc.clicks || 0;
103
+ doc.clicks = clicks + 1;
104
+ doc.completed = !doc.completed;
105
+ await db.put(doc);
106
+ };
107
+ const textSpan = document.createElement("span");
108
+ textSpan.innerText = `${doc.actor}:${doc.clicks || 0} ${doc.task}`;
109
+ const li = document.createElement("li");
110
+ li.appendChild(checkbox);
111
+ li.appendChild(textSpan);
112
+ document.querySelector("ul").appendChild(li);
113
+ }
114
+ };
115
+
116
+ async function initialize() {
117
+ ps = new URLSearchParams(location.search);
118
+ const listQ = ps.get("list");
119
+ setupDb(listQ || "my-list");
120
+ const input = document.querySelector("#list");
121
+ input.value = dbName;
122
+ redraw();
123
+ }
124
+
125
+ async function openDashboard(e) {
126
+ db.openDashboard();
127
+ }
128
+ window.openDashboard = openDashboard;
129
+
130
+ async function changeList(e) {
131
+ e.preventDefault();
132
+ const input = document.querySelector("#list");
133
+ dbName = input.value;
134
+ history.pushState(null, "", location.pathname + "?list=" + encodeURIComponent(dbName));
135
+ setupDb(dbName);
136
+ redraw();
137
+ }
138
+ window.changeList = changeList;
139
+
140
+ async function createTodoClick(e) {
141
+ e.preventDefault();
142
+ const input = document.querySelector("#todo");
143
+ input.disabled = true;
144
+ const ok = await db.put({
145
+ actor: actorTag,
146
+ created: Date.now(),
147
+ task: input.value,
148
+ completed: false,
149
+ });
150
+ input.disabled = false;
151
+ input.value = "";
152
+ }
153
+ window.createTodoClick = createTodoClick;
154
+
155
+ let worker;
156
+ async function startWorker() {
157
+ const button = document.querySelector("#robot");
158
+ button.innerText = "🦾";
159
+ const dcs = await db.allDocs();
160
+ console.log("start worker", dcs.rows.length);
161
+ // worker = setInterval(async () => {
162
+ // dcs.rows.map((r) => db.put({ ...r.value, clicks: (r.value.clicks || 0) + 1, completed: Math.random() > 0.5 }))
163
+ // }, 5000)
164
+ goWorker(dcs);
165
+ }
166
+ const goWorker = (dcs) => {
167
+ const timeout =
168
+ 10 +
169
+ Math.pow(db._crdt.clock.head.length + cx.loader.remoteWAL.walState.operations.length, 2) *
170
+ (Math.floor(Math.random() * 1000) + 1000);
171
+ // console.log('go worker', timeout/ 1000)
172
+ worker = setTimeout(async () => {
173
+ await Promise.all(
174
+ dcs.rows.slice(0, 5).map((r) => {
175
+ r.value.clicks = r.value.clicks || 0;
176
+ r.value.clicks += 1;
177
+ r.value.completed = Math.random() > 0.5;
178
+ db.put({ ...r.value });
179
+ }),
180
+ );
181
+ goWorker(await db.allDocs());
182
+ }, timeout);
183
+ };
184
+
185
+ const stopWorker = () => {
186
+ const button = document.querySelector("#robot");
187
+ button.innerText = "🤖";
188
+ console.log("stop worker");
189
+ clearTimeout(worker);
190
+ };
191
+ const toggleWorker = (e) => {
192
+ e.preventDefault();
193
+ if (worker) {
194
+ stopWorker();
195
+ } else {
196
+ startWorker(e);
197
+ }
198
+ };
199
+ window.toggleWorker = toggleWorker;
200
+
201
+ async function doCompact(e) {
202
+ e.preventDefault();
203
+ compactor = "🚕";
204
+ drawInfo();
205
+ await db.compact();
206
+ drawInfo();
207
+ compactor = "🚗";
208
+ }
209
+ window.doCompact = doCompact;
210
+
211
+ window.onload = initialize;
212
+ window.db = db;
213
+ }
214
+
215
+ todoApp();
216
+ </script>
217
+ </head>
218
+
219
+ <body>
220
+ <h1><a href="https://use-fireproof.com/">Fireproof</a> Test App</h1>
221
+ Database:
222
+ <input title="Change list" type="text" name="list" id="list" />
223
+ <button onclick="changeList(event)">Switch</button>
224
+
225
+ <p>This version of the Fireprof test app uses PartyKit as the storage backend. Refresh is automatic and live.</p>
226
+
227
+ <button id="robot" onclick="toggleWorker(event)">🤖</button>
228
+ <span id="carLog" onclick="doCompact(event)"></span>
229
+ <span id="cxInfo"></span>
230
+
231
+ <h3>Todos</h3>
232
+ <input title="Create a todo" type="text" name="todo" id="todo" />
233
+ <button onclick="createTodoClick(event)">Create Todo</button>
234
+ <ul></ul>
235
+ </body>
236
+ </html>
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/utils.ts","../../src/runtime/index.ts","../../src/runtime/data-dir.ts","../../src/runtime/store-sql/index.ts","../../src/runtime/store-sql/types.ts","../../src/runtime/store-sql/ensurer.ts","../../src/runtime/store-file-version.ts","../../src/runtime/store-indexdb-version.ts","../../src/runtime/store-sql/v0.19-sqlite/version.ts","../../src/runtime/store-file-utils.ts"],"sourcesContent":["import { Logger, LoggerImpl, IsLogger, Result, ResolveOnce } from \"@adviser/cement\";\nimport { SysContainer } from \"./runtime\";\nimport { uuidv7 } from \"uuidv7\";\n\nexport type { Logger };\n\nconst globalLogger: Logger = new LoggerImpl();\n\nexport interface LoggerOpts {\n readonly logger?: Logger;\n}\n\nconst registerFP_DEBUG = new ResolveOnce();\n\nexport function ensureLogger(\n optsOrLogger: Partial<LoggerOpts> | Logger,\n componentName: string,\n ctx?: Record<string, unknown>,\n): Logger {\n // if (!opts?.logger) {\n // throw new Error(\"logger is required\");\n // }\n let logger = globalLogger;\n if (IsLogger(optsOrLogger)) {\n logger = optsOrLogger;\n } else if (optsOrLogger && IsLogger(optsOrLogger.logger)) {\n logger = optsOrLogger.logger;\n }\n const cLogger = logger.With().Module(componentName); //.Str(\"this\", uuidv7());\n const debug: string[] = [];\n if (ctx) {\n if (\"debug\" in ctx) {\n if (typeof ctx.debug === \"string\" && ctx.debug.length > 0) {\n debug.push(ctx.debug);\n } else {\n debug.push(componentName);\n }\n delete ctx.debug;\n }\n if (\"this\" in ctx) {\n cLogger.Str(\"this\", uuidv7());\n delete ctx.this;\n }\n for (const [key, value] of Object.entries(ctx)) {\n switch (typeof value) {\n case \"string\":\n cLogger.Str(key, value);\n break;\n case \"number\":\n cLogger.Uint64(key, value);\n break;\n default:\n if (value instanceof Date) {\n cLogger.Str(key, value.toISOString());\n } else if (value instanceof URL) {\n cLogger.Str(key, value.toString());\n } else if (typeof value === \"function\") {\n cLogger.Ref(key, value);\n } else {\n cLogger.Any(key, value);\n }\n break;\n }\n }\n }\n registerFP_DEBUG\n .once(async () => {\n // console.log(\"registerFP_DEBUG\", SysContainer.env)\n SysContainer.env.onSet((key, value) => {\n // console.log(\"FP_DEBUG\", key, value, debug)\n if (value) {\n logger.SetDebug(value);\n }\n }, \"FP_DEBUG\");\n })\n .finally(() => {\n /* do nothing */\n });\n\n if (debug.length > 0) {\n logger.SetDebug(debug);\n }\n const out = cLogger.Logger();\n // out.Debug().Msg(\"logger ready\");\n return out;\n}\n\nexport type Joiner = (...toJoin: string[]) => string;\n\nexport function getStore(url: URL, logger: Logger, joiner: Joiner): string {\n let result = url.searchParams.get(\"store\");\n if (!result) throw logger.Error().Str(\"url\", url.toString()).Msg(`store not found`).AsError();\n if (url.searchParams.has(\"index\")) {\n result = joiner(url.searchParams.get(\"index\") || \"idx\", result);\n }\n return result;\n}\n\nexport function getKey(url: URL, logger: Logger): string {\n const result = url.searchParams.get(\"key\");\n if (!result) throw logger.Error().Str(\"url\", url.toString()).Msg(`key not found`).AsError();\n return result;\n}\n\nexport function getName(url: URL, logger: Logger): string {\n let result = url.searchParams.get(\"name\");\n if (!result) {\n result = SysContainer.dirname(url.pathname);\n if (result.length === 0) {\n throw logger.Error().Str(\"url\", url.toString()).Msg(`name not found`).AsError();\n }\n }\n return result;\n}\n\nexport function exception2Result<T = void>(fn: () => Promise<T>): Promise<Result<T>> {\n return fn()\n .then((value) => Result.Ok(value))\n .catch((e) => Result.Err(e));\n}\n\nexport async function exceptionWrapper<T, E extends Error>(fn: () => Promise<Result<T, E>>): Promise<Result<T, E>> {\n return fn().catch((e) => Result.Err(e));\n}\n","export * from \"./sys-container.js\";\nexport * from \"./data-dir.js\";\nexport * from \"./store-file-utils.js\";\n\nexport * as sql from \"./store-sql/index.js\";\n\nexport { FILESTORE_VERSION } from \"./store-file-version.js\";\nexport { INDEXDB_VERSION } from \"./store-indexdb-version.js\";\nexport { SQLITE_VERSION } from \"./store-sql/v0.19-sqlite/version.js\";\n","import { SysContainer } from \"./sys-container.js\";\nimport { isDeno, isNode } from \"std-env\";\n\nexport function dataDir(name?: string, base?: string | URL): string {\n if (!base) {\n if (isNode || isDeno) {\n base = SysContainer.env.get(\"FP_STORAGE_URL\") || `file://${SysContainer.join(SysContainer.homedir(), \".fireproof\")}`;\n } else {\n base = `indexdb://fp`;\n }\n }\n let url: URL;\n if (typeof base === \"string\") {\n try {\n url = new URL(base.toString());\n } catch (e) {\n try {\n base = `file://${base}`;\n url = new URL(base);\n } catch (e) {\n throw new Error(`invalid base url: ${base}`);\n }\n }\n } else {\n url = base;\n }\n url.searchParams.set(\"name\", name || \"\");\n return url.toString();\n}\n","// export * from \"./sqlite-adapter-better-sqlite3.js\";\nexport * from \"./types.js\";\nexport * from \"./ensurer.js\";\n","import { Logger, Result } from \"@adviser/cement\";\nimport type { RunResult } from \"better-sqlite3\";\n\nexport interface DBConnection {\n connect(): Promise<void>;\n readonly opts: SQLOpts;\n}\n\nexport interface SQLStore<IType, KType, OType = IType[]> {\n readonly dbConn: DBConnection;\n start(url: URL): Promise<void>;\n insert(url: URL, ose: IType): Promise<RunResult>;\n select(url: URL, car: KType): Promise<OType>;\n delete(url: URL, car: KType): Promise<RunResult>;\n close(url: URL): Promise<Result<void>>;\n destroy(url: URL): Promise<Result<void>>;\n}\n\nexport interface SQLTableNames {\n readonly data: string;\n readonly meta: string;\n readonly wal: string;\n}\n\nexport const DefaultSQLTableNames: SQLTableNames = {\n data: \"Datas\",\n meta: \"Metas\",\n wal: \"Wals\",\n};\n\nexport interface SQLOpts {\n readonly url: URL;\n readonly sqlFlavor: \"sqlite\" | \"mysql\" | \"postgres\";\n readonly tableNames: SQLTableNames;\n readonly logger: Logger;\n readonly textEncoder: TextEncoder;\n readonly textDecoder: TextDecoder;\n}\n\nexport interface WalKey {\n readonly name: string;\n readonly branch: string;\n}\n\nexport interface WalRecord extends WalKey {\n readonly state: Uint8Array;\n readonly updated_at: Date;\n}\n\nexport type WalSQLStore = SQLStore<WalRecord, WalKey>;\n\nexport interface MetaType {\n readonly name: string;\n readonly branch: string;\n readonly meta: Uint8Array;\n}\n\nexport interface MetaRecordKey {\n readonly name: string;\n readonly branch: string;\n}\n\nexport interface MetaRecord extends MetaRecordKey {\n readonly meta: Uint8Array;\n readonly updated_at: Date;\n}\n\nexport type MetaSQLStore = SQLStore<MetaRecord, MetaRecordKey>;\n\nexport interface DataRecord {\n readonly name: string;\n readonly car: string;\n readonly data: Uint8Array;\n readonly updated_at: Date;\n}\n\nexport type DataSQLStore = SQLStore<DataRecord, string>;\n","import { ensureLogger, type Logger } from \"../../utils\";\nimport { SQLOpts, SQLTableNames, DefaultSQLTableNames } from \"./types\";\n\nfunction sqlTableName(...names: string[]): string {\n return names\n .map((name) => name.replace(/^[^a-zA-Z0-9]+/, \"\").replace(/[^a-zA-Z0-9]+/g, \"_\"))\n .filter((i) => i.length)\n .join(\"_\");\n}\n\nfunction ensureTableNames(url: URL, opts?: Partial<SQLOpts>): SQLTableNames {\n let isIndex = \"\";\n if (url.searchParams.has(\"index\")) {\n isIndex = url.searchParams.get(\"index\") || \".idx\";\n }\n const ret = opts?.tableNames || DefaultSQLTableNames;\n // console.log(\"isIndex->\", opts?.url, isIndex, sqlTableName(isIndex, ret.data));\n if (isIndex.length) {\n return {\n data: sqlTableName(isIndex, ret.data),\n meta: sqlTableName(isIndex, ret.meta),\n wal: sqlTableName(isIndex, ret.wal),\n };\n }\n return {\n data: sqlTableName(ret.data),\n meta: sqlTableName(ret.meta),\n wal: sqlTableName(ret.wal),\n };\n}\n\nconst textEncoder = new TextEncoder();\nfunction ensureTextEncoder(opts?: Partial<SQLOpts>): TextEncoder {\n return opts?.textEncoder || textEncoder;\n}\n\nconst textDecoder = new TextDecoder();\nfunction ensureTextDecoder(opts?: Partial<SQLOpts>): TextDecoder {\n return opts?.textDecoder || textDecoder;\n}\n\nfunction url2sqlFlavor(url: URL, logger: Logger): \"sqlite\" | \"mysql\" | \"postgres\" {\n const flavor = url.protocol.replace(/:.*$/, \"\");\n switch (flavor) {\n case \"sqlite\":\n case \"mysql\":\n case \"postgres\":\n return flavor;\n default:\n throw logger.Error().Str(\"flavor\", flavor).Msg(\"unsupported protocol\").AsError();\n }\n}\n\nexport function ensureSQLOpts(url: URL, opts: Partial<SQLOpts>, componentName: string, ctx?: Record<string, unknown>): SQLOpts {\n const logger = ensureLogger(opts, componentName, ctx);\n return {\n url,\n sqlFlavor: url2sqlFlavor(url, logger),\n tableNames: ensureTableNames(url, opts),\n logger,\n textEncoder: ensureTextEncoder(opts),\n textDecoder: ensureTextDecoder(opts),\n };\n}\n","export const FILESTORE_VERSION = \"v0.19-file\";\n","export const INDEXDB_VERSION = \"v0.19-indexdb\";\n","export const SQLITE_VERSION = \"v0.19-sqlite\";\n","import { Logger, getStore } from \"../utils.js\";\nimport { SysContainer } from \"./sys-container.js\";\n\nexport async function getPath(url: URL, logger: Logger): Promise<string> {\n const basePath = url\n .toString()\n .replace(new RegExp(`^${url.protocol}//`), \"\")\n .replace(/\\?.*$/, \"\");\n const name = url.searchParams.get(\"name\");\n if (name) {\n const version = url.searchParams.get(\"version\");\n if (!version) throw logger.Error().Str(\"url\", url.toString()).Msg(`version not found`).AsError();\n return SysContainer.join(basePath, version, name);\n }\n return SysContainer.join(basePath);\n}\n\nexport function getFileName(url: URL, key: string, logger: Logger): string {\n switch (getStore(url, logger, (...a: string[]) => a.join(\"/\"))) {\n case \"data\":\n return key + \".car\";\n case \"meta\":\n return key + \".json\";\n default:\n throw logger.Error().Str(\"url\", url.toString()).Msg(`unsupported store type`).AsError();\n }\n}\n\nexport function ensureIndexName(url: URL, name: string): string {\n if (url.searchParams.has(\"index\")) {\n name = (url.searchParams.get(\"index\")?.replace(/[^a-zA-Z0-9]/g, \"\") || \"idx\") + \"-\" + name;\n }\n return name;\n}\n"],"mappings":"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","names":["e"]}