@astrale-os/kernel-server 0.5.0-beta.8 → 1.0.0-beta.1

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 (241) hide show
  1. package/dist/capture.d.ts +0 -1
  2. package/dist/capture.js +0 -1
  3. package/dist/cors/cors.d.ts +0 -1
  4. package/dist/cors/cors.js +11 -4
  5. package/dist/cors/index.d.ts +0 -1
  6. package/dist/cors/index.js +0 -1
  7. package/dist/cors/types.d.ts +0 -1
  8. package/dist/cors/types.js +0 -1
  9. package/dist/errors/admission.d.ts +7 -0
  10. package/dist/errors/admission.js +22 -0
  11. package/dist/errors/availability.d.ts +0 -1
  12. package/dist/errors/availability.js +0 -1
  13. package/dist/errors/classify.d.ts +8 -1
  14. package/dist/errors/classify.js +15 -1
  15. package/dist/errors/index.d.ts +2 -2
  16. package/dist/errors/index.js +2 -2
  17. package/dist/errors/request-body.d.ts +0 -1
  18. package/dist/errors/request-body.js +0 -1
  19. package/dist/errors/response-body.d.ts +0 -1
  20. package/dist/errors/response-body.js +0 -1
  21. package/dist/index.d.ts +3 -4
  22. package/dist/index.js +2 -3
  23. package/dist/invocation/context.d.ts +3 -3
  24. package/dist/invocation/context.js +2 -2
  25. package/dist/invocation/identity.d.ts +1 -2
  26. package/dist/invocation/identity.js +1 -2
  27. package/dist/invocation/index.d.ts +1 -2
  28. package/dist/invocation/index.js +1 -2
  29. package/dist/invocation/release-route.d.ts +22 -0
  30. package/dist/invocation/release-route.js +32 -0
  31. package/dist/invocation/types.d.ts +8 -7
  32. package/dist/invocation/types.js +0 -1
  33. package/dist/issuer/exchange.d.ts +0 -1
  34. package/dist/issuer/exchange.js +20 -10
  35. package/dist/issuer/index.d.ts +0 -1
  36. package/dist/issuer/index.js +0 -1
  37. package/dist/issuer/routes.d.ts +0 -1
  38. package/dist/issuer/routes.js +57 -48
  39. package/dist/issuer/types.d.ts +5 -1
  40. package/dist/issuer/types.js +0 -1
  41. package/dist/lifecycle/active.d.ts +4 -1
  42. package/dist/lifecycle/active.js +48 -11
  43. package/dist/lifecycle/index.d.ts +0 -1
  44. package/dist/lifecycle/index.js +0 -1
  45. package/dist/release/delivery/handler.d.ts +9 -0
  46. package/dist/{publication → release}/delivery/handler.js +19 -13
  47. package/dist/release/delivery/index.d.ts +1 -0
  48. package/dist/release/delivery/index.js +1 -0
  49. package/dist/{publication → release}/delivery/types.d.ts +4 -5
  50. package/dist/release/delivery/types.js +1 -0
  51. package/dist/release/index.d.ts +3 -0
  52. package/dist/release/index.js +2 -0
  53. package/dist/release/served.d.ts +21 -0
  54. package/dist/release/served.js +10 -0
  55. package/dist/release/snapshot.d.ts +22 -0
  56. package/dist/release/snapshot.js +49 -0
  57. package/dist/release/table.d.ts +4 -0
  58. package/dist/release/table.js +11 -0
  59. package/dist/release/types.d.ts +23 -0
  60. package/dist/release/types.js +1 -0
  61. package/dist/routes/address.d.ts +2 -0
  62. package/dist/routes/address.js +6 -0
  63. package/dist/routes/binary.d.ts +9 -0
  64. package/dist/routes/binary.js +110 -0
  65. package/dist/routes/bundle.d.ts +5 -0
  66. package/dist/routes/bundle.js +50 -0
  67. package/dist/routes/csrf.d.ts +16 -0
  68. package/dist/routes/csrf.js +35 -0
  69. package/dist/routes/document.d.ts +6 -0
  70. package/dist/routes/document.js +57 -0
  71. package/dist/routes/index.d.ts +3 -2
  72. package/dist/routes/index.js +2 -2
  73. package/dist/routes/model.d.ts +15 -0
  74. package/dist/routes/model.js +1 -0
  75. package/dist/routes/native.d.ts +17 -0
  76. package/dist/routes/native.js +126 -0
  77. package/dist/routes/preflight.d.ts +4 -0
  78. package/dist/routes/preflight.js +55 -0
  79. package/dist/routes/response.d.ts +14 -0
  80. package/dist/routes/response.js +33 -0
  81. package/dist/routes/routes.d.ts +7 -24
  82. package/dist/routes/routes.js +24 -439
  83. package/dist/routes/snapshot.d.ts +13 -0
  84. package/dist/routes/snapshot.js +39 -0
  85. package/dist/routes/stream.d.ts +6 -0
  86. package/dist/routes/stream.js +122 -0
  87. package/dist/server.d.ts +0 -1
  88. package/dist/server.js +95 -51
  89. package/dist/transport/body.d.ts +0 -1
  90. package/dist/transport/body.js +0 -1
  91. package/dist/transport/codecs.d.ts +2 -3
  92. package/dist/transport/codecs.js +4 -4
  93. package/dist/transport/credential.d.ts +0 -1
  94. package/dist/transport/credential.js +0 -1
  95. package/dist/transport/http/binary-request.d.ts +11 -0
  96. package/dist/transport/http/binary-request.js +102 -0
  97. package/dist/transport/http/binary.d.ts +6 -0
  98. package/dist/transport/http/binary.js +35 -0
  99. package/dist/transport/http/byte-stream.d.ts +4 -0
  100. package/dist/transport/http/byte-stream.js +123 -0
  101. package/dist/transport/http/control.d.ts +12 -0
  102. package/dist/transport/http/control.js +24 -0
  103. package/dist/transport/http/handler.d.ts +8 -3
  104. package/dist/transport/http/handler.js +97 -45
  105. package/dist/transport/http/index.d.ts +3 -2
  106. package/dist/transport/http/index.js +2 -2
  107. package/dist/transport/http/model.d.ts +20 -0
  108. package/dist/transport/http/model.js +1 -0
  109. package/dist/transport/http/render.d.ts +3 -31
  110. package/dist/transport/http/render.js +18 -269
  111. package/dist/transport/http/response.d.ts +14 -0
  112. package/dist/transport/http/response.js +77 -0
  113. package/dist/transport/http/stream.d.ts +5 -0
  114. package/dist/transport/http/stream.js +134 -0
  115. package/dist/transport/index.d.ts +2 -2
  116. package/dist/transport/index.js +2 -2
  117. package/dist/transport/result.d.ts +13 -0
  118. package/dist/transport/result.js +35 -0
  119. package/dist/transport/router.d.ts +0 -1
  120. package/dist/transport/router.js +0 -1
  121. package/dist/transport/stream-error.d.ts +0 -1
  122. package/dist/transport/stream-error.js +0 -1
  123. package/dist/transport/types.d.ts +1 -2
  124. package/dist/transport/types.js +0 -1
  125. package/dist/transport/websocket/index.d.ts +0 -1
  126. package/dist/transport/websocket/index.js +0 -1
  127. package/dist/transport/websocket/session.d.ts +3 -3
  128. package/dist/transport/websocket/session.js +30 -30
  129. package/dist/transport/websocket/upgrade.d.ts +2 -3
  130. package/dist/transport/websocket/upgrade.js +7 -7
  131. package/dist/types.d.ts +33 -10
  132. package/dist/types.js +0 -1
  133. package/package.json +11 -22
  134. package/dist/capture.d.ts.map +0 -1
  135. package/dist/capture.js.map +0 -1
  136. package/dist/cors/cors.d.ts.map +0 -1
  137. package/dist/cors/cors.js.map +0 -1
  138. package/dist/cors/index.d.ts.map +0 -1
  139. package/dist/cors/index.js.map +0 -1
  140. package/dist/cors/types.d.ts.map +0 -1
  141. package/dist/cors/types.js.map +0 -1
  142. package/dist/errors/availability.d.ts.map +0 -1
  143. package/dist/errors/availability.js.map +0 -1
  144. package/dist/errors/classify.d.ts.map +0 -1
  145. package/dist/errors/classify.js.map +0 -1
  146. package/dist/errors/index.d.ts.map +0 -1
  147. package/dist/errors/index.js.map +0 -1
  148. package/dist/errors/request-body.d.ts.map +0 -1
  149. package/dist/errors/request-body.js.map +0 -1
  150. package/dist/errors/response-body.d.ts.map +0 -1
  151. package/dist/errors/response-body.js.map +0 -1
  152. package/dist/index.d.ts.map +0 -1
  153. package/dist/index.js.map +0 -1
  154. package/dist/invocation/context.d.ts.map +0 -1
  155. package/dist/invocation/context.js.map +0 -1
  156. package/dist/invocation/identity.d.ts.map +0 -1
  157. package/dist/invocation/identity.js.map +0 -1
  158. package/dist/invocation/index.d.ts.map +0 -1
  159. package/dist/invocation/index.js.map +0 -1
  160. package/dist/invocation/publication-route.d.ts +0 -14
  161. package/dist/invocation/publication-route.d.ts.map +0 -1
  162. package/dist/invocation/publication-route.js +0 -45
  163. package/dist/invocation/publication-route.js.map +0 -1
  164. package/dist/invocation/types.d.ts.map +0 -1
  165. package/dist/invocation/types.js.map +0 -1
  166. package/dist/issuer/exchange.d.ts.map +0 -1
  167. package/dist/issuer/exchange.js.map +0 -1
  168. package/dist/issuer/index.d.ts.map +0 -1
  169. package/dist/issuer/index.js.map +0 -1
  170. package/dist/issuer/routes.d.ts.map +0 -1
  171. package/dist/issuer/routes.js.map +0 -1
  172. package/dist/issuer/types.d.ts.map +0 -1
  173. package/dist/issuer/types.js.map +0 -1
  174. package/dist/lifecycle/active.d.ts.map +0 -1
  175. package/dist/lifecycle/active.js.map +0 -1
  176. package/dist/lifecycle/index.d.ts.map +0 -1
  177. package/dist/lifecycle/index.js.map +0 -1
  178. package/dist/publication/delivery/handler.d.ts +0 -10
  179. package/dist/publication/delivery/handler.d.ts.map +0 -1
  180. package/dist/publication/delivery/handler.js.map +0 -1
  181. package/dist/publication/delivery/index.d.ts +0 -3
  182. package/dist/publication/delivery/index.d.ts.map +0 -1
  183. package/dist/publication/delivery/index.js +0 -2
  184. package/dist/publication/delivery/index.js.map +0 -1
  185. package/dist/publication/delivery/types.d.ts.map +0 -1
  186. package/dist/publication/delivery/types.js +0 -2
  187. package/dist/publication/delivery/types.js.map +0 -1
  188. package/dist/publication/index.d.ts +0 -4
  189. package/dist/publication/index.d.ts.map +0 -1
  190. package/dist/publication/index.js +0 -3
  191. package/dist/publication/index.js.map +0 -1
  192. package/dist/publication/snapshot.d.ts +0 -16
  193. package/dist/publication/snapshot.d.ts.map +0 -1
  194. package/dist/publication/snapshot.js +0 -39
  195. package/dist/publication/snapshot.js.map +0 -1
  196. package/dist/publication/table.d.ts +0 -4
  197. package/dist/publication/table.d.ts.map +0 -1
  198. package/dist/publication/table.js +0 -17
  199. package/dist/publication/table.js.map +0 -1
  200. package/dist/publication/types.d.ts +0 -23
  201. package/dist/publication/types.d.ts.map +0 -1
  202. package/dist/publication/types.js +0 -2
  203. package/dist/publication/types.js.map +0 -1
  204. package/dist/publication/validator.d.ts +0 -4
  205. package/dist/publication/validator.d.ts.map +0 -1
  206. package/dist/publication/validator.js +0 -17
  207. package/dist/publication/validator.js.map +0 -1
  208. package/dist/routes/index.d.ts.map +0 -1
  209. package/dist/routes/index.js.map +0 -1
  210. package/dist/routes/routes.d.ts.map +0 -1
  211. package/dist/routes/routes.js.map +0 -1
  212. package/dist/server.d.ts.map +0 -1
  213. package/dist/server.js.map +0 -1
  214. package/dist/transport/body.d.ts.map +0 -1
  215. package/dist/transport/body.js.map +0 -1
  216. package/dist/transport/codecs.d.ts.map +0 -1
  217. package/dist/transport/codecs.js.map +0 -1
  218. package/dist/transport/credential.d.ts.map +0 -1
  219. package/dist/transport/credential.js.map +0 -1
  220. package/dist/transport/http/handler.d.ts.map +0 -1
  221. package/dist/transport/http/handler.js.map +0 -1
  222. package/dist/transport/http/index.d.ts.map +0 -1
  223. package/dist/transport/http/index.js.map +0 -1
  224. package/dist/transport/http/render.d.ts.map +0 -1
  225. package/dist/transport/http/render.js.map +0 -1
  226. package/dist/transport/index.d.ts.map +0 -1
  227. package/dist/transport/index.js.map +0 -1
  228. package/dist/transport/router.d.ts.map +0 -1
  229. package/dist/transport/router.js.map +0 -1
  230. package/dist/transport/stream-error.d.ts.map +0 -1
  231. package/dist/transport/stream-error.js.map +0 -1
  232. package/dist/transport/types.d.ts.map +0 -1
  233. package/dist/transport/types.js.map +0 -1
  234. package/dist/transport/websocket/index.d.ts.map +0 -1
  235. package/dist/transport/websocket/index.js.map +0 -1
  236. package/dist/transport/websocket/session.d.ts.map +0 -1
  237. package/dist/transport/websocket/session.js.map +0 -1
  238. package/dist/transport/websocket/upgrade.d.ts.map +0 -1
  239. package/dist/transport/websocket/upgrade.js.map +0 -1
  240. package/dist/types.d.ts.map +0 -1
  241. package/dist/types.js.map +0 -1
