@fireproof/core 0.18.0 → 0.19.0-dev-use-fix
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +29 -15
- package/chunk-AZVWSRER.js +208 -0
- package/chunk-AZVWSRER.js.map +1 -0
- package/chunk-H3A2HMMM.js +164 -0
- package/chunk-H3A2HMMM.js.map +1 -0
- package/chunk-NZNG6TQT.js +370 -0
- package/chunk-NZNG6TQT.js.map +1 -0
- package/chunk-VZGT7ZYP.js +22 -0
- package/chunk-VZGT7ZYP.js.map +1 -0
- package/chunk-ZHO4NMWL.js +39 -0
- package/chunk-ZHO4NMWL.js.map +1 -0
- package/index.cjs +4706 -0
- package/index.cjs.map +1 -0
- package/index.d.cts +1012 -0
- package/index.d.ts +1012 -0
- package/index.js +2856 -0
- package/index.js.map +1 -0
- package/metafile-cjs.json +1 -0
- package/metafile-esm.json +1 -0
- package/node-sys-container-E7LADX2Z.js +29 -0
- package/node-sys-container-E7LADX2Z.js.map +1 -0
- package/package.json +23 -109
- package/sqlite-data-store-3ST7XOLX.js +120 -0
- package/sqlite-data-store-3ST7XOLX.js.map +1 -0
- package/sqlite-meta-store-QOIMCSJ7.js +137 -0
- package/sqlite-meta-store-QOIMCSJ7.js.map +1 -0
- package/sqlite-wal-store-JFBQPOYT.js +123 -0
- package/sqlite-wal-store-JFBQPOYT.js.map +1 -0
- package/store-file-CSS5THFH.js +193 -0
- package/store-file-CSS5THFH.js.map +1 -0
- package/store-indexdb-DR4HELVP.js +20 -0
- package/store-indexdb-DR4HELVP.js.map +1 -0
- package/store-sql-BG6SMGQJ.js +344 -0
- package/store-sql-BG6SMGQJ.js.map +1 -0
- package/tests/blockstore/loader.test.ts +265 -0
- package/tests/blockstore/store.test.ts +164 -0
- package/tests/blockstore/transaction.test.ts +121 -0
- package/tests/fireproof/config.test.ts +212 -0
- package/tests/fireproof/crdt.test.ts +434 -0
- package/tests/fireproof/database.test.ts +466 -0
- package/tests/fireproof/fireproof.test.ts +602 -0
- package/tests/fireproof/hello.test.ts +54 -0
- package/tests/fireproof/indexer.test.ts +389 -0
- package/tests/helpers.ts +81 -0
- package/tests/react/useFireproof.test.tsx +19 -0
- package/tests/www/gallery.html +132 -0
- package/tests/www/iife.html +42 -0
- package/tests/www/todo-aws.html +232 -0
- package/tests/www/todo-ipfs.html +213 -0
- package/tests/www/todo-local.html +214 -0
- package/tests/www/todo-netlify.html +227 -0
- package/tests/www/todo.html +236 -0
- package/dist/browser/fireproof.cjs +0 -1172
- package/dist/browser/fireproof.cjs.map +0 -1
- package/dist/browser/fireproof.d.cts +0 -268
- package/dist/browser/fireproof.d.ts +0 -268
- package/dist/browser/fireproof.global.js +0 -24178
- package/dist/browser/fireproof.global.js.map +0 -1
- package/dist/browser/fireproof.js +0 -1147
- package/dist/browser/fireproof.js.map +0 -1
- package/dist/browser/metafile-cjs.json +0 -1
- package/dist/browser/metafile-esm.json +0 -1
- package/dist/browser/metafile-iife.json +0 -1
- package/dist/memory/fireproof.cjs +0 -1172
- package/dist/memory/fireproof.cjs.map +0 -1
- package/dist/memory/fireproof.d.cts +0 -268
- package/dist/memory/fireproof.d.ts +0 -268
- package/dist/memory/fireproof.global.js +0 -24178
- package/dist/memory/fireproof.global.js.map +0 -1
- package/dist/memory/fireproof.js +0 -1147
- package/dist/memory/fireproof.js.map +0 -1
- package/dist/memory/metafile-cjs.json +0 -1
- package/dist/memory/metafile-esm.json +0 -1
- package/dist/memory/metafile-iife.json +0 -1
- package/dist/node/fireproof.cjs +0 -1172
- package/dist/node/fireproof.cjs.map +0 -1
- package/dist/node/fireproof.d.cts +0 -268
- package/dist/node/fireproof.d.ts +0 -268
- package/dist/node/fireproof.global.js +0 -38540
- package/dist/node/fireproof.global.js.map +0 -1
- package/dist/node/fireproof.js +0 -1138
- package/dist/node/fireproof.js.map +0 -1
- package/dist/node/metafile-cjs.json +0 -1
- package/dist/node/metafile-esm.json +0 -1
- 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
|
19
|
+
import { fireproof } from "@fireproof/core";
|
23
20
|
|
24
|
-
const db = fireproof(
|
21
|
+
const db = fireproof("music-app");
|
25
22
|
|
26
|
-
await db.put({ _id:
|
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(
|
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
|
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,208 @@
|
|
1
|
+
import {
|
2
|
+
NotFoundError
|
3
|
+
} from "./chunk-VZGT7ZYP.js";
|
4
|
+
import {
|
5
|
+
INDEXDB_VERSION,
|
6
|
+
ensureLogger,
|
7
|
+
exception2Result,
|
8
|
+
exceptionWrapper,
|
9
|
+
getKey,
|
10
|
+
getStore
|
11
|
+
} from "./chunk-NZNG6TQT.js";
|
12
|
+
import {
|
13
|
+
SysContainer
|
14
|
+
} from "./chunk-H3A2HMMM.js";
|
15
|
+
|
16
|
+
// src/runtime/store-indexdb.ts
|
17
|
+
import { openDB } from "idb";
|
18
|
+
import { KeyedResolvOnce, Result } from "@adviser/cement";
|
19
|
+
function ensureVersion(url) {
|
20
|
+
const ret = new URL(url.toString());
|
21
|
+
ret.searchParams.set("version", url.searchParams.get("version") || INDEXDB_VERSION);
|
22
|
+
return ret;
|
23
|
+
}
|
24
|
+
function guardVersion(url) {
|
25
|
+
if (!url.searchParams.has("version")) {
|
26
|
+
return Result.Err(`missing version: ${url.toString()}`);
|
27
|
+
}
|
28
|
+
return Result.Ok(url);
|
29
|
+
}
|
30
|
+
var onceIndexDB = new KeyedResolvOnce();
|
31
|
+
function sanitzeKey(key) {
|
32
|
+
if (key.length === 1) {
|
33
|
+
key = key[0];
|
34
|
+
}
|
35
|
+
return key;
|
36
|
+
}
|
37
|
+
async function connectIdb(url, logger) {
|
38
|
+
const dbName = getIndexDBName(url, logger);
|
39
|
+
const once = await onceIndexDB.get(dbName.fullDb).once(async () => {
|
40
|
+
const db = await openDB(dbName.fullDb, 1, {
|
41
|
+
upgrade(db2) {
|
42
|
+
["version", "data", "wal", "meta", "idx.data", "idx.wal", "idx.meta"].map((store) => {
|
43
|
+
db2.createObjectStore(store, {
|
44
|
+
autoIncrement: false
|
45
|
+
});
|
46
|
+
});
|
47
|
+
}
|
48
|
+
});
|
49
|
+
const found = await db.get("version", "version");
|
50
|
+
const version = url.searchParams.get("version") || INDEXDB_VERSION;
|
51
|
+
if (!found) {
|
52
|
+
await db.put("version", { version }, "version");
|
53
|
+
} else if (found.version !== version) {
|
54
|
+
logger.Warn().Str("url", url.toString()).Str("version", version).Str("found", found.version).Msg("version mismatch");
|
55
|
+
}
|
56
|
+
return { db, dbName, version };
|
57
|
+
});
|
58
|
+
url.searchParams.set("version", once.version);
|
59
|
+
return once.db;
|
60
|
+
}
|
61
|
+
function joinDBName(...names) {
|
62
|
+
return names.map((i) => i.replace(/^[^a-zA-Z0-9]+/g, "").replace(/[^a-zA-Z0-9]+/g, "_")).filter((i) => i.length).join(".");
|
63
|
+
}
|
64
|
+
function getIndexDBName(iurl, logger) {
|
65
|
+
const url = ensureVersion(iurl);
|
66
|
+
const fullDb = url.pathname.replace(/^\/+/, "").replace(/\?.*$/, "");
|
67
|
+
const dbName = url.searchParams.get("name");
|
68
|
+
if (!dbName) throw logger.Error().Str("url", url.toString()).Msg(`name not found`).AsError();
|
69
|
+
const result = joinDBName(fullDb, dbName);
|
70
|
+
const objStore = getStore(url, logger, joinDBName);
|
71
|
+
const connectionKey = [result, objStore].join(":");
|
72
|
+
return {
|
73
|
+
fullDb: result,
|
74
|
+
objStore,
|
75
|
+
connectionKey,
|
76
|
+
dbName
|
77
|
+
};
|
78
|
+
}
|
79
|
+
var IndexDBGateway = class {
|
80
|
+
constructor(logger) {
|
81
|
+
this.db = {};
|
82
|
+
this.logger = logger;
|
83
|
+
}
|
84
|
+
idb() {
|
85
|
+
this.db;
|
86
|
+
}
|
87
|
+
async start(baseURL) {
|
88
|
+
return exception2Result(async () => {
|
89
|
+
this.logger.Debug().Url(baseURL).Msg("starting");
|
90
|
+
await SysContainer.start();
|
91
|
+
this.db = await connectIdb(baseURL, this.logger);
|
92
|
+
this.logger.Debug().Url(baseURL).Msg("started");
|
93
|
+
});
|
94
|
+
}
|
95
|
+
async close() {
|
96
|
+
return Result.Ok(void 0);
|
97
|
+
}
|
98
|
+
async destroy(baseUrl) {
|
99
|
+
return exception2Result(async () => {
|
100
|
+
const type = getStore(baseUrl, this.logger, joinDBName);
|
101
|
+
const idb = this.db;
|
102
|
+
const trans = idb.transaction(type, "readwrite");
|
103
|
+
const object_store = trans.objectStore(type);
|
104
|
+
const toDelete = [];
|
105
|
+
for (let cursor = await object_store.openCursor(); cursor; cursor = await cursor.continue()) {
|
106
|
+
toDelete.push(cursor.primaryKey);
|
107
|
+
}
|
108
|
+
for (const key of toDelete) {
|
109
|
+
await trans.db.delete(type, key);
|
110
|
+
}
|
111
|
+
await trans.done;
|
112
|
+
});
|
113
|
+
}
|
114
|
+
async get(url) {
|
115
|
+
return exceptionWrapper(async () => {
|
116
|
+
const key = getKey(url, this.logger);
|
117
|
+
const store = getStore(url, this.logger, joinDBName);
|
118
|
+
this.logger.Debug().Url(url).Str("key", key).Str("store", store).Msg("getting");
|
119
|
+
const tx = this.db.transaction([store], "readonly");
|
120
|
+
const bytes = await tx.objectStore(store).get(sanitzeKey(key));
|
121
|
+
await tx.done;
|
122
|
+
if (!bytes) {
|
123
|
+
return Result.Err(new NotFoundError(`missing ${key}`));
|
124
|
+
}
|
125
|
+
return Result.Ok(bytes);
|
126
|
+
});
|
127
|
+
}
|
128
|
+
async put(url, value) {
|
129
|
+
return exception2Result(async () => {
|
130
|
+
const key = getKey(url, this.logger);
|
131
|
+
const store = getStore(url, this.logger, joinDBName);
|
132
|
+
this.logger.Debug().Url(url).Str("key", key).Str("store", store).Msg("putting");
|
133
|
+
const tx = this.db.transaction([store], "readwrite");
|
134
|
+
await tx.objectStore(store).put(value, sanitzeKey(key));
|
135
|
+
await tx.done;
|
136
|
+
});
|
137
|
+
}
|
138
|
+
async delete(url) {
|
139
|
+
return exception2Result(async () => {
|
140
|
+
const key = getKey(url, this.logger);
|
141
|
+
const store = getStore(url, this.logger, joinDBName);
|
142
|
+
this.logger.Debug().Url(url).Str("key", key).Str("store", store).Msg("deleting");
|
143
|
+
const tx = this.db.transaction([store], "readwrite");
|
144
|
+
await tx.objectStore(store).delete(sanitzeKey(key));
|
145
|
+
await tx.done;
|
146
|
+
return Result.Ok(void 0);
|
147
|
+
});
|
148
|
+
}
|
149
|
+
};
|
150
|
+
var IndexDBDataGateway = class extends IndexDBGateway {
|
151
|
+
constructor(logger) {
|
152
|
+
super(ensureLogger(logger, "IndexDBDataGateway", {}));
|
153
|
+
}
|
154
|
+
buildUrl(baseUrl, key) {
|
155
|
+
const url = new URL(baseUrl.toString());
|
156
|
+
url.searchParams.set("key", key);
|
157
|
+
return Promise.resolve(Result.Ok(url));
|
158
|
+
}
|
159
|
+
};
|
160
|
+
var IndexDBWalGateway = class extends IndexDBGateway {
|
161
|
+
constructor(logger) {
|
162
|
+
super(ensureLogger(logger, "IndexDBWalGateway", {}));
|
163
|
+
}
|
164
|
+
buildUrl(baseUrl, key) {
|
165
|
+
const url = new URL(baseUrl.toString());
|
166
|
+
url.searchParams.set("key", key);
|
167
|
+
return Promise.resolve(Result.Ok(url));
|
168
|
+
}
|
169
|
+
};
|
170
|
+
var IndexDBMetaGateway = class extends IndexDBGateway {
|
171
|
+
constructor(logger) {
|
172
|
+
super(ensureLogger(logger, "IndexDBDataGateway", {}));
|
173
|
+
this.branches = /* @__PURE__ */ new Set();
|
174
|
+
}
|
175
|
+
async buildUrl(baseUrl, key) {
|
176
|
+
const url = new URL(baseUrl.toString());
|
177
|
+
this.branches.add(key);
|
178
|
+
url.searchParams.set("key", key);
|
179
|
+
return Result.Ok(url);
|
180
|
+
}
|
181
|
+
};
|
182
|
+
var txtEncoder = new TextEncoder();
|
183
|
+
var IndexDBTestStore = class {
|
184
|
+
constructor(logger) {
|
185
|
+
this.logger = ensureLogger(logger, "IndexDBTestStore", {});
|
186
|
+
}
|
187
|
+
async get(url, key) {
|
188
|
+
const db = await connectIdb(url, this.logger);
|
189
|
+
const store = getStore(url, this.logger, joinDBName);
|
190
|
+
this.logger.Debug().Str("key", key).Str("store", store).Msg("getting");
|
191
|
+
let bytes = await db.get(store, sanitzeKey(key));
|
192
|
+
this.logger.Debug().Str("key", key).Str("store", store).Int("len", bytes.length).Msg("got");
|
193
|
+
if (typeof bytes === "string") {
|
194
|
+
bytes = txtEncoder.encode(bytes);
|
195
|
+
}
|
196
|
+
return bytes;
|
197
|
+
}
|
198
|
+
};
|
199
|
+
|
200
|
+
export {
|
201
|
+
guardVersion,
|
202
|
+
getIndexDBName,
|
203
|
+
IndexDBDataGateway,
|
204
|
+
IndexDBWalGateway,
|
205
|
+
IndexDBMetaGateway,
|
206
|
+
IndexDBTestStore
|
207
|
+
};
|
208
|
+
//# sourceMappingURL=chunk-AZVWSRER.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../../src/runtime/store-indexdb.ts"],"sourcesContent":["import { openDB, IDBPDatabase } from \"idb\";\nimport { KeyedResolvOnce, Logger, Result } from \"@adviser/cement\";\n\nimport { TestStore } from \"../blockstore/types.js\";\nimport { INDEXDB_VERSION } from \"./store-indexdb-version.js\";\nimport { ensureLogger, exception2Result, exceptionWrapper, getKey, getStore } from \"../utils.js\";\nimport { Gateway, NotFoundError } from \"../blockstore/gateway.js\";\nimport { SysContainer } from \"./sys-container.js\";\n\nfunction ensureVersion(url: URL): URL {\n const ret = new URL(url.toString());\n ret.searchParams.set(\"version\", url.searchParams.get(\"version\") || INDEXDB_VERSION);\n return ret;\n}\n\nexport function guardVersion(url: URL): Result<URL> {\n if (!url.searchParams.has(\"version\")) {\n return Result.Err(`missing version: ${url.toString()}`);\n }\n return Result.Ok(url);\n}\n\nconst onceIndexDB = new KeyedResolvOnce<{\n readonly db: IDBPDatabase<unknown>;\n readonly dbName: DbName;\n readonly version: string;\n}>();\n\nfunction sanitzeKey(key: string | string[]): string | string[] {\n if (key.length === 1) {\n key = key[0];\n }\n return key;\n}\n\nasync function connectIdb(url: URL, logger: Logger): Promise<IDBPDatabase<unknown>> {\n const dbName = getIndexDBName(url, logger); // `fp.${this.STORAGE_VERSION}.${this.name}`;\n // const urlStr = url.toString().replace(/\\?.*$/, \"\");\n // console.log(`get:${this.id}`);\n // console.log(`connectIdb:pre:`, dbName, url.toString());\n const once = await onceIndexDB.get(dbName.fullDb).once(async () => {\n // console.log(`connectIdb:once:`, dbName, url.toString());\n const db = await openDB(dbName.fullDb, 1, {\n upgrade(db) {\n // console.log('upgrade:', dbName);\n [\"version\", \"data\", \"wal\", \"meta\", \"idx.data\", \"idx.wal\", \"idx.meta\"].map((store) => {\n db.createObjectStore(store, {\n autoIncrement: false,\n });\n });\n },\n });\n const found = await db.get(\"version\", \"version\");\n const version = url.searchParams.get(\"version\") || INDEXDB_VERSION;\n if (!found) {\n await db.put(\"version\", { version }, \"version\");\n } else if (found.version !== version) {\n logger\n .Warn()\n .Str(\"url\", url.toString())\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n .Str(\"version\", version!)\n .Str(\"found\", found.version)\n .Msg(\"version mismatch\");\n }\n return { db, dbName, version };\n });\n url.searchParams.set(\"version\", once.version);\n return once.db;\n}\n\nexport interface DbName {\n readonly fullDb: string;\n readonly objStore: string;\n readonly connectionKey: string;\n // readonly version: number;\n // readonly type: \"data\" | \"meta\" | \"wal\";\n readonly dbName: string;\n}\n\nfunction joinDBName(...names: string[]): string {\n return names\n .map((i) => i.replace(/^[^a-zA-Z0-9]+/g, \"\").replace(/[^a-zA-Z0-9]+/g, \"_\"))\n .filter((i) => i.length)\n .join(\".\");\n}\n\n// const schemaVersion = new Map<string, number>();\nexport function getIndexDBName(iurl: URL, logger: Logger): DbName {\n const url = ensureVersion(iurl);\n const fullDb = url.pathname.replace(/^\\/+/, \"\").replace(/\\?.*$/, \"\"); // cut leading slashes\n // const type = getStore(url);\n // const storageVersion = url.searchParams.get(\"version\");\n // not nice but we need to pass the version to the db name\n // url.searchParams.set(\"version\", storageVersion);\n // console.log(\"getIndexDBName:\", url.toString(), { fullDb, type, branch });\n // const dbName = fullDb.replace(new RegExp(`^fp.${storageVersion}.`), \"\"); // cut fp prefix\n const dbName = url.searchParams.get(\"name\");\n if (!dbName) throw logger.Error().Str(\"url\", url.toString()).Msg(`name not found`).AsError();\n const result = joinDBName(fullDb, dbName);\n const objStore = getStore(url, logger, joinDBName);\n const connectionKey = [result, objStore].join(\":\");\n return {\n fullDb: result,\n objStore,\n connectionKey,\n dbName,\n };\n}\n\nabstract class IndexDBGateway implements Gateway {\n readonly logger: Logger;\n constructor(logger: Logger) {\n this.logger = logger;\n }\n db: IDBPDatabase<unknown> = {} as IDBPDatabase<unknown>;\n idb() {\n this.db;\n }\n\n async start(baseURL: URL): Promise<Result<void>> {\n return exception2Result(async () => {\n this.logger.Debug().Url(baseURL).Msg(\"starting\");\n await SysContainer.start();\n this.db = await connectIdb(baseURL, this.logger);\n this.logger.Debug().Url(baseURL).Msg(\"started\");\n });\n }\n async close(): Promise<Result<void>> {\n return Result.Ok(undefined);\n }\n async destroy(baseUrl: URL): Promise<Result<void>> {\n return exception2Result(async () => {\n // return deleteDB(getIndexDBName(this.url).fullDb);\n const type = getStore(baseUrl, this.logger, joinDBName);\n // console.log(\"IndexDBDataStore:destroy\", type);\n const idb = this.db;\n const trans = idb.transaction(type, \"readwrite\");\n const object_store = trans.objectStore(type);\n const toDelete = [];\n for (let cursor = await object_store.openCursor(); cursor; cursor = await cursor.continue()) {\n toDelete.push(cursor.primaryKey);\n }\n for (const key of toDelete) {\n await trans.db.delete(type, key);\n }\n await trans.done;\n });\n }\n\n abstract buildUrl(baseUrl: URL, key: string): Promise<Result<URL>>;\n\n async get(url: URL) {\n return exceptionWrapper(async () => {\n const key = getKey(url, this.logger);\n const store = getStore(url, this.logger, joinDBName);\n this.logger.Debug().Url(url).Str(\"key\", key).Str(\"store\", store).Msg(\"getting\");\n const tx = this.db.transaction([store], \"readonly\");\n const bytes = await tx.objectStore(store).get(sanitzeKey(key));\n await tx.done;\n if (!bytes) {\n return Result.Err(new NotFoundError(`missing ${key}`));\n }\n return Result.Ok(bytes as Uint8Array);\n });\n }\n async put(url: URL, value: Uint8Array) {\n return exception2Result(async () => {\n const key = getKey(url, this.logger);\n const store = getStore(url, this.logger, joinDBName);\n this.logger.Debug().Url(url).Str(\"key\", key).Str(\"store\", store).Msg(\"putting\");\n const tx = this.db.transaction([store], \"readwrite\");\n await tx.objectStore(store).put(value, sanitzeKey(key));\n await tx.done;\n });\n }\n async delete(url: URL) {\n return exception2Result(async () => {\n const key = getKey(url, this.logger);\n const store = getStore(url, this.logger, joinDBName);\n this.logger.Debug().Url(url).Str(\"key\", key).Str(\"store\", store).Msg(\"deleting\");\n const tx = this.db.transaction([store], \"readwrite\");\n await tx.objectStore(store).delete(sanitzeKey(key));\n await tx.done;\n return Result.Ok(undefined);\n });\n }\n}\n\nexport class IndexDBDataGateway extends IndexDBGateway {\n constructor(logger: Logger) {\n super(ensureLogger(logger, \"IndexDBDataGateway\", {}));\n }\n\n buildUrl(baseUrl: URL, key: string): Promise<Result<URL>> {\n const url = new URL(baseUrl.toString());\n url.searchParams.set(\"key\", key);\n return Promise.resolve(Result.Ok(url));\n }\n}\n\nexport class IndexDBWalGateway extends IndexDBGateway {\n constructor(logger: Logger) {\n super(ensureLogger(logger, \"IndexDBWalGateway\", {}));\n }\n buildUrl(baseUrl: URL, key: string): Promise<Result<URL>> {\n const url = new URL(baseUrl.toString());\n url.searchParams.set(\"key\", key);\n return Promise.resolve(Result.Ok(url));\n }\n}\nexport class IndexDBMetaGateway extends IndexDBGateway {\n constructor(logger: Logger) {\n super(ensureLogger(logger, \"IndexDBDataGateway\", {}));\n }\n\n readonly branches = new Set<string>();\n async buildUrl(baseUrl: URL, key: string): Promise<Result<URL>> {\n const url = new URL(baseUrl.toString());\n this.branches.add(key);\n url.searchParams.set(\"key\", key);\n return Result.Ok(url);\n }\n}\n\nconst txtEncoder = new TextEncoder();\nexport class IndexDBTestStore implements TestStore {\n readonly logger: Logger;\n constructor(logger: Logger) {\n this.logger = ensureLogger(logger, \"IndexDBTestStore\", {});\n }\n async get(url: URL, key: string) {\n const db = await connectIdb(url, this.logger);\n const store = getStore(url, this.logger, joinDBName);\n this.logger.Debug().Str(\"key\", key).Str(\"store\", store).Msg(\"getting\");\n let bytes = await db.get(store, sanitzeKey(key));\n this.logger.Debug().Str(\"key\", key).Str(\"store\", store).Int(\"len\", bytes.length).Msg(\"got\");\n if (typeof bytes === \"string\") {\n bytes = txtEncoder.encode(bytes);\n }\n return bytes as Uint8Array;\n }\n}\n"],"mappings":"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","names":["db"]}
|
@@ -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":[]}
|