@fireproof/core 0.18.0 → 0.19.5-dev

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. package/README.md +29 -15
  2. package/chunk-7OGPZSGT.js +39 -0
  3. package/chunk-7OGPZSGT.js.map +1 -0
  4. package/chunk-H3A2HMMM.js +164 -0
  5. package/chunk-H3A2HMMM.js.map +1 -0
  6. package/chunk-HCXR2M5B.js +202 -0
  7. package/chunk-HCXR2M5B.js.map +1 -0
  8. package/chunk-QHSXUST7.js +208 -0
  9. package/chunk-QHSXUST7.js.map +1 -0
  10. package/chunk-VZGT7ZYP.js +22 -0
  11. package/chunk-VZGT7ZYP.js.map +1 -0
  12. package/index.cjs +4649 -0
  13. package/index.cjs.map +1 -0
  14. package/index.d.cts +911 -0
  15. package/index.d.ts +911 -0
  16. package/index.js +2923 -0
  17. package/index.js.map +1 -0
  18. package/metafile-cjs.json +1 -0
  19. package/metafile-esm.json +1 -0
  20. package/node-sys-container-E7LADX2Z.js +29 -0
  21. package/node-sys-container-E7LADX2Z.js.map +1 -0
  22. package/package.json +23 -109
  23. package/sqlite-data-store-YS4U7AQ4.js +120 -0
  24. package/sqlite-data-store-YS4U7AQ4.js.map +1 -0
  25. package/sqlite-meta-store-FJZSZG4R.js +137 -0
  26. package/sqlite-meta-store-FJZSZG4R.js.map +1 -0
  27. package/sqlite-wal-store-6JZ4URNS.js +123 -0
  28. package/sqlite-wal-store-6JZ4URNS.js.map +1 -0
  29. package/store-file-HMHPQTUV.js +193 -0
  30. package/store-file-HMHPQTUV.js.map +1 -0
  31. package/store-indexdb-MRVZG4OG.js +20 -0
  32. package/store-indexdb-MRVZG4OG.js.map +1 -0
  33. package/store-sql-5XMJ5OWJ.js +406 -0
  34. package/store-sql-5XMJ5OWJ.js.map +1 -0
  35. package/dist/browser/fireproof.cjs +0 -1172
  36. package/dist/browser/fireproof.cjs.map +0 -1
  37. package/dist/browser/fireproof.d.cts +0 -268
  38. package/dist/browser/fireproof.d.ts +0 -268
  39. package/dist/browser/fireproof.global.js +0 -24178
  40. package/dist/browser/fireproof.global.js.map +0 -1
  41. package/dist/browser/fireproof.js +0 -1147
  42. package/dist/browser/fireproof.js.map +0 -1
  43. package/dist/browser/metafile-cjs.json +0 -1
  44. package/dist/browser/metafile-esm.json +0 -1
  45. package/dist/browser/metafile-iife.json +0 -1
  46. package/dist/memory/fireproof.cjs +0 -1172
  47. package/dist/memory/fireproof.cjs.map +0 -1
  48. package/dist/memory/fireproof.d.cts +0 -268
  49. package/dist/memory/fireproof.d.ts +0 -268
  50. package/dist/memory/fireproof.global.js +0 -24178
  51. package/dist/memory/fireproof.global.js.map +0 -1
  52. package/dist/memory/fireproof.js +0 -1147
  53. package/dist/memory/fireproof.js.map +0 -1
  54. package/dist/memory/metafile-cjs.json +0 -1
  55. package/dist/memory/metafile-esm.json +0 -1
  56. package/dist/memory/metafile-iife.json +0 -1
  57. package/dist/node/fireproof.cjs +0 -1172
  58. package/dist/node/fireproof.cjs.map +0 -1
  59. package/dist/node/fireproof.d.cts +0 -268
  60. package/dist/node/fireproof.d.ts +0 -268
  61. package/dist/node/fireproof.global.js +0 -38540
  62. package/dist/node/fireproof.global.js.map +0 -1
  63. package/dist/node/fireproof.js +0 -1138
  64. package/dist/node/fireproof.js.map +0 -1
  65. package/dist/node/metafile-cjs.json +0 -1
  66. package/dist/node/metafile-esm.json +0 -1
  67. package/dist/node/metafile-iife.json +0 -1
package/README.md CHANGED
@@ -1,5 +1,3 @@
1
-
2
-
3
1
  # <img src="https://fireproof.storage/static/img/flame.svg" alt="Fireproof logo" width="25"> [Fireproof](https://fireproof.storage) realtime database
4
2
 
5
3
  <p align="right">
@@ -13,26 +11,25 @@
13
11
 
14
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.
15
13
 
16
-
17
- ### JavaScript quick start
14
+ ### JavaScript quick start
18
15
 
19
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.
20
17
 