package/dist/capture.d.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  /** Capture one receiver-bound method while preserving the capability's exact method type. */
2
2
  export declare function captureMethod<Receiver extends object, Name extends keyof Receiver>(input: Receiver, name: Name, invalidMessage: string): Receiver[Name];
3
- //# sourceMappingURL=capture.d.ts.map
package/dist/capture.js CHANGED
@@ -7,4 +7,3 @@ export function captureMethod(input, name, invalidMessage) {
7
7
  throw new TypeError(invalidMessage);
8
8
  return method.bind(input);
9
9
  }
10
- //# sourceMappingURL=capture.js.map
@@ -19,4 +19,3 @@ export interface CorsPolicy {
19
19
  }
20
20
  /** Admit one immutable policy. `false` delegates the complete concern to an outer application. */
21
21
  export declare function prepareCors(input: CorsConfig | false | undefined): CorsPolicy;
22
- //# sourceMappingURL=cors.d.ts.map
package/dist/cors/cors.js CHANGED
@@ -1,5 +1,6 @@
1
1
  /** Request-aware CORS admission shared by every Server-owned HTTP surface. */
2
2
  const TOKEN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u;
3
+ const PREFLIGHT_MAX_AGE_SECONDS = 24 * 60 * 60;
3
4
  /** Admit one immutable policy. `false` delegates the complete concern to an outer application. */
