@volter/world-runtime 2.0.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 (164) hide show
  1. package/LICENSE +202 -0
  2. package/dist/known-external-services.json +1108 -0
  3. package/dist/src/ancestry.d.ts +2 -0
  4. package/dist/src/ancestry.js +42 -0
  5. package/dist/src/app-url.d.ts +47 -0
  6. package/dist/src/app-url.js +239 -0
  7. package/dist/src/attach.d.ts +48 -0
  8. package/dist/src/attach.js +87 -0
  9. package/dist/src/branch.d.ts +20 -0
  10. package/dist/src/branch.js +65 -0
  11. package/dist/src/browser-proxy-cli.d.ts +2 -0
  12. package/dist/src/browser-proxy-cli.js +41 -0
  13. package/dist/src/ca-trust.d.ts +5 -0
  14. package/dist/src/ca-trust.js +64 -0
  15. package/dist/src/catalog.d.ts +31 -0
  16. package/dist/src/catalog.js +148 -0
  17. package/dist/src/changeset.d.ts +142 -0
  18. package/dist/src/changeset.js +570 -0
  19. package/dist/src/cli.d.ts +2 -0
  20. package/dist/src/cli.js +1262 -0
  21. package/dist/src/command-lifetime.d.ts +15 -0
  22. package/dist/src/command-lifetime.js +98 -0
  23. package/dist/src/configs.d.ts +18 -0
  24. package/dist/src/configs.js +119 -0
  25. package/dist/src/console-apart.d.ts +38 -0
  26. package/dist/src/console-apart.js +107 -0
  27. package/dist/src/consumers.d.ts +46 -0
  28. package/dist/src/consumers.js +200 -0
  29. package/dist/src/covers.d.ts +183 -0
  30. package/dist/src/covers.js +800 -0
  31. package/dist/src/fixture-env.d.ts +42 -0
  32. package/dist/src/fixture-env.js +221 -0
  33. package/dist/src/host-cli.d.ts +2 -0
  34. package/dist/src/host-cli.js +92 -0
  35. package/dist/src/host-fault-fixture.d.ts +32 -0
  36. package/dist/src/host-fault-fixture.js +100 -0
  37. package/dist/src/host-worker.d.ts +1 -0
  38. package/dist/src/host-worker.js +23 -0
  39. package/dist/src/host.d.ts +38 -0
  40. package/dist/src/host.js +135 -0
  41. package/dist/src/index.d.ts +48 -0
  42. package/dist/src/index.js +35 -0
  43. package/dist/src/infra-cli.d.ts +2 -0
  44. package/dist/src/infra-cli.js +136 -0
  45. package/dist/src/init.d.ts +227 -0
  46. package/dist/src/init.js +1117 -0
  47. package/dist/src/inject-map.d.ts +34 -0
  48. package/dist/src/inject-map.js +56 -0
  49. package/dist/src/lifecycle-record.d.ts +47 -0
  50. package/dist/src/lifecycle-record.js +196 -0
  51. package/dist/src/origin.d.ts +31 -0
  52. package/dist/src/origin.js +139 -0
  53. package/dist/src/pack-facts.d.ts +75 -0
  54. package/dist/src/pack-facts.js +98 -0
  55. package/dist/src/pglite-backing.d.ts +21 -0
  56. package/dist/src/pglite-backing.js +158 -0
  57. package/dist/src/pglite-host.mjs +147 -0
  58. package/dist/src/placeholder.d.ts +20 -0
  59. package/dist/src/placeholder.js +100 -0
  60. package/dist/src/prerequisites.d.ts +21 -0
  61. package/dist/src/prerequisites.js +49 -0
  62. package/dist/src/process-groups.d.ts +4 -0
  63. package/dist/src/process-groups.js +49 -0
  64. package/dist/src/project-inspect.d.ts +109 -0
  65. package/dist/src/project-inspect.js +827 -0
  66. package/dist/src/proxy-daemon.d.ts +2 -0
  67. package/dist/src/proxy-daemon.js +18 -0
  68. package/dist/src/redirect-proxy.d.ts +105 -0
  69. package/dist/src/redirect-proxy.js +665 -0
  70. package/dist/src/reflect.d.ts +74 -0
  71. package/dist/src/reflect.js +392 -0
  72. package/dist/src/resources.d.ts +26 -0
  73. package/dist/src/resources.js +22 -0
  74. package/dist/src/root.d.ts +114 -0
  75. package/dist/src/root.js +312 -0
  76. package/dist/src/run-task-worker.d.ts +1 -0
  77. package/dist/src/run-task-worker.js +38 -0
  78. package/dist/src/run-task.d.ts +18 -0
  79. package/dist/src/run-task.js +48 -0
  80. package/dist/src/runtime-test-support.d.ts +59 -0
  81. package/dist/src/runtime-test-support.js +205 -0
  82. package/dist/src/runtime.d.ts +256 -0
  83. package/dist/src/runtime.js +3502 -0
  84. package/dist/src/schema.d.ts +449 -0
  85. package/dist/src/schema.js +605 -0
  86. package/dist/src/serve.d.ts +30 -0
  87. package/dist/src/serve.js +82 -0
  88. package/dist/src/served-world.d.ts +194 -0
  89. package/dist/src/served-world.js +986 -0
  90. package/dist/src/service-exit.d.ts +46 -0
  91. package/dist/src/service-exit.js +195 -0
  92. package/dist/src/service-recorder.d.ts +1 -0
  93. package/dist/src/service-recorder.js +121 -0
  94. package/dist/src/sibling.d.ts +1 -0
  95. package/dist/src/sibling.js +9 -0
  96. package/dist/src/signals.d.ts +1 -0
  97. package/dist/src/signals.js +11 -0
  98. package/dist/src/storage-capacity.d.ts +8 -0
  99. package/dist/src/storage-capacity.js +61 -0
  100. package/dist/src/tail.d.ts +30 -0
  101. package/dist/src/tail.js +160 -0
  102. package/dist/src/tcp-port.d.ts +2 -0
  103. package/dist/src/tcp-port.js +36 -0
  104. package/dist/src/up-task-worker.d.ts +1 -0
  105. package/dist/src/up-task-worker.js +61 -0
  106. package/dist/src/up-task.d.ts +17 -0
  107. package/dist/src/up-task.js +49 -0
  108. package/dist/src/websocket-relay.d.ts +3 -0
  109. package/dist/src/websocket-relay.js +40 -0
  110. package/known-external-services.json +1108 -0
  111. package/package.json +83 -0
  112. package/src/ancestry.ts +36 -0
  113. package/src/app-url.ts +253 -0
  114. package/src/attach.ts +117 -0
  115. package/src/branch.ts +63 -0
  116. package/src/browser-proxy-cli.ts +44 -0
  117. package/src/ca-trust.ts +57 -0
  118. package/src/catalog.ts +156 -0
  119. package/src/changeset.ts +627 -0
  120. package/src/cli.ts +1111 -0
  121. package/src/command-lifetime.ts +79 -0
  122. package/src/configs.ts +110 -0
  123. package/src/console-apart.ts +90 -0
  124. package/src/consumers.ts +185 -0
  125. package/src/covers.ts +934 -0
  126. package/src/fixture-env.ts +230 -0
  127. package/src/host-cli.ts +90 -0
  128. package/src/host-worker.ts +23 -0
  129. package/src/host.ts +169 -0
  130. package/src/index.ts +171 -0
  131. package/src/infra-cli.ts +133 -0
  132. package/src/init.ts +1316 -0
  133. package/src/inject-map.ts +72 -0
  134. package/src/lifecycle-record.ts +168 -0
  135. package/src/origin.ts +134 -0
  136. package/src/pack-facts.ts +128 -0
  137. package/src/pglite-backing.ts +141 -0
  138. package/src/pglite-host.mjs +147 -0
  139. package/src/placeholder.ts +89 -0
  140. package/src/prerequisites.ts +66 -0
  141. package/src/process-groups.ts +33 -0
  142. package/src/project-inspect.ts +770 -0
  143. package/src/proxy-daemon.ts +21 -0
  144. package/src/redirect-proxy.ts +684 -0
  145. package/src/reflect.ts +440 -0
  146. package/src/resources.ts +22 -0
  147. package/src/root.ts +290 -0
  148. package/src/run-task-worker.ts +27 -0
  149. package/src/run-task.ts +44 -0
  150. package/src/runtime-test-support.ts +208 -0
  151. package/src/runtime.ts +3357 -0
  152. package/src/schema.ts +922 -0
  153. package/src/serve.ts +102 -0
  154. package/src/served-world.ts +812 -0
  155. package/src/service-exit.ts +175 -0
  156. package/src/service-recorder.ts +89 -0
  157. package/src/sibling.ts +10 -0
  158. package/src/signals.ts +10 -0
  159. package/src/storage-capacity.ts +60 -0
  160. package/src/tail.ts +205 -0
  161. package/src/tcp-port.ts +35 -0
  162. package/src/up-task-worker.ts +40 -0
  163. package/src/up-task.ts +45 -0
  164. package/src/websocket-relay.ts +32 -0
