@oliphaunt/wasix-ts 0.1.0 → 0.2.1

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.
Files changed (180) hide show
  1. package/ARCHITECTURE.md +55 -32
  2. package/CHANGELOG.md +38 -0
  3. package/README.md +19 -387
  4. package/THIRD_PARTY_NOTICES.md +5 -5
  5. package/lib/browser.d.ts +2 -0
  6. package/lib/browser.js +6 -0
  7. package/lib/{database.d.ts → core/database.d.ts} +4 -4
  8. package/lib/{database.js → core/database.js} +1 -1
  9. package/lib/core/open-config.d.ts +5 -0
  10. package/lib/core/open-config.js +28 -0
  11. package/lib/{public.d.ts → core/public.d.ts} +3 -3
  12. package/lib/{public.js → core/public.js} +2 -2
  13. package/lib/{types.d.ts → core/types.d.ts} +19 -43
  14. package/lib/direct.node.d.ts +2 -2
  15. package/lib/direct.node.js +2 -2
  16. package/lib/host/index.d.mts +1 -1
  17. package/lib/host/index.mjs +1 -1
  18. package/lib/host/provenance.json +1 -1
  19. package/lib/host/wasmer_js_bg.wasm +0 -0
  20. package/lib/hosts/browser/browser-public.d.ts +8 -0
  21. package/lib/hosts/browser/browser-public.js +1 -0
  22. package/lib/{client-common.d.ts → hosts/browser/client-common.d.ts} +3 -3
  23. package/lib/hosts/browser/client-common.js +17 -0
  24. package/lib/{client.d.ts → hosts/browser/client.d.ts} +1 -1
  25. package/lib/{client.js → hosts/browser/client.js} +5 -3
  26. package/lib/{direct-client-common.d.ts → hosts/browser/direct-client-common.d.ts} +9 -8
  27. package/lib/{direct-client-common.js → hosts/browser/direct-client-common.js} +17 -31
  28. package/lib/hosts/browser/initialize.d.ts +5 -0
  29. package/lib/hosts/browser/initialize.js +67 -0
  30. package/lib/{internal-common.d.ts → hosts/browser/internal-common.d.ts} +3 -3
  31. package/lib/{internal-common.js → hosts/browser/internal-common.js} +3 -3
  32. package/lib/{tool-worker-common.d.ts → hosts/browser/tool-worker-common.d.ts} +3 -3
  33. package/lib/{tool-worker-common.js → hosts/browser/tool-worker-common.js} +2 -2
  34. package/lib/{tool-worker.js → hosts/browser/tool-worker.js} +1 -1
  35. package/lib/{wasix-runtime.d.ts → hosts/browser/wasix-runtime.d.ts} +3 -3
  36. package/lib/{wasix-runtime.js → hosts/browser/wasix-runtime.js} +41 -25
  37. package/lib/{worker-client.d.ts → hosts/browser/worker-client.d.ts} +1 -1
  38. package/lib/{worker-client.js → hosts/browser/worker-client.js} +5 -4
  39. package/lib/{worker.js → hosts/browser/worker.js} +2 -2
  40. package/lib/{direct-client.d.ts → hosts/node-api/direct-client.d.ts} +1 -1
  41. package/lib/{direct-client.js → hosts/node-api/direct-client.js} +1 -1
  42. package/lib/{native-addon.d.ts → hosts/node-api/native-addon.d.ts} +28 -6
  43. package/lib/{native-addon.js → hosts/node-api/native-addon.js} +4 -5
  44. package/lib/hosts/node-api/native-public.d.ts +8 -0
  45. package/lib/hosts/node-api/native-public.js +1 -0
  46. package/lib/{native-server.d.ts → hosts/node-api/native-server.d.ts} +1 -1
  47. package/lib/{native-server.js → hosts/node-api/native-server.js} +3 -2
  48. package/lib/{native-session.d.ts → hosts/node-api/native-session.d.ts} +14 -4
  49. package/lib/{native-session.js → hosts/node-api/native-session.js} +93 -108
  50. package/lib/{node-actor.d.ts → hosts/node-api/node-actor.d.ts} +2 -2
  51. package/lib/{node-actor.js → hosts/node-api/node-actor.js} +1 -1
  52. package/lib/{node-client-common.d.ts → hosts/node-api/node-client-common.d.ts} +3 -3
  53. package/lib/{node-client-common.js → hosts/node-api/node-client-common.js} +4 -4
  54. package/lib/{node-client.d.ts → hosts/node-api/node-client.d.ts} +1 -1
  55. package/lib/{node-client.js → hosts/node-api/node-client.js} +1 -1
  56. package/lib/{node-direct.d.ts → hosts/node-api/node-direct.d.ts} +2 -2
  57. package/lib/{node-direct.js → hosts/node-api/node-direct.js} +1 -1
  58. package/lib/{node-worker-port.d.ts → hosts/node-api/node-worker-port.d.ts} +1 -1
  59. package/lib/{node-worker.js → hosts/node-api/node-worker.js} +1 -1
  60. package/lib/{worker-node-client.d.ts → hosts/node-api/worker-node-client.d.ts} +1 -1
  61. package/lib/{worker-node-client.js → hosts/node-api/worker-node-client.js} +5 -18
  62. package/lib/index.bun.d.ts +2 -2
  63. package/lib/index.bun.js +2 -2
  64. package/lib/index.d.ts +2 -2
  65. package/lib/index.deno.d.ts +2 -2
  66. package/lib/index.deno.js +2 -2
  67. package/lib/index.js +2 -2
  68. package/lib/index.node.d.ts +2 -2
  69. package/lib/index.node.js +2 -2
  70. package/lib/internal.d.ts +4 -4
  71. package/lib/internal.js +24 -4
  72. package/lib/internal.node.d.ts +4 -4
  73. package/lib/internal.node.js +2 -2
  74. package/lib/native-only.d.ts +1 -0
  75. package/lib/native-only.js +2 -0
  76. package/lib/protocol/protocol.d.ts +1 -0
  77. package/lib/protocol/protocol.js +1 -0
  78. package/lib/protocol/query.d.ts +1 -0
  79. package/lib/protocol/query.js +1 -0
  80. package/lib/{archive.d.ts → resources/archive.d.ts} +1 -1
  81. package/lib/{descriptor-validation.d.ts → resources/descriptor-validation.d.ts} +2 -2
  82. package/lib/{descriptor-validation.js → resources/descriptor-validation.js} +1 -1
  83. package/lib/{extension-descriptor.d.ts → resources/extension-descriptor.d.ts} +2 -2
  84. package/lib/{extensions.d.ts → resources/extensions.d.ts} +13 -6
  85. package/lib/{extensions.js → resources/extensions.js} +80 -155
  86. package/lib/resources/icu-descriptor.d.ts +3 -0
  87. package/lib/resources/icu-descriptor.js +16 -0
  88. package/lib/{runtime-descriptor.d.ts → resources/runtime-descriptor.d.ts} +1 -1
  89. package/lib/{runtime-descriptor.js → resources/runtime-descriptor.js} +1 -24
  90. package/lib/{tool-runtime.d.ts → resources/tool-runtime.d.ts} +8 -2
  91. package/lib/server.node.d.ts +1 -1
  92. package/lib/server.node.js +1 -1
  93. package/lib/{database-root.d.ts → storage/database-root.d.ts} +8 -0
  94. package/lib/{database-root.js → storage/database-root.js} +6 -0
  95. package/lib/storage/incremental-storage.d.ts +3 -3
  96. package/lib/storage/incremental-storage.js +2 -2
  97. package/lib/storage/indexed-db-provider.d.ts +2 -2
  98. package/lib/storage/indexed-db-provider.js +3 -3
  99. package/lib/storage/indexed-db.d.ts +2 -2
  100. package/lib/storage/indexed-db.js +1 -1
  101. package/lib/storage/node.d.ts +2 -2
  102. package/lib/storage/node.js +1 -1
  103. package/lib/storage/opfs-pool.d.ts +2 -2
  104. package/lib/storage/opfs-pool.js +4 -4
  105. package/lib/storage/opfs-provider.d.ts +2 -2
  106. package/lib/storage/opfs-provider.js +1 -1
  107. package/lib/storage/opfs.d.ts +2 -2
  108. package/lib/storage/opfs.js +1 -1
  109. package/lib/{physical-archive.js → storage/physical-archive.js} +4 -4
  110. package/lib/storage/restore-cleanup.d.ts +1 -1
  111. package/lib/storage/restore-cleanup.js +1 -1
  112. package/lib/{storage-provider.d.ts → storage/storage-provider.d.ts} +5 -11
  113. package/lib/{storage-provider.js → storage/storage-provider.js} +8 -13
  114. package/lib/{storage-snapshot.d.ts → storage/storage-snapshot.d.ts} +2 -2
  115. package/lib/{storage.d.ts → storage/types.d.ts} +8 -7
  116. package/lib/storage/web-lock.js +1 -1
  117. package/lib/worker-entry.bun.d.ts +2 -2
  118. package/lib/worker-entry.bun.js +2 -2
  119. package/lib/worker-entry.d.ts +2 -2
  120. package/lib/worker-entry.deno.d.ts +2 -2
  121. package/lib/worker-entry.deno.js +2 -2
  122. package/lib/worker-entry.js +2 -2
  123. package/lib/worker-entry.node.d.ts +2 -2
  124. package/lib/worker-entry.node.js +2 -2
  125. package/lib/{rpc.d.ts → workers/rpc.d.ts} +14 -34
  126. package/lib/{rpc.js → workers/rpc.js} +4 -4
  127. package/lib/{worker-dispatch.d.ts → workers/worker-dispatch.d.ts} +1 -1
  128. package/lib/{worker-dispatch.js → workers/worker-dispatch.js} +2 -2
  129. package/lib/{worker-rpc.d.ts → workers/worker-rpc.d.ts} +3 -3
  130. package/lib/{worker-rpc.js → workers/worker-rpc.js} +8 -12
  131. package/package.json +66 -30
  132. package/lib/client-common.js +0 -36
  133. package/lib/icu-descriptor.d.ts +0 -3
  134. package/lib/icu-descriptor.js +0 -92
  135. package/lib/protocol.d.ts +0 -1
  136. package/lib/protocol.js +0 -1
  137. package/lib/query.d.ts +0 -1
  138. package/lib/query.js +0 -1
  139. package/node_modules/@oliphaunt/js-core/README.md +0 -7
  140. package/node_modules/@oliphaunt/js-core/dist/commonjs/protocol.d.ts +0 -1
  141. package/node_modules/@oliphaunt/js-core/dist/commonjs/protocol.js +0 -22
  142. package/node_modules/@oliphaunt/js-core/dist/commonjs/query.d.ts +0 -255
  143. package/node_modules/@oliphaunt/js-core/dist/commonjs/query.js +0 -2068
  144. package/node_modules/@oliphaunt/js-core/dist/module/package.json +0 -3
  145. package/node_modules/@oliphaunt/js-core/dist/module/protocol.d.ts +0 -1
  146. package/node_modules/@oliphaunt/js-core/dist/module/protocol.js +0 -19
  147. package/node_modules/@oliphaunt/js-core/dist/module/query.d.ts +0 -255
  148. package/node_modules/@oliphaunt/js-core/dist/module/query.js +0 -2039
  149. package/node_modules/@oliphaunt/js-core/package.json +0 -21
  150. /package/lib/{errors.d.ts → core/errors.d.ts} +0 -0
  151. /package/lib/{errors.js → core/errors.js} +0 -0
  152. /package/lib/{startup-config.d.ts → core/startup-config.d.ts} +0 -0
  153. /package/lib/{startup-config.js → core/startup-config.js} +0 -0
  154. /package/lib/{types.js → core/types.js} +0 -0
  155. /package/lib/{tool-worker.d.ts → hosts/browser/tool-worker.d.ts} +0 -0
  156. /package/lib/{worker.d.ts → hosts/browser/worker.d.ts} +0 -0
  157. /package/lib/{host-runtime.d.ts → hosts/node-api/host-runtime.d.ts} +0 -0
  158. /package/lib/{host-runtime.js → hosts/node-api/host-runtime.js} +0 -0
  159. /package/lib/{node-worker-options.d.ts → hosts/node-api/node-worker-options.d.ts} +0 -0
  160. /package/lib/{node-worker-options.js → hosts/node-api/node-worker-options.js} +0 -0
  161. /package/lib/{node-worker-port.js → hosts/node-api/node-worker-port.js} +0 -0
  162. /package/lib/{node-worker.d.ts → hosts/node-api/node-worker.d.ts} +0 -0
  163. /package/lib/{byte-channel.d.ts → protocol/byte-channel.d.ts} +0 -0
  164. /package/lib/{byte-channel.js → protocol/byte-channel.js} +0 -0
  165. /package/lib/{pgwire-connection.d.ts → protocol/pgwire-connection.d.ts} +0 -0
  166. /package/lib/{pgwire-connection.js → protocol/pgwire-connection.js} +0 -0
  167. /package/lib/{pgwire.d.ts → protocol/pgwire.d.ts} +0 -0
  168. /package/lib/{pgwire.js → protocol/pgwire.js} +0 -0
  169. /package/lib/{archive.js → resources/archive.js} +0 -0
  170. /package/lib/{asset-source.d.ts → resources/asset-source.d.ts} +0 -0
  171. /package/lib/{asset-source.js → resources/asset-source.js} +0 -0
  172. /package/lib/{extension-descriptor.js → resources/extension-descriptor.js} +0 -0
  173. /package/lib/{tool-runtime.js → resources/tool-runtime.js} +0 -0
  174. /package/lib/{zstd.d.ts → resources/zstd.d.ts} +0 -0
  175. /package/lib/{zstd.js → resources/zstd.js} +0 -0
  176. /package/lib/{physical-archive.d.ts → storage/physical-archive.d.ts} +0 -0
  177. /package/lib/{storage-snapshot.js → storage/storage-snapshot.js} +0 -0
  178. /package/lib/{storage.js → storage/types.js} +0 -0
  179. /package/lib/{worker-transfer.d.ts → workers/worker-transfer.d.ts} +0 -0
  180. /package/lib/{worker-transfer.js → workers/worker-transfer.js} +0 -0