21
18
  ```js
22
- import { fireproof } from '@fireproof/core'
19
+ import { fireproof } from "@fireproof/core";
23
20
 
24
- const db = fireproof('music-app')
21
+ const db = fireproof("music-app");
25
22
 
26
- await db.put({ _id: 'beyonce', name: 'Beyoncé', hitSingles: 29 })
23
+ await db.put({ _id: "beyonce", name: "Beyoncé", hitSingles: 29 });
27
24
 
28
25
  db.subscribe(async () => {
29
- const topArtists = await db.query("hitSingles", { range: [30, Infinity] })
26
+ const topArtists = await db.query("hitSingles", { range: [30, Infinity] });
30
27
  // redraw the UI with the new topArtists
31
- })
28
+ });
32
29
 
33
- const beyonceDoc = await db.get('beyonce')
34
- beyonceDoc.hitSingles += 1
35
- await db.put(beyonceDoc)
30
+ const beyonceDoc = await db.get("beyonce");
31
+ beyonceDoc.hitSingles += 1;
32
+ await db.put(beyonceDoc);
36
33
  ```
37
34
 
38
35
  Jump to the docs site [for JavaScript API basics.](https://use-fireproof.com/docs/database-api/basics)
@@ -51,9 +48,10 @@ function App() {
51
48
 
52
49
  Read the [step-by-step React tutorial](https://use-fireproof.com/docs/react-tutorial) to get started.
53
50
 
54
- ## Why choose Fireproof
51
+ ## Why choose Fireproof
55
52
 
56
53
  Compared to other embedded databases, Fireproof:
54
+
57
55
  - is network aware, encrypted, and multi-writer safe
58
56
  - is designed for real-time collaboration with CRDTs
59
57
  - offers cryptographic causal integrity for all operations
@@ -77,7 +75,6 @@ With Fireproof, you **build first** and sync via your cloud of choice when you a
77
75
 
78
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).
79
77
 
80
-
81
78
  ### Install
82
79
 
83
80
  Get started with the React hooks:
@@ -95,7 +92,7 @@ npm install @fireproof/core
95
92
  The default build is optimized for browsers, to load the node build add `/node`:
96
93
 
97
94
  ```js
98
- import { fireproof } from '@fireproof/core/node'
95
+ import { fireproof } from "@fireproof/core/node";
99
96
  ```
100
97
 
101
98
  Add the database to any web page via HTML script tag (global is `Fireproof`):
@@ -106,6 +103,23 @@ Add the database to any web page via HTML script tag (global is `Fireproof`):
106
103
 
107
104
  Go ahead and write features, then [connect to any cloud backend](https://www.npmjs.com/package/@fireproof/connect) later.
108
105
 
106
+ ### Debug
107
+
108
+ to control the log output you an either use the FP_DEBUG environment variable or set the debug level in your code:
109
+
110
+ ```shell
111
+ FP_DEBUG='*' node myapp.js
112
+ ```
113
+
114
+ ```js
115
+ logger.setDebug(...moduleNameList or '*')
116
+ ```
117
+
118
+ if you are in the browser you can use the following code to set the debug level:
119
+
120
+ ```js
121
+ this[Symbol.for("FP_ENV")].set("FP_DEBUG", "*");
122
+ ```
109
123
 
110
124
  ## Thanks 🙏
111
125
 
@@ -0,0 +1,39 @@
1
+ import {
2
+ SQLITE_VERSION,
3
+ ensureLogger
4
+ } from "./chunk-HCXR2M5B.js";
5
+
6
+ // src/runtime/store-sql/v0.19-sqlite/sqlite-ensure-version.ts
7
+ import { ResolveOnce } from "@adviser/cement";
8
+ var once = new ResolveOnce();
9
+ async function ensureSQLiteVersion(url, dbConn) {
10
+ const version = await once.once(async () => {
11
+ const logger = ensureLogger(dbConn.opts, "ensureSQLiteVersion", {
12
+ version: SQLITE_VERSION,
13
+ url: dbConn.url.toString()
14
+ });
15
+ await dbConn.client.prepare(
16
+ `CREATE TABLE IF NOT EXISTS version (
17
+ version TEXT NOT NULL,
18
+ updated_at TEXT NOT NULL)`
19
+ ).run();
20
+ const rows = await dbConn.client.prepare(`select version from version`).all();
21
+ if (rows.length > 1) {
22
+ throw logger.Error().Msg(`more than one version row found`).AsError();
23
+ }
24
+ if (rows.length === 0) {
25
+ await dbConn.client.prepare(`insert into version (version, updated_at) values (?, ?)`).run(SQLITE_VERSION, (/* @__PURE__ */ new Date()).toISOString());
26
+ return SQLITE_VERSION;
27
+ }
28
+ if (rows[0].version !== SQLITE_VERSION) {
29
+ logger.Warn().Any("row", rows[0]).Msg(`version mismatch`);
30
+ }
31
+ return rows[0].version;
32
+ });
33
+ url.searchParams.set("version", version);
34
+ }
35
+
36
+ export {
37
+ ensureSQLiteVersion
38
+ };
39
+ //# sourceMappingURL=chunk-7OGPZSGT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/runtime/store-sql/v0.19-sqlite/sqlite-ensure-version.ts"],"sourcesContent":["import { SQLiteConnection } from \"../sqlite-adapter-better-sqlite3\";\nimport { SQLITE_VERSION } from \"./version\";\nimport { ResolveOnce } from \"@adviser/cement\";\nimport { ensureLogger } from \"../../../utils\";\n\nconst once = new ResolveOnce<string>();\nexport async function ensureSQLiteVersion(url: URL, dbConn: SQLiteConnection) {\n const version = await once.once(async () => {\n const logger = ensureLogger(dbConn.opts, \"ensureSQLiteVersion\", {\n version: SQLITE_VERSION,\n url: dbConn.url.toString(),\n });\n await dbConn.client\n .prepare(\n `CREATE TABLE IF NOT EXISTS version (\n version TEXT NOT NULL,\n updated_at TEXT NOT NULL)`,\n )\n .run();\n const rows = (await dbConn.client.prepare(`select version from version`).all()) as { version: string }[];\n if (rows.length > 1) {\n throw logger.Error().Msg(`more than one version row found`).AsError();\n }\n if (rows.length === 0) {\n await dbConn.client\n .prepare(`insert into version (version, updated_at) values (?, ?)`)\n .run(SQLITE_VERSION, new Date().toISOString());\n return SQLITE_VERSION;\n }\n if (rows[0].version !== SQLITE_VERSION) {\n logger.Warn().Any(\"row\", rows[0]).Msg(`version mismatch`);\n }\n return rows[0].version;\n });\n url.searchParams.set(\"version\", version);\n}\n"],"mappings":";;;;;;AAEA,SAAS,mBAAmB;AAG5B,IAAM,OAAO,IAAI,YAAoB;AACrC,eAAsB,oBAAoB,KAAU,QAA0B;AAC5E,QAAM,UAAU,MAAM,KAAK,KAAK,YAAY;AAC1C,UAAM,SAAS,aAAa,OAAO,MAAM,uBAAuB;AAAA,MAC9D,SAAS;AAAA,MACT,KAAK,OAAO,IAAI,SAAS;AAAA,IAC3B,CAAC;AACD,UAAM,OAAO,OACV;AAAA,MACC;AAAA;AAAA;AAAA,IAGF,EACC,IAAI;AACP,UAAM,OAAQ,MAAM,OAAO,OAAO,QAAQ,6BAA6B,EAAE,IAAI;AAC7E,QAAI,KAAK,SAAS,GAAG;AACnB,YAAM,OAAO,MAAM,EAAE,IAAI,iCAAiC,EAAE,QAAQ;AAAA,IACtE;AACA,QAAI,KAAK,WAAW,GAAG;AACrB,YAAM,OAAO,OACV,QAAQ,yDAAyD,EACjE,IAAI,iBAAgB,oBAAI,KAAK,GAAE,YAAY,CAAC;AAC/C,aAAO;AAAA,IACT;AACA,QAAI,KAAK,CAAC,EAAE,YAAY,gBAAgB;AACtC,aAAO,KAAK,EAAE,IAAI,OAAO,KAAK,CAAC,CAAC,EAAE,IAAI,kBAAkB;AAAA,IAC1D;AACA,WAAO,KAAK,CAAC,EAAE;AAAA,EACjB,CAAC;AACD,MAAI,aAAa,IAAI,WAAW,OAAO;AACzC;","names":[]}
@@ -0,0 +1,164 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ // src/types.ts
8
+ function isFalsy(value) {
9
+ return value === false && value === null && value === void 0;
10
+ }
11
+ function throwFalsy(value) {
12
+ if (isFalsy(value)) {
13
+ throw new Error("value is Falsy");
14
+ }
15
+ return value;
16
+ }
17
+ function falsyToUndef(value) {
18
+ if (isFalsy(value)) {
19
+ return void 0;
20
+ }
21
+ return value;
22
+ }
23
+
24
+ // src/runtime/sys-container.ts
25
+ import * as stdEnv from "std-env";
26
+ import { uuidv4 } from "uuidv7";
27
+ import { ResolveOnce, EnvImpl } from "@adviser/cement";
28
+ var onceStart = new ResolveOnce();
29
+ function join(...paths) {
30
+ return paths.map((i) => i.replace(/\/+$/, "")).join("/");
31
+ }
32
+ var envImpl = new EnvImpl({
33
+ symbol: "FP_ENV",
34
+ presetEnv: /* @__PURE__ */ new Map([
35
+ // ["FP_DEBUG", "xxx"],
36
+ // ["FP_ENV", "development"],
37
+ ])
38
+ });
39
+ var sysContainer = class {
40
+ constructor() {
41
+ this.freight = {
42
+ state: "seeded",
43
+ join,
44
+ dirname: (path) => path.split("/").slice(0, -1).join("/"),
45
+ homedir: () => {
46
+ throw new Error("SysContainer:homedir is not available in seeded state");
47
+ },
48
+ fileURLToPath: (strurl) => {
49
+ let url;
50
+ if (typeof strurl === "string") {
51
+ url = new URL(strurl);
52
+ } else {
53
+ url = strurl;
54
+ }
55
+ return url.pathname;
56
+ },
57
+ // assert: (condition: unknown, message?: string | Error) => {
58
+ // if (!condition) {
59
+ // if (message instanceof Error) {
60
+ // throw message;
61
+ // } else {
62
+ // throw new Error(message);
63
+ // }
64
+ // }
65
+ // },
66
+ mkdir: () => Promise.reject(new Error("SysContainer:mkdir is not available in seeded state")),
67
+ readdir: () => Promise.reject(new Error("SysContainer:readdir is not available in seeded state")),
68
+ rm: () => Promise.reject(new Error("SysContainer:rm is not available in seeded state")),
69
+ copyFile: () => Promise.reject(new Error("SysContainer:copyFile is not available in seeded state")),
70
+ readfile: () => Promise.reject(new Error("SysContainer:readfile is not available in seeded state")),
71
+ unlink: () => Promise.reject(new Error("SysContainer:unlink is not available in seeded state")),
72
+ writefile: () => Promise.reject(new Error("SysContainer:writefile is not available in seeded state")),
73
+ stat: () => Promise.reject(new Error("SysContainer:stat is not available in seeded state"))
74
+ };
75
+ this.id = uuidv4();
76
+ this.homedir = () => {
77
+ this.logSeeded("homedir");
78
+ return throwFalsy(this.freight).homedir();
79
+ };
80
+ this.env = envImpl;
81
+ }
82
+ async start() {
83
+ await onceStart.once(async () => {
84
+ switch (this.freight.state) {
85
+ case "seeded":
86
+ if (stdEnv.isNode) {
87
+ const { createNodeSysContainer } = await import("./node-sys-container-E7LADX2Z.js");
88
+ this.freight = await createNodeSysContainer();
89
+ } else {
90
+ this.freight.state = "browser";
91
+ }
92
+ return;
93
+ case "browser":
94
+ case "node":
95
+ return;
96
+ }
97
+ });
98
+ }
99
+ async readdir(path, options) {
100
+ this.logSeeded("readdir");
101
+ return throwFalsy(this.freight).readdir(path, options) || [];
102
+ }
103
+ async readdirent(path, options) {
104
+ this.logSeeded("readdirent");
105
+ return throwFalsy(this.freight).readdir(path, { ...options, withFileTypes: true }) || [];
106
+ }
107
+ async readfile(path, options) {
108
+ this.logSeeded("readfile");
109
+ return throwFalsy(this.freight).readfile(path, options);
110
+ }
111
+ async mkdir(path, options) {
112
+ this.logSeeded("mkdir");
113
+ return throwFalsy(this.freight).mkdir(path, options);
114
+ }
115
+ async rm(path, options) {
116
+ this.logSeeded("rm");
117
+ return throwFalsy(this.freight).rm(path, options);
118
+ }
119
+ async unlink(path) {
120
+ this.logSeeded("unlink");
121
+ return throwFalsy(this.freight).unlink(path);
122
+ }
123
+ async writefile(path, data) {
124
+ this.logSeeded("writefile");
125
+ return throwFalsy(this.freight).writefile(path, data);
126
+ }
127
+ async copyFile(source, destination) {
128
+ this.logSeeded("copyFile");
129
+ return throwFalsy(this.freight).copyFile(source, destination);
130
+ }
131
+ async stat(path) {
132
+ this.logSeeded("stat");
133
+ return throwFalsy(this.freight).stat(path);
134
+ }
135
+ fileURLToPath(url) {
136
+ this.logSeeded("fileURLToPath");
137
+ return throwFalsy(this.freight).fileURLToPath(url);
138
+ }
139
+ dirname(path) {
140
+ this.logSeeded("dirname");
141
+ return throwFalsy(this.freight).dirname(path);
142
+ }
143
+ join(...args) {
144
+ this.logSeeded("join");
145
+ return throwFalsy(this.freight).join(...args);
146
+ }
147
+ logSeeded(method) {
148
+ if (this.freight.state === "seeded") {
149
+ const err = new Error();
150
+ console.warn(`SysContainer.${method} is not available in seeded state:`, err.stack);
151
+ }
152
+ }
153
+ };
154
+ var SysContainer = new sysContainer();
155
+
156
+ export {
157
+ __export,
158
+ isFalsy,
159
+ throwFalsy,
160
+ falsyToUndef,
161
+ join,
162
+ SysContainer
163
+ };
164
+ //# sourceMappingURL=chunk-H3A2HMMM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types.ts","../../src/runtime/sys-container.ts"],"sourcesContent":["import type { EventLink } from \"@web3-storage/pail/clock/api\";\nimport type { Operation } from \"@web3-storage/pail/crdt/api\";\n\nimport type { DbMeta, CryptoOpts, StoreOpts, AnyLink } from \"./blockstore/index.js\";\nimport { Logger } from \"@adviser/cement\";\n\nexport type Falsy = false | null | undefined;\n\nexport function isFalsy(value: unknown): value is Falsy {\n return value === false && value === null && value === undefined;\n}\n\nexport function throwFalsy<T>(value: T | Falsy): T {\n if (isFalsy(value)) {\n throw new Error(\"value is Falsy\");\n }\n return value;\n}\n\nexport function falsyToUndef<T>(value: T | Falsy): T | undefined {\n if (isFalsy(value)) {\n return undefined;\n }\n return value;\n}\n\nexport interface ConfigOpts {\n readonly public?: boolean;\n readonly meta?: DbMeta;\n readonly persistIndexes?: boolean;\n readonly autoCompact?: number;\n readonly crypto?: CryptoOpts;\n readonly store?: StoreOpts;\n // readonly indexStore?: StoreOpts;\n readonly threshold?: number;\n readonly logger?: Logger;\n}\n\nexport type ClockLink = EventLink<Operation>;\n\nexport type ClockHead = ClockLink[];\n\nexport type DocFragment = Uint8Array | string | number | boolean | null | AnyLink | DocFragment[] | object;\n// | { [key: string]: DocFragment };\n\nexport type DocLiteral = string | number | boolean | Uint8Array | unknown;\n\nexport type DocObject = NonNullable<unknown>;\nexport type DocTypes = DocObject;\n\nexport type DocRecord<T extends DocObject> = T;\n\nexport type UnknownDoc = DocRecord<never>;\n\nexport type DocFiles = Record<string, DocFileMeta | File>;\n\nexport interface DocBase {\n readonly _id: string;\n readonly _files?: DocFiles;\n readonly _publicFiles?: DocFiles;\n readonly _deleted?: boolean;\n}\n\nexport type DocWithId<T extends DocTypes> = DocBase & T;\n\nexport type DocSet<T extends DocTypes> = Partial<DocBase> & T;\n\nexport interface DocFileMeta {\n readonly type: string;\n readonly size: number;\n readonly cid: AnyLink;\n readonly car?: AnyLink;\n url?: string;\n file?: () => Promise<File>;\n}\n\nexport interface DocUpdate<T extends DocTypes> {\n readonly id: string;\n readonly value?: DocSet<T>;\n readonly del?: boolean;\n readonly clock?: ClockLink; // would be useful to give ClockLinks a type\n}\n\n// todo merge into above\nexport interface DocValue<T extends DocTypes> {\n readonly doc: DocWithId<T>;\n readonly del: boolean;\n readonly cid: AnyLink;\n}\n\nexport type KeyLiteral = string | number | boolean;\nexport type IndexKeyType = KeyLiteral | KeyLiteral[];\nexport type IndexKey<K extends IndexKeyType> = [K, string];\n\nexport interface IndexUpdate<K extends IndexKeyType> {\n readonly key: IndexKey<K>;\n readonly value?: DocFragment;\n readonly del?: boolean;\n}\n\nexport interface IndexUpdateString {\n readonly key: string;\n readonly value?: DocFragment;\n readonly del?: boolean;\n}\n\n// export interface IndexRowObject<K extends IndexKeyType, T extends DocObject> {\n// readonly id: string;\n// readonly key: K;\n// readonly value: T\n// // readonly row: T // DocFragment;\n// // readonly doc?: DocWithId<T>;\n// // value?: T;\n// // readonly del?: boolean;\n// }\n\n// export interface IndexRowLiteral<K extends IndexKeyType, T extends DocLiteral> {\n// readonly id: string;\n// readonly key: IndexKey<K>;\n// readonly value: T\n// }\n\n// export type IndexRow<K extends IndexKeyType, T extends DocTypes> =\n// T extends DocLiteral ? IndexRowLiteral<K, T> : IndexRowObject<K, T>\n\nexport interface IndexRow<K extends IndexKeyType, T extends DocObject, R extends DocFragment> {\n readonly id: string;\n readonly key: K; // IndexKey<K>;\n readonly value: R;\n readonly doc?: DocWithId<T>;\n}\n\nexport interface IndexRows<K extends IndexKeyType, T extends DocObject, R extends DocFragment = T> {\n readonly rows: IndexRow<K, T, R>[];\n}\nexport interface CRDTMeta {\n readonly head: ClockHead;\n}\n\nexport interface IndexTransactionMeta {\n readonly indexes: Record<string, IdxMeta>;\n}\n\nexport interface FileTransactionMeta {\n readonly files?: AnyLink[];\n}\n\nexport type MetaType = CRDTMeta | IndexTransactionMeta | FileTransactionMeta;\n\nexport interface IdxMeta {\n readonly byId: AnyLink;\n readonly byKey: AnyLink;\n readonly map: string;\n readonly name: string;\n readonly head: ClockHead;\n}\n\nexport interface IdxMetaMap {\n readonly indexes?: Map<string, IdxMeta>;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport interface QueryOpts<K extends IndexKeyType> {\n readonly descending?: boolean;\n readonly limit?: number;\n includeDocs?: boolean;\n readonly range?: [IndexKeyType, IndexKeyType];\n readonly key?: DocFragment;\n readonly keys?: DocFragment[];\n prefix?: IndexKeyType;\n}\n\ntype EmitFn = (k: IndexKeyType, v?: DocFragment) => void;\nexport type MapFn<T extends DocTypes> = (doc: DocWithId<T>, emit: EmitFn) => DocFragment | unknown;\n\nexport interface ChangesOptions {\n readonly dirty?: boolean;\n readonly limit?: number;\n}\n\nexport interface ChangesResponseRow<T extends DocTypes> {\n readonly key: string;\n readonly value: DocWithId<T>;\n readonly clock?: ClockLink;\n}\n\nexport interface ChangesResponse<T extends DocTypes> {\n readonly clock: ClockHead;\n readonly rows: ChangesResponseRow<T>[];\n}\n\nexport interface DbResponse {\n readonly id: string;\n readonly clock: ClockHead;\n}\n\nexport type UpdateListenerFn<T extends DocTypes> = (docs: DocWithId<T>[]) => Promise<void> | void;\nexport type NoUpdateListenerFn = () => Promise<void> | void;\nexport type ListenerFn<T extends DocTypes> = UpdateListenerFn<T> | NoUpdateListenerFn;\n","import type { Dirent, MakeDirectoryOptions, ObjectEncodingOptions, PathLike, Stats } from \"node:fs\";\n\nimport * as stdEnv from \"std-env\";\nimport { uuidv4 } from \"uuidv7\";\nimport { ResolveOnce, EnvImpl } from \"@adviser/cement\";\n\nimport { throwFalsy } from \"../types.js\";\n\nexport interface NodeMap {\n state: \"seeded\" | \"browser\" | \"node\";\n join: (...args: string[]) => string;\n dirname: (path: string) => string;\n homedir: () => string;\n fileURLToPath: (url: string | URL) => string;\n // assert: (condition: unknown, message?: string | Error) => void;\n\n mkdir: (path: PathLike, options?: { recursive: boolean }) => Promise<string | undefined>;\n readdir: (path: PathLike, options?: unknown) => Promise<unknown[]>;\n\n rm: (path: PathLike, options?: MakeDirectoryOptions & { recursive: boolean }) => Promise<void>;\n copyFile: (source: PathLike, destination: PathLike) => Promise<void>;\n\n readfile: (path: PathLike, options?: { encoding: BufferEncoding; flag?: string }) => Promise<string>;\n\n stat: (path: PathLike) => Promise<Stats>;\n\n unlink: (path: PathLike) => Promise<void>;\n writefile: (path: PathLike, data: Uint8Array | string) => Promise<void>;\n}\n\n// export function assert(condition: unknown, message?: string | Error): asserts condition {\n// SysContainer.freight?.assert(condition, message);\n// }\n\nconst onceStart = new ResolveOnce<void>();\n\nexport function join(...paths: string[]): string {\n return paths.map((i) => i.replace(/\\/+$/, \"\")).join(\"/\");\n}\n\nconst envImpl = new EnvImpl({\n symbol: \"FP_ENV\",\n presetEnv: new Map([\n // [\"FP_DEBUG\", \"xxx\"],\n // [\"FP_ENV\", \"development\"],\n ]),\n});\n// console.log(`EnvImpl`, envImpl);\n\nclass sysContainer {\n freight: NodeMap = {\n state: \"seeded\",\n join,\n dirname: (path: string) => path.split(\"/\").slice(0, -1).join(\"/\"),\n homedir: () => {\n throw new Error(\"SysContainer:homedir is not available in seeded state\");\n },\n fileURLToPath: (strurl: string | URL) => {\n let url: URL;\n if (typeof strurl === \"string\") {\n url = new URL(strurl);\n } else {\n url = strurl;\n }\n return url.pathname;\n },\n // assert: (condition: unknown, message?: string | Error) => {\n // if (!condition) {\n // if (message instanceof Error) {\n // throw message;\n // } else {\n // throw new Error(message);\n // }\n // }\n // },\n mkdir: () => Promise.reject(new Error(\"SysContainer:mkdir is not available in seeded state\")),\n readdir: () => Promise.reject(new Error(\"SysContainer:readdir is not available in seeded state\")),\n rm: () => Promise.reject(new Error(\"SysContainer:rm is not available in seeded state\")),\n copyFile: () => Promise.reject(new Error(\"SysContainer:copyFile is not available in seeded state\")),\n readfile: () => Promise.reject(new Error(\"SysContainer:readfile is not available in seeded state\")),\n unlink: () => Promise.reject(new Error(\"SysContainer:unlink is not available in seeded state\")),\n writefile: () => Promise.reject(new Error(\"SysContainer:writefile is not available in seeded state\")),\n stat: () => Promise.reject(new Error(\"SysContainer:stat is not available in seeded state\")),\n };\n\n readonly id = uuidv4();\n\n async start(): Promise<void> {\n await onceStart.once(async () => {\n switch (this.freight.state) {\n case \"seeded\":\n if (stdEnv.isNode) {\n const { createNodeSysContainer } = await import(\"./node-sys-container.js\");\n // console.log(\"use NodeSysContainer\");\n this.freight = await createNodeSysContainer();\n } else {\n // console.log(\"use BrowserSysContainer\");\n this.freight.state = \"browser\";\n }\n return;\n case \"browser\":\n case \"node\":\n return;\n }\n });\n }\n\n async readdir(\n path: PathLike,\n options?:\n | (ObjectEncodingOptions & { withFileTypes?: false | undefined; recursive?: boolean })\n | BufferEncoding\n | null\n | undefined,\n ) {\n this.logSeeded(\"readdir\");\n return (throwFalsy(this.freight).readdir(path, options) as Promise<string[]>) || [];\n }\n async readdirent(\n path: PathLike,\n options: (ObjectEncodingOptions & { withFileTypes: true; recursive?: boolean }) | BufferEncoding | null | undefined,\n ): Promise<Dirent[]> {\n this.logSeeded(\"readdirent\");\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (throwFalsy(this.freight).readdir(path, { ...(options as any), withFileTypes: true }) as Promise<Dirent[]>) || [];\n }\n\n async readfile(path: PathLike, options?: { encoding: BufferEncoding; flag?: string }) {\n this.logSeeded(\"readfile\");\n return throwFalsy(this.freight).readfile(path, options) as unknown as Promise<Buffer>;\n }\n\n async mkdir(path: PathLike, options: { recursive: boolean }) {\n this.logSeeded(\"mkdir\");\n return throwFalsy(this.freight).mkdir(path, options);\n }\n\n async rm(path: PathLike, options: MakeDirectoryOptions & { recursive: boolean }) {\n this.logSeeded(\"rm\");\n return throwFalsy(this.freight).rm(path, options);\n }\n\n async unlink(path: PathLike) {\n this.logSeeded(\"unlink\");\n return throwFalsy(this.freight).unlink(path);\n }\n\n async writefile(path: PathLike, data: Uint8Array | string) {\n this.logSeeded(\"writefile\");\n return throwFalsy(this.freight).writefile(path, data);\n }\n\n async copyFile(source: PathLike, destination: PathLike) {\n this.logSeeded(\"copyFile\");\n return throwFalsy(this.freight).copyFile(source, destination);\n }\n\n async stat(path: PathLike) {\n this.logSeeded(\"stat\");\n return throwFalsy(this.freight).stat(path);\n }\n\n fileURLToPath(url: string | URL) {\n this.logSeeded(\"fileURLToPath\");\n return throwFalsy(this.freight).fileURLToPath(url);\n }\n\n dirname(path: string) {\n this.logSeeded(\"dirname\");\n return throwFalsy(this.freight).dirname(path);\n }\n\n join(...args: string[]): string {\n this.logSeeded(\"join\");\n return throwFalsy(this.freight).join(...args);\n }\n\n homedir = () => {\n this.logSeeded(\"homedir\");\n return throwFalsy(this.freight).homedir();\n };\n\n logSeeded(method: string) {\n if (this.freight.state === \"seeded\") {\n const err = new Error();\n console.warn(`SysContainer.${method} is not available in seeded state:`, err.stack);\n }\n }\n readonly env = envImpl;\n}\n\n// // eslint-disable-next-line @typescript-eslint/no-explicit-any\n// export async function saveImport(fName: string): Promise<any> {\n// try {\n// const i = await import(fName);\n// return i;\n// } catch (e: unknown) {\n// console.error(`saveImport failed for ${fName} with`, e);\n// throw e;\n// }\n// }\n\nexport const SysContainer = new sysContainer();\n"],"mappings":"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","names":[]}
@@ -0,0 +1,202 @@
1
+ import {
2
+ SysContainer,
3
+ __export,
4
+ join
5
+ } from "./chunk-H3A2HMMM.js";
6
+
7
+ // src/utils.ts
8
+ import { LoggerImpl, IsLogger, Result, ResolveOnce } from "@adviser/cement";
9
+
10
+ // src/runtime/index.ts
11
+ var runtime_exports = {};
12
+ __export(runtime_exports, {
13
+ FILESTORE_VERSION: () => FILESTORE_VERSION,
14
+ INDEXDB_VERSION: () => INDEXDB_VERSION,
15
+ SQLITE_VERSION: () => SQLITE_VERSION,
16
+ SysContainer: () => SysContainer,
17
+ dataDir: () => dataDir,
18
+ ensureIndexName: () => ensureIndexName,
19
+ getFileName: () => getFileName,
20
+ getPath: () => getPath,
21
+ join: () => join
22
+ });
23
+
24
+ // src/runtime/data-dir.ts
25
+ import { isDeno, isNode } from "std-env";
26
+ function dataDir(name, base) {
27
+ const dataDir2 = _dataDir(name, base);
28
+ return dataDir2;
29
+ }
30
+ function _dataDir(name, base) {
31
+ if (!base) {
32
+ if (isNode || isDeno) {
33
+ base = SysContainer.env.get("FP_STORAGE_URL") || `file://${SysContainer.join(SysContainer.homedir(), ".fireproof")}`;
34
+ } else {
35
+ base = `indexdb://fp`;
36
+ }
37
+ }
38
+ let url;
39
+ if (typeof base === "string") {
40
+ try {
41
+ url = new URL(base.toString());
42
+ } catch (e) {
43
+ try {
44
+ base = `file://${base}`;
45
+ url = new URL(base);
46
+ } catch (e2) {
47
+ throw new Error(`invalid base url: ${base}`);
48
+ }
49
+ }
50
+ } else {
51
+ url = base;
52
+ }
53
+ url.searchParams.set("name", name || "");
54
+ return url.toString();
55
+ }
56
+
57
+ // src/runtime/store-file-version.ts
58
+ var FILESTORE_VERSION = "v0.19-file";
59
+
60
+ // src/runtime/store-indexdb-version.ts
61
+ var INDEXDB_VERSION = "v0.19-indexdb";
62
+
63
+ // src/runtime/store-sql/v0.19-sqlite/version.ts
64
+ var SQLITE_VERSION = "v0.19-sqlite";
65
+
66
+ // src/utils.ts
67
+ import { uuidv7 } from "uuidv7";
68
+ var globalLogger = new LoggerImpl();
69
+ var registerFP_DEBUG = new ResolveOnce();
70
+ function ensureLogger(optsOrLogger, componentName, ctx) {
71
+ let logger = globalLogger;
72
+ if (IsLogger(optsOrLogger)) {
73
+ logger = optsOrLogger;
74
+ } else if (optsOrLogger && IsLogger(optsOrLogger.logger)) {
75
+ logger = optsOrLogger.logger;
76
+ }
77
+ const cLogger = logger.With().Module(componentName);
78
+ const debug = [];
79
+ if (ctx) {
80
+ if ("debug" in ctx) {
81
+ if (typeof ctx.debug === "string" && ctx.debug.length > 0) {
82
+ debug.push(ctx.debug);
83
+ } else {
84
+ debug.push(componentName);
85
+ }
86
+ delete ctx.debug;
87
+ }
88
+ if ("this" in ctx) {
89
+ cLogger.Str("this", uuidv7());
90
+ delete ctx.this;
91
+ }
92
+ for (const [key, value] of Object.entries(ctx)) {
93
+ switch (typeof value) {
94
+ case "string":
95
+ cLogger.Str(key, value);
96
+ break;
97
+ case "number":
98
+ cLogger.Uint64(key, value);
99
+ break;
100
+ default:
101
+ if (value instanceof Date) {
102
+ cLogger.Str(key, value.toISOString());
103
+ } else if (value instanceof URL) {
104
+ cLogger.Str(key, value.toString());
105
+ } else if (typeof value === "function") {
106
+ cLogger.Ref(key, value);
107
+ } else {
108
+ cLogger.Any(key, value);
109
+ }
110
+ break;
111
+ }
112
+ }
113
+ }
114
+ registerFP_DEBUG.once(async () => {
115
+ SysContainer.env.onSet((key, value) => {
116
+ if (value) {
117
+ logger.SetDebug(value);
118
+ }
119
+ }, "FP_DEBUG");
120
+ }).finally(() => {
121
+ });
122
+ if (debug.length > 0) {
123
+ logger.SetDebug(debug);
124
+ }
125
+ const out = cLogger.Logger();
126
+ return out;
127
+ }
128
+ function getStore(url, logger, joiner) {
129
+ let result = url.searchParams.get("store");
130
+ if (!result) throw logger.Error().Str("url", url.toString()).Msg(`store not found`).AsError();
131
+ if (url.searchParams.has("index")) {
132
+ result = joiner(url.searchParams.get("index") || "idx", result);
133
+ }
134
+ return result;
135
+ }
136
+ function getKey(url, logger) {
137
+ const result = url.searchParams.get("key");
138
+ if (!result) throw logger.Error().Str("url", url.toString()).Msg(`key not found`).AsError();
139
+ return result;
140
+ }
141
+ function getName(url, logger) {
142
+ let result = url.searchParams.get("name");
143
+ if (!result) {
144
+ result = SysContainer.dirname(url.pathname);
145
+ if (result.length === 0) {
146
+ throw logger.Error().Str("url", url.toString()).Msg(`name not found`).AsError();
147
+ }
148
+ }
149
+ return result;
150
+ }
151
+ function exception2Result(fn) {
152
+ return fn().then((value) => Result.Ok(value)).catch((e) => Result.Err(e));
153
+ }
154
+ async function exceptionWrapper(fn) {
155
+ return fn().catch((e) => Result.Err(e));
156
+ }
157
+
158
+ // src/runtime/store-file-utils.ts
159
+ async function getPath(url, logger) {
160
+ const basePath = url.toString().replace(new RegExp(`^${url.protocol}//`), "").replace(/\?.*$/, "");
161
+ const name = url.searchParams.get("name");
162
+ if (name) {
163
+ const version = url.searchParams.get("version");
164
+ if (!version) throw logger.Error().Str("url", url.toString()).Msg(`version not found`).AsError();
165
+ return SysContainer.join(basePath, version, name);
166
+ }
167
+ return SysContainer.join(basePath);
168
+ }
169
+ function getFileName(url, key, logger) {
170
+ switch (getStore(url, logger, (...a) => a.join("/"))) {
171
+ case "data":
172
+ return key + ".car";
173
+ case "meta":
174
+ return key + ".json";
175
+ default:
176
+ throw logger.Error().Str("url", url.toString()).Msg(`unsupported store type`).AsError();
177
+ }
178
+ }
179
+ function ensureIndexName(url, name) {
180
+ if (url.searchParams.has("index")) {
181
+ name = (url.searchParams.get("index")?.replace(/[^a-zA-Z0-9]/g, "") || "idx") + "-" + name;
182
+ }
183
+ return name;
184
+ }
185
+
186
+ export {
187
+ dataDir,
188
+ getPath,
189
+ getFileName,
190
+ ensureIndexName,
191
+ FILESTORE_VERSION,
192
+ INDEXDB_VERSION,
193
+ SQLITE_VERSION,
194
+ runtime_exports,
195
+ ensureLogger,
196
+ getStore,
197
+ getKey,
198
+ getName,
199
+ exception2Result,
200
+ exceptionWrapper
201
+ };
202
+ //# sourceMappingURL=chunk-HCXR2M5B.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils.ts","../../src/runtime/index.ts","../../src/runtime/data-dir.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 { 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 const dataDir = _dataDir(name, base);\n // console.log(\"dataDir->\", dataDir, name, base);\n return dataDir;\n}\n\nfunction _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 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":["dataDir","e"]}