@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.
Files changed (169) hide show
  1. package/ARCHITECTURE.md +655 -0
  2. package/CHANGELOG.md +33 -0
  3. package/LICENSE +21 -0
  4. package/README.md +404 -0
  5. package/THIRD_PARTY_NOTICES.md +20 -0
  6. package/lib/archive.d.ts +21 -0
  7. package/lib/archive.js +336 -0
  8. package/lib/asset-source.d.ts +4 -0
  9. package/lib/asset-source.js +15 -0
  10. package/lib/byte-channel.d.ts +27 -0
  11. package/lib/byte-channel.js +170 -0
  12. package/lib/client-common.d.ts +6 -0
  13. package/lib/client-common.js +36 -0
  14. package/lib/client.d.ts +7 -0
  15. package/lib/client.js +24 -0
  16. package/lib/database-root.d.ts +19 -0
  17. package/lib/database-root.js +139 -0
  18. package/lib/database.d.ts +135 -0
  19. package/lib/database.js +1039 -0
  20. package/lib/descriptor-validation.d.ts +10 -0
  21. package/lib/descriptor-validation.js +75 -0
  22. package/lib/direct-client-common.d.ts +50 -0
  23. package/lib/direct-client-common.js +717 -0
  24. package/lib/direct-client.d.ts +4 -0
  25. package/lib/direct-client.js +13 -0
  26. package/lib/direct.node.d.ts +2 -0
  27. package/lib/direct.node.js +2 -0
  28. package/lib/errors.d.ts +25 -0
  29. package/lib/errors.js +34 -0
  30. package/lib/extension-descriptor.d.ts +14 -0
  31. package/lib/extension-descriptor.js +419 -0
  32. package/lib/extensions.d.ts +68 -0
  33. package/lib/extensions.js +769 -0
  34. package/lib/host/LICENSE +21 -0
  35. package/lib/host/index.d.mts +123 -0
  36. package/lib/host/index.mjs +11 -0
  37. package/lib/host/provenance.json +16 -0
  38. package/lib/host/wasmer_js_bg.wasm +0 -0
  39. package/lib/host/worker.mjs +11 -0
  40. package/lib/host-runtime.d.ts +5 -0
  41. package/lib/host-runtime.js +13 -0
  42. package/lib/icu-descriptor.d.ts +3 -0
  43. package/lib/icu-descriptor.js +92 -0
  44. package/lib/index.bun.d.ts +2 -0
  45. package/lib/index.bun.js +2 -0
  46. package/lib/index.d.ts +2 -0
  47. package/lib/index.deno.d.ts +2 -0
  48. package/lib/index.deno.js +2 -0
  49. package/lib/index.js +2 -0
  50. package/lib/index.node.d.ts +2 -0
  51. package/lib/index.node.js +2 -0
  52. package/lib/internal-common.d.ts +12 -0
  53. package/lib/internal-common.js +274 -0
  54. package/lib/internal.d.ts +5 -0
  55. package/lib/internal.js +42 -0
  56. package/lib/internal.node.d.ts +5 -0
  57. package/lib/internal.node.js +8 -0
  58. package/lib/native-addon.d.ts +111 -0
  59. package/lib/native-addon.js +223 -0
  60. package/lib/native-server.d.ts +21 -0
  61. package/lib/native-server.js +109 -0
  62. package/lib/native-session.d.ts +60 -0
  63. package/lib/native-session.js +565 -0
  64. package/lib/node-actor.d.ts +7 -0
  65. package/lib/node-actor.js +10 -0
  66. package/lib/node-client-common.d.ts +9 -0
  67. package/lib/node-client-common.js +35 -0
  68. package/lib/node-client.d.ts +4 -0
  69. package/lib/node-client.js +13 -0
  70. package/lib/node-direct.d.ts +7 -0
  71. package/lib/node-direct.js +10 -0
  72. package/lib/node-worker-options.d.ts +5 -0
  73. package/lib/node-worker-options.js +65 -0
  74. package/lib/node-worker-port.d.ts +4 -0
  75. package/lib/node-worker-port.js +116 -0
  76. package/lib/node-worker.d.ts +1 -0
  77. package/lib/node-worker.js +38 -0
  78. package/lib/pgwire-connection.d.ts +60 -0
  79. package/lib/pgwire-connection.js +528 -0
  80. package/lib/pgwire.d.ts +3 -0
  81. package/lib/pgwire.js +105 -0
  82. package/lib/physical-archive.d.ts +29 -0
  83. package/lib/physical-archive.js +527 -0
  84. package/lib/protocol.d.ts +1 -0
  85. package/lib/protocol.js +1 -0
  86. package/lib/public.d.ts +4 -0
  87. package/lib/public.js +3 -0
  88. package/lib/query.d.ts +1 -0
  89. package/lib/query.js +1 -0
  90. package/lib/rpc.d.ts +203 -0
  91. package/lib/rpc.js +84 -0
  92. package/lib/runtime-descriptor.d.ts +3 -0
  93. package/lib/runtime-descriptor.js +79 -0
  94. package/lib/server.node.d.ts +1 -0
  95. package/lib/server.node.js +1 -0
  96. package/lib/startup-config.d.ts +2 -0
  97. package/lib/startup-config.js +19 -0
  98. package/lib/storage/bun.d.ts +6 -0
  99. package/lib/storage/bun.js +6 -0
  100. package/lib/storage/deno.d.ts +7 -0
  101. package/lib/storage/deno.js +7 -0
  102. package/lib/storage/incremental-storage.d.ts +25 -0
  103. package/lib/storage/incremental-storage.js +154 -0
  104. package/lib/storage/indexed-db-provider.d.ts +40 -0
  105. package/lib/storage/indexed-db-provider.js +259 -0
  106. package/lib/storage/indexed-db.d.ts +9 -0
  107. package/lib/storage/indexed-db.js +11 -0
  108. package/lib/storage/node.d.ts +10 -0
  109. package/lib/storage/node.js +13 -0
  110. package/lib/storage/opfs-pool.d.ts +31 -0
  111. package/lib/storage/opfs-pool.js +1271 -0
  112. package/lib/storage/opfs-provider.d.ts +4 -0
  113. package/lib/storage/opfs-provider.js +257 -0
  114. package/lib/storage/opfs.d.ts +8 -0
  115. package/lib/storage/opfs.js +10 -0
  116. package/lib/storage/restore-cleanup.d.ts +4 -0
  117. package/lib/storage/restore-cleanup.js +22 -0
  118. package/lib/storage/web-lock.d.ts +2 -0
  119. package/lib/storage/web-lock.js +64 -0
  120. package/lib/storage-provider.d.ts +47 -0
  121. package/lib/storage-provider.js +141 -0
  122. package/lib/storage-snapshot.d.ts +44 -0
  123. package/lib/storage-snapshot.js +274 -0
  124. package/lib/storage.d.ts +46 -0
  125. package/lib/storage.js +83 -0
  126. package/lib/tool-runtime.d.ts +43 -0
  127. package/lib/tool-runtime.js +93 -0
  128. package/lib/tool-worker-common.d.ts +48 -0
  129. package/lib/tool-worker-common.js +97 -0
  130. package/lib/tool-worker.d.ts +1 -0
  131. package/lib/tool-worker.js +10 -0
  132. package/lib/types.d.ts +230 -0
  133. package/lib/types.js +1 -0
  134. package/lib/wasix-runtime.d.ts +24 -0
  135. package/lib/wasix-runtime.js +186 -0
  136. package/lib/worker-client.d.ts +4 -0
  137. package/lib/worker-client.js +45 -0
  138. package/lib/worker-dispatch.d.ts +11 -0
  139. package/lib/worker-dispatch.js +174 -0
  140. package/lib/worker-entry.bun.d.ts +2 -0
  141. package/lib/worker-entry.bun.js +2 -0
  142. package/lib/worker-entry.d.ts +2 -0
  143. package/lib/worker-entry.deno.d.ts +2 -0
  144. package/lib/worker-entry.deno.js +2 -0
  145. package/lib/worker-entry.js +2 -0
  146. package/lib/worker-entry.node.d.ts +2 -0
  147. package/lib/worker-entry.node.js +2 -0
  148. package/lib/worker-node-client.d.ts +4 -0
  149. package/lib/worker-node-client.js +55 -0
  150. package/lib/worker-rpc.d.ts +36 -0
  151. package/lib/worker-rpc.js +422 -0
  152. package/lib/worker-transfer.d.ts +6 -0
  153. package/lib/worker-transfer.js +11 -0
  154. package/lib/worker.d.ts +1 -0
  155. package/lib/worker.js +21 -0
  156. package/lib/zstd.d.ts +4 -0
  157. package/lib/zstd.js +12 -0
  158. package/node_modules/@oliphaunt/js-core/README.md +7 -0
  159. package/node_modules/@oliphaunt/js-core/dist/commonjs/protocol.d.ts +1 -0
  160. package/node_modules/@oliphaunt/js-core/dist/commonjs/protocol.js +22 -0
  161. package/node_modules/@oliphaunt/js-core/dist/commonjs/query.d.ts +255 -0
  162. package/node_modules/@oliphaunt/js-core/dist/commonjs/query.js +2068 -0
  163. package/node_modules/@oliphaunt/js-core/dist/module/package.json +3 -0
  164. package/node_modules/@oliphaunt/js-core/dist/module/protocol.d.ts +1 -0
  165. package/node_modules/@oliphaunt/js-core/dist/module/protocol.js +19 -0
  166. package/node_modules/@oliphaunt/js-core/dist/module/query.d.ts +255 -0
  167. package/node_modules/@oliphaunt/js-core/dist/module/query.js +2039 -0
  168. package/node_modules/@oliphaunt/js-core/package.json +21 -0
  169. package/package.json +122 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,33 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 (2026-09-05)
