@volter/world-core 3.0.30 → 3.0.32
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/host-routing.cjs +106 -0
- package/dist/host-routing.d.cts +7 -0
- package/dist/inject.cjs +5 -8
- package/dist/src/board-keys.d.ts +6 -0
- package/dist/src/board-keys.js +4 -0
- package/dist/src/browser-cookie-jar.d.ts +9 -0
- package/dist/src/browser-cookie-jar.js +104 -0
- package/dist/src/browser-state.d.ts +52 -0
- package/dist/src/browser-state.js +105 -0
- package/dist/src/browser.d.ts +12 -0
- package/dist/src/browser.js +197 -0
- package/dist/src/derived-core.d.ts +3 -7
- package/dist/src/derived.d.ts +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/pack-fetch.d.ts +0 -3
- package/dist/src/pack-fetch.js +5 -26
- package/dist/src/public-suffixes.json +1 -0
- package/dist/src/runtime.d.ts +1 -1
- package/dist/src/runtime.js +1 -1
- package/dist/src/twin-fetch.d.ts +1 -1
- package/dist/src/twin-fetch.js +23 -4
- package/dist/vendor-hosts.cjs +13 -105
- package/dist/vendor-hosts.d.cts +3 -0
- package/host-routing.cjs +106 -0
- package/host-routing.d.cts +7 -0
- package/inject.cjs +5 -8
- package/package.json +11 -1
- package/src/board-keys.ts +4 -0
- package/src/browser-cookie-jar.ts +77 -0
- package/src/browser-session.ts +1 -1
- package/src/browser-state.ts +89 -0
- package/src/browser.ts +164 -0
- package/src/derived-core.ts +4 -5
- package/src/derived.ts +1 -1
- package/src/index.ts +2 -0
- package/src/pack-fetch.ts +6 -24
- package/src/public-suffixes.json +1 -0
- package/src/runtime.ts +2 -1
- package/src/twin-fetch.ts +9 -4
- package/vendor-hosts.cjs +13 -105
- package/vendor-hosts.d.cts +3 -0
- package/dist/src/browser-session-permit.d.ts +0 -13
- package/dist/src/browser-session-permit.js +0 -51
- package/src/browser-session-permit.ts +0 -43
|
@@ -268,7 +268,6 @@ export type VendorManifest = {
|
|
|
268
268
|
descriptor: Omit<PackDescriptor, 'vendor'>;
|
|
269
269
|
ingest?: IngestDecl;
|
|
270
270
|
rateBudget?: RateBudgetDeclaration;
|
|
271
|
-
browserSession?: DerivedManifest['browserSession'];
|
|
272
271
|
/** the vendor has no vendor-backed half (architecture, "The descriptor"): packOf copies it, and derives no state system */
|
|
273
272
|
vendorBacked?: DerivedManifest['vendorBacked'];
|
|
274
273
|
};
|
|
@@ -544,11 +543,6 @@ export type DerivedManifest = {
|
|
|
544
543
|
owner: string;
|
|
545
544
|
resource: string;
|
|
546
545
|
}>;
|
|
547
|
-
/** The browser session of a World's person, issued with world-ui's kit. Declaring it lets the World offer View as. */
|
|
548
|
-
browserSession?: {
|
|
549
|
-
cookie: string;
|
|
550
|
-
scope?: string;
|
|
551
|
-
};
|
|
552
546
|
/** the vendor's screens this pack serves or owes (demand decides which exist) */
|
|
553
547
|
screens?: ScreenDecl[];
|
|
554
548
|
/** The discovery door's facts (`GET /twin`): what the twin is of, what it stores, and how it is authenticated. */
|
|
@@ -689,8 +683,10 @@ export declare function render(r: TwinResource): Record<string, unknown>;
|
|
|
689
683
|
* a caller that pins an instant passes its own). */
|
|
690
684
|
/** One call of a protocol-3 pack's default data (`src/semantics/seed.ts` exports `seed: SeedCall[]`): a request to the
|
|
691
685
|
* vendor's own operation (or the pack's door), made in order against the twin by the runner `volter-world init` writes
|
|
692
|
-
* beside the copied data.
|
|
686
|
+
* beside the copied data. An ordinary path is relative to the twin base. A call naming a browser uses the
|
|
687
|
+
* vendor's absolute URL and is exported separately as `browserSeed`, after the ordinary `seed` calls. */
|
|
693
688
|
export type SeedCall = {
|
|
689
|
+
browser?: string;
|
|
694
690
|
method: string;
|
|
695
691
|
path: string;
|
|
696
692
|
body?: unknown;
|
package/dist/src/derived.d.ts
CHANGED
|
@@ -125,6 +125,7 @@ export type DerivedFetch = ((request: Request) => Promise<Response>) & {
|
|
|
125
125
|
export type Workspace = {
|
|
126
126
|
id: string;
|
|
127
127
|
path: string;
|
|
128
|
+
host?: string;
|
|
128
129
|
};
|
|
129
130
|
/** A page of the World's board (architecture, "The board"): a page there is to see at the vendor, a record's own (an
|
|
130
131
|
* account's profile, each of its posts, a site and each page it serves), as the vendor's pack lists them from its state
|
package/dist/src/index.d.ts
CHANGED
|
@@ -65,3 +65,4 @@ export * as git from './git/index.js';
|
|
|
65
65
|
export { parseScenarioDocument, scenarioFaultResult, ScenarioEngine, ScenarioError } from './scenario.js';
|
|
66
66
|
export type { PackScenarioAdapter, ScenarioDecision, ScenarioDocument, ScenarioExtractorSpec, ScenarioFault, ScenarioFaultResult, ScenarioFeatures, ScenarioHandler, ScenarioMatcher, ScenarioMissRecord, ScenarioStatus } from './scenario.js';
|
|
67
67
|
export { browserSessionToken, startBrowserSession, endBrowserSession } from './browser-session.js';
|
|
68
|
+
export { assertBrowserName, browserOrigin, validateBrowserState, cookieMatchesHost, type BrowserCookie, type BrowserState, type BrowserIndexedDB } from './browser-state.js';
|
package/dist/src/index.js
CHANGED
|
@@ -60,3 +60,4 @@ export * as git from "./git/index.js";
|
|
|
60
60
|
// ── the scenario grammar (architecture, "Behaviour") ───────────────────────────────────────────
|
|
61
61
|
export { parseScenarioDocument, scenarioFaultResult, ScenarioEngine, ScenarioError } from "./scenario.js";
|
|
62
62
|
export { browserSessionToken, startBrowserSession, endBrowserSession } from "./browser-session.js";
|
|
63
|
+
export { assertBrowserName, browserOrigin, validateBrowserState, cookieMatchesHost } from "./browser-state.js";
|
package/dist/src/pack-fetch.d.ts
CHANGED
|
@@ -56,12 +56,9 @@ export type LanePart = {
|
|
|
56
56
|
fetch: ((request: Request) => Promise<Response>) & {
|
|
57
57
|
serves?: (method: string, path: string) => boolean;
|
|
58
58
|
boards?: boolean;
|
|
59
|
-
drawsScreens?: boolean;
|
|
60
59
|
draws?: (url: string) => boolean;
|
|
61
60
|
/** the hosts the lane's built content screens name: its vendor's router sends `<base>/@<host>/` there */
|
|
62
61
|
contentHosts?: ReadonlyArray<string>;
|
|
63
|
-
/** A vendor's browser session applies to its lanes without a lane importing its parent's manifest. */
|
|
64
|
-
sessionDeclaration?: (session: NonNullable<DerivedManifest['browserSession']>) => void;
|
|
65
62
|
};
|
|
66
63
|
manifest: {
|
|
67
64
|
doors?: ReadonlyArray<{
|
package/dist/src/pack-fetch.js
CHANGED
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
// `screens/<id>.tsx`), and the API (the derived dispatch over the generated surface, the handlers and the core). Every
|
|
6
6
|
// one of them is answered over the contract's context, which the kernel opens: a pack opens none, reads the tree and
|
|
7
7
|
// writes it only through one.
|
|
8
|
-
import { startBrowserSession, endBrowserSession } from "./browser-session.js";
|
|
9
|
-
import { BROWSER_SESSION_PATH, takeBrowserSessionPermit } from "./browser-session-permit.js";
|
|
10
8
|
import { ORIGINAL_PATH_HEADER } from "./sigv4.js";
|
|
11
9
|
import { placedCookies, TWIN_PREFIX_HEADER } from "./twin-fetch.js";
|
|
12
10
|
import { PREFIX_PARAMS_HEADER } from "./derived.js";
|
|
@@ -21,7 +19,7 @@ import { deferPerform, performRequestGroup, RefusedWriteError, VendorWriteError
|
|
|
21
19
|
import { withCors } from "./cors.js";
|
|
22
20
|
import { contentAddressOf } from "./content-route.js";
|
|
23
21
|
import { getPack } from "./packRegistry.js";
|
|
24
|
-
import { hostRules } from '../
|
|
22
|
+
import { hostRules } from '../host-routing.cjs';
|
|
25
23
|
import { socketUpgrade } from "./sockets.js";
|
|
26
24
|
import { MACHINE_POOL, POOL_KINDS } from "./machines.js";
|
|
27
25
|
import { applyTwinWrite } from "./serve.js";
|
|
@@ -112,7 +110,6 @@ async function encoded(m, request, res) {
|
|
|
112
110
|
/** A pack's HTTP surface, as the kernel serves it from the pack's parts. */
|
|
113
111
|
export function createPackFetch(parts, options = {}) {
|
|
114
112
|
const m = parts.manifest;
|
|
115
|
-
let browserSession = m.browserSession;
|
|
116
113
|
const scope = {
|
|
117
114
|
...(options.root !== undefined ? { root: options.root } : {}),
|
|
118
115
|
...(options.clock ? { clock: options.clock } : {}),
|
|
@@ -223,7 +220,7 @@ export function createPackFetch(parts, options = {}) {
|
|
|
223
220
|
});
|
|
224
221
|
// the workspaces a person can be shown (Viewing a World): each built workspace screen's id and path, the pack's own
|
|
225
222
|
// and its lanes'
|
|
226
|
-
const workspaces = () => [...(m.screens ?? []).filter((s) => s.kind === 'workspace' && s.status === 'done' && parts.screens?.[s.id]).map((s) => ({ id: s.id, path: s.path })), ...lanesWorkspaces(parts.lanes ?? {})];
|
|
223
|
+
const workspaces = () => [...(m.screens ?? []).filter((s) => s.kind === 'workspace' && s.status === 'done' && parts.screens?.[s.id]).map((s) => ({ id: s.id, path: s.path, host: s.host })), ...lanesWorkspaces(parts.lanes ?? {})];
|
|
227
224
|
/** Whether a built screen a person views (a workspace or a flow, never content an API client reads) draws a url: its host
|
|
228
225
|
* one the screen names, its path the screen's or under it (a root screen draws its root alone). */
|
|
229
226
|
// by what the pack declares built (a screen drawn by another's handler, as X's profile is by its web pages, is built)
|
|
@@ -231,7 +228,6 @@ export function createPackFetch(parts, options = {}) {
|
|
|
231
228
|
const hosts = [s.host, ...(s.hosts ?? [])].map(hostMatcher);
|
|
232
229
|
return { root: s.path.replace(/\/+$/, '') === '', host: (h) => hosts.some((match) => match(h)), path: pathMatcher(s.path, true) };
|
|
233
230
|
});
|
|
234
|
-
const drawsScreens = viewed.length > 0 || Object.values(parts.lanes ?? {}).some((l) => l.fetch.drawsScreens);
|
|
235
231
|
const drawsUrl = (at) => {
|
|
236
232
|
try {
|
|
237
233
|
const u = new URL(at);
|
|
@@ -381,7 +377,7 @@ export function createPackFetch(parts, options = {}) {
|
|
|
381
377
|
if (request.method === 'GET' && path === '/twin' && m.discovery) {
|
|
382
378
|
const d = m.discovery;
|
|
383
379
|
// the workspaces a person can be shown (Viewing a World): each built workspace screen's id and path
|
|
384
|
-
const shown =
|
|
380
|
+
const shown = workspaces().length ? { screens: workspaces() } : {};
|
|
385
381
|
// a model vendor's: its state, and what its scenario scripts, with the scenario's live counts
|
|
386
382
|
if (parts.scenario && d.behavior) {
|
|
387
383
|
return Response.json({ ...shown, ...twinManifest({
|
|
@@ -399,20 +395,6 @@ export function createPackFetch(parts, options = {}) {
|
|
|
399
395
|
// header would make a payout time makes the caller's), but a tenant's, when the vendor keeps tenants apart
|
|
400
396
|
if (parts.clock)
|
|
401
397
|
await runAsVendorMove(async () => parts.clock(await open(new Request(request.url, m.tenant ? { headers: request.headers } : {}), 'clock', 'POST', '/_twin/clock', {})));
|
|
402
|
-
if (path === BROWSER_SESSION_PATH && browserSession) {
|
|
403
|
-
if (request.method !== 'POST' || readOnly)
|
|
404
|
-
return Response.json({ error: 'a browser session needs a permitted write' }, { status: 403 });
|
|
405
|
-
const choice = takeBrowserSessionPermit(request, m.service, options.root);
|
|
406
|
-
if (!choice)
|
|
407
|
-
return Response.json({ error: 'only the World can change this browser session' }, { status: 403 });
|
|
408
|
-
const ctx = await open(request, 'browser-session', 'POST', BROWSER_SESSION_PATH, {});
|
|
409
|
-
const person = choice.person === null ? null : ctx.rowsRaw('_person').find((p) => p.id === choice.person && typeof p.email === 'string');
|
|
410
|
-
if (person === undefined)
|
|
411
|
-
return Response.json({ error: 'that person is no longer in the World' }, { status: 404 });
|
|
412
|
-
const cleared = await endBrowserSession(ctx, browserSession.cookie);
|
|
413
|
-
const cookie = person ? await startBrowserSession(ctx, String(person.email), browserSession.cookie, browserSession.scope) : cleared;
|
|
414
|
-
return new Response(null, { status: 303, headers: { location: choice.land, 'set-cookie': cookie } });
|
|
415
|
-
}
|
|
416
398
|
if (path.startsWith('/_twin/')) {
|
|
417
399
|
// the World's machine pool, enrolled by the kernel for a vendor that runs images (machines.ts)
|
|
418
400
|
if (m.machines && path === '/_twin/machine-pool' && request.method === 'POST') {
|
|
@@ -531,7 +513,7 @@ export function createPackFetch(parts, options = {}) {
|
|
|
531
513
|
async (asked) => engineOf()?.serve(asked)) : undefined;
|
|
532
514
|
// what serves each operation: the pack's own, and each lane's
|
|
533
515
|
const owners = () => ({ ...api.owners(), ...lanesOwners(parts.lanes ?? {}) });
|
|
534
|
-
return derivedRequestScopes(m, Object.assign(served, {
|
|
516
|
+
return derivedRequestScopes(m, Object.assign(served, { owners, serves, workspaces, boards: Boolean(parts.board), draws: drawsUrl, contentHosts, ...(upgrade ? { upgrade } : {}) }));
|
|
535
517
|
}
|
|
536
518
|
/** The vendor's gateway over its lanes: the lane a request goes to (a door to the lane that declares it, then the first
|
|
537
519
|
* route whose conditions all hold, then the default), behind the gateway's CORS; undefined when none takes it. */
|
|
@@ -591,9 +573,6 @@ const lanesOwners = (lanes) => Object.assign({}, ...Object.values(lanes).map((l)
|
|
|
591
573
|
/** The workspaces a vendor's lanes draw, as one list. */
|
|
592
574
|
const lanesWorkspaces = (lanes) => Object.values(lanes).flatMap((l) => l.fetch.workspaces?.() ?? []);
|
|
593
575
|
export function createVendorFetch(manifest, lanes) {
|
|
594
|
-
if (manifest.browserSession)
|
|
595
|
-
for (const part of Object.values(lanes))
|
|
596
|
-
part.fetch.sessionDeclaration?.(manifest.browserSession);
|
|
597
576
|
const lane = laneRouter(manifest.vendor, manifest.lanes, lanes);
|
|
598
577
|
return Object.assign(async (request) => {
|
|
599
578
|
const path = new URL(request.url).pathname.replace(/\/+$/, '') || '/';
|
|
@@ -616,7 +595,7 @@ export function createVendorFetch(manifest, lanes) {
|
|
|
616
595
|
if (request.method === 'GET' && path === '/twin' && manifest.discovery) {
|
|
617
596
|
// the vendor's screens are its lanes' (a dashboard drawn by one lane is the vendor's)
|
|
618
597
|
const screens = lanesWorkspaces(lanes);
|
|
619
|
-
return Response.json({ ...statefulTwinManifest({ vendor: manifest.vendor, ...manifest.discovery }),
|
|
598
|
+
return Response.json({ ...statefulTwinManifest({ vendor: manifest.vendor, ...manifest.discovery }), ...(screens.length ? { screens } : {}) });
|
|
620
599
|
}
|
|
621
600
|
const to = lane(request);
|
|
622
601
|
return to ? to(request) : Response.json({ error: `${manifest.vendor}: no lane serves ${request.method} ${path}` }, { status: 404 });
|