@astrale-os/kernel-server 0.5.0-beta.7 → 0.5.0-beta.71
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/capture.d.ts +0 -1
- package/dist/capture.js +0 -1
- package/dist/cors/cors.d.ts +0 -1
- package/dist/cors/cors.js +11 -4
- package/dist/cors/index.d.ts +0 -1
- package/dist/cors/index.js +0 -1
- package/dist/cors/types.d.ts +0 -1
- package/dist/cors/types.js +0 -1
- package/dist/errors/admission.d.ts +7 -0
- package/dist/errors/admission.js +22 -0
- package/dist/errors/availability.d.ts +0 -1
- package/dist/errors/availability.js +0 -1
- package/dist/errors/classify.d.ts +8 -1
- package/dist/errors/classify.js +15 -1
- package/dist/errors/index.d.ts +2 -2
- package/dist/errors/index.js +2 -2
- package/dist/errors/request-body.d.ts +0 -1
- package/dist/errors/request-body.js +0 -1
- package/dist/errors/response-body.d.ts +0 -1
- package/dist/errors/response-body.js +0 -1
- package/dist/index.d.ts +8 -4
- package/dist/index.js +7 -3
- package/dist/invocation/context.d.ts +3 -3
- package/dist/invocation/context.js +2 -2
- package/dist/invocation/identity.d.ts +1 -2
- package/dist/invocation/identity.js +1 -2
- package/dist/invocation/index.d.ts +1 -2
- package/dist/invocation/index.js +1 -2
- package/dist/invocation/legacy/index.d.ts +20 -0
- package/dist/invocation/legacy/index.js +20 -0
- package/dist/invocation/{publication-route.d.ts → legacy/publication-route.d.ts} +7 -5
- package/dist/invocation/{publication-route.js → legacy/publication-route.js} +7 -13
- package/dist/invocation/release-route.d.ts +26 -0
- package/dist/invocation/release-route.js +55 -0
- package/dist/invocation/types.d.ts +20 -7
- package/dist/invocation/types.js +0 -1
- package/dist/issuer/exchange.d.ts +0 -1
- package/dist/issuer/exchange.js +20 -10
- package/dist/issuer/index.d.ts +0 -1
- package/dist/issuer/index.js +0 -1
- package/dist/issuer/routes.d.ts +0 -1
- package/dist/issuer/routes.js +33 -5
- package/dist/issuer/types.d.ts +5 -1
- package/dist/issuer/types.js +0 -1
- package/dist/lifecycle/active.d.ts +4 -1
- package/dist/lifecycle/active.js +48 -11
- package/dist/lifecycle/index.d.ts +0 -1
- package/dist/lifecycle/index.js +0 -1
- package/dist/release/delivery/handler.d.ts +13 -0
- package/dist/{publication → release}/delivery/handler.js +42 -15
- package/dist/{publication → release}/delivery/index.d.ts +0 -1
- package/dist/{publication → release}/delivery/index.js +0 -1
- package/dist/release/delivery/types.d.ts +21 -0
- package/dist/release/delivery/types.js +1 -0
- package/dist/release/index.d.ts +3 -0
- package/dist/release/index.js +2 -0
- package/dist/release/legacy/delivery.d.ts +18 -0
- package/dist/release/legacy/delivery.js +2 -0
- package/dist/release/legacy/index.d.ts +39 -0
- package/dist/release/legacy/index.js +38 -0
- package/dist/release/legacy/snapshot.d.ts +26 -0
- package/dist/release/legacy/snapshot.js +55 -0
- package/dist/release/legacy/table.d.ts +5 -0
- package/dist/{publication → release/legacy}/table.js +5 -6
- package/dist/release/legacy/types.d.ts +31 -0
- package/dist/release/legacy/types.js +1 -0
- package/dist/release/served.d.ts +30 -0
- package/dist/release/served.js +14 -0
- package/dist/release/snapshot.d.ts +26 -0
- package/dist/release/snapshot.js +54 -0
- package/dist/release/table.d.ts +4 -0
- package/dist/release/table.js +11 -0
- package/dist/release/types.d.ts +33 -0
- package/dist/release/types.js +1 -0
- package/dist/routes/index.d.ts +1 -2
- package/dist/routes/index.js +1 -2
- package/dist/routes/routes.d.ts +9 -7
- package/dist/routes/routes.js +314 -123
- package/dist/server.d.ts +0 -1
- package/dist/server.js +110 -48
- package/dist/transport/body.d.ts +0 -1
- package/dist/transport/body.js +0 -1
- package/dist/transport/codecs.d.ts +2 -3
- package/dist/transport/codecs.js +4 -4
- package/dist/transport/credential.d.ts +0 -1
- package/dist/transport/credential.js +0 -1
- package/dist/transport/http/binary-request.d.ts +11 -0
- package/dist/transport/http/binary-request.js +102 -0
- package/dist/transport/http/handler.d.ts +8 -3
- package/dist/transport/http/handler.js +95 -45
- package/dist/transport/http/index.d.ts +0 -1
- package/dist/transport/http/index.js +0 -1
- package/dist/transport/http/render.d.ts +9 -4
- package/dist/transport/http/render.js +150 -5
- package/dist/transport/index.d.ts +0 -1
- package/dist/transport/index.js +0 -1
- package/dist/transport/router.d.ts +0 -1
- package/dist/transport/router.js +0 -1
- package/dist/transport/stream-error.d.ts +0 -1
- package/dist/transport/stream-error.js +0 -1
- package/dist/transport/types.d.ts +1 -2
- package/dist/transport/types.js +0 -1
- package/dist/transport/websocket/index.d.ts +0 -1
- package/dist/transport/websocket/index.js +0 -1
- package/dist/transport/websocket/session.d.ts +3 -3
- package/dist/transport/websocket/session.js +30 -30
- package/dist/transport/websocket/upgrade.d.ts +2 -3
- package/dist/transport/websocket/upgrade.js +7 -7
- package/dist/types.d.ts +32 -6
- package/dist/types.js +0 -1
- package/package.json +12 -15
- package/dist/capture.d.ts.map +0 -1
- package/dist/capture.js.map +0 -1
- package/dist/cors/cors.d.ts.map +0 -1
- package/dist/cors/cors.js.map +0 -1
- package/dist/cors/index.d.ts.map +0 -1
- package/dist/cors/index.js.map +0 -1
- package/dist/cors/types.d.ts.map +0 -1
- package/dist/cors/types.js.map +0 -1
- package/dist/errors/availability.d.ts.map +0 -1
- package/dist/errors/availability.js.map +0 -1
- package/dist/errors/classify.d.ts.map +0 -1
- package/dist/errors/classify.js.map +0 -1
- package/dist/errors/index.d.ts.map +0 -1
- package/dist/errors/index.js.map +0 -1
- package/dist/errors/request-body.d.ts.map +0 -1
- package/dist/errors/request-body.js.map +0 -1
- package/dist/errors/response-body.d.ts.map +0 -1
- package/dist/errors/response-body.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/invocation/context.d.ts.map +0 -1
- package/dist/invocation/context.js.map +0 -1
- package/dist/invocation/identity.d.ts.map +0 -1
- package/dist/invocation/identity.js.map +0 -1
- package/dist/invocation/index.d.ts.map +0 -1
- package/dist/invocation/index.js.map +0 -1
- package/dist/invocation/publication-route.d.ts.map +0 -1
- package/dist/invocation/publication-route.js.map +0 -1
- package/dist/invocation/types.d.ts.map +0 -1
- package/dist/invocation/types.js.map +0 -1
- package/dist/issuer/exchange.d.ts.map +0 -1
- package/dist/issuer/exchange.js.map +0 -1
- package/dist/issuer/index.d.ts.map +0 -1
- package/dist/issuer/index.js.map +0 -1
- package/dist/issuer/routes.d.ts.map +0 -1
- package/dist/issuer/routes.js.map +0 -1
- package/dist/issuer/types.d.ts.map +0 -1
- package/dist/issuer/types.js.map +0 -1
- package/dist/lifecycle/active.d.ts.map +0 -1
- package/dist/lifecycle/active.js.map +0 -1
- package/dist/lifecycle/index.d.ts.map +0 -1
- package/dist/lifecycle/index.js.map +0 -1
- package/dist/publication/delivery/handler.d.ts +0 -10
- package/dist/publication/delivery/handler.d.ts.map +0 -1
- package/dist/publication/delivery/handler.js.map +0 -1
- package/dist/publication/delivery/index.d.ts.map +0 -1
- package/dist/publication/delivery/index.js.map +0 -1
- package/dist/publication/delivery/types.d.ts +0 -12
- package/dist/publication/delivery/types.d.ts.map +0 -1
- package/dist/publication/delivery/types.js +0 -2
- package/dist/publication/delivery/types.js.map +0 -1
- package/dist/publication/index.d.ts +0 -4
- package/dist/publication/index.d.ts.map +0 -1
- package/dist/publication/index.js +0 -3
- package/dist/publication/index.js.map +0 -1
- package/dist/publication/snapshot.d.ts +0 -16
- package/dist/publication/snapshot.d.ts.map +0 -1
- package/dist/publication/snapshot.js +0 -39
- package/dist/publication/snapshot.js.map +0 -1
- package/dist/publication/table.d.ts +0 -4
- package/dist/publication/table.d.ts.map +0 -1
- package/dist/publication/table.js.map +0 -1
- package/dist/publication/types.d.ts +0 -23
- package/dist/publication/types.d.ts.map +0 -1
- package/dist/publication/types.js +0 -2
- package/dist/publication/types.js.map +0 -1
- package/dist/publication/validator.d.ts +0 -4
- package/dist/publication/validator.d.ts.map +0 -1
- package/dist/publication/validator.js +0 -17
- package/dist/publication/validator.js.map +0 -1
- package/dist/routes/index.d.ts.map +0 -1
- package/dist/routes/index.js.map +0 -1
- package/dist/routes/routes.d.ts.map +0 -1
- package/dist/routes/routes.js.map +0 -1
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/transport/body.d.ts.map +0 -1
- package/dist/transport/body.js.map +0 -1
- package/dist/transport/codecs.d.ts.map +0 -1
- package/dist/transport/codecs.js.map +0 -1
- package/dist/transport/credential.d.ts.map +0 -1
- package/dist/transport/credential.js.map +0 -1
- package/dist/transport/http/handler.d.ts.map +0 -1
- package/dist/transport/http/handler.js.map +0 -1
- package/dist/transport/http/index.d.ts.map +0 -1
- package/dist/transport/http/index.js.map +0 -1
- package/dist/transport/http/render.d.ts.map +0 -1
- package/dist/transport/http/render.js.map +0 -1
- package/dist/transport/index.d.ts.map +0 -1
- package/dist/transport/index.js.map +0 -1
- package/dist/transport/router.d.ts.map +0 -1
- package/dist/transport/router.js.map +0 -1
- package/dist/transport/stream-error.d.ts.map +0 -1
- package/dist/transport/stream-error.js.map +0 -1
- package/dist/transport/types.d.ts.map +0 -1
- package/dist/transport/types.js.map +0 -1
- package/dist/transport/websocket/index.d.ts.map +0 -1
- package/dist/transport/websocket/index.js.map +0 -1
- package/dist/transport/websocket/session.d.ts.map +0 -1
- package/dist/transport/websocket/session.js.map +0 -1
- package/dist/transport/websocket/upgrade.d.ts.map +0 -1
- package/dist/transport/websocket/upgrade.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
package/dist/issuer/exchange.js
CHANGED
|
@@ -2,6 +2,7 @@ import { inspect as inspectCredential } from '@astrale-os/kernel-core/auth/crede
|
|
|
2
2
|
import * as errors from '@astrale-os/kernel-protocol/errors';
|
|
3
3
|
import * as exchangeProtocol from '@astrale-os/kernel-protocol/issuer/exchange';
|
|
4
4
|
import { paths as issuerPaths } from '@astrale-os/kernel-protocol/issuer/paths';
|
|
5
|
+
import { admissionRefusal, retryAfterHeaders } from '../errors/index.js';
|
|
5
6
|
const PROVIDER_CODES = new Set([
|
|
6
7
|
errors.CODES.AUTH_INVALID,
|
|
7
8
|
errors.CODES.AUTH_EXPIRED,
|
|
@@ -24,7 +25,10 @@ export function mount(app, issuer, provider, cors, active, timeoutMs) {
|
|
|
24
25
|
}
|
|
25
26
|
app.all(path, async (context) => {
|
|
26
27
|
const request = context.req.raw;
|
|
27
|
-
const respond = (payload, extra) => json(payload, errors.httpStatusOf(payload.error), request, cors,
|
|
28
|
+
const respond = (payload, extra) => json(payload, errors.httpStatusOf(payload.error), request, cors, {
|
|
29
|
+
...retryAfterHeaders(payload.error),
|
|
30
|
+
...extra,
|
|
31
|
+
});
|
|
28
32
|
let admitted;
|
|
29
33
|
try {
|
|
30
34
|
admitted = exchangeProtocol.acceptHttpRequest({
|
|
@@ -40,12 +44,9 @@ export function mount(app, issuer, provider, cors, active, timeoutMs) {
|
|
|
40
44
|
}
|
|
41
45
|
throw cause;
|
|
42
46
|
}
|
|
43
|
-
if (!active.isAccepting) {
|
|
44
|
-
return respond(error('BACKEND_UNAVAILABLE', 'Token exchange is unavailable.'));
|
|
45
|
-
}
|
|
46
47
|
const operation = active.begin(timeoutMs, request.signal);
|
|
47
48
|
if (operation === undefined) {
|
|
48
|
-
return respond(
|
|
49
|
+
return respond(exchangeProtocol.acceptErrorResponse({ error: admissionRefusal(active.isAccepting) }));
|
|
49
50
|
}
|
|
50
51
|
try {
|
|
51
52
|
try {
|
|
@@ -60,6 +61,11 @@ export function mount(app, issuer, provider, cors, active, timeoutMs) {
|
|
|
60
61
|
}
|
|
61
62
|
throw cause;
|
|
62
63
|
}
|
|
64
|
+
if (operation.timedOut) {
|
|
65
|
+
return respond(error('DEADLINE_EXCEEDED', 'Token-exchange deadline elapsed.'));
|
|
66
|
+
}
|
|
67
|
+
if (operation.signal.aborted)
|
|
68
|
+
throw operation.signal.reason;
|
|
63
69
|
let output;
|
|
64
70
|
try {
|
|
65
71
|
output = await provider.exchange(admitted, { signal: operation.signal });
|
|
@@ -68,6 +74,8 @@ export function mount(app, issuer, provider, cors, active, timeoutMs) {
|
|
|
68
74
|
if (operation.timedOut) {
|
|
69
75
|
return respond(error('DEADLINE_EXCEEDED', 'Token-exchange deadline elapsed.'));
|
|
70
76
|
}
|
|
77
|
+
if (operation.signal.aborted)
|
|
78
|
+
throw operation.signal.reason;
|
|
71
79
|
if (cause instanceof errors.ProtocolError && PROVIDER_CODES.has(cause.payload.code)) {
|
|
72
80
|
return respond(exchangeProtocol.acceptErrorResponse({ error: cause.payload }));
|
|
73
81
|
}
|
|
@@ -76,6 +84,8 @@ export function mount(app, issuer, provider, cors, active, timeoutMs) {
|
|
|
76
84
|
if (operation.timedOut) {
|
|
77
85
|
return respond(error('DEADLINE_EXCEEDED', 'Token-exchange deadline elapsed.'));
|
|
78
86
|
}
|
|
87
|
+
if (operation.signal.aborted)
|
|
88
|
+
throw operation.signal.reason;
|
|
79
89
|
const response = exchangeProtocol.acceptResponse(output);
|
|
80
90
|
if (inspectCredential(response.token).claims.exp !== response.expiresAt) {
|
|
81
91
|
throw new TypeError('Token-exchange provider returned inconsistent expiry evidence.');
|
|
@@ -125,13 +135,13 @@ function error(code, message) {
|
|
|
125
135
|
});
|
|
126
136
|
}
|
|
127
137
|
function json(value, status, request, cors, extra) {
|
|
138
|
+
const additional = new Headers(extra);
|
|
128
139
|
const headers = new Headers(exchangeProtocol.responseHeaders());
|
|
129
|
-
|
|
140
|
+
const exposed = additional.has('retry-after') ? ['retry-after'] : [];
|
|
141
|
+
for (const [name, value] of Object.entries(cors.response(request, exposed))) {
|
|
130
142
|
headers.set(name, value);
|
|
131
|
-
if (extra !== undefined) {
|
|
132
|
-
for (const [name, value] of new Headers(extra))
|
|
133
|
-
headers.set(name, value);
|
|
134
143
|
}
|
|
144
|
+
for (const [name, value] of additional)
|
|
145
|
+
headers.set(name, value);
|
|
135
146
|
return new Response(JSON.stringify(value), { status, headers });
|
|
136
147
|
}
|
|
137
|
-
//# sourceMappingURL=exchange.js.map
|
package/dist/issuer/index.d.ts
CHANGED
package/dist/issuer/index.js
CHANGED
package/dist/issuer/routes.d.ts
CHANGED
|
@@ -11,4 +11,3 @@ export declare function issuerRouteReservations(input: Issuer, tokenExchange?: b
|
|
|
11
11
|
export declare function mountIssuer(app: ServerRouter, input: Issuer, cors: CorsPolicy, active: ActiveOperations, timeoutMs: number, tokenExchange?: Provider): void;
|
|
12
12
|
/** Admit static discovery configuration before Runtime Boot performs any durable work. */
|
|
13
13
|
export declare function admitIssuer(input: Issuer): Issuer;
|
|
14
|
-
//# sourceMappingURL=routes.d.ts.map
|
package/dist/issuer/routes.js
CHANGED
|
@@ -2,7 +2,8 @@ import { configuration } from '@astrale-os/kernel-protocol/issuer/configuration'
|
|
|
2
2
|
import { hosted } from '@astrale-os/kernel-protocol/issuer/hosted';
|
|
3
3
|
import { keySet } from '@astrale-os/kernel-protocol/issuer/key-set';
|
|
4
4
|
import { paths as issuerPaths } from '@astrale-os/kernel-protocol/issuer/paths';
|
|
5
|
-
import {
|
|
5
|
+
import { workflowEngine } from '@astrale-os/kernel-protocol/issuer/workflow-engine';
|
|
6
|
+
import { admissionRefusal, IssuerKeysUnavailableError, retryAfterHeaders } from '../errors/index.js';
|
|
6
7
|
import { mount } from './exchange.js';
|
|
7
8
|
export function issuerRouteReservations(input, tokenExchange = false) {
|
|
8
9
|
const paths = issuerPaths(input.issuer);
|
|
@@ -13,6 +14,9 @@ export function issuerRouteReservations(input, tokenExchange = false) {
|
|
|
13
14
|
if (tokenExchange) {
|
|
14
15
|
reservations.push(Object.freeze({ path: paths.tokenExchange, methods: Object.freeze(['POST']) }));
|
|
15
16
|
}
|
|
17
|
+
if (input.workflowEngineKeys !== undefined) {
|
|
18
|
+
reservations.push(Object.freeze({ path: paths.workflowEngine, methods: Object.freeze(['GET']) }));
|
|
19
|
+
}
|
|
16
20
|
if (input.loadIssuerPublicKeys !== undefined) {
|
|
17
21
|
const base = new URL(input.issuer).pathname.replace(/\/+$/u, '');
|
|
18
22
|
reservations.push(Object.freeze({
|
|
@@ -32,11 +36,28 @@ export function mountIssuer(app, input, cors, active, timeoutMs, tokenExchange)
|
|
|
32
36
|
...cors.response(request),
|
|
33
37
|
'cache-control': 'no-cache',
|
|
34
38
|
});
|
|
39
|
+
// A lifecycle refusal names saturation or drain and presents its retry delay.
|
|
40
|
+
const refusal = (request) => {
|
|
41
|
+
const refused = admissionRefusal(active.isAccepting);
|
|
42
|
+
const retry = retryAfterHeaders(refused);
|
|
43
|
+
return {
|
|
44
|
+
body: { error: refused.message },
|
|
45
|
+
headers: {
|
|
46
|
+
...cors.response(request, Object.keys(retry)),
|
|
47
|
+
'cache-control': 'no-cache',
|
|
48
|
+
...retry,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
};
|
|
35
52
|
const algorithm = input.signingAlgorithm ?? 'ES256';
|
|
36
53
|
const discovery = configuration(issuer, [algorithm], {
|
|
37
54
|
tokenExchange: tokenExchange !== undefined,
|
|
38
55
|
});
|
|
39
56
|
app.get(paths.configuration, (context) => context.json(discovery, 200, headers(context.req.raw)));
|
|
57
|
+
if (input.workflowEngineKeys !== undefined) {
|
|
58
|
+
const engine = workflowEngine(issuer, input.workflowEngineKeys);
|
|
59
|
+
app.get(paths.workflowEngine, (context) => context.json(engine, 200, headers(context.req.raw)));
|
|
60
|
+
}
|
|
40
61
|
if (cors.enabled) {
|
|
41
62
|
app.options(paths.configuration, (context) => cors.preflight(context.req.raw, { methods: ['GET'] }));
|
|
42
63
|
app.options(paths.keys, (context) => cors.preflight(context.req.raw, { methods: ['GET'] }));
|
|
@@ -44,7 +65,8 @@ export function mountIssuer(app, input, cors, active, timeoutMs, tokenExchange)
|
|
|
44
65
|
app.get(paths.keys, async (context) => {
|
|
45
66
|
const operation = active.begin(timeoutMs, context.req.raw.signal);
|
|
46
67
|
if (operation === undefined) {
|
|
47
|
-
|
|
68
|
+
const refused = refusal(context.req.raw);
|
|
69
|
+
return context.json(refused.body, 503, refused.headers);
|
|
48
70
|
}
|
|
49
71
|
try {
|
|
50
72
|
const keys = await input.loadPublicKeys(operation.signal);
|
|
@@ -76,7 +98,8 @@ export function mountIssuer(app, input, cors, active, timeoutMs, tokenExchange)
|
|
|
76
98
|
return context.json({ error: 'Issuer not found.' }, 404, headers(context.req.raw));
|
|
77
99
|
const operation = active.begin(timeoutMs, context.req.raw.signal);
|
|
78
100
|
if (operation === undefined) {
|
|
79
|
-
|
|
101
|
+
const refused = refusal(context.req.raw);
|
|
102
|
+
return context.json(refused.body, 503, refused.headers);
|
|
80
103
|
}
|
|
81
104
|
try {
|
|
82
105
|
const keys = await hostedKeys(loadIssuerPublicKeys, hostedIssuer, operation.signal, algorithm);
|
|
@@ -100,7 +123,8 @@ export function mountIssuer(app, input, cors, active, timeoutMs, tokenExchange)
|
|
|
100
123
|
return context.json({ error: 'Issuer not found.' }, 404, headers(context.req.raw));
|
|
101
124
|
const operation = active.begin(timeoutMs, context.req.raw.signal);
|
|
102
125
|
if (operation === undefined) {
|
|
103
|
-
|
|
126
|
+
const refused = refusal(context.req.raw);
|
|
127
|
+
return context.json(refused.body, 503, refused.headers);
|
|
104
128
|
}
|
|
105
129
|
try {
|
|
106
130
|
const keys = await hostedKeys(loadIssuerPublicKeys, hostedIssuer, operation.signal, algorithm);
|
|
@@ -136,9 +160,14 @@ export function admitIssuer(input) {
|
|
|
136
160
|
}
|
|
137
161
|
const loadPublicKeys = input.loadPublicKeys;
|
|
138
162
|
const loadIssuerPublicKeys = input.loadIssuerPublicKeys;
|
|
163
|
+
// A Kernel that drives an engine publishes it; invalid keys fail closed at boot.
|
|
164
|
+
const workflowEngineKeys = input.workflowEngineKeys === undefined
|
|
165
|
+
? undefined
|
|
166
|
+
: workflowEngine(issuer, input.workflowEngineKeys).identity_keys;
|
|
139
167
|
return Object.freeze({
|
|
140
168
|
issuer,
|
|
141
169
|
signingAlgorithm,
|
|
170
|
+
...(workflowEngineKeys === undefined ? {} : { workflowEngineKeys }),
|
|
142
171
|
loadPublicKeys: (signal) => loadPublicKeys.call(input, signal),
|
|
143
172
|
...(loadIssuerPublicKeys === undefined
|
|
144
173
|
? {}
|
|
@@ -147,4 +176,3 @@ export function admitIssuer(input) {
|
|
|
147
176
|
}),
|
|
148
177
|
});
|
|
149
178
|
}
|
|
150
|
-
//# sourceMappingURL=routes.js.map
|
package/dist/issuer/types.d.ts
CHANGED
|
@@ -8,5 +8,9 @@ export interface Issuer {
|
|
|
8
8
|
loadPublicKeys(signal: AbortSignal): Promise<readonly JsonWebKey[]>;
|
|
9
9
|
/** Optional hosted-key discovery for issuers below `<issuer>/iss/:thumbprint`. */
|
|
10
10
|
readonly loadIssuerPublicKeys?: (issuer: IssuerId, signal: AbortSignal) => Promise<readonly JsonWebKey[]>;
|
|
11
|
+
/**
|
|
12
|
+
* Request identity keys of the workflow engine this Kernel drives, published at
|
|
13
|
+
* `<issuer>/.well-known/astrale/workflow-engine.json` so Domains verify the engine's requests.
|
|
14
|
+
*/
|
|
15
|
+
readonly workflowEngineKeys?: readonly string[];
|
|
11
16
|
}
|
|
12
|
-
//# sourceMappingURL=types.d.ts.map
|
package/dist/issuer/types.js
CHANGED
|
@@ -12,6 +12,8 @@ export interface ActiveOperation {
|
|
|
12
12
|
/** Register cooperative cleanup and return an idempotent unregistration function. */
|
|
13
13
|
onCancel(cancel: CancelWork): () => void;
|
|
14
14
|
cancel(reason: string): void;
|
|
15
|
+
/** Replace the remaining budget after a trusted transport binding is admitted. */
|
|
16
|
+
extend(timeoutMs: number): void;
|
|
15
17
|
settle(): void;
|
|
16
18
|
readonly finished: Promise<void>;
|
|
17
19
|
}
|
|
@@ -26,6 +28,8 @@ export declare class ActiveOperations {
|
|
|
26
28
|
private changed;
|
|
27
29
|
constructor(maximumConcurrentOperations: number);
|
|
28
30
|
get isAccepting(): boolean;
|
|
31
|
+
/** Whether a newly arriving operation can be admitted without semantic dispatch. */
|
|
32
|
+
get isAvailable(): boolean;
|
|
29
33
|
begin(timeoutMs: number, externalSignal?: AbortSignal): ActiveOperation | undefined;
|
|
30
34
|
attachSocket(socket: ActiveSocket): boolean;
|
|
31
35
|
detachSocket(socket: ActiveSocket): void;
|
|
@@ -37,4 +41,3 @@ export declare class ActiveOperations {
|
|
|
37
41
|
private closeSockets;
|
|
38
42
|
}
|
|
39
43
|
export {};
|
|
40
|
-
//# sourceMappingURL=active.d.ts.map
|
package/dist/lifecycle/active.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// Streaming iterators can need several microtasks to return after cancellation. Keep the
|
|
2
|
+
// cleanup join bounded even when a producer ignores its cancellation signal.
|
|
3
|
+
const CANCELLATION_CLEANUP_GRACE_MS = 250;
|
|
1
4
|
export class ActiveOperations {
|
|
2
5
|
maximumConcurrentOperations;
|
|
3
6
|
accepting = true;
|
|
@@ -13,10 +16,13 @@ export class ActiveOperations {
|
|
|
13
16
|
get isAccepting() {
|
|
14
17
|
return this.accepting;
|
|
15
18
|
}
|
|
19
|
+
/** Whether a newly arriving operation can be admitted without semantic dispatch. */
|
|
20
|
+
get isAvailable() {
|
|
21
|
+
return this.accepting && this.operations.size < this.maximumConcurrentOperations;
|
|
22
|
+
}
|
|
16
23
|
begin(timeoutMs, externalSignal) {
|
|
17
|
-
if (!this.
|
|
24
|
+
if (!this.isAvailable)
|
|
18
25
|
return undefined;
|
|
19
|
-
}
|
|
20
26
|
const operation = new Operation(Date.now() + timeoutMs, () => {
|
|
21
27
|
this.operations.delete(operation);
|
|
22
28
|
this.changed?.();
|
|
@@ -63,19 +69,32 @@ export class ActiveOperations {
|
|
|
63
69
|
}
|
|
64
70
|
close(deadline) {
|
|
65
71
|
this.drain();
|
|
66
|
-
this.closing
|
|
72
|
+
if (this.closing === undefined) {
|
|
73
|
+
const flight = this.closeOnce(deadline);
|
|
74
|
+
this.closing = flight;
|
|
75
|
+
void flight.catch(() => {
|
|
76
|
+
// A failed close leaves admission terminal, but residual work may settle later.
|
|
77
|
+
// Let the same owner join that cleanup on its next close attempt.
|
|
78
|
+
if (this.closing === flight)
|
|
79
|
+
this.closing = undefined;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
67
82
|
return this.closing;
|
|
68
83
|
}
|
|
69
84
|
async closeOnce(deadline) {
|
|
70
85
|
await this.waitUntilIdleOr(deadline);
|
|
86
|
+
const hasCancellationWork = [...this.operations].some((operation) => operation.hasCancellationWork);
|
|
71
87
|
if (this.operations.size > 0) {
|
|
72
88
|
for (const operation of this.operations)
|
|
73
89
|
operation.cancel('server closing');
|
|
74
90
|
}
|
|
75
91
|
this.closeSockets();
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
92
|
+
if (hasCancellationWork) {
|
|
93
|
+
await this.waitUntilIdleOr(Date.now() + CANCELLATION_CLEANUP_GRACE_MS);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
await Promise.resolve();
|
|
97
|
+
}
|
|
79
98
|
if (this.operations.size > 0 || this.backgroundTasks.size > 0) {
|
|
80
99
|
this.closed = true;
|
|
81
100
|
throw new Error(`Server close deadline elapsed with ${this.operations.size} active operation(s) and ${this.backgroundTasks.size} background task(s).`);
|
|
@@ -110,11 +129,11 @@ export class ActiveOperations {
|
|
|
110
129
|
}
|
|
111
130
|
}
|
|
112
131
|
class Operation {
|
|
113
|
-
deadline;
|
|
114
132
|
onSettled;
|
|
115
133
|
controller = new AbortController();
|
|
116
134
|
cancelWork = new Set();
|
|
117
135
|
timer;
|
|
136
|
+
deadlineValue;
|
|
118
137
|
external;
|
|
119
138
|
settled = false;
|
|
120
139
|
cancelled = false;
|
|
@@ -122,15 +141,31 @@ class Operation {
|
|
|
122
141
|
resolveFinished;
|
|
123
142
|
finished;
|
|
124
143
|
constructor(deadline, onSettled) {
|
|
125
|
-
this.deadline = deadline;
|
|
126
144
|
this.onSettled = onSettled;
|
|
145
|
+
this.deadlineValue = deadline;
|
|
127
146
|
this.finished = new Promise((resolve) => {
|
|
128
147
|
this.resolveFinished = resolve;
|
|
129
148
|
});
|
|
130
|
-
this.timer =
|
|
149
|
+
this.timer = this.arm();
|
|
150
|
+
}
|
|
151
|
+
get deadline() {
|
|
152
|
+
return this.deadlineValue;
|
|
153
|
+
}
|
|
154
|
+
extend(timeoutMs) {
|
|
155
|
+
if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0 || timeoutMs > 2_147_483_647) {
|
|
156
|
+
throw new TypeError('Active operation timeout is invalid.');
|
|
157
|
+
}
|
|
158
|
+
if (this.cancelled || this.settled)
|
|
159
|
+
return;
|
|
160
|
+
clearTimeout(this.timer);
|
|
161
|
+
this.deadlineValue = Date.now() + timeoutMs;
|
|
162
|
+
this.timer = this.arm();
|
|
163
|
+
}
|
|
164
|
+
arm() {
|
|
165
|
+
return setTimeout(() => {
|
|
131
166
|
this.timeout = true;
|
|
132
167
|
this.cancel('invocation deadline exceeded');
|
|
133
|
-
}, Math.min(Math.max(0,
|
|
168
|
+
}, Math.min(Math.max(0, this.deadlineValue - Date.now()), 2_147_483_647));
|
|
134
169
|
}
|
|
135
170
|
link(signal) {
|
|
136
171
|
if (signal === undefined)
|
|
@@ -148,6 +183,9 @@ class Operation {
|
|
|
148
183
|
get timedOut() {
|
|
149
184
|
return this.timeout;
|
|
150
185
|
}
|
|
186
|
+
get hasCancellationWork() {
|
|
187
|
+
return this.cancelWork.size > 0;
|
|
188
|
+
}
|
|
151
189
|
onCancel(cancel) {
|
|
152
190
|
if (this.cancelled) {
|
|
153
191
|
void settleCancellation(cancel, abortReason(this.controller.signal));
|
|
@@ -197,4 +235,3 @@ async function settleCancellation(cancel, reason) {
|
|
|
197
235
|
function abortReason(signal) {
|
|
198
236
|
return signal.reason instanceof Error ? signal.reason.message : 'operation cancelled';
|
|
199
237
|
}
|
|
200
|
-
//# sourceMappingURL=active.js.map
|
package/dist/lifecycle/index.js
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ActiveOperations } from '../../lifecycle/index.js';
|
|
2
|
+
import type { Served } from '../served.js';
|
|
3
|
+
import type { Provider } from './types.js';
|
|
4
|
+
export interface Limits {
|
|
5
|
+
readonly maximumDeliveryBytes: number;
|
|
6
|
+
readonly invocationTimeoutMs: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Serve one delivery request against the exact snapshot that selected its URL, in the request's
|
|
10
|
+
* version: Delivery v2 names the served release, Delivery v1 the served Publication (a release's
|
|
11
|
+
* frozen v3 projection). A v3-input destination keeps its Delivery v1 decoder.
|
|
12
|
+
*/
|
|
13
|
+
export declare function handleDelivery(request: Request, snapshot: Served, provider: Provider | undefined, active: ActiveOperations, limits: Limits, corsFor: (exposedHeaders?: readonly string[]) => Readonly<Record<string, string>>): Promise<Response>;
|
|
@@ -1,23 +1,34 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import * as codecs from '@astrale-os/kernel-protocol/codecs';
|
|
2
|
+
import * as release from '@astrale-os/kernel-protocol/release';
|
|
3
|
+
import { admissionRefusal, DeliveryUnavailableError, retryAfterHeaders, } from '../../errors/index.js';
|
|
3
4
|
import { RequestBodyInvalidError, RequestBodyTooLargeError } from '../../errors/index.js';
|
|
4
5
|
import { readBoundedBody } from '../../transport/index.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import { servedDocument } from '../served.js';
|
|
7
|
+
const delivery = release.delivery;
|
|
8
|
+
const publicationDelivery = release.legacy.delivery;
|
|
9
|
+
/**
|
|
10
|
+
* Serve one delivery request against the exact snapshot that selected its URL, in the request's
|
|
11
|
+
* version: Delivery v2 names the served release, Delivery v1 the served Publication (a release's
|
|
12
|
+
* frozen v3 projection). A v3-input destination keeps its Delivery v1 decoder.
|
|
13
|
+
*/
|
|
14
|
+
export async function handleDelivery(request, snapshot, provider, active, limits, corsFor) {
|
|
15
|
+
const cors = corsFor();
|
|
8
16
|
if (request.method !== 'POST') {
|
|
9
17
|
return response({ error: 'Delivery requires POST.' }, 405, cors);
|
|
10
18
|
}
|
|
11
19
|
if (provider === undefined) {
|
|
12
20
|
return response({ error: 'Delivery is unavailable.' }, 503, cors);
|
|
13
21
|
}
|
|
14
|
-
const advertised = snapshot.
|
|
22
|
+
const advertised = servedDocument(snapshot).delivery;
|
|
15
23
|
if (advertised === undefined) {
|
|
16
24
|
return response({ error: 'Delivery is unavailable.' }, 404, cors);
|
|
17
25
|
}
|
|
18
26
|
const operation = active.begin(limits.invocationTimeoutMs, request.signal);
|
|
19
|
-
if (operation === undefined)
|
|
20
|
-
|
|
27
|
+
if (operation === undefined) {
|
|
28
|
+
const refusal = admissionRefusal(active.isAccepting);
|
|
29
|
+
const retry = retryAfterHeaders(refusal);
|
|
30
|
+
return response({ error: refusal.message }, 503, { ...corsFor(Object.keys(retry)), ...retry });
|
|
31
|
+
}
|
|
21
32
|
try {
|
|
22
33
|
const authorization = request.headers.get('authorization');
|
|
23
34
|
const token = bearer(authorization);
|
|
@@ -55,7 +66,10 @@ export async function handleDelivery(request, snapshot, provider, active, limits
|
|
|
55
66
|
}
|
|
56
67
|
let input;
|
|
57
68
|
try {
|
|
58
|
-
input =
|
|
69
|
+
input =
|
|
70
|
+
snapshot.kind === 'release'
|
|
71
|
+
? delivery.acceptRequest(decoded)
|
|
72
|
+
: publicationDelivery.acceptRequest(decoded);
|
|
59
73
|
}
|
|
60
74
|
catch (cause) {
|
|
61
75
|
if (cause instanceof delivery.Error && cause.code === 'DELIVERY_REQUEST_INVALID') {
|
|
@@ -63,8 +77,13 @@ export async function handleDelivery(request, snapshot, provider, active, limits
|
|
|
63
77
|
}
|
|
64
78
|
throw cause;
|
|
65
79
|
}
|
|
66
|
-
|
|
67
|
-
|
|
80
|
+
const named = input.version === 2 ? input.release : input.etag;
|
|
81
|
+
const served = input.version === 2 ? servedRelease(snapshot) : snapshot.publication.etag;
|
|
82
|
+
if (named !== served) {
|
|
83
|
+
const error = input.version === 2
|
|
84
|
+
? 'Release digest differs from request.'
|
|
85
|
+
: 'Publication ETag differs from request.';
|
|
86
|
+
return response({ error }, 409, cors);
|
|
68
87
|
}
|
|
69
88
|
let candidate;
|
|
70
89
|
try {
|
|
@@ -81,7 +100,8 @@ export async function handleDelivery(request, snapshot, provider, active, limits
|
|
|
81
100
|
}
|
|
82
101
|
let created;
|
|
83
102
|
try {
|
|
84
|
-
created =
|
|
103
|
+
created =
|
|
104
|
+
input.version === 2 ? delivery.accept(candidate) : publicationDelivery.accept(candidate);
|
|
85
105
|
}
|
|
86
106
|
catch (cause) {
|
|
87
107
|
if (cause instanceof delivery.Error) {
|
|
@@ -89,8 +109,12 @@ export async function handleDelivery(request, snapshot, provider, active, limits
|
|
|
89
109
|
}
|
|
90
110
|
throw cause;
|
|
91
111
|
}
|
|
92
|
-
|
|
93
|
-
|
|
112
|
+
const delivered = created.version === 2 ? created.release.digest : created.publication.etag;
|
|
113
|
+
if (delivered !== served) {
|
|
114
|
+
const error = created.version === 2
|
|
115
|
+
? 'Delivery provider returned a different release.'
|
|
116
|
+
: 'Delivery provider returned a different Publication.';
|
|
117
|
+
return response({ error }, 500, cors);
|
|
94
118
|
}
|
|
95
119
|
const encoded = codecs.json.encode(created);
|
|
96
120
|
if (encodedSize(encoded) > limits.maximumDeliveryBytes) {
|
|
@@ -104,6 +128,10 @@ export async function handleDelivery(request, snapshot, provider, active, limits
|
|
|
104
128
|
operation.settle();
|
|
105
129
|
}
|
|
106
130
|
}
|
|
131
|
+
/** Digest a Delivery v2 must name: only a release-backed destination serves one. */
|
|
132
|
+
function servedRelease(snapshot) {
|
|
133
|
+
return snapshot.kind === 'release' ? snapshot.release.digest : undefined;
|
|
134
|
+
}
|
|
107
135
|
function bearer(input) {
|
|
108
136
|
if (input === null)
|
|
109
137
|
return undefined;
|
|
@@ -124,4 +152,3 @@ function encodedSize(input) {
|
|
|
124
152
|
function toBody(input) {
|
|
125
153
|
return input.buffer.slice(input.byteOffset, input.byteOffset + input.byteLength);
|
|
126
154
|
}
|
|
127
|
-
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type * as release from '@astrale-os/kernel-protocol/release';
|
|
2
|
+
export interface Context {
|
|
3
|
+
/** Omitted for a public endpoint; otherwise the exact admitted retrieval credential. */
|
|
4
|
+
readonly token?: release.delivery.Token;
|
|
5
|
+
readonly signal: AbortSignal;
|
|
6
|
+
}
|
|
7
|
+
/** Provider-owned retrieval, construction, and attestation signing. */
|
|
8
|
+
export interface Provider {
|
|
9
|
+
/**
|
|
10
|
+
* Answer in the request's version: a Delivery v2 carrying the served release for a v2 request,
|
|
11
|
+
* and a Delivery v1 carrying the served Publication (at a release-backed destination, its frozen
|
|
12
|
+
* v3 projection) for a deprecated v1 request. A v3-input destination passes only v1 requests.
|
|
13
|
+
* Throw DeliveryUnavailableError only for an expected dependency outage.
|
|
14
|
+
*
|
|
15
|
+
* A release-backed destination (`ServerOptions.release`) passes v2 requests, so its provider
|
|
16
|
+
* must answer both versions. The deprecated v1-only `publication.delivery.Provider` still
|
|
17
|
+
* type-checks here, because method parameters are compared bivariantly, but every v2 request
|
|
18
|
+
* it receives fails with 500 `Delivery provider returned an invalid response.`
|
|
19
|
+
*/
|
|
20
|
+
create(request: release.delivery.Request | release.legacy.delivery.Request, context: Context): Promise<release.delivery.Delivery | release.legacy.delivery.Delivery>;
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type * as release from '@astrale-os/kernel-protocol/release';
|
|
2
|
+
import type { Context as DeliveryContext } from '../delivery/types.js';
|
|
3
|
+
/** @deprecated Successor: `release.delivery.Context`, the same retrieval context. */
|
|
4
|
+
export type Context = DeliveryContext;
|
|
5
|
+
/**
|
|
6
|
+
* The Delivery v1 provider of a v3-input destination, which only ever receives v1 requests. It
|
|
7
|
+
* remains assignable to `release.delivery.Provider`, so existing providers keep configuring a
|
|
8
|
+
* Server unchanged. Pass it only with `ServerOptions.publication`: a release-backed destination
|
|
9
|
+
* also passes Delivery v2 requests, which this provider cannot answer.
|
|
10
|
+
*
|
|
11
|
+
* @deprecated Successor: `release.delivery.Provider`, which answers a v2 request over the release
|
|
12
|
+
* and a v1 request over its frozen v3 projection.
|
|
13
|
+
*/
|
|
14
|
+
export interface Provider {
|
|
15
|
+
create(request: release.legacy.delivery.Request, context: Context): Promise<release.legacy.delivery.Delivery>;
|
|
16
|
+
}
|
|
17
|
+
/** @deprecated Successor: `release.delivery.handleDelivery`, which serves both snapshots. */
|
|
18
|
+
export { handleDelivery, type Limits } from '../delivery/handler.js';
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Publication snapshot of a v3-input destination: a Server built from a v2/v3 Publication
|
|
3
|
+
* serves `domain.json`, its bundle, Delivery v1 and its native routes exactly as before the release
|
|
4
|
+
* snapshot, and keeps the #508 same-schema and schema-drift continuity
|
|
5
|
+
* (`server/invocation/legacy/publication-route.ts`). Its answers are pinned byte for byte by the
|
|
6
|
+
* golden transcript of `server/__tests__/transcripts.test.ts`.
|
|
7
|
+
*
|
|
8
|
+
* @deprecated Use `ServerOptions.release` with `prepareReleaseSnapshot`, which serves a
|
|
9
|
+
* `DomainRelease` at `release.json` beside its frozen v3 projection at `domain.json` and admits
|
|
10
|
+
* only exact routing.
|
|
11
|
+
*
|
|
12
|
+
* Short-term consumers:
|
|
13
|
+
* - the legacy direct-mode Workers built by an SDK that seals v2/v3 only: the domains platform
|
|
14
|
+
* Domains, Shell, the Services `development` environment and `ui:domain`, until they serve
|
|
15
|
+
* releases;
|
|
16
|
+
* - an SDK Worker whose deployment host binds no build digest, which serves today's v3 document;
|
|
17
|
+
* - the Host's intrinsic Kernel and Host Domain publishers (`host/kernel/publication/`) and the
|
|
18
|
+
* FalkorDB qualification remote Domain, until the Host serves its intrinsic release.
|
|
19
|
+
*
|
|
20
|
+
* Removal, in a separate breaking release: the conditions of `protocol/release/legacy/index.ts`
|
|
21
|
+
* hold (no stable Worker serves a v2/v3 document, no installation pins one), no supported SDK
|
|
22
|
+
* builds a v3-input Worker, and the intrinsic Kernel and Host Domains serve a release. Then
|
|
23
|
+
* delete, in the same PR:
|
|
24
|
+
* - this folder with its `.spec` (its v1-only Delivery `Provider` included), the `publication`
|
|
25
|
+
* namespace, `preparePublicationSnapshot` and the Publication snapshot types of
|
|
26
|
+
* `server/index.ts` and `server/.spec/api.d.ts`, and the `./publication/snapshot` subpath
|
|
27
|
+
* (source and `dist`) of `server/package.json`;
|
|
28
|
+
* - `ServerOptions.publication` (`server/types.ts`) and `HandlerRequest.publication`
|
|
29
|
+
* (`server/invocation/types.ts`), with the `publication` branch of `Served`
|
|
30
|
+
* (`server/release/served.ts`) and every `kind === 'publication'` branch it selects in
|
|
31
|
+
* `server/routes/routes.ts`, `server/release/delivery/handler.ts` and `admitVia`;
|
|
32
|
+
* - `server/invocation/legacy/` (laws SV-PUBLICATION-CONTINUITY, SV-PUBLICATION-ADMITS-LEGACY-VIA);
|
|
33
|
+
* - the golden transcript that records a v3-input server, keeping the one of a server without a
|
|
34
|
+
* source.
|
|
35
|
+
*/
|
|
36
|
+
export { preparePublicationSnapshot, readPreparedPublicationSnapshot, type PreparedPublicationSnapshot, } from './snapshot.js';
|
|
37
|
+
export type { PublicationSnapshot, PublicationSnapshotInput, PublicationSource } from './types.js';
|
|
38
|
+
/** @deprecated The Delivery v1 boundary of a v3-input destination; use `release.delivery`. */
|
|
39
|
+
export * as delivery from './delivery.js';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Publication snapshot of a v3-input destination: a Server built from a v2/v3 Publication
|
|
3
|
+
* serves `domain.json`, its bundle, Delivery v1 and its native routes exactly as before the release
|
|
4
|
+
* snapshot, and keeps the #508 same-schema and schema-drift continuity
|
|
5
|
+
* (`server/invocation/legacy/publication-route.ts`). Its answers are pinned byte for byte by the
|
|
6
|
+
* golden transcript of `server/__tests__/transcripts.test.ts`.
|
|
7
|
+
*
|
|
8
|
+
* @deprecated Use `ServerOptions.release` with `prepareReleaseSnapshot`, which serves a
|
|
9
|
+
* `DomainRelease` at `release.json` beside its frozen v3 projection at `domain.json` and admits
|
|
10
|
+
* only exact routing.
|
|
11
|
+
*
|
|
12
|
+
* Short-term consumers:
|
|
13
|
+
* - the legacy direct-mode Workers built by an SDK that seals v2/v3 only: the domains platform
|
|
14
|
+
* Domains, Shell, the Services `development` environment and `ui:domain`, until they serve
|
|
15
|
+
* releases;
|
|
16
|
+
* - an SDK Worker whose deployment host binds no build digest, which serves today's v3 document;
|
|
17
|
+
* - the Host's intrinsic Kernel and Host Domain publishers (`host/kernel/publication/`) and the
|
|
18
|
+
* FalkorDB qualification remote Domain, until the Host serves its intrinsic release.
|
|
19
|
+
*
|
|
20
|
+
* Removal, in a separate breaking release: the conditions of `protocol/release/legacy/index.ts`
|
|
21
|
+
* hold (no stable Worker serves a v2/v3 document, no installation pins one), no supported SDK
|
|
22
|
+
* builds a v3-input Worker, and the intrinsic Kernel and Host Domains serve a release. Then
|
|
23
|
+
* delete, in the same PR:
|
|
24
|
+
* - this folder with its `.spec` (its v1-only Delivery `Provider` included), the `publication`
|
|
25
|
+
* namespace, `preparePublicationSnapshot` and the Publication snapshot types of
|
|
26
|
+
* `server/index.ts` and `server/.spec/api.d.ts`, and the `./publication/snapshot` subpath
|
|
27
|
+
* (source and `dist`) of `server/package.json`;
|
|
28
|
+
* - `ServerOptions.publication` (`server/types.ts`) and `HandlerRequest.publication`
|
|
29
|
+
* (`server/invocation/types.ts`), with the `publication` branch of `Served`
|
|
30
|
+
* (`server/release/served.ts`) and every `kind === 'publication'` branch it selects in
|
|
31
|
+
* `server/routes/routes.ts`, `server/release/delivery/handler.ts` and `admitVia`;
|
|
32
|
+
* - `server/invocation/legacy/` (laws SV-PUBLICATION-CONTINUITY, SV-PUBLICATION-ADMITS-LEGACY-VIA);
|
|
33
|
+
* - the golden transcript that records a v3-input server, keeping the one of a server without a
|
|
34
|
+
* source.
|
|
35
|
+
*/
|
|
36
|
+
export { preparePublicationSnapshot, readPreparedPublicationSnapshot, } from './snapshot.js';
|
|
37
|
+
/** @deprecated The Delivery v1 boundary of a v3-input destination; use `release.delivery`. */
|
|
38
|
+
export * as delivery from './delivery.js';
|