package/src/serve.ts ADDED
@@ -0,0 +1,102 @@
1
+ // Remote worlds (docs/guides/route-a-cli-through-the-world.md): a served world publishes its manifest over
2
+ // HTTP and opens ONE advertised TLS door (the reflect front terminating the
3
+ // advertised hostname alongside vendor hosts). The manifest an attacher
4
+ // fetches has every vendor rewritten to the advertised origin — the injector
5
+ // preserves the vendor Host header, the door routes by it, the twin answers.
6
+ // Read-only publication: the manifest endpoint tracks no attachers and takes
7
+ // no writes. An optional attach token protects manifest publication.
8
+ import { timingSafeEqual } from 'node:crypto';
9
+ import { createServer as createHttpServer, type Server as HttpServer } from 'node:http';
10
+ import { deriveWorldManifest, type WorldManifest } from './attach.ts';
11
+ import { statusWorld } from './runtime.ts';
12
+
13
+ export const MANIFEST_PATH = '/.well-known/volter-world';
14
+
15
+ /** The manifest a REMOTE attacher sees: every vendor behind the one advertised
16
+ * door. The serving side keeps routing against its own loopback env. */
17
+ export function advertiseWorldManifest(name: string, root: string, advertisedOrigin: string): WorldManifest {
18
+ const local = deriveWorldManifest(name, statusWorld(name, root).env);
19
+ const vendors: Record<string, string> = {};
20
+ // /__vendor/<id> keeps the fetch flow routable through the one door (the
21
+ // injector's fetch patch rewrites URLs wholesale and loses the vendor Host);
22
+ // the http/https flow still Host-routes and ignores the origin's path.
23
+ for (const vendor of Object.keys(local.vendors)) vendors[vendor] = `${advertisedOrigin}/__vendor/${vendor}`;
24
+ return { ...local, vendors };
25
+ }
26
+
27
+ export interface ManifestServerOptions {
28
+ manifest: () => WorldManifest;
29
+ host?: string;
30
+ port?: number;
31
+ /** when set, GET requires `Authorization: Bearer <token>` — the attach token
32
+ * for a shared world (docs/guides/route-a-cli-through-the-world.md). Constant-time-ish compare via length
33
+ * gate + timingSafeEqual to avoid trivial token oracles. */
34
+ token?: string;
35
+ }
36
+
37
+ export interface ManifestServerHandle {
38
+ port: number;
39
+ close(): Promise<void>;
40
+ }
41
+
42
+ export async function startManifestServer(options: ManifestServerOptions): Promise<ManifestServerHandle> {
43
+ const server: HttpServer = createHttpServer((request, response) => {
44
+ if (options.token !== undefined) {
45
+ const presented = (request.headers.authorization ?? '').replace(/^Bearer\s+/i, '');
46
+ const expected = Buffer.from(options.token);
47
+ const actual = Buffer.from(presented);
48
+ if (actual.length !== expected.length || !timingSafeEqual(actual, expected)) {
49
+ response.writeHead(401, { 'content-type': 'text/plain' });
50
+ response.end('attach token required\n');
51
+ return;
52
+ }
53
+ }
54
+ if (request.method !== 'GET' || (request.url !== MANIFEST_PATH && request.url !== '/')) {
55
+ response.writeHead(404, { 'content-type': 'text/plain' });
56
+ response.end('volter-world: GET ' + MANIFEST_PATH + '\n');
57
+ return;
58
+ }
59
+ response.writeHead(200, { 'content-type': 'application/json' });
60
+ response.end(`${JSON.stringify(options.manifest(), null, 2)}\n`);
61
+ });
62
+ await new Promise<void>((resolveListen, reject) => {
63
+ server.once('error', reject);
64
+ server.listen(options.port ?? 0, options.host ?? '0.0.0.0', () => resolveListen());
65
+ });
66
+ const address = server.address();
67
+ return {
68
+ port: typeof address === 'object' && address ? address.port : (options.port ?? 0),
69
+ async close() {
70
+ await new Promise<void>((resolveClose) => server.close(() => resolveClose()));
71
+ },
72
+ };
73
+ }
74
+
75
+ /** Fetch a remote world's manifest. Accepts the manifest URL itself or the
76
+ * world's base URL (the well-known path is appended). */
77
+ export async function fetchRemoteManifest(ref: string, options: { token?: string } = {}): Promise<WorldManifest> {
78
+ const base = ref.replace(/\/$/, '');
79
+ const url = base.endsWith(MANIFEST_PATH) ? base : `${base}${MANIFEST_PATH}`;
80
+ const response = await fetch(url, options.token === undefined ? undefined : { headers: { authorization: `Bearer ${options.token}` } });
81
+ if (!response.ok) throw new Error(`remote world manifest: ${url} → ${response.status}`);
82
+ const manifest = (await response.json()) as WorldManifest;
83
+ if (typeof manifest.name !== 'string' || typeof manifest.vendors !== 'object' || manifest.vendors === null) {
84
+ throw new Error(`remote world manifest: ${url} returned no manifest`);
85
+ }
86
+ return manifest;
87
+ }
88
+
89
+ /** The env a remote env-attachment exports: vendor twin URLs (the advertised
90
+ * door), suggested fake credentials, CA trust, and the injector preload. */
91
+ export function remoteAttachEnv(
92
+ manifest: WorldManifest,
93
+ options: { caFile?: string; injectPath: string },
94
+ ): Record<string, string> {
95
+ const env: Record<string, string> = { ...manifest.env };
96
+ for (const [vendor, origin] of Object.entries(manifest.vendors)) {
97
+ env[`${vendor.toUpperCase()}_TWIN_URL`] = origin;
98
+ }
99
+ env.NODE_OPTIONS = `--require ${options.injectPath}`;
100
+ if (options.caFile !== undefined) env.NODE_EXTRA_CA_CERTS = options.caFile;
101
+ return env;
102
+ }