@volter/twin-fly 0.1.1 → 0.1.3
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/fly-server.js +7 -4
- package/package.json +3 -3
- package/src/fly-server.ts +7 -4
package/dist/src/fly-server.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// engine is a provider behind a door, never the serve path's business.
|
|
12
12
|
import { serveHttp } from '@volter/world-core';
|
|
13
13
|
import { rows, VIRTUAL_FLY_RUNTIME } from "./fly-machines.js";
|
|
14
|
-
import { worldNow, statefulTwinManifest } from '@volter/world-core';
|
|
14
|
+
import { isReadOnlyRequest, worldNow, statefulTwinManifest, withRequestScopes } from '@volter/world-core';
|
|
15
15
|
import { handleFlyTwinRequest } from "./fly-twin.js";
|
|
16
16
|
/**
|
|
17
17
|
* The pack's whole HTTP surface as a plain fetch (runtime contract R12b): `createFlyTwinServer`
|
|
@@ -23,10 +23,13 @@ import { handleFlyTwinRequest } from "./fly-twin.js";
|
|
|
23
23
|
* header map, which the adapter's fixed request shape does not thread.
|
|
24
24
|
*/
|
|
25
25
|
export function createFlyTwinFetch(options = {}) {
|
|
26
|
-
const readOnly = options.readOnly ?? false;
|
|
27
26
|
const root = options.root; // undefined resolves through the kernel's projectRoot — the serve path never reads the process (R4)
|
|
28
27
|
const runtime = options.runtime ?? VIRTUAL_FLY_RUNTIME;
|
|
29
|
-
|
|
28
|
+
// a read-only request (x-volter-read-only) is a request to a read-only twin: a machine read answers the
|
|
29
|
+
// control plane's current state without folding a runtime exit into it (no inspect, no restart, no
|
|
30
|
+
// write), nothing is written (withRequestScopes: the pack opts in)
|
|
31
|
+
return withRequestScopes(async function flyTwinFetch(request) {
|
|
32
|
+
const readOnly = (options.readOnly ?? false) || isReadOnlyRequest(request);
|
|
30
33
|
const url = new URL(request.url);
|
|
31
34
|
// GET /twin — the discovery manifest (education inside the twin). Constants only: no
|
|
32
35
|
// clock, no state, so every replay of this door is byte-identical (R9).
|
|
@@ -49,7 +52,7 @@ export function createFlyTwinFetch(options = {}) {
|
|
|
49
52
|
if (status === 204 || out === null)
|
|
50
53
|
return new Response(null, { status });
|
|
51
54
|
return new Response(JSON.stringify(out), { status, headers: { 'content-type': 'application/json' } });
|
|
52
|
-
};
|
|
55
|
+
}, { refuse: () => Response.json({ error: 'read-only twin: writes are disabled' }, { status: 405 }) });
|
|
53
56
|
}
|
|
54
57
|
export async function createFlyTwinServer(options = {}) {
|
|
55
58
|
const readOnly = options.readOnly ?? false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/twin-fly",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Local Fly.io Machines API twin (api.machines.dev v1: apps/machines/volumes/secrets CRUD, machine lifecycle states+events, leases, wait) whose execution plane is REAL local Docker — control plane twinned, containers genuinely run. Built on @volter/world-core.",
|
|
5
5
|
"author": "Volter (https://github.com/volter-ai)",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -36,12 +36,12 @@
|
|
|
36
36
|
"postpack": "node ../../../scripts/publish/prepare-publish.mjs postpack"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@volter/world-core": "2.0.
|
|
39
|
+
"@volter/world-core": "2.0.3"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/bun": "^1.2.20",
|
|
43
43
|
"@types/node": "^24.0.0",
|
|
44
|
-
"@volter/world-core": "2.0.
|
|
44
|
+
"@volter/world-core": "2.0.3",
|
|
45
45
|
"@volter/world-tooling": "0.1.0",
|
|
46
46
|
"typescript": "^5.9.0"
|
|
47
47
|
},
|
package/src/fly-server.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// engine is a provider behind a door, never the serve path's business.
|
|
12
12
|
import { serveHttp } from '@volter/world-core';
|
|
13
13
|
import { rows, VIRTUAL_FLY_RUNTIME, type FlyContainerRuntime } from './fly-machines.ts';
|
|
14
|
-
import { worldNow, statefulTwinManifest} from '@volter/world-core';
|
|
14
|
+
import { isReadOnlyRequest, worldNow, statefulTwinManifest, withRequestScopes } from '@volter/world-core';
|
|
15
15
|
import { handleFlyTwinRequest } from './fly-twin.ts';
|
|
16
16
|
|
|
17
17
|
/** Options every Fly-twin HTTP surface needs, independent of who owns the socket. The
|
|
@@ -34,10 +34,13 @@ export interface FlyTwinFetchOptions {
|
|
|
34
34
|
* header map, which the adapter's fixed request shape does not thread.
|
|
35
35
|
*/
|
|
36
36
|
export function createFlyTwinFetch(options: FlyTwinFetchOptions = {}): (request: Request) => Promise<Response> {
|
|
37
|
-
const readOnly = options.readOnly ?? false;
|
|
38
37
|
const root = options.root; // undefined resolves through the kernel's projectRoot — the serve path never reads the process (R4)
|
|
39
38
|
const runtime = options.runtime ?? VIRTUAL_FLY_RUNTIME;
|
|
40
|
-
|
|
39
|
+
// a read-only request (x-volter-read-only) is a request to a read-only twin: a machine read answers the
|
|
40
|
+
// control plane's current state without folding a runtime exit into it (no inspect, no restart, no
|
|
41
|
+
// write), nothing is written (withRequestScopes: the pack opts in)
|
|
42
|
+
return withRequestScopes(async function flyTwinFetch(request: Request): Promise<Response> {
|
|
43
|
+
const readOnly = (options.readOnly ?? false) || isReadOnlyRequest(request);
|
|
41
44
|
const url = new URL(request.url);
|
|
42
45
|
// GET /twin — the discovery manifest (education inside the twin). Constants only: no
|
|
43
46
|
// clock, no state, so every replay of this door is byte-identical (R9).
|
|
@@ -59,7 +62,7 @@ export function createFlyTwinFetch(options: FlyTwinFetchOptions = {}): (request:
|
|
|
59
62
|
});
|
|
60
63
|
if (status === 204 || out === null) return new Response(null, { status });
|
|
61
64
|
return new Response(JSON.stringify(out), { status, headers: { 'content-type': 'application/json' } });
|
|
62
|
-
};
|
|
65
|
+
}, { refuse: () => Response.json({ error: 'read-only twin: writes are disabled' }, { status: 405 }) });
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
export async function createFlyTwinServer(
|