4
5
  export function prepareCors(input) {
5
6
  if (input === false)
@@ -61,11 +62,18 @@ export function prepareCors(input) {
61
62
  return new Response(null, { status: 403, headers: response(request) });
62
63
  }
63
64
  const allowedMethods = [...routeMethods].filter((method) => methods?.has(method) ?? true);
64
- const allowedHeaders = requestedHeaders.length > 0 ? requestedHeaders : [...routeHeaders];
65
+ // Advertise the whole header allowance, not an echo of the request: Chromium and WebKit keep
66
+ // one preflight result per origin and URL, so an echo would preflight again whenever a later
67
+ // call adds a permitted header. Requested names, already admitted, add only what a
68
+ // wildcard-header route cannot enumerate.
69
+ const allowedHeaders = new Set([...routeHeaders].filter((name) => headers?.has(name) ?? true));
70
+ for (const name of requestedHeaders)
71
+ allowedHeaders.add(name);
65
72
  const output = new Headers(response(request));
66
73
  output.set('access-control-allow-methods', [...allowedMethods, 'OPTIONS'].join(', '));
67
- if (allowedHeaders.length > 0) {
68
- output.set('access-control-allow-headers', allowedHeaders.join(', '));
74
+ output.set('access-control-max-age', String(PREFLIGHT_MAX_AGE_SECONDS));
75
+ if (allowedHeaders.size > 0) {
76
+ output.set('access-control-allow-headers', [...allowedHeaders].join(', '));
69
77
  }
70
78
  appendVary(output, 'access-control-request-method');
71
79
  appendVary(output, 'access-control-request-headers');
@@ -133,4 +141,3 @@ function appendVary(headers, value) {
133
141
  names.add(value);
134
142
  headers.set('vary', [...names].join(', '));
135
143
  }
136
- //# sourceMappingURL=cors.js.map
@@ -1,3 +1,2 @@
1
1
  export { prepareCors, type CorsPolicy, type CorsRoute } from './cors.js';
2
2
  export type { CorsConfig } from './types.js';
3
- //# sourceMappingURL=index.d.ts.map
@@ -1,2 +1 @@
1
1
  export { prepareCors } from './cors.js';
2
- //# sourceMappingURL=index.js.map
@@ -9,4 +9,3 @@ export interface CorsConfig {
9
9
  /** Emit Access-Control-Allow-Credentials; requires one explicit origin rather than `*`. */
10
10
  readonly credentials?: boolean;
11
11
  }
12
- //# sourceMappingURL=types.d.ts.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=types.js.map
@@ -0,0 +1,7 @@
1
+ import * as errors from '@astrale-os/kernel-protocol/errors';
2
+ /** Advisory delay before a request the Server did not admit is sent again. */
3
+ export declare const ADMISSION_RETRY_AFTER_MS = 1000;
4
+ /** Public refusal of an operation the Server did not admit; nothing ran. */
5
+ export declare function admissionRefusal(accepting: boolean): errors.ErrorPayload;
6
+ /** HTTP presentation of a public error's retry delay, when it has one. */
7
+ export declare function retryAfterHeaders(error: errors.ErrorPayload): Readonly<Record<string, string>>;
@@ -0,0 +1,22 @@
1
+ import * as errors from '@astrale-os/kernel-protocol/errors';
2
+ /** Advisory delay before a request the Server did not admit is sent again. */
3
+ export const ADMISSION_RETRY_AFTER_MS = 1_000;
4
+ /** Public refusal of an operation the Server did not admit; nothing ran. */
5
+ export function admissionRefusal(accepting) {
6
+ return accepting
7
+ ? {
8
+ code: errors.CODES.BACKEND_UNAVAILABLE,
9
+ message: 'Server is at capacity; retry later.',
10
+ data: errors.retryReason(errors.RETRY_REASONS.CAPACITY_EXHAUSTED, ADMISSION_RETRY_AFTER_MS),
11
+ }
12
+ : {
13
+ code: errors.CODES.BACKEND_UNAVAILABLE,
14
+ message: 'Server is draining; retry later.',
15
+ data: errors.retryReason(errors.RETRY_REASONS.SERVER_DRAINING, ADMISSION_RETRY_AFTER_MS),
16
+ };
17
+ }
18
+ /** HTTP presentation of a public error's retry delay, when it has one. */
19
+ export function retryAfterHeaders(error) {
20
+ const retryAfterMs = errors.retryAfterOf(error);
21
+ return retryAfterMs === undefined ? {} : { 'retry-after': errors.retryAfterField(retryAfterMs) };
22
+ }
@@ -8,4 +8,3 @@ export declare class IssuerKeysUnavailableError extends Error {
8
8
  readonly name = "IssuerKeysUnavailableError";
9
9
  constructor(message?: string, options?: ErrorOptions);
10
10
  }
11
- //# sourceMappingURL=availability.d.ts.map
@@ -12,4 +12,3 @@ export class IssuerKeysUnavailableError extends Error {
12
12
  super(message, options);
13
13
  }
14
14
  }
15
- //# sourceMappingURL=availability.js.map
@@ -1,4 +1,11 @@
1
1
  import * as errors from '@astrale-os/kernel-protocol/errors';
2
2
  /** Convert only errors owned by an admitted Server or Protocol boundary into safe public data. */
3
3
  export declare function classifyError(input: unknown): errors.ErrorPayload;
4
- //# sourceMappingURL=classify.d.ts.map
4
+ /**
5
+ * Classify the failure of one request. Its own deadline or cancellation names the failure, except an
6
+ * outcome already unknown: ending the request proves nothing about an effect.
7
+ */
8
+ export declare function classifyRequestError(input: unknown, request: {
9
+ readonly timedOut: boolean;
10
+ readonly signal: AbortSignal;
11
+ }): errors.ErrorPayload;
@@ -17,6 +17,21 @@ export function classifyError(input) {
17
17
  }
18
18
  return internal(input);
19
19
  }