4
+
5
+
6
+ ### ⚠ BREAKING CHANGES
7
+
8
+ * **wasix-ts:** run host runtimes through Rust Node-API ([#156](https://github.com/f0rr0/oliphaunt/issues/156))
9
+ * **sdk:** unify embedded PostgreSQL public APIs ([#153](https://github.com/f0rr0/oliphaunt/issues/153))
10
+ * Rust WASIX removes temporary/application-data storage variants, and browser IndexedDB uses the new per-database v3 layout without migrating prior generations.
11
+
12
+ ### Features
13
+
14
+ * **sdk:** unify embedded PostgreSQL public APIs ([#153](https://github.com/f0rr0/oliphaunt/issues/153)) ([4384d1b](https://github.com/f0rr0/oliphaunt/commit/4384d1bdfafee07e4e1963ac68027b4bcf002a1e))
15
+ * unify native and WASIX runtimes and SDKs ([#129](https://github.com/f0rr0/oliphaunt/issues/129)) ([fae2bd7](https://github.com/f0rr0/oliphaunt/commit/fae2bd7bde00ae436d9b62ba6a37d919679ac790))
16
+ * **wasix-ts:** run host runtimes through Rust Node-API ([#156](https://github.com/f0rr0/oliphaunt/issues/156)) ([28e07be](https://github.com/f0rr0/oliphaunt/commit/28e07be782388915b28ad3fd30e3e78143710d28))
17
+
18
+
19
+ ### Bug Fixes
20
+
21
+ * **ci:** preserve native lifecycle server sessions ([#165](https://github.com/f0rr0/oliphaunt/issues/165)) ([b8cab0b](https://github.com/f0rr0/oliphaunt/commit/b8cab0be2b86c6b9fab4c279add89113c5797d23))
22
+
23
+
24
+ ### Performance Improvements
25
+
26
+ * **js:** streamline exec response handling ([#158](https://github.com/f0rr0/oliphaunt/issues/158)) ([5eaf05b](https://github.com/f0rr0/oliphaunt/commit/5eaf05b8a8d21bd974b9fcb6d618103be5689151))
27
+ * **wasix:** preserve and accelerate seek end ([#154](https://github.com/f0rr0/oliphaunt/issues/154)) ([169852f](https://github.com/f0rr0/oliphaunt/commit/169852f22d1c5eab4cfd30c17ccca014b8d84592))
28
+
29
+
30
+ ### Code Refactoring
31
+
32
+ * **ci:** align product and release task boundaries ([#170](https://github.com/f0rr0/oliphaunt/issues/170)) ([009a5f5](https://github.com/f0rr0/oliphaunt/commit/009a5f5ec0659d70f6a22902c071a81e0806fabe))
33
+ * **ci:** model independent product dependencies ([#173](https://github.com/f0rr0/oliphaunt/issues/173)) ([2d5f90c](https://github.com/f0rr0/oliphaunt/commit/2d5f90c837ef7ecd8b43c2547e4b3c9b04767121))
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 oliphaunt-wasix Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,404 @@
1
+ # `@oliphaunt/wasix-ts`
2
+
3
+ Portable PostgreSQL 18 for TypeScript. Browser conditions run the canonical
4
+ `liboliphaunt-wasix` guest through the patched Wasmer JavaScript host. Node.js,
5
+ Bun, Deno, and Electron conditions run the same WASIX runtime through a Rust
6
+ Oliphaunt Node-API addon. The public TypeScript API is shared by both hosts.
7
+
8
+ In browsers the root owns PostgreSQL in the importing JavaScript realm. On
9
+ native hosts the root uses a dedicated Rust owner thread. The explicit
10
+ `/direct` import runs synchronously in the importing realm, while `/worker`
11
+ uses a separate JavaScript Worker on every runtime.
12
+
13
+ ## Install
14
+
15
+ ```sh
16
+ pnpm add @oliphaunt/wasix-ts
17
+ ```
18
+
19
+ The published SDK is one universal browser-and-server package. Its browser host
20
+ files and exact `@oliphaunt/liboliphaunt-wasix` dependency are therefore
21
+ installed on Node.js, Bun, Deno, and Electron too, although native export
22
+ conditions never load them. The matching target-filtered optional platform
23
+ package embeds the runtime, both cluster profiles, tools, and qualified
24
+ extension catalog used on those hosts. Carrier packages have no install scripts
25
+ and do not download a binary at install or first use. Applications do not
26
+ configure raw runtime assets.
27
+
28
+ Published Node-API 8 carriers currently cover:
29
+
30
+ - macOS arm64;
31
+ - Linux arm64 and x64 with glibc; and
32
+ - Windows x64 with MSVC.
33
+
34
+ There is no published carrier yet for macOS x64, Linux musl, or Windows arm64.
35
+ The native loader detects Linux libc before resolving a carrier and explicitly
36
+ rejects musl or an unidentifiable libc; it cannot load a `-gnu` carrier through
37
+ an override on an unsupported host. Opening a database on another server target
38
+ fails with an explicit unsupported-platform error rather than falling back to
39
+ the browser Wasmer host.
40
+
41
+ Deno must resolve the npm package through a local `node_modules` directory and
42
+ must be granted `--allow-ffi`, `--allow-read`, and `--allow-env` in addition to any filesystem
43
+ permissions the application needs. The `/worker` entrypoint uses Deno's
44
+ Node-compatible Worker implementation and does not spawn a process. The package
45
+ smoke uses explicit host permissions. The qualified Deno surface is
46
+ the Deno CLI version declared by this package; managed Deno Deploy is not
47
+ currently a qualified distribution target.
48
+
49
+ Electron applications that use ASAR should leave `**/prebuilds/**` unpacked and
50
+ ship the generated `app.asar.unpacked` directory beside `app.asar`. This keeps
51
+ the addon and any platform loader companions, including the Windows app-local
52
+ VC runtime, in one loadable directory. Electron can temporarily extract a
53
+ packed native module, but the unpacked layout avoids that startup overhead and
54
+ antivirus interaction. Carrier qualification loads the addon from this
55
+ packaged layout and proves that a missing unpacked companion fails explicitly.
56
+
57
+ Optional ICU data and its matching `icu` seed are selected explicitly:
58
+
59
+ ```ts
60
+ import Oliphaunt from '@oliphaunt/wasix-ts';
61
+ import icu from '@oliphaunt/wasix-icu';
62
+
63
+ await using database = await Oliphaunt.open({ icu });
64
+ ```
65
+
66
+ Browser conditions load the ICU assets from their portable carrier. Each
67
+ native platform carrier contains one addon with both `standard` and `icu`
68
+ profiles, and the existing `icu` option selects the database profile. The loader checks
69
+ the exact SDK/carrier version, WASIX runtime version, addon ABI, Node-API level,
70
+ target, and ICU profile before running native code.
71
+
72
+ ## Query PostgreSQL
73
+
74
+ ```ts
75
+ import Oliphaunt from '@oliphaunt/wasix-ts';
76
+
77
+ await using database = await Oliphaunt.open();
78
+
79
+ await database.execute('create table todo (title text not null)');
80
+ await database.execute('insert into todo values ($1)', ['ship it']);
81
+
82
+ const result = await database.query(
83
+ 'select title from todo where title = $1',
84
+ ['ship it'],
85
+ );
86
+ console.log(result.rows[0]?.title);
87
+ ```
88
+
89
+ `execute` asserts one command with no rows. `query` accepts command-only or
90
+ row-producing SQL and defaults to decoded object rows; array rows, text value
91
+ mode, and immutable per-query OID codecs are available. Object mode rejects
92
+ duplicate field names; use `rowMode: 'array'` to preserve them positionally.
93
+ `queryRaw` retains ordered nullable bytes and complete field metadata. `exec` returns ordered
94
+ simple-query results, while `describe` resolves parameter OIDs and optional
95
+ result fields without executing. Structured operations preserve command
96
+ metadata and ordered notices.
97
+
98
+ Safe scalar parameters are resolved and encoded inside one owned operation.
99
+ Use `text`, `binary`, `typedNull`, `json`, or `array` with `postgresOids` for a
100
+ deterministic type, or an immutable per-query encoder for an extension OID.
101
+ Unsupported and mismatched values fail rather than being guessed.
102
+
103
+ `execProtocolRaw` is the buffered PostgreSQL frontend-protocol escape hatch.
104
+ `execProtocolRawStream` delivers the same response through a synchronous
105
+ callback. Every surface invokes it serially with at most 64 KiB per chunk and
106
+ waits for it to return before producing the next chunk. Direct sessions invoke
107
+ the callback inline; the native actor and Worker paths use bounded
108
+ acknowledgements across their existing thread boundary. COPY-sized responses
109
+ therefore need not be retained as one JavaScript value. A thrown callback, including
110
+ the deterministic error for returning a Promise or thenable, is rethrown
111
+ unchanged only after the guest confirms recovery to `ReadyForQuery`; the
112
+ recovered database remains reusable. An asynchronous callback cannot provide
113
+ this backpressure contract.
114
+ The callback also cannot reenter the same database or transaction;
115
+ fire-and-forget calls are rejected instead of being queued behind the stream.
116
+ Neither method interprets responses for the caller. A buffered raw rejection,
117
+ or a streamed execution, transport, or recovery failure, poisons the handle and
118
+ takes precedence over a simultaneous callback error; close it and open a new
119
+ database instead of assuming the physical session recovered.
120
+
121
+ PostgreSQL `ErrorResponse` values reject with `PostgresError`, including the
122
+ SQLSTATE and structured diagnostic fields.
123
+
124
+ ## Transactions
125
+
126
+ ```ts
127
+ await database.transaction(async (transaction) => {
128
+ await transaction.execute('insert into todo values ($1)', ['inside transaction']);
129
+ return transaction.query('select count(*)::int4 as count from todo');
130
+ });
131
+ ```
132
+
133
+ The callback exclusively owns the session from `BEGIN` through its final
134
+ boundary. It mirrors query/raw query, execute, exec, and describe; database-level
135
+ operations reject while it is active. One-shot `rollback()` closes the
136
+ transaction and lets the callback return without a later commit.
137
+
138
+ Raw protocol is database-only and deliberately absent from the callback handle.
139
+ Do not issue manual `BEGIN`, `START TRANSACTION`, `COMMIT`, `END`, `ABORT`,
140
+ `PREPARE TRANSACTION`, or `AND CHAIN` inside the callback; return/throw or call
141
+ `rollback()` instead. `SAVEPOINT` and `ROLLBACK TO` are supported. `ROLLBACK AND
142
+ CHAIN` is unsupported contract misuse and has the same PostgreSQL wire
143
+ tag/readiness state as `ROLLBACK TO`, so the SDK rejects `ROLLBACK`/`ABORT ...
144
+ AND CHAIN` before dispatch and still validates every actual protocol boundary.
145
+ A proven ownership escape makes the database close-only and never causes a
146
+ speculative SDK `COMMIT` or `ROLLBACK`.
147
+
148
+ Callback failures trigger a best-effort `ROLLBACK`. Once `COMMIT` has been
149
+ sent, the binding never sends a second rollback. PostgreSQL's clean `ROLLBACK`
150
+ response is a known aborted outcome; a transport failure or malformed response
151
+ after `COMMIT` makes the outcome unknown and poisons the handle until close.
152
+ Persistent publication completes before a successful transaction resolves.
153
+ After rollback and its required publication succeed, the original callback
154
+ failure is rethrown unchanged. If the callback and rollback both fail, an
155
+ `AggregateError` preserves the callback failure followed by the rollback
156
+ failure. If an earlier independent database or protocol failure has already
157
+ poisoned or expired transaction ownership and the callback then throws a
158
+ different value, an `AggregateError` preserves the callback failure followed by
159
+ that database failure; the database is close-only. Ordinary PostgreSQL statement
160
+ errors that remain safely rollbackable are not automatically aggregated.
161
+
162
+ ## Storage
163
+
164
+ Omitting `storage` creates a fresh true-memory database. Persistent adapters
165
+ are explicit, host-specific imports:
166
+
167
+ ```ts
168
+ import Oliphaunt from '@oliphaunt/wasix-ts';
169
+ import { directory } from '@oliphaunt/wasix-ts/storage/node';
170
+
171
+ const storage = directory('./data/todos');
172
+ let database = await Oliphaunt.open({ storage });
173
+ await database.execute('create table if not exists todo (title text not null)');
174
+ await database.close();
175
+
176
+ database = await Oliphaunt.open({ storage });
177
+ await database.close();
178
+ ```
179
+
180
+ Use `storage/bun` or `storage/deno` for those runtimes, and
181
+ `storage/indexed-db` or `storage/opfs` in browsers.
182
+
183
+ A Node, Bun, Deno, or Electron directory is a managed root with exactly:
184
+
185
+ ```text
186
+ .oliphaunt.json
187
+ pgdata/
188
+ ```
189
+
190
+ The descriptor records the shared database-root schema, PostgreSQL major, and
191
+ WASIX physical format. Runtime source fingerprints and package hashes validate
192
+ the asset graph; they are not physical-reopen identity. Native and WASIX roots
193
+ are not rejected merely because of the originating family.
194
+
195
+ Rust and WASIX TypeScript bindings use the same root and physical-archive
196
+ contracts. On Node.js, Bun, Deno, and Electron the Rust runtime holds the managed
197
+ root's OS advisory lock for the database lifetime. The same lock protects actor,
198
+ direct, Worker, and Rust owners. Always close the current owner before handing a
199
+ root to another process, Worker, or binding.
200
+
201
+ The Rust host owns directory durability for Node.js, Bun, Deno, and Electron. IndexedDB
202
+ publishes a delta in one transaction. OPFS uses synchronous backing files for
203
+ `/worker` and when the root entrypoint is imported inside an application-owned
204
+ Dedicated Worker.
205
+ The root entrypoint in a browser Window uses the same opaque format through a
206
+ copy-on-write portable path. Both OPFS paths flush or publish in
207
+ PostgreSQL-safe order. A
208
+ publication failure rejects with `WasixStorageError`; an uncertain state
209
+ poisons the live database handle.
210
+
211
+ All native-host entrypoints may be used inside an application-owned Worker,
212
+ including with directory storage. Close the database before terminating that
213
+ Worker. The lock is owned by the Rust runtime rather than a JavaScript marker
214
+ directory, and an orderly package Worker close waits for native quiescence,
215
+ posts its terminal reply, and then lets the Worker exit itself.
216
+
217
+ `close()` is one terminal, idempotent teardown attempt. It stops admitting new
218
+ work and lets work already accepted by the database FIFO finish. The root actor
219
+ and `/server` await their Rust owner teardown. `/direct` closes synchronously at
220
+ the native boundary. `/worker` closes its direct native session at quiescence,
221
+ replies, and self-exits; it is never force-terminated across an active Node-API
222
+ frame. Concurrent and later calls return the same promise. Provider, host, and
223
+ Worker transport failures are preserved.
224
+ If teardown rejects, `closed` still becomes `true`: cleanup was attempted and
225
+ a destroyed isolated owner or guest is never treated as a retryable live session.
226
+ An unexpected `/worker` crash also makes `closed` true as soon as the transport
227
+ observes ownership loss. Later operations fail without posting more work;
228
+ `close()` remains idempotent and reports that terminal transport failure while
229
+ finishing any remaining package-owned cleanup.
230
+
231
+ Forgetting a database handle schedules generation-guarded best-effort cleanup
232
+ of only that handle's actor, direct session, or Worker generation. A stale
233
+ finalizer cannot affect a later open. Finalizers are not prompt or observable,
234
+ so applications must still use `close()` or `await using` when ownership release
235
+ matters.
236
+
237
+ ## Backup and restore
238
+
239
+ ```ts
240
+ const backup = await database.backup();
241
+ await database.close();
242
+
243
+ await Oliphaunt.restore(directory('./data/restored'), backup);
244
+ ```
245
+
246
+ `backup()` performs PostgreSQL online physical backup without replacing the
247
+ session. The archive is the shared strict ustar format containing
248
+ `pgdata/**` and `.oliphaunt/backup-manifest.properties`. `restore` accepts only
249
+ an absent or empty persistent destination, validates the complete archive
250
+ before publication, and creates the receiving storage provider's outer
251
+ identity. Browser root restores in its importing realm. On native hosts the
252
+ root uses the Rust owner actor, `/direct` restores on the importing JavaScript
253
+ thread, and `/worker` uses a temporary package-owned Worker.
254
+
255
+ ## Extensions
256
+
257
+ Import package-authored WASIX extension descriptors and pass them at open:
258
+
259
+ ```ts
260
+ import Oliphaunt from '@oliphaunt/wasix-ts';
261
+ import pgtap from '@oliphaunt/extension-pgtap-wasix';
262
+
263
+ await using database = await Oliphaunt.open({ extensions: [pgtap] });
264
+ await database.execute('CREATE EXTENSION pgtap');
265
+ const version = await database.query('select pgtap_version()');
266
+ ```
267
+
268
+ The call shape and lifecycle ownership are host-independent. A browser verifies
269
+ the selected carrier and its dependency closure, installs its artifacts before
270
+ startup, and applies required startup/preload settings. Node.js, Bun, Deno, and Electron
271
+ validate the same descriptor but resolve its SQL name against the extension
272
+ catalog compiled into the platform addon. Release addons contain the complete
273
+ currently supported extension catalog; they do not load arbitrary side-module
274
+ bytes from npm at runtime. Adding or upgrading a server extension therefore
275
+ requires a matching N-API carrier release. This increases the carrier size in
276
+ exchange for eliminating runtime archive expansion and dynamic linking on the
277
+ native path.
278
+
279
+ Neither host runs database-local `CREATE EXTENSION`, `LOAD`, schema,
280
+ post-create, upgrade, or migration SQL. Applications and ORM migrations own
281
+ those ordinary PostgreSQL statements explicitly; selecting a descriptor makes
282
+ its code available but leaves the extension uninstalled in the database.
283
+
284
+ ## Calling shape and execution placement
285
+
286
+ The normal import keeps the public API consistent while selecting the safest
287
+ default placement for the host:
288
+
289
+ ```ts
290
+ import Oliphaunt from '@oliphaunt/wasix-ts';
291
+
292
+ await using database = await Oliphaunt.open();
293
+ ```
294
+
295
+ On Node.js, Bun, Deno, and Electron, use `/direct` only when the lowest-hop path
296
+ is more important than keeping the importing event loop responsive:
297
+
298
+ ```ts
299
+ import DirectOliphaunt from '@oliphaunt/wasix-ts/direct';
300
+
301
+ await using database = await DirectOliphaunt.open();
302
+ ```
303
+
304
+ Use the explicit Worker import when a separate JavaScript realm is part of the
305
+ application's isolation or placement model:
306
+
307
+ ```ts
308
+ import WorkerOliphaunt from '@oliphaunt/wasix-ts/worker';
309
+
310
+ await using database = await WorkerOliphaunt.open();
311
+ ```
312
+
313
+ All imports expose the same PostgreSQL interface and retain the promise-shaped
314
+ public API. A Promise does not itself imply off-thread execution. In a browser,
315
+ the root steps the Wasmer guest in the importing realm. On native hosts, the
316
+ root uses one Rust owner actor so PostgreSQL does not block the importing event
317
+ loop. `/direct` calls the synchronous Rust database on the importing thread and
318
+ removes that actor hop. `/worker` uses a real package-owned JavaScript Worker on
319
+ every runtime and loads the direct implementation inside it.
320
+
321
+ Importing the browser root or `/direct` from an application Worker blocks only
322
+ that Worker; importing the browser root in a Window can block the page. Browser
323
+ Worker use requires cross-origin isolation. Chromium Window compilation
324
+ of native side modules larger than 8 MiB requires `/worker`.
325
+
326
+ ## Optional PostgreSQL tools
327
+
328
+ Install `@oliphaunt/wasix-tools` when the application needs standard plain
329
+ `pg_dump` or non-interactive `psql`:
330
+
331
+ ```ts
332
+ import Oliphaunt from '@oliphaunt/wasix-ts';
333
+ import WorkerOliphaunt from '@oliphaunt/wasix-ts/worker';
334
+ import { pgDump, psql } from '@oliphaunt/wasix-tools';
335
+
336
+ await using source = await Oliphaunt.open();
337
+ const sql = await pgDump(source, { args: ['--schema-only'] });
338
+ await using target = await WorkerOliphaunt.open();
339
+ await psql(target, { script: sql });
340
+ ```
341
+
342
+ `pgDump()` runs with the database's existing owner, so it supports root,
343
+ `/direct`, and `/worker` entrypoints where available. In browsers, `psql()` requires `/worker`
344
+ because restoring COPY input is full duplex. Node.js, Bun, Deno, and Electron route both
345
+ tools through the frontend binaries compiled into the native carrier, so
346
+ `psql()` works with root, `/direct`, and `/worker` on those hosts. The optional
347
+ `@oliphaunt/wasix-tools` package remains the public opt-in API even though the
348
+ native carrier includes the tool code at build time. Adding or changing a tool
349
+ requires a matching N-API carrier release.
350
+
351
+ The package preserves PostgreSQL's normal plain SQL and COPY output. It does
352
+ not support interactive psql, custom dump archives, parallel jobs, or
353
+ pg_restore.
354
+
355
+ ## Optional local server
356
+
357
+ Node, Bun, Deno, and Electron may import `openServer` from the shared host-only server
358
+ subpath. Package export conditions select the runtime; browsers cannot resolve
359
+ this entrypoint:
360
+
361
+ ```ts
362
+ import { openServer } from '@oliphaunt/wasix-ts/server';
363
+
364
+ await using server = await openServer({
365
+ listen: { transport: 'tcp' },
366
+ });
367
+ console.log(server.connectionString);
368
+ ```
369
+
370
+ The lightweight compatibility endpoint binds IPv4 loopback with an automatic
371
+ port when `port` is omitted. Unix hosts may instead pass
372
+ `{ transport: 'unix', directory, port? }`; the socket follows PostgreSQL's
373
+ `.s.PGSQL.<port>` convention. One complete client connection owns the single
374
+ embedded backend at a time; another connection may wait in the operating-system
375
+ backlog, so configure client pools with a maximum size of one. The server
376
+ entrypoint wraps the Rust `OliphauntServer` directly; it does not create a
377
+ JavaScript socket relay or managed Worker. The listener and storage lease
378
+ persist, while each admitted client receives a fresh backend.
379
+ Use the separate WASIX postmaster product for concurrent PostgreSQL sessions.
380
+ The server's read-only `closed` property remains `false` while terminal teardown
381
+ is running and becomes `true` when that memoized attempt settles, including when
382
+ cleanup rejects.
383
+
384
+ ## Scope
385
+
386
+ The core database surface remains limited to open, execute/query/queryRaw,
387
+ exec/describe, buffered and callback-streamed raw protocol, callback
388
+ transaction, physical backup/restore, read-only `closed`, and close.
389
+ Tools and local sockets stay in optional packages or host-only subpaths.
390
+ Cancellation and a dedicated typed COPY reader/writer are not exposed today.
391
+
392
+ ## Qualification
393
+
394
+ ```sh
395
+ pnpm --dir src/bindings/wasix-ts typecheck
396
+ pnpm --dir src/bindings/wasix-ts test
397
+ moon run oliphaunt-wasix-ts:package
398
+ pnpm --dir src/runtimes/wasix-napi check
399
+ ```
400
+
401
+ Runtime carrier and browser/Node/Bun/Deno/Electron host smokes are defined in the
402
+ packages' Moon tasks. Native-host smokes install the packed SDK and matching
403
+ packed optional carrier into a fresh external project; they never use a
404
+ developer-machine adjacent addon as the release proof.
@@ -0,0 +1,20 @@
1
+ # Third-Party Notices
2
+
3
+ Oliphaunt source code in this repository is licensed under the MIT license in
4
+ `LICENSE`.
5
+
6
+ This file is the repository-level notice index. Product-specific runtime and
7
+ packaging notices live next to the product that ships the relevant artifacts:
8
+
9
+ - `src/runtimes/liboliphaunt/native/THIRD_PARTY_NOTICES.md`
10
+ - `src/bindings/wasix-rust/THIRD_PARTY_NOTICES.md`
11
+
12
+ Shared PostgreSQL source pins, third-party source pins, and extension metadata
13
+ are maintained in `src/postgres/versions/18/`, `src/sources/third-party/`, and
14
+ `src/extensions/`. Generated release artifacts must include the notices and
15
+ exact pinned license bytes for every product and third-party component they
16
+ ship.
17
+
18
+ Canonical runtime license snapshots live in
19
+ `src/runtimes/liboliphaunt/licenses/`; their source pins and digests are
20
+ enforced by `tools/release/release-notices.mjs`.
@@ -0,0 +1,21 @@
1
+ import type { SerializedAssetSource } from './rpc.js';
2
+ export type DirectoryFiles = Record<string, Uint8Array>;
3
+ export type ExtractedArchive = {
4
+ files: Map<string, Uint8Array>;
5
+ directories: Set<string>;
6
+ };
7
+ export type WasixDirectoryMount = {
8
+ files: DirectoryFiles;
9
+ directories: string[];
10
+ };
11
+ export type WasixRuntimeLayout = {
12
+ module: Uint8Array;
13
+ mounts: Record<string, WasixDirectoryMount>;
14
+ };
15
+ export declare function extractTar(archive: Uint8Array): ExtractedArchive;
16
+ /** @internal Validate and project an extracted cluster seed for a `/base` mount. */
17
+ export declare function clusterSeedMount(clusterSeed: ExtractedArchive): WasixDirectoryMount;
18
+ /** @internal Materialize runtime support mounts without loading a cluster seed. */
19
+ export declare function layoutRuntimeSupport(runtime: ExtractedArchive): WasixRuntimeLayout;
20
+ export declare function loadAsset(source: SerializedAssetSource, label: string): Promise<Uint8Array>;
21
+ export declare function decompressIfNeeded(bytes: Uint8Array): Uint8Array;