@@ -1,14 +1,15 @@
1
- import { WasixDatabaseImpl, createWasixDeferred, normalizeWasixDatabaseIdentity, } from './database.js';
2
- import { WasixStorageError } from './errors.js';
3
- import { prepareWasixRuntime } from './extensions.js';
4
- import { assertSuccessfulStartupResponse, startupPacket } from './pgwire.js';
5
- import { BackupModeExitUnconfirmedError, createPhysicalArchive } from './physical-archive.js';
6
- import { simpleQuery } from './protocol.js';
7
- import { assertSuccessfulQueryResponse, PostgresError } from './query.js';
8
- import { acquireWasixStorage, canonicalJson, } from './storage-provider.js';
9
- import { serveWasixProtocolConnection, SynchronousPgDumpConnection, } from './pgwire-connection.js';
10
- import { materializeWasixToolMounts, prepareWasixToolAsset, releaseWasixToolMounts, validateWasixToolDescriptor, wasixToolAssetIdentity, wasixToolRunOptions, } from './tool-runtime.js';
11
- import { normalizeWasixStartupGUCs } from './startup-config.js';
1
+ import { initializeWasixStorage } from './initialize.js';
2
+ import { WasixDatabaseImpl, createWasixDeferred, normalizeWasixDatabaseIdentity, } from '../../core/database.js';
3
+ import { WasixStorageError } from '../../core/errors.js';
4
+ import { prepareWasixRuntime } from '../../resources/extensions.js';
5
+ import { assertSuccessfulStartupResponse, startupPacket } from '../../protocol/pgwire.js';
6
+ import { BackupModeExitUnconfirmedError, createPhysicalArchive, } from '../../storage/physical-archive.js';
7
+ import { simpleQuery } from '../../protocol/protocol.js';
8
+ import { assertSuccessfulQueryResponse, PostgresError } from '../../protocol/query.js';
9
+ import { acquireWasixStorage, canonicalJson, } from '../../storage/storage-provider.js';
10
+ import { serveWasixProtocolConnection, SynchronousPgDumpConnection, } from '../../protocol/pgwire-connection.js';
11
+ import { materializeWasixToolMounts, prepareWasixToolAsset, releaseWasixToolMounts, validateWasixToolDescriptor, wasixToolAssetIdentity, wasixToolRunOptions, } from '../../resources/tool-runtime.js';
12
+ import { normalizeWasixStartupGUCs } from '../../core/startup-config.js';
12
13
  import { compileWasixModule, composeLifecycleFailure, configureWasixDatabase, configureWasixRole, describeError, materializeWasixMounts, wasixPostgresArgs, wasixPostgresEnvironment, } from './wasix-runtime.js';