20
+ /**
21
+ * Classify the failure of one request. Its own deadline or cancellation names the failure, except an
22
+ * outcome already unknown: ending the request proves nothing about an effect.
23
+ */
24
+ export function classifyRequestError(input, request) {
25
+ if (input instanceof errors.ProtocolError &&
26
+ input.payload.code === errors.CODES.OUTCOME_UNKNOWN) {
27
+ return input.payload;
28
+ }
29
+ if (request.timedOut)
30
+ return publicError('DEADLINE_EXCEEDED', 'Invocation deadline exceeded.');
31
+ if (request.signal.aborted)
32
+ return publicError('CANCELLED', 'Invocation was cancelled.');
33
+ return classifyError(input);
34
+ }
20
35
  function publicError(name, message) {
21
36
  return { code: errors.CODES[name], message };
22
37
  }
@@ -39,4 +54,3 @@ function reportInternal(input) {
39
54
  code: stableCode(input),
40
55
  });
41
56
  }
42
- //# sourceMappingURL=classify.js.map
@@ -1,5 +1,5 @@
1
+ export { ADMISSION_RETRY_AFTER_MS, admissionRefusal, retryAfterHeaders } from './admission.js';
1
2
  export { DeliveryUnavailableError, IssuerKeysUnavailableError } from './availability.js';
