@oliphaunt/wasix-ts 0.1.0 → 0.2.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 +55 -32
- package/CHANGELOG.md +31 -0
- package/README.md +19 -387
- package/THIRD_PARTY_NOTICES.md +5 -5
- package/lib/browser.d.ts +2 -0
- package/lib/browser.js +6 -0
- package/lib/{database.d.ts → core/database.d.ts} +4 -4
- package/lib/{database.js → core/database.js} +1 -1
- package/lib/core/open-config.d.ts +5 -0
- package/lib/core/open-config.js +28 -0
- package/lib/{public.d.ts → core/public.d.ts} +3 -3
- package/lib/{public.js → core/public.js} +2 -2
- package/lib/{types.d.ts → core/types.d.ts} +19 -43
- package/lib/direct.node.d.ts +2 -2
- package/lib/direct.node.js +2 -2
- package/lib/host/index.d.mts +1 -1
- package/lib/host/index.mjs +1 -1
- package/lib/host/provenance.json +1 -1
- package/lib/host/wasmer_js_bg.wasm +0 -0
- package/lib/hosts/browser/browser-public.d.ts +8 -0
- package/lib/hosts/browser/browser-public.js +1 -0
- package/lib/{client-common.d.ts → hosts/browser/client-common.d.ts} +3 -3
- package/lib/hosts/browser/client-common.js +17 -0
- package/lib/{client.d.ts → hosts/browser/client.d.ts} +1 -1
- package/lib/{client.js → hosts/browser/client.js} +5 -3
- package/lib/{direct-client-common.d.ts → hosts/browser/direct-client-common.d.ts} +9 -8
- package/lib/{direct-client-common.js → hosts/browser/direct-client-common.js} +17 -31
- package/lib/hosts/browser/initialize.d.ts +5 -0
- package/lib/hosts/browser/initialize.js +67 -0
- package/lib/{internal-common.d.ts → hosts/browser/internal-common.d.ts} +3 -3
- package/lib/{internal-common.js → hosts/browser/internal-common.js} +3 -3
- package/lib/{tool-worker-common.d.ts → hosts/browser/tool-worker-common.d.ts} +3 -3
- package/lib/{tool-worker-common.js → hosts/browser/tool-worker-common.js} +2 -2
- package/lib/{tool-worker.js → hosts/browser/tool-worker.js} +1 -1
- package/lib/{wasix-runtime.d.ts → hosts/browser/wasix-runtime.d.ts} +3 -3
- package/lib/{wasix-runtime.js → hosts/browser/wasix-runtime.js} +41 -25
- package/lib/{worker-client.d.ts → hosts/browser/worker-client.d.ts} +1 -1
- package/lib/{worker-client.js → hosts/browser/worker-client.js} +5 -4
- package/lib/{worker.js → hosts/browser/worker.js} +2 -2
- package/lib/{direct-client.d.ts → hosts/node-api/direct-client.d.ts} +1 -1
- package/lib/{direct-client.js → hosts/node-api/direct-client.js} +1 -1
- package/lib/{native-addon.d.ts → hosts/node-api/native-addon.d.ts} +28 -6
- package/lib/{native-addon.js → hosts/node-api/native-addon.js} +4 -5
- package/lib/hosts/node-api/native-public.d.ts +8 -0
- package/lib/hosts/node-api/native-public.js +1 -0
- package/lib/{native-server.d.ts → hosts/node-api/native-server.d.ts} +1 -1
- package/lib/{native-server.js → hosts/node-api/native-server.js} +3 -2
- package/lib/{native-session.d.ts → hosts/node-api/native-session.d.ts} +14 -4
- package/lib/{native-session.js → hosts/node-api/native-session.js} +93 -108
- package/lib/{node-actor.d.ts → hosts/node-api/node-actor.d.ts} +2 -2
- package/lib/{node-actor.js → hosts/node-api/node-actor.js} +1 -1
- package/lib/{node-client-common.d.ts → hosts/node-api/node-client-common.d.ts} +3 -3
- package/lib/{node-client-common.js → hosts/node-api/node-client-common.js} +4 -4
- package/lib/{node-client.d.ts → hosts/node-api/node-client.d.ts} +1 -1
- package/lib/{node-client.js → hosts/node-api/node-client.js} +1 -1
- package/lib/{node-direct.d.ts → hosts/node-api/node-direct.d.ts} +2 -2
- package/lib/{node-direct.js → hosts/node-api/node-direct.js} +1 -1
- package/lib/{node-worker-port.d.ts → hosts/node-api/node-worker-port.d.ts} +1 -1
- package/lib/{node-worker.js → hosts/node-api/node-worker.js} +1 -1
- package/lib/{worker-node-client.d.ts → hosts/node-api/worker-node-client.d.ts} +1 -1
- package/lib/{worker-node-client.js → hosts/node-api/worker-node-client.js} +5 -18
- package/lib/index.bun.d.ts +2 -2
- package/lib/index.bun.js +2 -2
- package/lib/index.d.ts +2 -2
- package/lib/index.deno.d.ts +2 -2
- package/lib/index.deno.js +2 -2
- package/lib/index.js +2 -2
- package/lib/index.node.d.ts +2 -2
- package/lib/index.node.js +2 -2
- package/lib/internal.d.ts +4 -4
- package/lib/internal.js +24 -4
- package/lib/internal.node.d.ts +4 -4
- package/lib/internal.node.js +2 -2
- package/lib/native-only.d.ts +1 -0
- package/lib/native-only.js +2 -0
- package/lib/protocol/protocol.d.ts +1 -0
- package/lib/protocol/protocol.js +1 -0
- package/lib/protocol/query.d.ts +1 -0
- package/lib/protocol/query.js +1 -0
- package/lib/{archive.d.ts → resources/archive.d.ts} +1 -1
- package/lib/{descriptor-validation.d.ts → resources/descriptor-validation.d.ts} +2 -2
- package/lib/{descriptor-validation.js → resources/descriptor-validation.js} +1 -1
- package/lib/{extension-descriptor.d.ts → resources/extension-descriptor.d.ts} +2 -2
- package/lib/{extensions.d.ts → resources/extensions.d.ts} +13 -6
- package/lib/{extensions.js → resources/extensions.js} +80 -155
- package/lib/resources/icu-descriptor.d.ts +3 -0
- package/lib/resources/icu-descriptor.js +16 -0
- package/lib/{runtime-descriptor.d.ts → resources/runtime-descriptor.d.ts} +1 -1
- package/lib/{runtime-descriptor.js → resources/runtime-descriptor.js} +1 -24
- package/lib/{tool-runtime.d.ts → resources/tool-runtime.d.ts} +8 -2
- package/lib/server.node.d.ts +1 -1
- package/lib/server.node.js +1 -1
- package/lib/{database-root.d.ts → storage/database-root.d.ts} +8 -0
- package/lib/{database-root.js → storage/database-root.js} +6 -0
- package/lib/storage/incremental-storage.d.ts +3 -3
- package/lib/storage/incremental-storage.js +2 -2
- package/lib/storage/indexed-db-provider.d.ts +2 -2
- package/lib/storage/indexed-db-provider.js +3 -3
- package/lib/storage/indexed-db.d.ts +2 -2
- package/lib/storage/indexed-db.js +1 -1
- package/lib/storage/node.d.ts +2 -2
- package/lib/storage/node.js +1 -1
- package/lib/storage/opfs-pool.d.ts +2 -2
- package/lib/storage/opfs-pool.js +4 -4
- package/lib/storage/opfs-provider.d.ts +2 -2
- package/lib/storage/opfs-provider.js +1 -1
- package/lib/storage/opfs.d.ts +2 -2
- package/lib/storage/opfs.js +1 -1
- package/lib/{physical-archive.js → storage/physical-archive.js} +4 -4
- package/lib/storage/restore-cleanup.d.ts +1 -1
- package/lib/storage/restore-cleanup.js +1 -1
- package/lib/{storage-provider.d.ts → storage/storage-provider.d.ts} +5 -11
- package/lib/{storage-provider.js → storage/storage-provider.js} +8 -13
- package/lib/{storage-snapshot.d.ts → storage/storage-snapshot.d.ts} +2 -2
- package/lib/{storage.d.ts → storage/types.d.ts} +8 -7
- package/lib/storage/web-lock.js +1 -1
- package/lib/worker-entry.bun.d.ts +2 -2
- package/lib/worker-entry.bun.js +2 -2
- package/lib/worker-entry.d.ts +2 -2
- package/lib/worker-entry.deno.d.ts +2 -2
- package/lib/worker-entry.deno.js +2 -2
- package/lib/worker-entry.js +2 -2
- package/lib/worker-entry.node.d.ts +2 -2
- package/lib/worker-entry.node.js +2 -2
- package/lib/{rpc.d.ts → workers/rpc.d.ts} +14 -34
- package/lib/{rpc.js → workers/rpc.js} +4 -4
- package/lib/{worker-dispatch.d.ts → workers/worker-dispatch.d.ts} +1 -1
- package/lib/{worker-dispatch.js → workers/worker-dispatch.js} +2 -2
- package/lib/{worker-rpc.d.ts → workers/worker-rpc.d.ts} +3 -3
- package/lib/{worker-rpc.js → workers/worker-rpc.js} +8 -12
- package/package.json +66 -30
- package/lib/client-common.js +0 -36
- package/lib/icu-descriptor.d.ts +0 -3
- package/lib/icu-descriptor.js +0 -92
- package/lib/protocol.d.ts +0 -1
- package/lib/protocol.js +0 -1
- package/lib/query.d.ts +0 -1
- package/lib/query.js +0 -1
- package/node_modules/@oliphaunt/js-core/README.md +0 -7
- package/node_modules/@oliphaunt/js-core/dist/commonjs/protocol.d.ts +0 -1
- package/node_modules/@oliphaunt/js-core/dist/commonjs/protocol.js +0 -22
- package/node_modules/@oliphaunt/js-core/dist/commonjs/query.d.ts +0 -255
- package/node_modules/@oliphaunt/js-core/dist/commonjs/query.js +0 -2068
- package/node_modules/@oliphaunt/js-core/dist/module/package.json +0 -3
- package/node_modules/@oliphaunt/js-core/dist/module/protocol.d.ts +0 -1
- package/node_modules/@oliphaunt/js-core/dist/module/protocol.js +0 -19
- package/node_modules/@oliphaunt/js-core/dist/module/query.d.ts +0 -255
- package/node_modules/@oliphaunt/js-core/dist/module/query.js +0 -2039
- package/node_modules/@oliphaunt/js-core/package.json +0 -21
- /package/lib/{errors.d.ts → core/errors.d.ts} +0 -0
- /package/lib/{errors.js → core/errors.js} +0 -0
- /package/lib/{startup-config.d.ts → core/startup-config.d.ts} +0 -0
- /package/lib/{startup-config.js → core/startup-config.js} +0 -0
- /package/lib/{types.js → core/types.js} +0 -0
- /package/lib/{tool-worker.d.ts → hosts/browser/tool-worker.d.ts} +0 -0
- /package/lib/{worker.d.ts → hosts/browser/worker.d.ts} +0 -0
- /package/lib/{host-runtime.d.ts → hosts/node-api/host-runtime.d.ts} +0 -0
- /package/lib/{host-runtime.js → hosts/node-api/host-runtime.js} +0 -0
- /package/lib/{node-worker-options.d.ts → hosts/node-api/node-worker-options.d.ts} +0 -0
- /package/lib/{node-worker-options.js → hosts/node-api/node-worker-options.js} +0 -0
- /package/lib/{node-worker-port.js → hosts/node-api/node-worker-port.js} +0 -0
- /package/lib/{node-worker.d.ts → hosts/node-api/node-worker.d.ts} +0 -0
- /package/lib/{byte-channel.d.ts → protocol/byte-channel.d.ts} +0 -0
- /package/lib/{byte-channel.js → protocol/byte-channel.js} +0 -0
- /package/lib/{pgwire-connection.d.ts → protocol/pgwire-connection.d.ts} +0 -0
- /package/lib/{pgwire-connection.js → protocol/pgwire-connection.js} +0 -0
- /package/lib/{pgwire.d.ts → protocol/pgwire.d.ts} +0 -0
- /package/lib/{pgwire.js → protocol/pgwire.js} +0 -0
- /package/lib/{archive.js → resources/archive.js} +0 -0
- /package/lib/{asset-source.d.ts → resources/asset-source.d.ts} +0 -0
- /package/lib/{asset-source.js → resources/asset-source.js} +0 -0
- /package/lib/{extension-descriptor.js → resources/extension-descriptor.js} +0 -0
- /package/lib/{tool-runtime.js → resources/tool-runtime.js} +0 -0
- /package/lib/{zstd.d.ts → resources/zstd.d.ts} +0 -0
- /package/lib/{zstd.js → resources/zstd.js} +0 -0
- /package/lib/{physical-archive.d.ts → storage/physical-archive.d.ts} +0 -0
- /package/lib/{storage-snapshot.js → storage/storage-snapshot.js} +0 -0
- /package/lib/{storage.js → storage/types.js} +0 -0
- /package/lib/{worker-transfer.d.ts → workers/worker-transfer.d.ts} +0 -0
- /package/lib/{worker-transfer.js → workers/worker-transfer.js} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { SerializedExtensionCarrier } from '
|
|
2
|
-
import type { WasixExtensionDescriptor, WasixExtensionDescriptorInput } from '
|
|
1
|
+
import type { SerializedExtensionCarrier } from '../workers/rpc.js';
|
|
2
|
+
import type { WasixExtensionDescriptor, WasixExtensionDescriptorInput } from '../core/types.js';
|
|
3
3
|
export type SerializedWasixExtensions = {
|
|
4
4
|
selectedSqlNames: string[];
|
|
5
5
|
carriers: Record<string, SerializedExtensionCarrier>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ExtractedArchive, type WasixDirectoryMount, type WasixRuntimeLayout } from './archive.js';
|
|
2
|
-
import type { SerializedOpenOptions, SerializedRuntimeDescriptor, SerializedToolRuntimeDescriptor } from '
|
|
3
|
-
import { type WasixPhysicalIdentity } from '
|
|
4
|
-
import type { WasixAssetManifest } from '
|
|
2
|
+
import type { SerializedOpenOptions, SerializedRuntimeDescriptor, SerializedToolRuntimeDescriptor } from '../workers/rpc.js';
|
|
3
|
+
import { type WasixPhysicalIdentity } from '../storage/database-root.js';
|
|
4
|
+
import type { WasixAssetManifest } from '../core/types.js';
|
|
5
5
|
type CatalogProfile = 'standard' | 'icu';
|
|
6
6
|
/** Internal kebab-case projection used while installing an imported carrier. */
|
|
7
7
|
type ProjectedExtensionLifecycle = {
|
|
@@ -33,7 +33,7 @@ export type ResolvedWasixExtensions = {
|
|
|
33
33
|
};
|
|
34
34
|
export type PreparedWasixRuntime = {
|
|
35
35
|
layout: WasixRuntimeLayout;
|
|
36
|
-
loadClusterSeed()
|
|
36
|
+
loadClusterSeed?: () => Promise<WasixDirectoryMount>;
|
|
37
37
|
moduleSha256: string;
|
|
38
38
|
catalogProfile: 'standard' | 'icu';
|
|
39
39
|
icuEnabled: boolean;
|
|
@@ -47,6 +47,15 @@ export type PreparedWasixRuntime = {
|
|
|
47
47
|
* configuration; database-local installation remains explicit application SQL.
|
|
48
48
|
*/
|
|
49
49
|
export declare function prepareWasixRuntime(options: SerializedOpenOptions): Promise<PreparedWasixRuntime>;
|
|
50
|
+
export declare function loadSeedBytes(seed: NonNullable<SerializedOpenOptions['seed']>): Promise<{
|
|
51
|
+
archive: Uint8Array<ArrayBufferLike>;
|
|
52
|
+
manifest: Uint8Array<ArrayBufferLike>;
|
|
53
|
+
}>;
|
|
54
|
+
export declare function loadIcuData(icu: NonNullable<SerializedOpenOptions['icu']>): Promise<{
|
|
55
|
+
data: Uint8Array<ArrayBufferLike>;
|
|
56
|
+
manifest: Uint8Array<ArrayBufferLike>;
|
|
57
|
+
treeSha256: string;
|
|
58
|
+
}>;
|
|
50
59
|
/** Require the package-authored archive identities to match the canonical manifest. */
|
|
51
60
|
export declare function assertRuntimeDescriptorMatchesManifest(descriptor: SerializedRuntimeDescriptor, manifest: WasixAssetManifest): void;
|
|
52
61
|
/** Verify only the runtime assets consumed by PostgreSQL frontend tools. */
|
|
@@ -59,8 +68,6 @@ export declare function overlayExtensionArchive(layout: WasixRuntimeLayout, arch
|
|
|
59
68
|
export declare function mergeExtensionStartupGUCs(configured: Readonly<Record<string, string>>, extensions: readonly ProjectedExtensionInstall[]): Record<string, string>;
|
|
60
69
|
/** @internal Validate the host-independent standard/ICU seed profile contract. */
|
|
61
70
|
export declare function assertClusterSeedProfileContract(value: unknown, expectedProfile: CatalogProfile): void;
|
|
62
|
-
/** @internal Verify that a separately distributed ICU carrier belongs to this runtime. */
|
|
63
|
-
export declare function assertIcuDescriptorMatchesRuntime(runtime: SerializedRuntimeDescriptor, icu: NonNullable<SerializedOpenOptions['icu']>, manifest: WasixAssetManifest): void;
|
|
64
71
|
/** @internal Validate and add exact-archive-verified ICU files to the runtime tree. */
|
|
65
72
|
export declare function overlayIcuArchive(runtime: ExtractedArchive, icu: ExtractedArchive): void;
|
|
66
73
|
/** @internal Shared verification for separately carried WASIX tool modules. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { clusterSeedMount, decompressIfNeeded, extractTar, layoutRuntimeSupport, loadAsset, } from './archive.js';
|
|
2
|
-
import { WASIX_PHYSICAL_IDENTITY } from '
|
|
2
|
+
import { WASIX_PHYSICAL_IDENTITY } from '../storage/database-root.js';
|
|
3
3
|
const decoder = new TextDecoder('utf-8', { fatal: true });
|
|
4
4
|
const SQL_NAME = /^[a-z0-9][a-z0-9_-]*$/;
|
|
5
5
|
const SHA256 = /^[a-f0-9]{64}$/;
|
|
@@ -13,45 +13,23 @@ const SHARED_PRELOAD_LIBRARIES = 'shared_preload_libraries';
|
|
|
13
13
|
export async function prepareWasixRuntime(options) {
|
|
14
14
|
const descriptor = options.runtime;
|
|
15
15
|
const profile = options.icu === undefined ? 'standard' : 'icu';
|
|
16
|
-
const
|
|
17
|
-
const seedManifestDescriptor = options.icu?.clusterSeedManifest ?? descriptor.standardSeedManifest;
|
|
18
|
-
const prefetchedSeedAssets = options.storage.kind === 'memory'
|
|
19
|
-
? loadClusterSeedAssets(profile, seedArchiveDescriptor, seedManifestDescriptor)
|
|
20
|
-
: undefined;
|
|
21
|
-
// Memory storage is always new, so overlap its required seed download with
|
|
22
|
-
// the runtime closure. Persistent providers must inspect storage first.
|
|
23
|
-
void prefetchedSeedAssets?.catch(() => undefined);
|
|
24
|
-
const [manifestBytes, runtimeBytes, icuDataBytes] = await Promise.all([
|
|
16
|
+
const [manifestBytes, runtimeBytes, icuData] = await Promise.all([
|
|
25
17
|
loadAsset(descriptor.manifest.source, 'WASIX asset manifest'),
|
|
26
18
|
loadAsset(descriptor.runtimeArchive.source, 'WASIX runtime archive'),
|
|
27
|
-
options.icu === undefined
|
|
28
|
-
? Promise.resolve(undefined)
|
|
29
|
-
: loadAsset(options.icu.dataArchive.source, 'WASIX ICU data archive'),
|
|
19
|
+
options.icu === undefined ? Promise.resolve(undefined) : loadIcuData(options.icu),
|
|
30
20
|
]);
|
|
31
21
|
await Promise.all([
|
|
32
22
|
assertDeclaredAssetBytes(manifestBytes, descriptor.manifest.size, descriptor.manifest.sha256, 'WASIX asset manifest'),
|
|
33
23
|
assertDeclaredAssetBytes(runtimeBytes, descriptor.runtimeArchive.size, descriptor.runtimeArchive.sha256, 'WASIX runtime archive'),
|
|
34
|
-
...(options.icu === undefined || icuDataBytes === undefined
|
|
35
|
-
? []
|
|
36
|
-
: [
|
|
37
|
-
assertDeclaredAssetBytes(icuDataBytes, options.icu.dataArchive.size, options.icu.dataArchive.sha256, 'WASIX ICU data archive'),
|
|
38
|
-
]),
|
|
39
24
|
]);
|
|
40
25
|
const manifest = parseWasixAssetManifest(manifestBytes);
|
|
41
26
|
assertRuntimeDescriptorMatchesManifest(descriptor, manifest);
|
|
42
|
-
const selectedSeed = manifest['cluster-seeds'][profile];
|
|
43
|
-
assertRuntimeArchiveMatchesManifest(seedArchiveDescriptor, selectedSeed, `WASIX ${profile} cluster seed archive`);
|
|
44
|
-
if (options.icu !== undefined) {
|
|
45
|
-
assertIcuDescriptorMatchesRuntime(options.runtime, options.icu, manifest);
|
|
46
|
-
}
|
|
47
|
-
const eagerClusterSeed = prefetchedSeedAssets === undefined
|
|
48
|
-
? undefined
|
|
49
|
-
: loadClusterSeed(options, manifest, selectedSeed, profile, seedArchiveDescriptor, seedManifestDescriptor, prefetchedSeedAssets);
|
|
50
|
-
void eagerClusterSeed?.catch(() => undefined);
|
|
51
27
|
const runtime = extractTar(decompressIfNeeded(runtimeBytes));
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
|
|
28
|
+
if (icuData !== undefined) {
|
|
29
|
+
overlayIcuArchive(runtime, {
|
|
30
|
+
files: new Map([['share/icu/icudt76l.dat', icuData.data]]),
|
|
31
|
+
directories: new Set(['share', 'share/icu']),
|
|
32
|
+
});
|
|
55
33
|
}
|
|
56
34
|
const layout = layoutRuntimeSupport(runtime);
|
|
57
35
|
assertExtensionCarriersCompatible(descriptor, manifest, options.extensionCarriers);
|
|
@@ -79,7 +57,11 @@ export async function prepareWasixRuntime(options) {
|
|
|
79
57
|
}
|
|
80
58
|
return {
|
|
81
59
|
layout,
|
|
82
|
-
|
|
60
|
+
...(options.seed === undefined
|
|
61
|
+
? {}
|
|
62
|
+
: {
|
|
63
|
+
loadClusterSeed: lazyClusterSeedLoader(options, manifest, profile, icuData?.treeSha256),
|
|
64
|
+
}),
|
|
83
65
|
moduleSha256: manifest.runtime['module-sha256'],
|
|
84
66
|
catalogProfile: profile,
|
|
85
67
|
icuEnabled: options.icu !== undefined,
|
|
@@ -87,48 +69,70 @@ export async function prepareWasixRuntime(options) {
|
|
|
87
69
|
physicalIdentity: WASIX_PHYSICAL_IDENTITY,
|
|
88
70
|
};
|
|
89
71
|
}
|
|
90
|
-
function lazyClusterSeedLoader(options,
|
|
91
|
-
let cached
|
|
92
|
-
const forgetRejectedAttempt = (attempt) => {
|
|
93
|
-
void attempt.catch(() => {
|
|
94
|
-
if (cached === attempt)
|
|
95
|
-
cached = undefined;
|
|
96
|
-
});
|
|
97
|
-
};
|
|
98
|
-
if (cached !== undefined)
|
|
99
|
-
forgetRejectedAttempt(cached);
|
|
72
|
+
function lazyClusterSeedLoader(options, runtime, profile, icuTree) {
|
|
73
|
+
let cached;
|
|
100
74
|
return () => {
|
|
101
75
|
if (cached === undefined) {
|
|
102
|
-
|
|
103
|
-
cached
|
|
104
|
-
|
|
76
|
+
cached = loadClusterSeed(options, runtime, profile, icuTree);
|
|
77
|
+
void cached.catch(() => {
|
|
78
|
+
cached = undefined;
|
|
79
|
+
});
|
|
105
80
|
}
|
|
106
81
|
return cached;
|
|
107
82
|
};
|
|
108
83
|
}
|
|
109
|
-
function
|
|
110
|
-
|
|
111
|
-
loadAsset(
|
|
112
|
-
loadAsset(
|
|
84
|
+
export async function loadSeedBytes(seed) {
|
|
85
|
+
const [archive, manifest] = await Promise.all([
|
|
86
|
+
loadAsset(seed.archive, 'WASIX seed archive'),
|
|
87
|
+
loadAsset(seed.manifest, 'WASIX seed manifest'),
|
|
113
88
|
]);
|
|
89
|
+
return { archive, manifest };
|
|
114
90
|
}
|
|
115
|
-
async function
|
|
116
|
-
const [
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
assertDeclaredAssetBytes(archiveBytes, archiveDescriptor.size, archiveDescriptor.sha256, `WASIX ${profile} cluster seed`),
|
|
120
|
-
assertDeclaredAssetBytes(manifestBytes, manifestDescriptor.size, manifestDescriptor.sha256, `WASIX ${profile} cluster seed manifest`),
|
|
91
|
+
export async function loadIcuData(icu) {
|
|
92
|
+
const [data, manifest] = await Promise.all([
|
|
93
|
+
loadAsset(icu.data, 'ICU data'),
|
|
94
|
+
loadAsset(icu.manifest, 'ICU manifest'),
|
|
121
95
|
]);
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
96
|
+
const fields = new Map();
|
|
97
|
+
for (const line of decodeUtf8(manifest).split(/\r?\n/)) {
|
|
98
|
+
if (!line.trim() || line.startsWith('#'))
|
|
99
|
+
continue;
|
|
100
|
+
const at = line.indexOf('=');
|
|
101
|
+
if (at <= 0 || fields.has(line.slice(0, at)))
|
|
102
|
+
throw new Error('invalid ICU manifest');
|
|
103
|
+
fields.set(line.slice(0, at), line.slice(at + 1));
|
|
104
|
+
}
|
|
105
|
+
if (fields.get('schema') !== 'oliphaunt-icu-data-v1' ||
|
|
106
|
+
fields.get('artifactRole') !== 'icu-data' ||
|
|
107
|
+
fields.get('icuDataVersion') !== '76.1' ||
|
|
108
|
+
fields.get('icuDataForm') !== 'files-le') {
|
|
109
|
+
throw new Error('incompatible ICU data manifest');
|
|
110
|
+
}
|
|
111
|
+
const treeSha256 = requireSha256(fields.get('icuDataTreeSha256'), 'ICU logical tree');
|
|
112
|
+
const prefix = new TextEncoder().encode('icudt76l.dat\0' + data.length + '\0');
|
|
113
|
+
const tree = new Uint8Array(prefix.length + data.length + 1);
|
|
114
|
+
tree.set(prefix);
|
|
115
|
+
tree.set(data, prefix.length);
|
|
116
|
+
tree[tree.length - 1] = 10;
|
|
117
|
+
await assertSha256(tree, treeSha256, 'ICU data tree');
|
|
118
|
+
return { data, manifest, treeSha256 };
|
|
119
|
+
}
|
|
120
|
+
async function loadClusterSeed(options, runtime, profile, icuTree) {
|
|
121
|
+
if (options.seed === undefined)
|
|
122
|
+
throw new Error('new browser storage requires an explicit seed');
|
|
123
|
+
const { archive, manifest } = await loadSeedBytes(options.seed);
|
|
124
|
+
const seed = parseClusterSeedManifest(manifest, profile);
|
|
125
|
+
verifyClusterSeedIdentity(options, runtime, seed, icuTree);
|
|
126
|
+
await assertDeclaredAssetBytes(archive, seed.archive.compressedBytes, seed.archive.sha256, 'WASIX seed');
|
|
127
|
+
const unpacked = extractTar(decompressIfNeeded(archive));
|
|
128
|
+
verifyPostgresIdentity(runtime, seed.runtime.postgresMajor, unpacked.files.get('PG_VERSION'));
|
|
129
|
+
if (!unpacked.files.has('global/pg_control'))
|
|
130
|
+
throw new Error('WASIX seed is missing global/pg_control');
|
|
131
|
+
return clusterSeedMount(unpacked);
|
|
127
132
|
}
|
|
128
133
|
/** Require the package-authored archive identities to match the canonical manifest. */
|
|
129
134
|
export function assertRuntimeDescriptorMatchesManifest(descriptor, manifest) {
|
|
130
135
|
assertToolRuntimeDescriptorMatchesManifest(descriptor, manifest);
|
|
131
|
-
assertRuntimeArchiveMatchesManifest(descriptor.standardSeedArchive, manifest['cluster-seeds'].standard, 'WASIX standard cluster seed archive');
|
|
132
136
|
}
|
|
133
137
|
/** Verify only the runtime assets consumed by PostgreSQL frontend tools. */
|
|
134
138
|
export function assertToolRuntimeDescriptorMatchesManifest(descriptor, manifest) {
|
|
@@ -172,33 +176,6 @@ export function parseWasixAssetManifest(bytes) {
|
|
|
172
176
|
requireString(entry.name, `WASIX runtime export ${index} name`);
|
|
173
177
|
requireString(entry.kind, `WASIX runtime export ${index} kind`);
|
|
174
178
|
}
|
|
175
|
-
const seeds = requireObject(manifest['cluster-seeds'], 'WASIX asset manifest cluster-seeds');
|
|
176
|
-
requireExactKeys(seeds, ['icu', 'standard'], 'WASIX asset manifest cluster-seeds');
|
|
177
|
-
for (const profile of ['standard', 'icu']) {
|
|
178
|
-
const seed = requireObject(seeds[profile], `WASIX ${profile} cluster seed`);
|
|
179
|
-
const expectedRole = profile === 'standard' ? 'cluster-seed-standard' : 'cluster-seed-icu';
|
|
180
|
-
if (seed['catalog-profile'] !== profile || seed['artifact-role'] !== expectedRole) {
|
|
181
|
-
throw new Error(`WASIX ${profile} cluster seed has a mismatched profile or artifact role`);
|
|
182
|
-
}
|
|
183
|
-
requireAssetPath(seed.archive, `WASIX ${profile} cluster seed archive`);
|
|
184
|
-
requireAssetPath(seed.manifest, `WASIX ${profile} cluster seed manifest`);
|
|
185
|
-
requireSha256(seed.sha256, `WASIX ${profile} cluster seed archive`);
|
|
186
|
-
requireSafeInteger(seed.size, `WASIX ${profile} cluster seed archive size`);
|
|
187
|
-
requireSha256(seed['runtime-module-sha256'], `WASIX ${profile} seed runtime module`);
|
|
188
|
-
requireString(seed['postgres-version'], `WASIX ${profile} seed PostgreSQL version`);
|
|
189
|
-
requireString(seed['source-fingerprint'], `WASIX ${profile} seed source fingerprint`);
|
|
190
|
-
if (seed['physical-format'] !== 'wasix-pg18-v1' ||
|
|
191
|
-
seed['compatibility-key'] !== 'wasix-pg18-datum32-v1') {
|
|
192
|
-
throw new Error(`WASIX ${profile} cluster seed has an incompatible physical identity`);
|
|
193
|
-
}
|
|
194
|
-
if (profile === 'icu') {
|
|
195
|
-
requireSha256(seed['icu-data-tree-sha256'], 'WASIX ICU seed data tree');
|
|
196
|
-
}
|
|
197
|
-
else if (seed['icu-data-tree-sha256'] !== undefined) {
|
|
198
|
-
throw new Error('WASIX standard cluster seed must not identify ICU data');
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
requireString(manifest['source-fingerprint'], 'WASIX asset source fingerprint');
|
|
202
179
|
const runtimeSupport = requireArray(manifest['runtime-support'], 'WASIX runtime-support entries');
|
|
203
180
|
for (const [index, value] of runtimeSupport.entries()) {
|
|
204
181
|
const support = requireObject(value, `WASIX runtime-support entry ${index}`);
|
|
@@ -402,19 +379,18 @@ function parseClusterSeedManifest(bytes, expectedProfile) {
|
|
|
402
379
|
'catalogProfile',
|
|
403
380
|
'extensions',
|
|
404
381
|
'icu',
|
|
405
|
-
'initProfile',
|
|
406
382
|
'requiredRuntimeFeatures',
|
|
407
383
|
'runtime',
|
|
408
384
|
'schema',
|
|
409
385
|
'source',
|
|
410
386
|
], label);
|
|
411
387
|
assertClusterSeedProfileContract(root, expectedProfile);
|
|
412
|
-
requireString(root.initProfile, `${label} init profile`);
|
|
413
388
|
const runtime = requireObject(root.runtime, `${label} runtime`);
|
|
414
389
|
requireExactKeys(runtime, [
|
|
415
390
|
'compatibilityKey',
|
|
416
391
|
'consumerSha256',
|
|
417
392
|
'engineFamily',
|
|
393
|
+
'target',
|
|
418
394
|
'initdbSha256',
|
|
419
395
|
'physicalFormat',
|
|
420
396
|
'postgresMajor',
|
|
@@ -436,8 +412,8 @@ function parseClusterSeedManifest(bytes, expectedProfile) {
|
|
|
436
412
|
requireSha256(runtime[field], `${label} runtime ${field}`);
|
|
437
413
|
}
|
|
438
414
|
const source = requireObject(root.source, `${label} source`);
|
|
439
|
-
requireExactKeys(source, ['
|
|
440
|
-
for (const field of ['
|
|
415
|
+
requireExactKeys(source, ['producer'], `${label} source`);
|
|
416
|
+
for (const field of ['producer']) {
|
|
441
417
|
requireString(source[field], `${label} source ${field}`);
|
|
442
418
|
}
|
|
443
419
|
const archive = requireObject(root.archive, `${label} archive`);
|
|
@@ -486,82 +462,32 @@ export function assertClusterSeedProfileContract(value, expectedProfile) {
|
|
|
486
462
|
throw new Error(`${label} must require exactly the ICU runtime feature`);
|
|
487
463
|
}
|
|
488
464
|
const icu = requireObject(root.icu, `${label} ICU identity`);
|
|
489
|
-
|
|
490
|
-
'artifactRole',
|
|
491
|
-
'dataForm',
|
|
492
|
-
'dataTreeSha256',
|
|
493
|
-
'dataVersion',
|
|
494
|
-
'sourceCommit',
|
|
495
|
-
'upstreamVersion',
|
|
496
|
-
], `${label} ICU identity`);
|
|
497
|
-
for (const field of [
|
|
498
|
-
'artifactRole',
|
|
499
|
-
'dataForm',
|
|
500
|
-
'dataVersion',
|
|
501
|
-
'sourceCommit',
|
|
502
|
-
'upstreamVersion',
|
|
503
|
-
]) {
|
|
465
|
+
for (const field of ['artifactRole', 'dataForm', 'dataVersion']) {
|
|
504
466
|
requireString(icu[field], `${label} ICU ${field}`);
|
|
505
467
|
}
|
|
506
468
|
requireSha256(icu.dataTreeSha256, `${label} ICU data tree`);
|
|
507
469
|
if (icu.artifactRole !== 'icu-data' ||
|
|
508
|
-
icu.upstreamVersion !== '76.1' ||
|
|
509
470
|
icu.dataVersion !== '76.1' ||
|
|
510
471
|
icu.dataForm !== 'files-le') {
|
|
511
472
|
throw new Error(`${label} has an incompatible ICU identity`);
|
|
512
473
|
}
|
|
513
474
|
}
|
|
514
|
-
|
|
515
|
-
export function assertIcuDescriptorMatchesRuntime(runtime, icu, manifest) {
|
|
516
|
-
if (icu.compatibility.runtimeProduct !== runtime.product ||
|
|
517
|
-
icu.compatibility.runtimeVersion !== runtime.version) {
|
|
518
|
-
throw new Error(`WASIX ICU carrier targets ${icu.compatibility.runtimeProduct}@${icu.compatibility.runtimeVersion}, not ${runtime.product}@${runtime.version}`);
|
|
519
|
-
}
|
|
520
|
-
if (icu.compatibility.dataTreeSha256 !== manifest['cluster-seeds'].icu['icu-data-tree-sha256']) {
|
|
521
|
-
throw new Error('WASIX ICU data and ICU cluster seed identify different logical data trees');
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
function verifyClusterSeedIdentity(options, outer, selected, seed, archive) {
|
|
525
|
-
const profile = seed.catalogProfile;
|
|
475
|
+
function verifyClusterSeedIdentity(options, outer, seed, icuTree) {
|
|
526
476
|
if (seed.runtime.product !== options.runtime.product ||
|
|
527
477
|
seed.runtime.version !== options.runtime.version ||
|
|
528
478
|
seed.runtime.engineFamily !== 'wasix' ||
|
|
479
|
+
seed.runtime.target !== 'portable' ||
|
|
529
480
|
seed.runtime.physicalFormat !== 'wasix-pg18-v1' ||
|
|
530
481
|
seed.runtime.compatibilityKey !== 'wasix-pg18-datum32-v1' ||
|
|
531
|
-
seed.runtime.postgresMajor !== 18
|
|
532
|
-
|
|
533
|
-
|
|
482
|
+
seed.runtime.postgresMajor !== 18 ||
|
|
483
|
+
seed.source.producer !== 'wasix-initdb')
|
|
484
|
+
throw new Error('WASIX seed has an incompatible runtime identity');
|
|
534
485
|
if (seed.runtime.consumerSha256 !== seed.runtime.producerSha256 ||
|
|
535
|
-
seed.runtime.consumerSha256 !== outer.runtime['module-sha256']
|
|
536
|
-
seed
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
seed.source.fingerprint !== selected['source-fingerprint']) {
|
|
541
|
-
throw new Error(`WASIX ${profile} cluster seed has a different source fingerprint`);
|
|
542
|
-
}
|
|
543
|
-
if (seed.archive.path !== archive.archive ||
|
|
544
|
-
seed.archive.path !== selected.archive ||
|
|
545
|
-
seed.archive.sha256 !== archive.sha256 ||
|
|
546
|
-
seed.archive.sha256 !== selected.sha256 ||
|
|
547
|
-
seed.archive.compressedBytes !== archive.size ||
|
|
548
|
-
seed.archive.compressedBytes !== selected.size) {
|
|
549
|
-
throw new Error(`WASIX ${profile} cluster seed archive identity is inconsistent`);
|
|
550
|
-
}
|
|
551
|
-
if (seed.archive.path !== `cluster-seeds/${profile}.tar.zst`) {
|
|
552
|
-
throw new Error(`WASIX ${profile} cluster seed has a non-canonical archive path`);
|
|
553
|
-
}
|
|
554
|
-
if (profile === 'icu') {
|
|
555
|
-
const icu = options.icu;
|
|
556
|
-
if (icu === undefined ||
|
|
557
|
-
seed.icu === null ||
|
|
558
|
-
seed.icu.artifactRole !== 'icu-data' ||
|
|
559
|
-
seed.icu.upstreamVersion !== icu.compatibility.dataVersion ||
|
|
560
|
-
seed.icu.dataVersion !== icu.compatibility.dataVersion ||
|
|
561
|
-
seed.icu.dataForm !== icu.compatibility.dataForm ||
|
|
562
|
-
seed.icu.dataTreeSha256 !== icu.compatibility.dataTreeSha256) {
|
|
563
|
-
throw new Error('WASIX ICU cluster seed does not match the selected ICU data carrier');
|
|
564
|
-
}
|
|
486
|
+
seed.runtime.consumerSha256 !== outer.runtime['module-sha256']) {
|
|
487
|
+
throw new Error('WASIX seed was produced by a different runtime module');
|
|
488
|
+
}
|
|
489
|
+
if (seed.catalogProfile === 'icu' && seed.icu?.dataTreeSha256 !== icuTree) {
|
|
490
|
+
throw new Error('WASIX ICU seed does not match the selected ICU data');
|
|
565
491
|
}
|
|
566
492
|
}
|
|
567
493
|
/** @internal Validate and add exact-archive-verified ICU files to the runtime tree. */
|
|
@@ -620,14 +546,13 @@ async function assertDeclaredAssetBytes(bytes, expectedSize, expectedSha256, lab
|
|
|
620
546
|
}
|
|
621
547
|
await assertSha256(bytes, expectedSha256, label);
|
|
622
548
|
}
|
|
623
|
-
function verifyPostgresIdentity(manifest,
|
|
549
|
+
function verifyPostgresIdentity(manifest, seedMajor, pgVersionBytes) {
|
|
624
550
|
if (pgVersionBytes === undefined) {
|
|
625
551
|
throw new Error('WASIX cluster seed is missing PG_VERSION');
|
|
626
552
|
}
|
|
627
553
|
const pgVersion = decodeUtf8(pgVersionBytes).trim();
|
|
628
554
|
const runtimeMajor = manifest.runtime['postgres-version'].split('.')[0];
|
|
629
|
-
|
|
630
|
-
if (pgVersion !== runtimeMajor || pgVersion !== seedMajor) {
|
|
555
|
+
if (pgVersion !== runtimeMajor || pgVersion !== String(seedMajor)) {
|
|
631
556
|
throw new Error(`WASIX runtime/cluster seed PostgreSQL major mismatch: runtime ${runtimeMajor}, seed ${seedMajor}, PG_VERSION ${pgVersion}`);
|
|
632
557
|
}
|
|
633
558
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { requireAssetSource, requireExactObject, serializeAssetSource, } from './descriptor-validation.js';
|
|
2
|
+
function source(value, label) {
|
|
3
|
+
const size = value instanceof Uint8Array || value instanceof ArrayBuffer ? value.byteLength : 0;
|
|
4
|
+
return serializeAssetSource(requireAssetSource(value, label, size));
|
|
5
|
+
}
|
|
6
|
+
export function serializeWasixIcuDescriptor(value) {
|
|
7
|
+
const data = requireExactObject(value, ['data', 'manifest'], 'ICU data');
|
|
8
|
+
return { data: source(data.data, 'ICU data'), manifest: source(data.manifest, 'ICU manifest') };
|
|
9
|
+
}
|
|
10
|
+
export function serializeWasixSeed(value) {
|
|
11
|
+
const seed = requireExactObject(value, ['archive', 'manifest'], 'WASIX seed');
|
|
12
|
+
return {
|
|
13
|
+
archive: source(seed.archive, 'seed archive'),
|
|
14
|
+
manifest: source(seed.manifest, 'seed manifest'),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { SerializedRuntimeDescriptor } from '
|
|
1
|
+
import type { SerializedRuntimeDescriptor } from '../workers/rpc.js';
|
|
2
2
|
/** Validate an imported runtime carrier before any bytes cross the worker boundary. */
|
|
3
3
|
export declare function serializeWasixRuntimeDescriptor(value: unknown): SerializedRuntimeDescriptor;
|
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
import { requireAssetSource, requireExactObject, requireSafeRelativeAssetPath, requireSha256, requireSize, requireVersion, serializeAssetSource, } from './descriptor-validation.js';
|
|
2
|
-
const DESCRIPTOR_FIELDS = [
|
|
3
|
-
'manifest',
|
|
4
|
-
'product',
|
|
5
|
-
'runtime',
|
|
6
|
-
'runtimeArchive',
|
|
7
|
-
'schema',
|
|
8
|
-
'standardSeedArchive',
|
|
9
|
-
'standardSeedManifest',
|
|
10
|
-
'version',
|
|
11
|
-
];
|
|
2
|
+
const DESCRIPTOR_FIELDS = ['manifest', 'product', 'runtime', 'runtimeArchive', 'schema', 'version'];
|
|
12
3
|
const ARCHIVE_FIELDS = ['archive', 'sha256', 'size', 'source'];
|
|
13
4
|
const MANIFEST_FIELDS = ['sha256', 'size', 'source'];
|
|
14
5
|
/** Validate an imported runtime carrier before any bytes cross the worker boundary. */
|
|
@@ -20,8 +11,6 @@ export function serializeWasixRuntimeDescriptor(value) {
|
|
|
20
11
|
product: value.product,
|
|
21
12
|
version: value.version,
|
|
22
13
|
runtimeArchive: serializeArchive(value.runtimeArchive),
|
|
23
|
-
standardSeedArchive: serializeArchive(value.standardSeedArchive),
|
|
24
|
-
standardSeedManifest: serializeManifest(value.standardSeedManifest),
|
|
25
14
|
manifest: {
|
|
26
15
|
sha256: value.manifest.sha256,
|
|
27
16
|
size: value.manifest.size,
|
|
@@ -42,12 +31,7 @@ function validateRuntimeDescriptor(value, label) {
|
|
|
42
31
|
}
|
|
43
32
|
requireVersion(descriptor.version, `${label} version`);
|
|
44
33
|
validateArchive(descriptor.runtimeArchive, `${label} runtime archive`);
|
|
45
|
-
validateArchive(descriptor.standardSeedArchive, `${label} standard cluster seed archive`);
|
|
46
|
-
validateManifest(descriptor.standardSeedManifest, `${label} standard cluster seed manifest`);
|
|
47
34
|
validateManifest(descriptor.manifest, `${label} manifest`);
|
|
48
|
-
if (descriptor.runtimeArchive.archive === descriptor.standardSeedArchive.archive) {
|
|
49
|
-
throw new Error(`${label} runtime and standard cluster seed archives must have distinct paths`);
|
|
50
|
-
}
|
|
51
35
|
}
|
|
52
36
|
function validateArchive(value, label) {
|
|
53
37
|
const archive = requireExactObject(value, ARCHIVE_FIELDS, label);
|
|
@@ -70,10 +54,3 @@ function serializeArchive(archive) {
|
|
|
70
54
|
source: serializeAssetSource(archive.source),
|
|
71
55
|
};
|
|
72
56
|
}
|
|
73
|
-
function serializeManifest(manifest) {
|
|
74
|
-
return {
|
|
75
|
-
sha256: manifest.sha256,
|
|
76
|
-
size: manifest.size,
|
|
77
|
-
source: serializeAssetSource(manifest.source),
|
|
78
|
-
};
|
|
79
|
-
}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import type { Directory, RunWasixOptions } from '
|
|
2
|
-
import type { SerializedAssetSource } from '
|
|
1
|
+
import type { Directory, RunWasixOptions } from '../host/index.mjs';
|
|
2
|
+
import type { SerializedAssetSource } from '../workers/rpc.js';
|
|
3
3
|
export type WasixToolDescriptor = Readonly<{
|
|
4
4
|
name: 'pg_dump' | 'psql';
|
|
5
5
|
sha256: string;
|
|
6
6
|
size: number;
|
|
7
7
|
source: SerializedAssetSource;
|
|
8
|
+
/** Selected native target carrier; browser execution only needs source. */
|
|
9
|
+
aot?: Readonly<{
|
|
10
|
+
source: SerializedAssetSource;
|
|
11
|
+
manifest: SerializedAssetSource;
|
|
12
|
+
}>;
|
|
8
13
|
}>;
|
|
9
14
|
export type WasixToolProcessOptions = Readonly<{
|
|
10
15
|
runtimeVersion: string;
|
|
@@ -12,6 +17,7 @@ export type WasixToolProcessOptions = Readonly<{
|
|
|
12
17
|
args: readonly string[];
|
|
13
18
|
/** @internal An exact ArrayBuffer-backed view is transferred and consumed. */
|
|
14
19
|
stdin?: Uint8Array;
|
|
20
|
+
command?: string;
|
|
15
21
|
}>;
|
|
16
22
|
export type WasixToolProcessResult = Readonly<{
|
|
17
23
|
exitCode: number;
|
package/lib/server.node.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { type OliphauntServer, openServer, type ServerListen, type ServerOpenConfig, } from './native-server.js';
|
|
1
|
+
export { type OliphauntServer, openServer, type ServerListen, type ServerOpenConfig, } from './hosts/node-api/native-server.js';
|
package/lib/server.node.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { openServer, } from './native-server.js';
|
|
1
|
+
export { openServer, } from './hosts/node-api/native-server.js';
|
|
@@ -3,6 +3,14 @@ export declare const DATABASE_ROOT_SCHEMA = "oliphaunt-database-root-v1";
|
|
|
3
3
|
export declare const DATABASE_ROOT_PGDATA = "pgdata";
|
|
4
4
|
export declare const DATABASE_ROOT_POSTGRES_MAJOR: 18;
|
|
5
5
|
export declare const WASIX_PHYSICAL_FORMAT: "wasix-pg18-v1";
|
|
6
|
+
/** Stable fields that determine whether a WASIX runtime may open stored PGDATA. */
|
|
7
|
+
export type WasixPhysicalIdentity = Readonly<{
|
|
8
|
+
schema: 'oliphaunt-physical-format-v1';
|
|
9
|
+
engineFamily: 'wasix';
|
|
10
|
+
postgresMajor: number;
|
|
11
|
+
physicalFormat: string;
|
|
12
|
+
}>;
|
|
13
|
+
export declare const WASIX_PHYSICAL_IDENTITY: WasixPhysicalIdentity;
|
|
6
14
|
export declare const NATIVE_PHYSICAL_FORMAT = "native-pg18-v1";
|
|
7
15
|
export type DatabaseRootDescriptor = Readonly<{
|
|
8
16
|
schema: typeof DATABASE_ROOT_SCHEMA;
|
|
@@ -4,6 +4,12 @@ export const DATABASE_ROOT_SCHEMA = 'oliphaunt-database-root-v1';
|
|
|
4
4
|
export const DATABASE_ROOT_PGDATA = 'pgdata';
|
|
5
5
|
export const DATABASE_ROOT_POSTGRES_MAJOR = CARRIER_POSTGRES_MAJOR;
|
|
6
6
|
export const WASIX_PHYSICAL_FORMAT = CARRIER_PHYSICAL_FORMAT;
|
|
7
|
+
export const WASIX_PHYSICAL_IDENTITY = Object.freeze({
|
|
8
|
+
schema: 'oliphaunt-physical-format-v1',
|
|
9
|
+
engineFamily: 'wasix',
|
|
10
|
+
postgresMajor: DATABASE_ROOT_POSTGRES_MAJOR,
|
|
11
|
+
physicalFormat: WASIX_PHYSICAL_FORMAT,
|
|
12
|
+
});
|
|
7
13
|
export const NATIVE_PHYSICAL_FORMAT = 'native-pg18-v1';
|
|
8
14
|
export function wasixDatabaseRootDescriptor() {
|
|
9
15
|
return {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { WasixStorageCommitState } from '../errors.js';
|
|
2
|
-
import type { WasixClusterSeedLoader, WasixStorageLease } from '
|
|
3
|
-
import { type StorageDelta, type StoredSnapshot } from '
|
|
1
|
+
import type { WasixStorageCommitState } from '../core/errors.js';
|
|
2
|
+
import type { WasixClusterSeedLoader, WasixStorageLease } from './storage-provider.js';
|
|
3
|
+
import { type StorageDelta, type StoredSnapshot } from './storage-snapshot.js';
|
|
4
4
|
export type ExclusiveStorageLock = {
|
|
5
5
|
release(): Promise<void>;
|
|
6
6
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { composeWasixStorageFailure, WasixStorageError } from '../errors.js';
|
|
2
|
-
import { applyStorageDeltaToEntries, snapshotStorageDelta, snapshotToMount, } from '
|
|
1
|
+
import { composeWasixStorageFailure, WasixStorageError } from '../core/errors.js';
|
|
2
|
+
import { applyStorageDeltaToEntries, snapshotStorageDelta, snapshotToMount, } from './storage-snapshot.js';
|
|
3
3
|
/**
|
|
4
4
|
* Shared lifecycle for browser stores backed by the Wasmer mutation journal.
|
|
5
5
|
* Providers own their atomicity and validation; this layer owns delta capture,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type WasixClusterSeedLoader, type WasixPhysicalIdentity, type WasixStorageLease } from '
|
|
2
|
-
import { type StorageDelta, type StoredSnapshot } from '
|
|
1
|
+
import { type WasixClusterSeedLoader, type WasixPhysicalIdentity, type WasixStorageLease } from './storage-provider.js';
|
|
2
|
+
import { type StorageDelta, type StoredSnapshot } from './storage-snapshot.js';
|
|
3
3
|
import { type ExclusiveStorageLock } from './incremental-storage.js';
|
|
4
4
|
type StoredMetadata = {
|
|
5
5
|
schema: 'oliphaunt-wasix-indexed-db-v1';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { WasixStorageError } from '../errors.js';
|
|
2
|
-
import { assertWasixPhysicalIdentity, physicalIdentityMatches, } from '
|
|
3
|
-
import { requireRecord, validateStoredSnapshot, } from '
|
|
1
|
+
import { WasixStorageError } from '../core/errors.js';
|
|
2
|
+
import { assertWasixPhysicalIdentity, physicalIdentityMatches, } from './storage-provider.js';
|
|
3
|
+
import { requireRecord, validateStoredSnapshot, } from './storage-snapshot.js';
|
|
4
4
|
import { acquireIncrementalStorage } from './incremental-storage.js';
|
|
5
5
|
import { releaseRestoreLock } from './restore-cleanup.js';
|
|
6
6
|
import { acquireExclusiveWebLock } from './web-lock.js';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { type PersistentWasixStorage } from '
|
|
1
|
+
import { type PersistentWasixStorage } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Select an origin-scoped persistent database.
|
|
4
4
|
*
|
|
5
5
|
* Every completed protocol operation commits only journaled PGDATA path
|
|
6
6
|
* changes in one atomic read-write IndexedDB transaction before its Promise resolves.
|
|
7
7
|
*/
|
|
8
|
-
export declare function indexedDB(name: string): PersistentWasixStorage
|
|
8
|
+
export declare function indexedDB(name: string): PersistentWasixStorage<'indexed-db'>;
|
|
9
9
|
export default indexedDB;
|
package/lib/storage/node.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type PersistentWasixStorage } from '
|
|
1
|
+
import { type PersistentWasixStorage } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Persist a managed database below a Node.js host directory.
|
|
4
4
|
*
|
|
@@ -6,5 +6,5 @@ import { type PersistentWasixStorage } from '../storage.js';
|
|
|
6
6
|
* and performs PostgreSQL-safe durable writes at each native operation
|
|
7
7
|
* boundary. Network and cross-host shared filesystems are unsupported.
|
|
8
8
|
*/
|
|
9
|
-
export declare function directory(path: string | URL): PersistentWasixStorage
|
|
9
|
+
export declare function directory(path: string | URL): PersistentWasixStorage<'directory'>;
|
|
10
10
|
export default directory;
|
package/lib/storage/node.js
CHANGED