@oliphaunt/wasix-ts 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +655 -0
- package/CHANGELOG.md +33 -0
- package/LICENSE +21 -0
- package/README.md +404 -0
- package/THIRD_PARTY_NOTICES.md +20 -0
- package/lib/archive.d.ts +21 -0
- package/lib/archive.js +336 -0
- package/lib/asset-source.d.ts +4 -0
- package/lib/asset-source.js +15 -0
- package/lib/byte-channel.d.ts +27 -0
- package/lib/byte-channel.js +170 -0
- package/lib/client-common.d.ts +6 -0
- package/lib/client-common.js +36 -0
- package/lib/client.d.ts +7 -0
- package/lib/client.js +24 -0
- package/lib/database-root.d.ts +19 -0
- package/lib/database-root.js +139 -0
- package/lib/database.d.ts +135 -0
- package/lib/database.js +1039 -0
- package/lib/descriptor-validation.d.ts +10 -0
- package/lib/descriptor-validation.js +75 -0
- package/lib/direct-client-common.d.ts +50 -0
- package/lib/direct-client-common.js +717 -0
- package/lib/direct-client.d.ts +4 -0
- package/lib/direct-client.js +13 -0
- package/lib/direct.node.d.ts +2 -0
- package/lib/direct.node.js +2 -0
- package/lib/errors.d.ts +25 -0
- package/lib/errors.js +34 -0
- package/lib/extension-descriptor.d.ts +14 -0
- package/lib/extension-descriptor.js +419 -0
- package/lib/extensions.d.ts +68 -0
- package/lib/extensions.js +769 -0
- package/lib/host/LICENSE +21 -0
- package/lib/host/index.d.mts +123 -0
- package/lib/host/index.mjs +11 -0
- package/lib/host/provenance.json +16 -0
- package/lib/host/wasmer_js_bg.wasm +0 -0
- package/lib/host/worker.mjs +11 -0
- package/lib/host-runtime.d.ts +5 -0
- package/lib/host-runtime.js +13 -0
- package/lib/icu-descriptor.d.ts +3 -0
- package/lib/icu-descriptor.js +92 -0
- package/lib/index.bun.d.ts +2 -0
- package/lib/index.bun.js +2 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.deno.d.ts +2 -0
- package/lib/index.deno.js +2 -0
- package/lib/index.js +2 -0
- package/lib/index.node.d.ts +2 -0
- package/lib/index.node.js +2 -0
- package/lib/internal-common.d.ts +12 -0
- package/lib/internal-common.js +274 -0
- package/lib/internal.d.ts +5 -0
- package/lib/internal.js +42 -0
- package/lib/internal.node.d.ts +5 -0
- package/lib/internal.node.js +8 -0
- package/lib/native-addon.d.ts +111 -0
- package/lib/native-addon.js +223 -0
- package/lib/native-server.d.ts +21 -0
- package/lib/native-server.js +109 -0
- package/lib/native-session.d.ts +60 -0
- package/lib/native-session.js +565 -0
- package/lib/node-actor.d.ts +7 -0
- package/lib/node-actor.js +10 -0
- package/lib/node-client-common.d.ts +9 -0
- package/lib/node-client-common.js +35 -0
- package/lib/node-client.d.ts +4 -0
- package/lib/node-client.js +13 -0
- package/lib/node-direct.d.ts +7 -0
- package/lib/node-direct.js +10 -0
- package/lib/node-worker-options.d.ts +5 -0
- package/lib/node-worker-options.js +65 -0
- package/lib/node-worker-port.d.ts +4 -0
- package/lib/node-worker-port.js +116 -0
- package/lib/node-worker.d.ts +1 -0
- package/lib/node-worker.js +38 -0
- package/lib/pgwire-connection.d.ts +60 -0
- package/lib/pgwire-connection.js +528 -0
- package/lib/pgwire.d.ts +3 -0
- package/lib/pgwire.js +105 -0
- package/lib/physical-archive.d.ts +29 -0
- package/lib/physical-archive.js +527 -0
- package/lib/protocol.d.ts +1 -0
- package/lib/protocol.js +1 -0
- package/lib/public.d.ts +4 -0
- package/lib/public.js +3 -0
- package/lib/query.d.ts +1 -0
- package/lib/query.js +1 -0
- package/lib/rpc.d.ts +203 -0
- package/lib/rpc.js +84 -0
- package/lib/runtime-descriptor.d.ts +3 -0
- package/lib/runtime-descriptor.js +79 -0
- package/lib/server.node.d.ts +1 -0
- package/lib/server.node.js +1 -0
- package/lib/startup-config.d.ts +2 -0
- package/lib/startup-config.js +19 -0
- package/lib/storage/bun.d.ts +6 -0
- package/lib/storage/bun.js +6 -0
- package/lib/storage/deno.d.ts +7 -0
- package/lib/storage/deno.js +7 -0
- package/lib/storage/incremental-storage.d.ts +25 -0
- package/lib/storage/incremental-storage.js +154 -0
- package/lib/storage/indexed-db-provider.d.ts +40 -0
- package/lib/storage/indexed-db-provider.js +259 -0
- package/lib/storage/indexed-db.d.ts +9 -0
- package/lib/storage/indexed-db.js +11 -0
- package/lib/storage/node.d.ts +10 -0
- package/lib/storage/node.js +13 -0
- package/lib/storage/opfs-pool.d.ts +31 -0
- package/lib/storage/opfs-pool.js +1271 -0
- package/lib/storage/opfs-provider.d.ts +4 -0
- package/lib/storage/opfs-provider.js +257 -0
- package/lib/storage/opfs.d.ts +8 -0
- package/lib/storage/opfs.js +10 -0
- package/lib/storage/restore-cleanup.d.ts +4 -0
- package/lib/storage/restore-cleanup.js +22 -0
- package/lib/storage/web-lock.d.ts +2 -0
- package/lib/storage/web-lock.js +64 -0
- package/lib/storage-provider.d.ts +47 -0
- package/lib/storage-provider.js +141 -0
- package/lib/storage-snapshot.d.ts +44 -0
- package/lib/storage-snapshot.js +274 -0
- package/lib/storage.d.ts +46 -0
- package/lib/storage.js +83 -0
- package/lib/tool-runtime.d.ts +43 -0
- package/lib/tool-runtime.js +93 -0
- package/lib/tool-worker-common.d.ts +48 -0
- package/lib/tool-worker-common.js +97 -0
- package/lib/tool-worker.d.ts +1 -0
- package/lib/tool-worker.js +10 -0
- package/lib/types.d.ts +230 -0
- package/lib/types.js +1 -0
- package/lib/wasix-runtime.d.ts +24 -0
- package/lib/wasix-runtime.js +186 -0
- package/lib/worker-client.d.ts +4 -0
- package/lib/worker-client.js +45 -0
- package/lib/worker-dispatch.d.ts +11 -0
- package/lib/worker-dispatch.js +174 -0
- package/lib/worker-entry.bun.d.ts +2 -0
- package/lib/worker-entry.bun.js +2 -0
- package/lib/worker-entry.d.ts +2 -0
- package/lib/worker-entry.deno.d.ts +2 -0
- package/lib/worker-entry.deno.js +2 -0
- package/lib/worker-entry.js +2 -0
- package/lib/worker-entry.node.d.ts +2 -0
- package/lib/worker-entry.node.js +2 -0
- package/lib/worker-node-client.d.ts +4 -0
- package/lib/worker-node-client.js +55 -0
- package/lib/worker-rpc.d.ts +36 -0
- package/lib/worker-rpc.js +422 -0
- package/lib/worker-transfer.d.ts +6 -0
- package/lib/worker-transfer.js +11 -0
- package/lib/worker.d.ts +1 -0
- package/lib/worker.js +21 -0
- package/lib/zstd.d.ts +4 -0
- package/lib/zstd.js +12 -0
- package/node_modules/@oliphaunt/js-core/README.md +7 -0
- package/node_modules/@oliphaunt/js-core/dist/commonjs/protocol.d.ts +1 -0
- package/node_modules/@oliphaunt/js-core/dist/commonjs/protocol.js +22 -0
- package/node_modules/@oliphaunt/js-core/dist/commonjs/query.d.ts +255 -0
- package/node_modules/@oliphaunt/js-core/dist/commonjs/query.js +2068 -0
- package/node_modules/@oliphaunt/js-core/dist/module/package.json +3 -0
- package/node_modules/@oliphaunt/js-core/dist/module/protocol.d.ts +1 -0
- package/node_modules/@oliphaunt/js-core/dist/module/protocol.js +19 -0
- package/node_modules/@oliphaunt/js-core/dist/module/query.d.ts +255 -0
- package/node_modules/@oliphaunt/js-core/dist/module/query.js +2039 -0
- package/node_modules/@oliphaunt/js-core/package.json +21 -0
- package/package.json +122 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { WasixStorageError } from '../errors.js';
|
|
2
|
+
import { assertWasixPhysicalIdentity, physicalIdentityMatches, } from '../storage-provider.js';
|
|
3
|
+
import { requireRecord, validateStoredSnapshot, } from '../storage-snapshot.js';
|
|
4
|
+
import { acquireIncrementalStorage } from './incremental-storage.js';
|
|
5
|
+
import { releaseRestoreLock } from './restore-cleanup.js';
|
|
6
|
+
import { acquireExclusiveWebLock } from './web-lock.js';
|
|
7
|
+
const DATABASE_PREFIX = '@oliphaunt/wasix-ts:indexed-db:v1:';
|
|
8
|
+
const DATABASE_VERSION = 1;
|
|
9
|
+
const METADATA_STORE = 'metadata';
|
|
10
|
+
const ENTRY_STORE = 'entries';
|
|
11
|
+
const METADATA_KEY = 'database';
|
|
12
|
+
export async function acquireIndexedDbStorage(name, loadClusterSeed, identity) {
|
|
13
|
+
return acquireIndexedDbStorageWithBackend(name, loadClusterSeed, identity, browserBackend());
|
|
14
|
+
}
|
|
15
|
+
export async function restoreIndexedDbStorage(name, snapshot, identity) {
|
|
16
|
+
const lock = await acquireExclusiveWebLock(`@oliphaunt/wasix-ts:indexed-db:${name}`, `IndexedDB storage ${JSON.stringify(name)}`);
|
|
17
|
+
let database;
|
|
18
|
+
let failure;
|
|
19
|
+
let published = false;
|
|
20
|
+
try {
|
|
21
|
+
const factory = globalThis.indexedDB;
|
|
22
|
+
if (factory === undefined) {
|
|
23
|
+
throw new WasixStorageError('IndexedDB is unavailable in this @oliphaunt/wasix-ts host', {
|
|
24
|
+
code: 'unavailable',
|
|
25
|
+
commitState: 'unchanged',
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
database = await openStorageDatabase(factory, name);
|
|
29
|
+
if ((await readStoredDatabase(database, name)) !== undefined) {
|
|
30
|
+
throw new WasixStorageError(`IndexedDB storage ${JSON.stringify(name)} already exists`, {
|
|
31
|
+
code: 'incomplete',
|
|
32
|
+
commitState: 'unchanged',
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
await applyStoredDatabaseDelta(database, name, identity, {
|
|
36
|
+
directories: snapshot.directories,
|
|
37
|
+
files: snapshot.files,
|
|
38
|
+
deleted: [],
|
|
39
|
+
});
|
|
40
|
+
published = true;
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
failure = error;
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
database?.close();
|
|
47
|
+
failure = await releaseRestoreLock(lock, `IndexedDB storage ${JSON.stringify(name)}`, published ? 'persisted' : 'unchanged', failure);
|
|
48
|
+
}
|
|
49
|
+
if (failure !== undefined)
|
|
50
|
+
throw failure;
|
|
51
|
+
}
|
|
52
|
+
/** @internal Narrow dependency seam for deterministic provider failure tests. */
|
|
53
|
+
export async function acquireIndexedDbStorageWithBackend(name, loadClusterSeed, identity, backend) {
|
|
54
|
+
return acquireIncrementalStorage(`IndexedDB storage ${JSON.stringify(name)}`, loadClusterSeed, {
|
|
55
|
+
acquireLock: () => backend.acquireLock(name),
|
|
56
|
+
async openStore() {
|
|
57
|
+
const database = await backend.openDatabase(name);
|
|
58
|
+
return {
|
|
59
|
+
async read() {
|
|
60
|
+
const stored = await database.read();
|
|
61
|
+
return stored === undefined ? undefined : validateStoredDatabase(stored, name, identity);
|
|
62
|
+
},
|
|
63
|
+
apply: (delta) => database.apply(identity, delta),
|
|
64
|
+
close: () => database.close(),
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function browserBackend() {
|
|
70
|
+
return {
|
|
71
|
+
acquireLock: (name) => acquireExclusiveWebLock(`@oliphaunt/wasix-ts:indexed-db:${name}`, `IndexedDB storage ${JSON.stringify(name)}`),
|
|
72
|
+
async openDatabase(name) {
|
|
73
|
+
const factory = globalThis.indexedDB;
|
|
74
|
+
if (factory === undefined) {
|
|
75
|
+
throw new WasixStorageError('IndexedDB is unavailable in this @oliphaunt/wasix-ts host', {
|
|
76
|
+
code: 'unavailable',
|
|
77
|
+
commitState: 'unchanged',
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
const database = await openStorageDatabase(factory, name);
|
|
81
|
+
return {
|
|
82
|
+
read: () => readStoredDatabase(database, name),
|
|
83
|
+
apply: (identity, delta) => applyStoredDatabaseDelta(database, name, identity, delta),
|
|
84
|
+
close: () => database.close(),
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/** @internal Validate IndexedDB rows before any bytes reach Wasmer. */
|
|
90
|
+
export function validateStoredDatabase(value, name, identity) {
|
|
91
|
+
let stored;
|
|
92
|
+
try {
|
|
93
|
+
stored = requireRecord(value, `IndexedDB storage ${JSON.stringify(name)}`);
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
throw corrupt(name, `has a malformed database record: ${describeError(error)}`, error);
|
|
97
|
+
}
|
|
98
|
+
if (stored.schema !== 'oliphaunt-wasix-indexed-db-v1' || stored.name !== name) {
|
|
99
|
+
throw corrupt(name, 'has an unsupported or mismatched database record');
|
|
100
|
+
}
|
|
101
|
+
if (!hasExactKeys(stored, ['entries', 'name', 'physicalIdentity', 'schema'])) {
|
|
102
|
+
throw corrupt(name, 'has an unsupported or mismatched database record');
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
if (!physicalIdentityMatches(stored.physicalIdentity, identity)) {
|
|
106
|
+
throw new WasixStorageError(`IndexedDB storage ${JSON.stringify(name)} is incompatible with the selected WASIX runtime`, { code: 'incompatible', commitState: 'unchanged' });
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
if (error instanceof WasixStorageError)
|
|
111
|
+
throw error;
|
|
112
|
+
throw corrupt(name, `has malformed identity metadata: ${describeError(error)}`, error);
|
|
113
|
+
}
|
|
114
|
+
if (!Array.isArray(stored.entries))
|
|
115
|
+
throw corrupt(name, 'has malformed entry rows');
|
|
116
|
+
const directories = [];
|
|
117
|
+
const files = [];
|
|
118
|
+
for (const candidate of stored.entries) {
|
|
119
|
+
let entry;
|
|
120
|
+
try {
|
|
121
|
+
entry = requireRecord(candidate, `IndexedDB storage ${JSON.stringify(name)} entry`);
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
throw corrupt(name, `contains a malformed entry row: ${describeError(error)}`, error);
|
|
125
|
+
}
|
|
126
|
+
if (typeof entry.path !== 'string')
|
|
127
|
+
throw corrupt(name, 'contains a mismatched entry row');
|
|
128
|
+
if (entry.type === 'dir') {
|
|
129
|
+
if (!hasExactKeys(entry, ['path', 'type'])) {
|
|
130
|
+
throw corrupt(name, `contains malformed entry ${JSON.stringify(entry.path)}`);
|
|
131
|
+
}
|
|
132
|
+
directories.push(entry.path);
|
|
133
|
+
}
|
|
134
|
+
else if (entry.type === 'file' && entry.bytes instanceof Uint8Array) {
|
|
135
|
+
if (!hasExactKeys(entry, ['bytes', 'path', 'type'])) {
|
|
136
|
+
throw corrupt(name, `contains malformed entry ${JSON.stringify(entry.path)}`);
|
|
137
|
+
}
|
|
138
|
+
files.push({ path: entry.path, bytes: entry.bytes });
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
throw corrupt(name, `contains malformed entry ${JSON.stringify(entry.path)}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return validateStoredSnapshot({ schema: 'oliphaunt-wasix-directory-snapshot-v1', directories, files }, String(identity.postgresMajor), {
|
|
145
|
+
label: `IndexedDB storage ${JSON.stringify(name)}`,
|
|
146
|
+
corrupt: (detail, cause) => corrupt(name, detail, cause),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
function hasExactKeys(value, expected) {
|
|
150
|
+
const keys = Object.keys(value).sort();
|
|
151
|
+
return keys.length === expected.length && keys.every((key, index) => key === expected[index]);
|
|
152
|
+
}
|
|
153
|
+
/** @internal Stable physical IndexedDB name for one logical Oliphaunt database. */
|
|
154
|
+
export function indexedDbDatabaseName(name) {
|
|
155
|
+
return `${DATABASE_PREFIX}${name}`;
|
|
156
|
+
}
|
|
157
|
+
function openStorageDatabase(factory, name) {
|
|
158
|
+
return new Promise((resolve, reject) => {
|
|
159
|
+
const request = factory.open(indexedDbDatabaseName(name), DATABASE_VERSION);
|
|
160
|
+
let settled = false;
|
|
161
|
+
request.onupgradeneeded = () => {
|
|
162
|
+
const database = request.result;
|
|
163
|
+
if (!database.objectStoreNames.contains(METADATA_STORE)) {
|
|
164
|
+
database.createObjectStore(METADATA_STORE);
|
|
165
|
+
}
|
|
166
|
+
if (!database.objectStoreNames.contains(ENTRY_STORE)) {
|
|
167
|
+
database.createObjectStore(ENTRY_STORE, { keyPath: 'path' });
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
request.onerror = () => {
|
|
171
|
+
settled = true;
|
|
172
|
+
reject(request.error ?? new Error('IndexedDB open failed'));
|
|
173
|
+
};
|
|
174
|
+
request.onblocked = () => {
|
|
175
|
+
settled = true;
|
|
176
|
+
reject(new Error(`IndexedDB schema creation for ${JSON.stringify(name)} is blocked by another page`));
|
|
177
|
+
};
|
|
178
|
+
request.onsuccess = () => {
|
|
179
|
+
if (settled)
|
|
180
|
+
request.result.close();
|
|
181
|
+
else {
|
|
182
|
+
settled = true;
|
|
183
|
+
resolve(request.result);
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
export async function readStoredDatabase(database, name) {
|
|
189
|
+
const transaction = database.transaction([METADATA_STORE, ENTRY_STORE], 'readonly');
|
|
190
|
+
const complete = transactionComplete(transaction);
|
|
191
|
+
const metadataRequest = transaction.objectStore(METADATA_STORE).get(METADATA_KEY);
|
|
192
|
+
const entriesRequest = transaction.objectStore(ENTRY_STORE).getAll();
|
|
193
|
+
let metadata;
|
|
194
|
+
let entries;
|
|
195
|
+
try {
|
|
196
|
+
[metadata, entries] = await Promise.all([
|
|
197
|
+
requestValue(metadataRequest),
|
|
198
|
+
requestValue(entriesRequest),
|
|
199
|
+
]);
|
|
200
|
+
await complete;
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
// Observe the transaction promise even when an individual request fails;
|
|
204
|
+
// otherwise its later abort becomes an unhandled rejection in the host.
|
|
205
|
+
await complete.catch(() => undefined);
|
|
206
|
+
throw error;
|
|
207
|
+
}
|
|
208
|
+
if (metadata === undefined) {
|
|
209
|
+
if (entries.length > 0)
|
|
210
|
+
throw corrupt(name, 'contains entries without identity metadata');
|
|
211
|
+
return undefined;
|
|
212
|
+
}
|
|
213
|
+
return { ...metadata, entries: entries };
|
|
214
|
+
}
|
|
215
|
+
export async function applyStoredDatabaseDelta(database, name, identity, delta) {
|
|
216
|
+
const transaction = database.transaction([METADATA_STORE, ENTRY_STORE], 'readwrite');
|
|
217
|
+
transaction.objectStore(METADATA_STORE).put({
|
|
218
|
+
schema: 'oliphaunt-wasix-indexed-db-v1',
|
|
219
|
+
name,
|
|
220
|
+
physicalIdentity: assertWasixPhysicalIdentity(identity),
|
|
221
|
+
}, METADATA_KEY);
|
|
222
|
+
const entries = transaction.objectStore(ENTRY_STORE);
|
|
223
|
+
for (const path of delta.deleted)
|
|
224
|
+
entries.delete(path);
|
|
225
|
+
for (const path of delta.directories) {
|
|
226
|
+
entries.put({ path, type: 'dir' });
|
|
227
|
+
}
|
|
228
|
+
for (const { path, bytes } of delta.files) {
|
|
229
|
+
entries.put({
|
|
230
|
+
path,
|
|
231
|
+
type: 'file',
|
|
232
|
+
bytes,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
await transactionComplete(transaction);
|
|
236
|
+
}
|
|
237
|
+
function requestValue(request) {
|
|
238
|
+
return new Promise((resolve, reject) => {
|
|
239
|
+
request.onsuccess = () => resolve(request.result);
|
|
240
|
+
request.onerror = () => reject(request.error ?? new Error('IndexedDB request failed'));
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
function transactionComplete(transaction) {
|
|
244
|
+
return new Promise((resolve, reject) => {
|
|
245
|
+
transaction.oncomplete = () => resolve();
|
|
246
|
+
transaction.onerror = () => reject(transaction.error ?? new Error('IndexedDB transaction failed'));
|
|
247
|
+
transaction.onabort = () => reject(transaction.error ?? new Error('IndexedDB transaction aborted'));
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
function corrupt(name, detail, cause) {
|
|
251
|
+
return new WasixStorageError(`IndexedDB storage ${JSON.stringify(name)} ${detail}`, {
|
|
252
|
+
code: 'corrupt',
|
|
253
|
+
commitState: 'unchanged',
|
|
254
|
+
...(cause === undefined ? {} : { cause }),
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
function describeError(error) {
|
|
258
|
+
return error instanceof Error ? error.message : String(error);
|
|
259
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type PersistentWasixStorage } from '../storage.js';
|
|
2
|
+
/**
|
|
3
|
+
* Select an origin-scoped persistent database.
|
|
4
|
+
*
|
|
5
|
+
* Every completed protocol operation commits only journaled PGDATA path
|
|
6
|
+
* changes in one atomic read-write IndexedDB transaction before its Promise resolves.
|
|
7
|
+
*/
|
|
8
|
+
export declare function indexedDB(name: string): PersistentWasixStorage;
|
|
9
|
+
export default indexedDB;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { defineIndexedDbStorage } from '../storage.js';
|
|
2
|
+
/**
|
|
3
|
+
* Select an origin-scoped persistent database.
|
|
4
|
+
*
|
|
5
|
+
* Every completed protocol operation commits only journaled PGDATA path
|
|
6
|
+
* changes in one atomic read-write IndexedDB transaction before its Promise resolves.
|
|
7
|
+
*/
|
|
8
|
+
export function indexedDB(name) {
|
|
9
|
+
return defineIndexedDbStorage(name);
|
|
10
|
+
}
|
|
11
|
+
export default indexedDB;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type PersistentWasixStorage } from '../storage.js';
|
|
2
|
+
/**
|
|
3
|
+
* Persist a managed database below a Node.js host directory.
|
|
4
|
+
*
|
|
5
|
+
* Rust opens the selected managed root directly, owns its OS advisory lock,
|
|
6
|
+
* and performs PostgreSQL-safe durable writes at each native operation
|
|
7
|
+
* boundary. Network and cross-host shared filesystems are unsupported.
|
|
8
|
+
*/
|
|
9
|
+
export declare function directory(path: string | URL): PersistentWasixStorage;
|
|
10
|
+
export default directory;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { fileURLToPath } from 'node:url';
|
|
2
|
+
import { defineDirectoryStorage } from '../storage.js';
|
|
3
|
+
/**
|
|
4
|
+
* Persist a managed database below a Node.js host directory.
|
|
5
|
+
*
|
|
6
|
+
* Rust opens the selected managed root directly, owns its OS advisory lock,
|
|
7
|
+
* and performs PostgreSQL-safe durable writes at each native operation
|
|
8
|
+
* boundary. Network and cross-host shared filesystems are unsupported.
|
|
9
|
+
*/
|
|
10
|
+
export function directory(path) {
|
|
11
|
+
return defineDirectoryStorage(typeof path === 'string' ? path : fileURLToPath(path));
|
|
12
|
+
}
|
|
13
|
+
export default directory;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type WasixClusterSeedLoader, type WasixPhysicalIdentity, type WasixStorageSyncBoundary } from '../storage-provider.js';
|
|
2
|
+
import { type StorageDelta, type StoredSnapshot } from '../storage-snapshot.js';
|
|
3
|
+
export declare const OPFS_POOL_ROOT = ".oliphaunt-wasix-pool-v1";
|
|
4
|
+
export type PooledOpfsDatabase = Readonly<{
|
|
5
|
+
snapshot: StoredSnapshot | undefined;
|
|
6
|
+
state: 'new' | 'existing';
|
|
7
|
+
}>;
|
|
8
|
+
type BridgeResult = [result: number, responseLength: number, value0: number, value1: number];
|
|
9
|
+
/**
|
|
10
|
+
* A same-realm synchronous OPFS filesystem for the WASIX host.
|
|
11
|
+
*
|
|
12
|
+
* Logical PostgreSQL paths live in one atomic state file while relation bytes
|
|
13
|
+
* live in flat, pre-opened backing files. That deliberate opacity removes all
|
|
14
|
+
* asynchronous OPFS namespace calls from PostgreSQL's hot syscall path.
|
|
15
|
+
*/
|
|
16
|
+
export declare class DirectOpfsPool {
|
|
17
|
+
#private;
|
|
18
|
+
readonly state: 'new' | 'existing';
|
|
19
|
+
readonly request: (opcode: number, path: string, buffer: Uint8Array, arg0: number, arg1: number, flags: number) => BridgeResult;
|
|
20
|
+
private constructor();
|
|
21
|
+
static open(name: string, loadClusterSeed: WasixClusterSeedLoader, physicalIdentity: WasixPhysicalIdentity): Promise<DirectOpfsPool>;
|
|
22
|
+
sync(boundary: WasixStorageSyncBoundary): Promise<void>;
|
|
23
|
+
close(clean: boolean): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
export declare function inspectPooledOpfsDatabase(database: FileSystemDirectoryHandle, name: string, physicalIdentity: WasixPhysicalIdentity): Promise<PooledOpfsDatabase>;
|
|
26
|
+
/** Reset only an unpublished first-open generation before portable hydration. */
|
|
27
|
+
export declare function preparePooledOpfsDatabase(database: FileSystemDirectoryHandle, name: string, loadClusterSeed: WasixClusterSeedLoader, physicalIdentity: WasixPhysicalIdentity): Promise<PooledOpfsDatabase>;
|
|
28
|
+
export declare function applyPooledOpfsDelta(database: FileSystemDirectoryHandle, name: string, physicalIdentity: WasixPhysicalIdentity, delta: StorageDelta): Promise<void>;
|
|
29
|
+
export declare function openPooledDatabaseDirectory(name: string): Promise<FileSystemDirectoryHandle>;
|
|
30
|
+
export declare function openPooledOpfsRoot(): Promise<FileSystemDirectoryHandle>;
|
|
31
|
+
export {};
|