2
- export { classifyError } from './classify.js';
3
+ export { classifyError, classifyRequestError } from './classify.js';
3
4
  export { RequestBodyInvalidError, RequestBodyTooLargeError } from './request-body.js';
4
5
  export { ResponseBodyTooLargeError } from './response-body.js';
5
- //# sourceMappingURL=index.d.ts.map
@@ -1,5 +1,5 @@
1
+ export { ADMISSION_RETRY_AFTER_MS, admissionRefusal, retryAfterHeaders } from './admission.js';
1
2
  export { DeliveryUnavailableError, IssuerKeysUnavailableError } from './availability.js';
2
- export { classifyError } from './classify.js';
3
+ export { classifyError, classifyRequestError } from './classify.js';
3
4
  export { RequestBodyInvalidError, RequestBodyTooLargeError } from './request-body.js';
4
5
  export { ResponseBodyTooLargeError } from './response-body.js';
5
- //# sourceMappingURL=index.js.map
@@ -5,4 +5,3 @@ export declare class RequestBodyTooLargeError extends Error {
5
5
  export declare class RequestBodyInvalidError extends Error {
6
6
  constructor(message: string);
7
7
  }
8
- //# sourceMappingURL=request-body.d.ts.map
@@ -12,4 +12,3 @@ export class RequestBodyInvalidError extends Error {
12
12
  this.name = 'RequestBodyInvalidError';
13
13
  }
14
14
  }