13
14
  const preparedRuntimes = new Map();
14
15
  const MAX_PREPARED_RUNTIMES = 1;
@@ -70,7 +71,7 @@ export class DirectWasixSession {
70
71
  }
71
72
  const prepared = await dependencies.prepareRuntime(options);
72
73
  const startupGUCs = normalizeWasixStartupGUCs(prepared.startupGUCs);
73
- const eagerClusterSeed = options.storage.kind === 'memory' ? prepared.loadClusterSeed() : undefined;
74
+ const eagerClusterSeed = options.storage.kind === 'memory' ? prepared.loadClusterSeed?.() : undefined;
74
75
  const [, module] = await Promise.all([
75
76
  initializeHost(host),
76
77
  dependencies.compileModule(prepared.layout.module, prepared.moduleSha256),
@@ -82,7 +83,7 @@ export class DirectWasixSession {
82
83
  if (options.username !== 'postgres') {
83
84
  throw newStorageRoleError(options.username);
84
85
  }
85
- return eagerClusterSeed ?? prepared.loadClusterSeed();
86
+ return (eagerClusterSeed ?? prepared.loadClusterSeed?.() ?? initializeWasixStorage(host, prepared));
86
87
  }, prepared.physicalIdentity);
87
88
  let instance;
88
89
  let baseDirectory;
@@ -608,6 +609,9 @@ function asError(error) {
608
609
  }
609
610
  /** @internal Cache verified runtime materialization without caching transient failures. */
610
611
  export function prepareRuntimeCached(options, prepare = prepareWasixRuntime) {
612
+ // Explicit resource URLs/bytes can change independently of the runtime carrier.
613
+ if (options.seed !== undefined || options.icu !== undefined)
614
+ return prepare(options);
611
615
  const identity = preparedRuntimeIdentity(options);
612
616
  let prepared = preparedRuntimes.get(identity);
613
617
  if (prepared === undefined) {
@@ -682,29 +686,11 @@ function preparedRuntimeIdentity(options) {
682
686
  product: runtime.product,
683
687
  version: runtime.version,
684
688
  runtimeArchive: assetIdentity(runtime.runtimeArchive),
685
- standardSeedArchive: assetIdentity(runtime.standardSeedArchive),
686
- standardSeedManifest: {
687
- sha256: runtime.standardSeedManifest.sha256,
688
- size: runtime.standardSeedManifest.size,
689
- },
690
689
  manifest: {
691
690
  sha256: runtime.manifest.sha256,
692
691
  size: runtime.manifest.size,
693
692
  },
694
693
  },
695
- icu: options.icu === undefined
696
- ? null
697
- : {
698
- product: options.icu.product,
699
- version: options.icu.version,
700
- compatibility: options.icu.compatibility,
701
- dataArchive: assetIdentity(options.icu.dataArchive),
702
- clusterSeedArchive: assetIdentity(options.icu.clusterSeedArchive),
703
- clusterSeedManifest: {
704
- sha256: options.icu.clusterSeedManifest.sha256,
705
- size: options.icu.clusterSeedManifest.size,
706
- },
707
- },
708
694
  extensions: options.extensions,
709
695
  carriers: Object.values(options.extensionCarriers)
710
696
  .sort((left, right) => left.sqlName.localeCompare(right.sqlName))
@@ -0,0 +1,5 @@
1
+ import type { PreparedWasixRuntime } from '../../resources/extensions.js';
2
+ import type { WasixDirectoryMount } from '../../resources/archive.js';
3
+ import type { DirectWasixHost } from './direct-client-common.js';
4
+ /** Run the runtime's initdb in an isolated WASIX process tree for a new root. */
5
+ export declare function initializeWasixStorage(host: DirectWasixHost, runtime: PreparedWasixRuntime): Promise<WasixDirectoryMount>;
@@ -0,0 +1,67 @@
1
+ import { snapshotStorageDirectory, snapshotToMount } from '../../storage/storage-snapshot.js';
2
+ import { materializeWasixMounts } from './wasix-runtime.js';
3
+ import { releaseWasixToolMounts } from '../../resources/tool-runtime.js';
4
+ /** Run the runtime's initdb in an isolated WASIX process tree for a new root. */
5
+ export async function initializeWasixStorage(host, runtime) {
6
+ if (host.runWasix === undefined)
7
+ throw new Error('WASIX host does not provide initdb execution');
8
+ const initdb = runtime.layout.mounts['/bin']?.files.initdb;
9
+ if (initdb === undefined)
10
+ throw new Error('WASIX runtime archive is missing bin/initdb');
11
+ const { mounts, baseDirectory } = await materializeWasixMounts(host.Directory, runtime.layout, {
12
+ files: {},
13
+ directories: [],
14
+ });
15
+ let snapshot;
16
+ try {
17
+ const instance = await host.runWasix(initdb, {
18
+ program: '/bin/initdb',
19
+ cwd: '/',
20
+ stdin: '',
21
+ mount: mounts,
22
+ args: [
23
+ '--allow-group-access',
24
+ '--encoding',
25
+ 'UTF8',
26
+ '--locale',
27
+ 'C.UTF-8',
28
+ '--locale-provider',
29
+ 'libc',
30
+ '--auth',
31
+ 'trust',
32
+ '-D',
33
+ '/base',
34
+ ],
35
+ env: {
36
+ PGDATA: '/base',
37
+ PGSYSCONFDIR: '/base',
38
+ HOME: '/home/postgres',
39
+ USER: 'postgres',
40
+ LOGNAME: 'postgres',
41
+ PGCLIENTENCODING: 'UTF8',
42
+ PATH: '/bin',
43
+ LC_CTYPE: 'C.UTF-8',
44
+ TZ: 'UTC',
45
+ PGTZ: 'UTC',
46
+ PG_COLOR: 'never',
47
+ ...(runtime.icuEnabled
48
+ ? { ICU_DATA: '/share/icu', OLIPHAUNT_INTERNAL_ICU_READY: '1' }
49
+ : { OLIPHAUNT_INTERNAL_SKIP_ICU_DISCOVERY: '1' }),
50
+ },
51
+ });
52
+ // wait consumes the wasm-bindgen instance handle.
53
+ const output = await instance.wait();
54
+ if (!output.ok || output.code !== 0) {
55
+ throw new Error(`WASIX initdb failed (${output.code}): ${output.stderr.trim()}`);
56
+ }
57
+ if ((await baseDirectory.readTextFile('PG_VERSION')).trim() !== '18') {
58
+ throw new Error('WASIX initdb did not create a PostgreSQL 18 cluster');
59
+ }
60
+ snapshot = snapshotToMount(await snapshotStorageDirectory(baseDirectory));
61
+ }
62
+ catch (primary) {
63
+ releaseWasixToolMounts(mounts, { primary });
64
+ }
65
+ releaseWasixToolMounts(mounts);
66
+ return snapshot;
67
+ }
@@ -1,7 +1,7 @@
1
- import type { OliphauntDatabase } from './types.js';
1
+ import type { OliphauntDatabase } from '../../core/types.js';
2
2
  import type { WasixToolWorkerRequest, WasixToolWorkerResponse } from './tool-worker-common.js';
3
- import { type WasixToolProcessOptions, type WasixToolProcessResult } from './tool-runtime.js';
4
- export type { WasixToolDescriptor, WasixToolProcessOptions, WasixToolProcessResult, } from './tool-runtime.js';
3
+ import { type WasixToolProcessOptions, type WasixToolProcessResult } from '../../resources/tool-runtime.js';
4
+ export type { WasixToolDescriptor, WasixToolProcessOptions, WasixToolProcessResult, } from '../../resources/tool-runtime.js';
5
5
  export type WasixToolWorkerPort = Readonly<{
6
6
  postMessage(request: WasixToolWorkerRequest, transfer?: ArrayBuffer[]): void;
7
7
  terminate(): void | Promise<void>;
@@ -1,7 +1,7 @@
1
1
  import defaultWasixRuntime from '@oliphaunt/liboliphaunt-wasix';
2
- import { closeWasixByteChannel, createWasixByteChannel, failWasixByteChannel, wasixByteChannelProtocolOutcomeUnknown, } from './byte-channel.js';
3
- import { assertWasixProtocolConnectionTarget, registerWasixDatabaseResource, reserveWasixProtocolConnection, runWasixPgDumpProcess, } from './database.js';
4
- import { validateWasixToolDescriptor, } from './tool-runtime.js';
2
+ import { closeWasixByteChannel, createWasixByteChannel, failWasixByteChannel, wasixByteChannelProtocolOutcomeUnknown, } from '../../protocol/byte-channel.js';
3
+ import { assertWasixProtocolConnectionTarget, registerWasixDatabaseResource, reserveWasixProtocolConnection, runWasixPgDumpProcess, } from '../../core/database.js';
4
+ import { validateWasixToolDescriptor, } from '../../resources/tool-runtime.js';
5
5
  const controllers = new WeakMap();
6
6
  /** @internal Shared browser/server tool orchestration; public API lives in the optional package. */
7
7
  export function runWasixToolProcess(database, options, createWorker) {
@@ -1,6 +1,6 @@
1
- import { type WasixByteChannel } from './byte-channel.js';
2
- import type { Directory, OliphauntPreparedTool, OliphauntToolOutput, RunWasixOptions } from './host/index.mjs';
3
- import { type WasixToolDescriptor } from './tool-runtime.js';
1
+ import { type WasixByteChannel } from '../../protocol/byte-channel.js';
2
+ import type { Directory, OliphauntPreparedTool, OliphauntToolOutput, RunWasixOptions } from '../../host/index.mjs';
3
+ import { type WasixToolDescriptor } from '../../resources/tool-runtime.js';
4
4
  export type WasixToolWorkerRequest = WasixToolPrepareRequest | WasixToolRunRequest;
5
5
  export type WasixToolPrepareRequest = Readonly<{
6
6
  id: number;
@@ -1,5 +1,5 @@
1
- import { closeWasixByteChannel, failWasixByteChannel, markWasixByteChannelProtocolComplete, markWasixByteChannelProtocolStarted, readWasixByteChannelSync, wasixByteChannelProtocolOutcomeUnknown, writeWasixByteChannelSync, } from './byte-channel.js';
2
- import { materializeWasixToolMounts, prepareWasixToolAsset, releaseWasixToolMounts, wasixToolAssetIdentity, wasixToolRunOptions, } from './tool-runtime.js';
1
+ import { closeWasixByteChannel, failWasixByteChannel, markWasixByteChannelProtocolComplete, markWasixByteChannelProtocolStarted, readWasixByteChannelSync, wasixByteChannelProtocolOutcomeUnknown, writeWasixByteChannelSync, } from '../../protocol/byte-channel.js';
2
+ import { materializeWasixToolMounts, prepareWasixToolAsset, releaseWasixToolMounts, wasixToolAssetIdentity, wasixToolRunOptions, } from '../../resources/tool-runtime.js';
3
3
  /** @internal Stateful dispatcher owned by one persistent outer tool worker. */
4
4
  export function createWasixToolWorkerDispatcher(host) {
5
5
  let hostInitialization;
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="webworker" />
2
- import * as host from './host/index.mjs';
2
+ import * as host from '../../host/index.mjs';
3
3
  import { createWasixToolWorkerDispatcher, toolWorkerResponseTransfers, } from './tool-worker-common.js';
4
4
  const scope = globalThis;
5
5
  const dispatch = createWasixToolWorkerDispatcher(host);
@@ -1,6 +1,6 @@
1
- import type { WasixDirectoryMount, WasixRuntimeLayout } from './archive.js';
2
- import type { Directory } from './host/index.mjs';
3
- import type { SerializedOpenOptions } from './rpc.js';
1
+ import type { WasixDirectoryMount, WasixRuntimeLayout } from '../../resources/archive.js';
2
+ import type { Directory } from '../../host/index.mjs';
3
+ import type { SerializedOpenOptions } from '../../workers/rpc.js';
4
4
  /** @internal Verified-module compilation cache shared by direct opens in one JS realm. */
5
5
  export declare function compileWasixModule(module: Uint8Array, sha256: string): Promise<WebAssembly.Module>;
6
6
  /** @internal Materialize the exact runtime mounts shared by both execution surfaces. */
@@ -1,7 +1,8 @@
1
- import { WasixStorageError } from './errors.js';
2
- import { simpleQuery } from './protocol.js';
3
- import { assertSuccessfulQueryResponse, PostgresError } from './query.js';
4
- import { normalizeWasixStartupGUCs } from './startup-config.js';
1
+ import { WasixStorageError } from '../../core/errors.js';
2
+ import { simpleQuery } from '../../protocol/protocol.js';
3
+ import { assertSuccessfulQueryResponse, PostgresError } from '../../protocol/query.js';
4
+ import { normalizeWasixStartupGUCs } from '../../core/startup-config.js';
5
+ import { releaseWasixToolMounts } from '../../resources/tool-runtime.js';
5
6
  let compiledModuleCache;
6
7
  /** @internal Verified-module compilation cache shared by direct opens in one JS realm. */
7
8
  export function compileWasixModule(module, sha256) {
@@ -22,18 +23,23 @@ export function compileWasixModule(module, sha256) {
22
23
  /** @internal Materialize the exact runtime mounts shared by both execution surfaces. */
23
24
  export async function materializeWasixMounts(DirectoryConstructor, layout, pgdata, createPgdataDirectory) {
24
25
  const mounts = await materializeMountMap(DirectoryConstructor, layout);
25
- let baseDirectory;
26
- if (createPgdataDirectory !== undefined) {
27
- baseDirectory = await createPgdataDirectory(DirectoryConstructor);
28
- }
29
- else {
30
- if (pgdata === undefined) {
31
- throw new Error('portable WASIX storage did not provide a PGDATA mount');
26
+ try {
27
+ let baseDirectory;
28
+ if (createPgdataDirectory !== undefined) {
29
+ baseDirectory = await createPgdataDirectory(DirectoryConstructor);
30
+ }
31
+ else {
32
+ if (pgdata === undefined) {
33
+ throw new Error('portable WASIX storage did not provide a PGDATA mount');
34
+ }
35
+ baseDirectory = await materializeDirectory(DirectoryConstructor, pgdata);
32
36
  }
33
- baseDirectory = await materializeDirectory(DirectoryConstructor, pgdata);
37
+ mounts['/base'] = baseDirectory;
38
+ return { mounts, baseDirectory };
39
+ }
40
+ catch (primary) {
41
+ releaseWasixToolMounts(mounts, { primary });
34
42
  }
35
- mounts['/base'] = baseDirectory;
36
- return { mounts, baseDirectory };
37
43
  }
38
44
  /** @internal Materialize runtime support mounts for frontend tools. */
39
45
  export function materializeWasixSupportMounts(DirectoryConstructor, layout) {
@@ -41,23 +47,33 @@ export function materializeWasixSupportMounts(DirectoryConstructor, layout) {
41
47
  }
42
48
  async function materializeMountMap(DirectoryConstructor, layout) {
43
49
  const mounts = {};
44
- for (const [mountPath, contents] of Object.entries(layout.mounts)) {
45
- mounts[mountPath] = await materializeDirectory(DirectoryConstructor, contents);
50
+ try {
51
+ for (const [mountPath, contents] of Object.entries(layout.mounts)) {
52
+ mounts[mountPath] = await materializeDirectory(DirectoryConstructor, contents);
53
+ }
54
+ return mounts;
55
+ }
56
+ catch (primary) {
57
+ releaseWasixToolMounts(mounts, { primary });
46
58
  }
47
- return mounts;
48
59
  }
49
60
  async function materializeDirectory(DirectoryConstructor, contents) {
50
61
  const directory = new DirectoryConstructor(contents.files);
51
- const existing = directoriesImpliedByFiles(Object.keys(contents.files));
52
- const explicit = [...new Set(contents.directories)].sort(compareDirectoryDepth);
53
- for (const path of explicit) {
54
- if (existing.has(path)) {
55
- continue;
62
+ try {
63
+ const existing = directoriesImpliedByFiles(Object.keys(contents.files));
64
+ const explicit = [...new Set(contents.directories)].sort(compareDirectoryDepth);
65
+ for (const path of explicit) {
66
+ if (existing.has(path)) {
67
+ continue;
68
+ }
69
+ await directory.createDir(path);
70
+ existing.add(path);
56
71
  }
57
- await directory.createDir(path);
58
- existing.add(path);
72
+ return directory;
73
+ }
74
+ catch (primary) {
75
+ releaseWasixToolMounts({ directory }, { primary });
59
76
  }
60
- return directory;
61
77
  }
62
78
  function directoriesImpliedByFiles(paths) {
63
79
  const directories = new Set();
@@ -1,4 +1,4 @@
1
- import type { OliphauntClient, OliphauntDatabase, OpenConfig } from './types.js';
1
+ import type { OliphauntClient, OliphauntDatabase, OpenConfig } from './browser-public.js';
2
2
  /** Open PostgreSQL in a package-owned browser Worker. */
3
3
  export declare function openWasix(config?: OpenConfig): Promise<OliphauntDatabase>;
4
4
  export declare const Oliphaunt: OliphauntClient;
@@ -1,14 +1,15 @@
1
- import { serializeOpenConfig } from './client-common.js';
2
- import { openWasixWithWorker, restoreWasixWithWorker } from './worker-rpc.js';
1
+ import { requireBrowserStorage, serializeOpenConfig } from '../../core/open-config.js';
2
+ import { openWasixWithWorker, restoreWasixWithWorker, } from '../../workers/worker-rpc.js';
3
3
  /** Open PostgreSQL in a package-owned browser Worker. */
4
4
  export async function openWasix(config = {}) {
5
5
  const openOptions = serializeOpenConfig(config);
6
+ requireBrowserStorage(openOptions);
6
7
  assertBrowserWorkerEnvironment();
7
- return openWasixWithWorker(createBrowserWorker, openOptions);
8
+ return openWasixWithWorker(createBrowserWorker, openOptions, requireBrowserStorage);
8
9
  }
9
10
  async function restoreBrowserWasix(storage, bytes) {
10
11
  assertBrowserWorkerEnvironment();
11
- return restoreWasixWithWorker(createBrowserWorker, storage, bytes);
12
+ return restoreWasixWithWorker(createBrowserWorker, storage, bytes, requireBrowserStorage);
12
13
  }
13
14
  function assertBrowserWorkerEnvironment() {
14
15
  if (globalThis.crossOriginIsolated !== true) {
@@ -1,7 +1,7 @@
1
1
  /// <reference lib="webworker" />
2
- import * as host from './host/index.mjs';
2
+ import * as host from '../../host/index.mjs';
3
3
  import { openBrowserWorkerSession } from './direct-client-common.js';
4
- import { createWorkerSessionDispatcher } from './worker-dispatch.js';
4
+ import { createWorkerSessionDispatcher } from '../../workers/worker-dispatch.js';
5
5
  const scope = globalThis;
6
6
  const directHost = {
7
7
  Directory: host.Directory,
@@ -1,4 +1,4 @@
1
- import type { OliphauntClient, OliphauntDatabase, OpenConfig } from './types.js';
1
+ import type { OliphauntClient, OliphauntDatabase, OpenConfig } from './native-public.js';
2
2
  /** Open PostgreSQL in the importing realm, where native work blocks its event loop. */
3
3
  export declare function openWasix(config?: OpenConfig): Promise<OliphauntDatabase>;
4
4
  export declare const Oliphaunt: OliphauntClient;
@@ -1,4 +1,4 @@
1
- import { serializeOpenConfig } from './client-common.js';
1
+ import { serializeOpenConfig } from '../../core/open-config.js';
2
2
  import { requireNodeStorage, restoreNodeWasixDirect } from './node-client-common.js';
3
3
  import { openNodeDirect } from './node-direct.js';
4
4
  /** Open PostgreSQL in the importing realm, where native work blocks its event loop. */
@@ -4,6 +4,15 @@ export type NativeWasixStorage = Readonly<{
4
4
  kind: 'directory';
5
5
  path: string;
6
6
  }>;
7
+ export type NativeWasixExtensionPackage = Readonly<{
8
+ sqlName: string;
9
+ product: string;
10
+ version: string;
11
+ packageJson: string;
12
+ aotPackageJson?: string;
13
+ archiveSha256: string;
14
+ archiveSize: number;
15
+ }>;
7
16
  export type NativeProfile = 'standard' | 'icu';
8
17
  export type NativeWasixOpenOptions = Readonly<{
9
18
  profile: NativeProfile;
@@ -12,6 +21,15 @@ export type NativeWasixOpenOptions = Readonly<{
12
21
  database: string;
13
22
  startupGucs: Record<string, string>;
14
23
  extensions: string[];
24
+ extensionPackages?: NativeWasixExtensionPackage[];
25
+ seed?: {
26
+ archive: Uint8Array;
27
+ manifest: Uint8Array;
28
+ };
29
+ icuData?: {
30
+ data: Uint8Array;
31
+ manifest: Uint8Array;
32
+ };
15
33
  }>;
16
34
  export type NativeWasixServerListen = Readonly<{
17
35
  transport: 'tcp';
@@ -29,8 +47,8 @@ export type NativeWasixDatabaseHandle = {
29
47
  execProtocolRaw(request: Uint8Array): Uint8Array;
30
48
  execProtocolRawStream(request: Uint8Array, onChunk: (chunk: Uint8Array) => void): 'complete' | 'callbackAborted';
31
49
  backup(): Uint8Array;
32
- pgDump(args: string[]): NativeWasixToolResult;
33
- psql(args: string[], command?: string, script?: string): NativeWasixToolResult;
50
+ pgDump(args: readonly string[], assets: NativeWasixToolAssets): NativeWasixToolResult;
51
+ psql(args: readonly string[], assets: NativeWasixToolAssets, command?: string, script?: string): NativeWasixToolResult;
34
52
  close(): void;
35
53
  };
36
54
  export type NativeWasixActorDatabaseHandle = {
@@ -38,8 +56,8 @@ export type NativeWasixActorDatabaseHandle = {
38
56
  execProtocolRaw(request: Uint8Array): Promise<Uint8Array>;
39
57
  execProtocolRawStream(request: Uint8Array, onChunk: (chunk: Uint8Array) => void): Promise<'complete' | 'callbackAborted'>;
40
58
  backup(): Promise<Uint8Array>;
41
- pgDump(args: string[]): Promise<NativeWasixToolResult>;
42
- psql(args: string[], command?: string, script?: string): Promise<NativeWasixToolResult>;
59
+ pgDump(args: readonly string[], assets: NativeWasixToolAssets): Promise<NativeWasixToolResult>;
60
+ psql(args: readonly string[], assets: NativeWasixToolAssets, command?: string, script?: string): Promise<NativeWasixToolResult>;
43
61
  close(): Promise<void>;
44
62
  };
45
63
  export type NativeWasixToolResult = Readonly<{
@@ -47,6 +65,11 @@ export type NativeWasixToolResult = Readonly<{
47
65
  stdout: Uint8Array;
48
66
  stderr: Uint8Array;
49
67
  }>;
68
+ export type NativeWasixToolAssets = Readonly<{
69
+ wasm: Uint8Array;
70
+ aot: Uint8Array;
71
+ manifest: string;
72
+ }>;
50
73
  export type NativeWasixServerHandle = {
51
74
  readonly connectionString: string;
52
75
  readonly closed: boolean;
@@ -71,9 +94,8 @@ export type NativeWasixAddon = {
71
94
  nodeApiVersion(): number;
72
95
  runtimeVersion(): string;
73
96
  supportedProfiles(): readonly NativeProfile[];
74
- payloadIdentity(component: 'runtimeArchive' | 'standardSeedArchive' | 'standardSeedManifest' | 'icuDataArchive' | 'icuSeedArchive' | 'icuSeedManifest'): string;
97
+ payloadIdentity(component: 'runtimeArchive'): string;
75
98
  extensionIdentity(sqlName: string): string;
76
- toolIdentity(name: 'pg_dump' | 'psql'): string;
77
99
  };
78
100
  type WasixPackageMetadata = Readonly<{
79
101
  name?: string;
@@ -86,11 +86,11 @@ export function optionalEnvironmentValue(name, read = (key) => process.env[key],
86
86
  }
87
87
  }
88
88
  function packageMetadata() {
89
- const path = fileURLToPath(new URL('../package.json', import.meta.url));
89
+ const path = fileURLToPath(new URL('../../../package.json', import.meta.url));
90
90
  return JSON.parse(readFileSync(path, 'utf8'));
91
91
  }
92
92
  function packageAdjacentAddons() {
93
- const here = dirname(fileURLToPath(import.meta.url));
93
+ const here = resolve(dirname(fileURLToPath(import.meta.url)), '../..');
94
94
  const file = `${ADDON_STEM}.node`;
95
95
  return [join(here, file), join(here, '..', file)];
96
96
  }
@@ -186,12 +186,11 @@ export function validateNativeWasixAddon(addon, path, metadata) {
186
186
  typeof addon.runtimeVersion !== 'function' ||
187
187
  typeof addon.supportedProfiles !== 'function' ||
188
188
  typeof addon.payloadIdentity !== 'function' ||
189
- typeof addon.extensionIdentity !== 'function' ||
190
- typeof addon.toolIdentity !== 'function') {
189
+ typeof addon.extensionIdentity !== 'function') {
191
190
  throw new Error(`Oliphaunt WASIX native addon ${path} has an invalid export surface`);
192
191
  }
193
192
  const expectedAbi = metadata.oliphaunt?.wasixAddonAbiVersion;
194
- if (expectedAbi !== 1 || addon.addonAbiVersion() !== expectedAbi) {
193
+ if (expectedAbi !== 3 || addon.addonAbiVersion() !== expectedAbi) {
195
194
  throw new Error(`Oliphaunt WASIX native addon ${path} has an incompatible addon ABI`);
196
195
  }
197
196
  const expectedNodeApi = metadata.oliphaunt?.nodeApiVersion;
@@ -0,0 +1,8 @@
1
+ export * from '../../core/public.js';
2
+ import type * as Types from '../../core/types.js';
3
+ import type * as Storage from '../../storage/types.js';
4
+ type StorageKind = 'memory' | 'directory';
5
+ export type OpenConfig = Types.OpenConfig<StorageKind>;
6
+ export type OliphauntClient = Types.OliphauntClient<StorageKind>;
7
+ export type WasixStorage = Storage.WasixStorage<StorageKind>;
8
+ export type PersistentWasixStorage = Storage.PersistentWasixStorage<Exclude<StorageKind, 'memory'>>;
@@ -0,0 +1 @@
1
+ export * from '../../core/public.js';
@@ -1,4 +1,4 @@
1
- import type { OpenConfig } from './types.js';
1
+ import type { OpenConfig } from './native-public.js';
2
2
  export type ServerListen = Readonly<{
3
3
  transport: 'tcp';
4
4
  port?: number;
@@ -1,6 +1,6 @@
1
1
  import { resolve } from 'node:path';
2
- import { serializeOpenConfig } from './client-common.js';
3
- import { mapNativeError, nativeWasixOpenOptions, requireCompatibleNativeWasixAddon, } from './native-session.js';
2
+ import { serializeOpenConfig } from '../../core/open-config.js';
3
+ import { mapNativeError, nativeWasixOpenOptions, loadNativeResources, requireCompatibleNativeWasixAddon, } from './native-session.js';
4
4
  import { requireNodeStorage } from './node-client-common.js';
5
5
  /** Open the Rust WASIX local server without a JavaScript socket/protocol relay. */
6
6
  export async function openServer(config = {}) {
@@ -24,6 +24,7 @@ export async function openServer(config = {}) {
24
24
  try {
25
25
  handle = await addon.NativeWasixServer.open({
26
26
  ...nativeWasixOpenOptions(options, storage),
27
+ ...(await loadNativeResources(options)),
27
28
  listen,
28
29
  });
29
30
  connectionString = validateServerHandle(handle);
@@ -1,8 +1,8 @@
1
1
  import { type NativeWasixAddon, type NativeWasixOpenOptions } from './native-addon.js';
2
- import { type WasixDatabaseIdentity, type WasixDatabaseSession, type WasixDatabaseSessionTerminalState, type WasixPersistenceMode, type WasixProtocolStreamOutcome } from './database.js';
3
- import type { SerializedOpenOptions } from './rpc.js';
4
- import type { WasixStorageSyncBoundary } from './storage-provider.js';
5
- import type { WasixPgDumpProcessOptions, WasixToolProcessOptions, WasixToolProcessResult } from './tool-runtime.js';
2
+ import { type WasixDatabaseIdentity, type WasixDatabaseSession, type WasixDatabaseSessionTerminalState, type WasixPersistenceMode, type WasixProtocolStreamOutcome } from '../../core/database.js';
3
+ import type { SerializedOpenOptions } from '../../workers/rpc.js';
4
+ import type { WasixStorageSyncBoundary } from '../../storage/storage-provider.js';
5
+ import type { WasixPgDumpProcessOptions, WasixToolProcessOptions, WasixToolProcessResult } from '../../resources/tool-runtime.js';
6
6
  /** @internal A synchronous Rust Oliphaunt owned by the importing JavaScript realm. */
7
7
  export declare class NativeWasixSession implements WasixDatabaseSession {
8
8
  #private;
@@ -53,6 +53,16 @@ export declare function restoreNativeWasixDirect(options: SerializedOpenOptions,
53
53
  export declare function restoreNativeWasixStorageDirect(storage: SerializedOpenOptions['storage'], bytes: Uint8Array, addon?: NativeWasixAddon): Promise<void>;
54
54
  /** @internal Validate serialized package descriptors against the selected addon. */
55
55
  export declare function requireCompatibleNativeWasixAddon(options: SerializedOpenOptions): NativeWasixAddon;
56
+ export declare function loadNativeResources(options: SerializedOpenOptions): Promise<{
57
+ icuData?: {
58
+ data: Uint8Array<ArrayBufferLike>;
59
+ manifest: Uint8Array<ArrayBufferLike>;
60
+ } | undefined;
61
+ seed?: {
62
+ archive: Uint8Array<ArrayBufferLike>;
63
+ manifest: Uint8Array<ArrayBufferLike>;
64
+ } | undefined;
65
+ }>;
56
66
  /** @internal Project already-validated TS config onto the narrow native ABI. */
57
67
  export declare function nativeWasixOpenOptions(options: SerializedOpenOptions, storage: NativeWasixOpenOptions['storage']): NativeWasixOpenOptions;
58
68
  /** @internal Translate only the exact tagged native storage contract. */