@volter/world-runtime 3.0.7 → 3.0.9
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/dist/src/served-world.js +10 -6
- package/package.json +4 -4
- package/src/served-world.ts +7 -5
package/dist/src/served-world.js
CHANGED
|
@@ -26,7 +26,7 @@ import { getActiveWorldStore, withHistoryLocks, captureHistory, historyAtInstant
|
|
|
26
26
|
// to `.volter/token` and `.volter/token.read` (0600).
|
|
27
27
|
// One writer per world by construction: the doors run in this process, serialized per twin.
|
|
28
28
|
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync, rmSync } from 'node:fs';
|
|
29
|
-
import { CALLER_HEADER, callerForHeader, newTraceparent, parseTraceparent, traceparentForDelivery, readTwinRequestJournalFrom, assertSafeChangesetName, blobDigest, destinationOf, getActiveBlobStore, journalTwinRequest, loadCheck, twinRequestJournalFailures, openSealedAt, readTwinRequestJournal, serveHttp, twinRequestCredentials, TWIN_PREFIX_HEADER, validateRemoteOrigin } from '@volter/world-core/runtime';
|
|
29
|
+
import { CALLER_HEADER, callerForHeader, newTraceparent, parseTraceparent, traceparentForDelivery, readTwinRequestJournalFrom, assertSafeChangesetName, blobDigest, destinationOf, getActiveBlobStore, journalTwinRequest, loadCheck, twinRequestJournalFailures, openSealedAt, readTwinRequestJournal, serveHttp, twinRequestCredentials, TWIN_PREFIX_HEADER, TWIN_SITES_HEADER, validateRemoteOrigin } from '@volter/world-core/runtime';
|
|
30
30
|
import { APP_READ_ENDPOINT_ENV } from "./init.js";
|
|
31
31
|
import { packFacts } from "./pack-facts.js";
|
|
32
32
|
import { grantOf, presentedSecrets, sameSecret, spentPasses, verifyPass } from '@volter/world-access';
|
|
@@ -941,6 +941,14 @@ export class WorldDoors {
|
|
|
941
941
|
headers.set(TWIN_PREFIX_HEADER, `/${this.served}/${vendor}`);
|
|
942
942
|
headers.set('x-forwarded-host', url.host);
|
|
943
943
|
headers.set('x-forwarded-proto', url.protocol.replace(':', ''));
|
|
944
|
+
// where this World shows the hostnames its twins answer, for a page that links one (twinSiteUrl): under its own
|
|
945
|
+
// origin on this machine (siteOfHost); a World without one shows none
|
|
946
|
+
const own = this.host.browserOrigin?.() ?? null;
|
|
947
|
+
const sites = own ? new URL(own) : null;
|
|
948
|
+
if (sites && sites.hostname.endsWith('.localhost'))
|
|
949
|
+
headers.set(TWIN_SITES_HEADER, `${sites.protocol}//{host}.${sites.host}`);
|
|
950
|
+
else
|
|
951
|
+
headers.delete(TWIN_SITES_HEADER);
|
|
944
952
|
const body = request.method === 'GET' || request.method === 'HEAD' ? undefined : await request.arrayBuffer();
|
|
945
953
|
const answer = await twin(new Request(`${url.origin}/${tail.join('/')}${url.search}`, { method: request.method, headers, ...(body === undefined ? {} : { body }), redirect: 'manual' }));
|
|
946
954
|
// an upgrade the twin answered (a tunnel's control or visitor socket) goes back as it is
|
|
@@ -985,7 +993,7 @@ export class WorldDoors {
|
|
|
985
993
|
// what leaves for the vendor before the seal is applied: no World token in any header it can arrive
|
|
986
994
|
// under (an SDK's own `Authorization: Bearer` included), no cookie, no routing headers of this World
|
|
987
995
|
const caller = new Headers(request.headers);
|
|
988
|
-
for (const h of [TOKEN_HEADER, TWINS_KEY_HEADER, TWIN_PREFIX_HEADER, CALLER_HEADER, 'host', 'x-forwarded-host', 'x-forwarded-proto', 'cookie'])
|
|
996
|
+
for (const h of [TOKEN_HEADER, TWINS_KEY_HEADER, TWIN_PREFIX_HEADER, TWIN_SITES_HEADER, CALLER_HEADER, 'host', 'x-forwarded-host', 'x-forwarded-proto', 'cookie'])
|
|
989
997
|
caller.delete(h);
|
|
990
998
|
// a secret this World minted (`tok_…`, live, revoked or expired) or one that opens it never leaves
|
|
991
999
|
const authorization = caller.get('authorization');
|
|
@@ -1175,10 +1183,6 @@ export class WorldDoors {
|
|
|
1175
1183
|
return Response.json(await this.map());
|
|
1176
1184
|
if (kind === 'timeline' && !name && request.method === 'GET')
|
|
1177
1185
|
return this.timeline(url);
|
|
1178
|
-
// the sites this World's twins answer (a Workers Custom Domain, an R2 public domain), each read in a browser at
|
|
1179
|
-
// `<hostname>.<the World's origin>` (siteOfHost)
|
|
1180
|
-
if (kind === 'sites' && !name && request.method === 'GET')
|
|
1181
|
-
return Response.json({ world: this.served, sites: (await this.claimedHosts(url.origin)).flatMap((c) => c.hosts.map((host) => ({ twin: c.vendor, host }))) });
|
|
1182
1186
|
if (kind === 'diff' && !name && request.method === 'GET') {
|
|
1183
1187
|
const delta = diffWorld(this.name, { root: this.worldRoot });
|
|
1184
1188
|
// what another World pushed here is in its changeset already: never this World's uncut changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/world-runtime",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.9",
|
|
4
4
|
"description": "World configs for twins: boot named local runtimes, allocate ports, generate world.env/instance.json, and run apps against fake-key twin worlds.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"twin",
|
|
@@ -68,14 +68,14 @@
|
|
|
68
68
|
"node": ">=22.3"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
|
-
"@volter/world-core": "3.0.
|
|
72
|
-
"@volter/world-console": "3.0.
|
|
71
|
+
"@volter/world-core": "3.0.9",
|
|
72
|
+
"@volter/world-console": "3.0.4"
|
|
73
73
|
},
|
|
74
74
|
"dependencies": {
|
|
75
75
|
"@electric-sql/pglite": "0.5.8",
|
|
76
76
|
"@electric-sql/pglite-pgvector": "0.0.9",
|
|
77
77
|
"@volter/world-access": "3.0.1",
|
|
78
|
-
"@volter/world-core": "3.0.
|
|
78
|
+
"@volter/world-core": "3.0.9",
|
|
79
79
|
"pg-gateway": "0.3.0-beta.4",
|
|
80
80
|
"smol-toml": "^1.8.0",
|
|
81
81
|
"yaml": "2.9.0"
|
package/src/served-world.ts
CHANGED
|
@@ -26,7 +26,7 @@ import { getActiveWorldStore, withHistoryLocks, captureHistory, historyAtInstant
|
|
|
26
26
|
// to `.volter/token` and `.volter/token.read` (0600).
|
|
27
27
|
// One writer per world by construction: the doors run in this process, serialized per twin.
|
|
28
28
|
import { chmodSync, existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync , rmSync} from 'node:fs';
|
|
29
|
-
import { CALLER_HEADER, callerForHeader, newTraceparent, parseTraceparent, traceparentForDelivery, readTwinRequestJournalFrom, type TwinRequestJournalCursor, assertSafeChangesetName, blobDigest, destinationOf, getActiveBlobStore, journalTwinRequest, loadCheck, twinRequestJournalFailures, openSealedAt, readTwinRequestJournal, serveHttp, twinRequestCredentials, TWIN_PREFIX_HEADER, validateRemoteOrigin, type SealedCredential, type TwinStreamConnection, type TwinStreamSink } from '@volter/world-core/runtime';
|
|
29
|
+
import { CALLER_HEADER, callerForHeader, newTraceparent, parseTraceparent, traceparentForDelivery, readTwinRequestJournalFrom, type TwinRequestJournalCursor, assertSafeChangesetName, blobDigest, destinationOf, getActiveBlobStore, journalTwinRequest, loadCheck, twinRequestJournalFailures, openSealedAt, readTwinRequestJournal, serveHttp, twinRequestCredentials, TWIN_PREFIX_HEADER, TWIN_SITES_HEADER, validateRemoteOrigin, type SealedCredential, type TwinStreamConnection, type TwinStreamSink } from '@volter/world-core/runtime';
|
|
30
30
|
import { APP_READ_ENDPOINT_ENV } from './init.ts';
|
|
31
31
|
import { packFacts } from './pack-facts.ts';
|
|
32
32
|
import { grantOf, presentedSecrets, sameSecret, spentPasses, verifyPass, type TrustedIssuer, type WorldCredentials } from '@volter/world-access';
|
|
@@ -827,6 +827,11 @@ export class WorldDoors {
|
|
|
827
827
|
// the twin is mounted under this World's path: live URLs it mints must carry it (twinPublicBase)
|
|
828
828
|
headers.set(TWIN_PREFIX_HEADER, `/${this.served}/${vendor}`);
|
|
829
829
|
headers.set('x-forwarded-host', url.host); headers.set('x-forwarded-proto', url.protocol.replace(':', ''));
|
|
830
|
+
// where this World shows the hostnames its twins answer, for a page that links one (twinSiteUrl): under its own
|
|
831
|
+
// origin on this machine (siteOfHost); a World without one shows none
|
|
832
|
+
const own = this.host.browserOrigin?.() ?? null;
|
|
833
|
+
const sites = own ? new URL(own) : null;
|
|
834
|
+
if (sites && sites.hostname.endsWith('.localhost')) headers.set(TWIN_SITES_HEADER, `${sites.protocol}//{host}.${sites.host}`); else headers.delete(TWIN_SITES_HEADER);
|
|
830
835
|
const body = request.method === 'GET' || request.method === 'HEAD' ? undefined : await request.arrayBuffer();
|
|
831
836
|
const answer = await twin(new Request(`${url.origin}/${tail.join('/')}${url.search}`, { method: request.method, headers, ...(body === undefined ? {} : { body }), redirect: 'manual' }));
|
|
832
837
|
// an upgrade the twin answered (a tunnel's control or visitor socket) goes back as it is
|
|
@@ -868,7 +873,7 @@ export class WorldDoors {
|
|
|
868
873
|
// what leaves for the vendor before the seal is applied: no World token in any header it can arrive
|
|
869
874
|
// under (an SDK's own `Authorization: Bearer` included), no cookie, no routing headers of this World
|
|
870
875
|
const caller = new Headers(request.headers);
|
|
871
|
-
for (const h of [TOKEN_HEADER, TWINS_KEY_HEADER, TWIN_PREFIX_HEADER, CALLER_HEADER, 'host', 'x-forwarded-host', 'x-forwarded-proto', 'cookie']) caller.delete(h);
|
|
876
|
+
for (const h of [TOKEN_HEADER, TWINS_KEY_HEADER, TWIN_PREFIX_HEADER, TWIN_SITES_HEADER, CALLER_HEADER, 'host', 'x-forwarded-host', 'x-forwarded-proto', 'cookie']) caller.delete(h);
|
|
872
877
|
// a secret this World minted (`tok_…`, live, revoked or expired) or one that opens it never leaves
|
|
873
878
|
const authorization = caller.get('authorization');
|
|
874
879
|
const offered = authorization ? presentedSecrets(new Headers({ authorization }), { token: TOKEN_HEADER, twinsKey: TWINS_KEY_HEADER }) : [];
|
|
@@ -1013,9 +1018,6 @@ export class WorldDoors {
|
|
|
1013
1018
|
}
|
|
1014
1019
|
if (kind === 'map' && !name && request.method === 'GET') return Response.json(await this.map());
|
|
1015
1020
|
if (kind === 'timeline' && !name && request.method === 'GET') return this.timeline(url);
|
|
1016
|
-
// the sites this World's twins answer (a Workers Custom Domain, an R2 public domain), each read in a browser at
|
|
1017
|
-
// `<hostname>.<the World's origin>` (siteOfHost)
|
|
1018
|
-
if (kind === 'sites' && !name && request.method === 'GET') return Response.json({ world: this.served, sites: (await this.claimedHosts(url.origin)).flatMap((c) => c.hosts.map((host) => ({ twin: c.vendor, host }))) });
|
|
1019
1021
|
if (kind === 'diff' && !name && request.method === 'GET') {
|
|
1020
1022
|
const delta = diffWorld(this.name, { root: this.worldRoot });
|
|
1021
1023
|
// what another World pushed here is in its changeset already: never this World's uncut changes
|