15
- //# sourceMappingURL=request-body.js.map
@@ -2,4 +2,3 @@ export declare class ResponseBodyTooLargeError extends Error {
2
2
  readonly maximumBytes: number;
3
3
  constructor(maximumBytes: number);
4
4
  }
5
- //# sourceMappingURL=response-body.d.ts.map
@@ -6,4 +6,3 @@ export class ResponseBodyTooLargeError extends Error {
6
6
  this.name = 'ResponseBodyTooLargeError';
7
7
  }
8
8
  }
9
- //# sourceMappingURL=response-body.js.map
package/dist/index.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  export { createServer, prepareServer } from './server.js';
2
2
  export { DeliveryUnavailableError, IssuerKeysUnavailableError } from './errors/index.js';
3
- export { preparePublicationSnapshot } from './publication/index.js';
4
- export * as publication from './publication/index.js';
5
- export type { Application, ApplicationHost, CorsConfig, ExecutionControl, Handler, HandlerRequest, HandlerResult, HandlerStream, HealthProbe, InvocationContext, InvocationSource, RequestBackground, RequestEvidence, RequestSleep, Issuer, exchange, PreparedServer, PublicationSnapshot, PublicationSnapshotInput, PublicationSource, Server, ServerCloseOptions, ServerConfig, ServerLimits, ServerOptions, WebSocketAdapter, WebSocketHandlers, WebSocketLike, WebSocketUpgradeOptions, } from './types.js';
6
- //# sourceMappingURL=index.d.ts.map
3
+ export { prepareReleaseSnapshot } from './release/index.js';
4
+ export * as release from './release/index.js';
5
+ export type { Application, ApplicationHost, CorsConfig, ExecutionControl, Handler, HandlerRequest, HandlerResult, HandlerStream, HealthProbe, InvocationContext, InvocationSource, RequestBackground, RequestEvidence, RequestSleep, Issuer, exchange, PreparedServer, ReleaseSnapshot, ReleaseSnapshotInput, ReleaseSource, Server, ServerCloseOptions, ServerConfig, ServerLimits, ServerOptions, WebSocketAdapter, WebSocketHandlers, WebSocketLike, WebSocketUpgradeOptions, } from './types.js';
package/dist/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  export { createServer, prepareServer } from './server.js';
2
2
  export { DeliveryUnavailableError, IssuerKeysUnavailableError } from './errors/index.js';
3
- export { preparePublicationSnapshot } from './publication/index.js';
4
- export * as publication from './publication/index.js';
5
- //# sourceMappingURL=index.js.map
3
+ export { prepareReleaseSnapshot } from './release/index.js';
4
+ export * as release from './release/index.js';
@@ -1,7 +1,7 @@
1
- import type { invocation as protocol } from '@astrale-os/kernel-protocol';
1
+ import type { BinaryRequestBody } from '@astrale-os/kernel-core/callable';
2
+ import type * as protocol from '@astrale-os/kernel-protocol/invocation';
2
3
  import type { ActiveOperation, ActiveOperations } from '../lifecycle/index.js';
3
4
  import type { ApplicationHost, InvocationContext } from './types.js';
4
- export declare function invocationContext(assigned: protocol.InvocationId, operation: ActiveOperation, active: ActiveOperations, host?: ApplicationHost, requestBody?: Uint8Array, idempotencyKey?: protocol.IdempotencyKey): InvocationContext;
5
+ export declare function invocationContext(assigned: protocol.InvocationId, operation: ActiveOperation, active: ActiveOperations, host?: ApplicationHost, requestBody?: Uint8Array, idempotencyKey?: protocol.IdempotencyKey, binary?: BinaryRequestBody): InvocationContext;
5
6
  /** Default non-durable timer used when the application host supplies no timer capability. */
6
7
  export declare function defaultSleep(durationMs: number): Promise<void>;
7
- //# sourceMappingURL=context.d.ts.map
@@ -1,4 +1,4 @@
1
- export function invocationContext(assigned, operation, active, host, requestBody, idempotencyKey) {
1
+ export function invocationContext(assigned, operation, active, host, requestBody, idempotencyKey, binary) {
2
2
  const body = requestBody?.slice();
3
3
  return Object.freeze({
4
4
  invocation: assigned,
@@ -9,6 +9,7 @@ export function invocationContext(assigned, operation, active, host, requestBody
9
9
  },
10
10
  ...(idempotencyKey === undefined ? {} : { idempotencyKey }),
11
11
  ...(body === undefined ? {} : { request: Object.freeze({ body: () => body.slice() }) }),
12
+ ...(binary === undefined ? {} : { binary }),
12
13
  });
13
14
  }
14
15
  /** Default non-durable timer used when the application host supplies no timer capability. */
@@ -58,4 +59,3 @@ function sleepDuration(input) {
58
59
  }
59
60
  return input;
60
61
  }
61
- //# sourceMappingURL=context.js.map
@@ -1,5 +1,5 @@
1
1
  import type { IssuerId } from '@astrale-os/kernel-core/auth';
2
- import type { invocation as protocol } from '@astrale-os/kernel-protocol';
2
+ import type * as protocol from '@astrale-os/kernel-protocol/invocation';
3
3
  /** Injected source-owned identity allocator captured before Server readiness. */
4
4
  export interface InvocationSource {
5
5
  readonly source: IssuerId;
@@ -7,4 +7,3 @@ export interface InvocationSource {
7
7
  }
8
8
  export type NextInvocationId = () => protocol.InvocationId;
9
9
  export declare function captureInvocationSource(input: InvocationSource): NextInvocationId;
10
- //# sourceMappingURL=identity.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { issuer } from '@astrale-os/kernel-core/auth';
2
- import { invocation as protocolInvocation } from '@astrale-os/kernel-protocol';
2
+ import * as protocolInvocation from '@astrale-os/kernel-protocol/invocation';
3
3
  import { captureMethod } from '../capture.js';
4
4
  export function captureInvocationSource(input) {
5
5
  if (input === null || typeof input !== 'object') {
@@ -9,4 +9,3 @@ export function captureInvocationSource(input) {
9
9
  const next = captureMethod(input, 'next', 'Server Invocation source is invalid.');
10
10
  return () => protocolInvocation.acceptInvocationId({ source, id: next() });
11
11
  }
12
- //# sourceMappingURL=identity.js.map
@@ -1,5 +1,4 @@
1
1
  export { defaultSleep, invocationContext } from './context.js';
2
2
  export { captureInvocationSource, type InvocationSource, type NextInvocationId, } from './identity.js';
3
- export { publicationRouteDecision, type PublicationRouteDecision } from './publication-route.js';
3
+ export { admitVia, releaseRouteDecision, type RouteDecision } from './release-route.js';
4
4
  export type { ApplicationHost, ExecutionControl, Handler, HandlerRequest, HandlerResult, HandlerStream, InvocationContext, RequestBackground, RequestEvidence, RequestSleep, } from './types.js';
5
- //# sourceMappingURL=index.d.ts.map
@@ -1,4 +1,3 @@
1
1
  export { defaultSleep, invocationContext } from './context.js';
2
2
  export { captureInvocationSource, } from './identity.js';
3
- export { publicationRouteDecision } from './publication-route.js';
4
- //# sourceMappingURL=index.js.map
3
+ export { admitVia, releaseRouteDecision } from './release-route.js';
@@ -0,0 +1,22 @@
1
+ import type { ErrorPayload } from '@astrale-os/kernel-protocol/errors';
2
+ import type { Via } from '@astrale-os/kernel-protocol/invocation';
3
+ import type { DomainRelease, ReleaseDigest, ReleaseRef } from '@astrale-os/kernel-protocol/release';
4
+ import type { Served } from '../release/served.js';
5
+ export type RouteDecision = {
6
+ readonly kind: 'admitted';
7
+ } | {
8
+ readonly kind: 'rejected';
9
+ readonly error: ErrorPayload;
10
+ }
11
+ /** DEPLOYMENT_RETIRED includes the requested release only when the witness identifies it. */
12
+ | {
13
+ readonly kind: 'retired';
14
+ readonly release?: ReleaseDigest;
15
+ };
16
+ /**
17
+ * Only the exact served release admits. Never report the served digest as retired when
18
+ * the witness pairs it with a different revision or issuer.
19
+ */
20
+ export declare function releaseRouteDecision(current: DomainRelease, installed: ReleaseRef): RouteDecision;
21
+ /** Admit routing against the exact release before credential resolution. */
22
+ export declare function admitVia(served: Served | undefined, via: Via): RouteDecision;
@@ -0,0 +1,32 @@
1
+ import { CODES } from '@astrale-os/kernel-protocol/errors';
2
+ import { compareReferences, reference } from '@astrale-os/kernel-protocol/release';
3
+ const ADMITTED = Object.freeze({ kind: 'admitted' });
4
+ const RETIRED = Object.freeze({ kind: 'retired' });
5
+ /**
6
+ * Only the exact served release admits. Never report the served digest as retired when
7
+ * the witness pairs it with a different revision or issuer.
8
+ */
9
+ export function releaseRouteDecision(current, installed) {
10
+ switch (compareReferences(reference(current), installed)) {
11
+ case 'exact':
12
+ return ADMITTED;
13
+ case 'release-drift':
14
+ return installed.digest === current.digest
15
+ ? RETIRED
16
+ : Object.freeze({ kind: 'retired', release: installed.digest });
17
+ case 'origin-drift':
18
+ return invalid('Routed release origin differs from the served Domain.');
19
+ }
20
+ }
21
+ /** Admit routing against the exact release before credential resolution. */
22
+ export function admitVia(served, via) {
23
+ return served === undefined
24
+ ? invalid('Release routing requires a release-backed destination.')
25
+ : releaseRouteDecision(served.release, via.release);
26
+ }
27
+ function invalid(message) {
28
+ return Object.freeze({
29
+ kind: 'rejected',
30
+ error: Object.freeze({ code: CODES.INVALID_REQUEST, message }),
31
+ });
32
+ }
@@ -1,8 +1,8 @@
1
1
  import type { CredentialInput } from '@astrale-os/kernel-core/auth';
2
- import type { CallableResult } from '@astrale-os/kernel-core/domain';
2
+ import type { BinaryRequestBody, CallableResult } from '@astrale-os/kernel-core/callable';
3
3
  import type { Value } from '@astrale-os/kernel-dsl/value';
4
- import type { invocation as protocol } from '@astrale-os/kernel-protocol';
5
- import type { PublicationSnapshot } from '../publication/index.js';
4
+ import type * as protocol from '@astrale-os/kernel-protocol/invocation';
5
+ import type { ReleaseSnapshot } from '../release/index.js';
6
6
  /** Optional platform retention and timer adaptation for one Fetch invocation. */
7
7
  export interface ApplicationHost {
8
8
  waitUntil(promise: Promise<unknown>): void;
@@ -27,6 +27,8 @@ export interface InvocationContext {
27
27
  readonly execution: ExecutionControl;
28
28
  readonly idempotencyKey?: protocol.IdempotencyKey;
29
29
  readonly request?: RequestEvidence;
30
+ /** Root-only binary HTTP ingress; ordinary envelopes and WebSocket carry none. */
31
+ readonly binary?: BinaryRequestBody;
30
32
  readonly background: RequestBackground;
31
33
  /** Rejects promptly when execution is cancelled or reaches its deadline. */
32
34
  readonly sleep: RequestSleep;
@@ -49,15 +51,14 @@ export interface HandlerRequest {
49
51
  readonly credential?: CredentialInput;
50
52
  /** Source-only effective delegation forwarded unchanged to Runtime. */
51
53
  readonly delegate?: protocol.Delegate;
52
- /** Destination routing witness forwarded after exact or same-schema Server admission. */
54
+ /** Destination witness admitted against the exact served release. */
53
55
  readonly via?: protocol.Via;
54
56
  /** Source-only local-target or remote-revision Schema Registration precondition. */
55
57
  readonly schema?: protocol.SchemaTarget;
56
- /** Exact Server-pinned serving generation for a Publication-backed request. */
57
- readonly publication?: PublicationSnapshot;
58
+ /** Exact Server-pinned release for a request at a release-backed destination. */
59
+ readonly release?: ReleaseSnapshot;
58
60
  readonly context: InvocationContext;
59
61
  }
60
62
  export interface Handler {
61
63
  dispatch(request: HandlerRequest): Promise<HandlerResult>;
62
64
  }
63
- //# sourceMappingURL=types.d.ts.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=types.js.map
@@ -10,4 +10,3 @@ export interface Provider {
10
10
  }
11
11
  export declare function capture(input: Provider): Provider;
12
12
  export declare function mount(app: ServerRouter, issuer: string, provider: Provider, cors: CorsPolicy, active: ActiveOperations, timeoutMs: number): void;
13
- //# sourceMappingURL=exchange.d.ts.map
@@ -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, extra);
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(error('LIMIT_EXCEEDED', 'Token-exchange limit exceeded.'));
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
- for (const [name, value] of Object.entries(cors.response(request)))
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
@@ -1,4 +1,3 @@
1
1
  export { admitIssuer, issuerRouteReservations, mountIssuer, type IssuerRouteReservation, } from './routes.js';
2
2
  export type * as exchange from './exchange.js';
3
3
  export type { Issuer } from './types.js';
4
- //# sourceMappingURL=index.d.ts.map
@@ -1,2 +1 @@
1
1
  export { admitIssuer, issuerRouteReservations, mountIssuer, } from './routes.js';
2
- //# sourceMappingURL=index.js.map
@@ -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