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

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 (178) 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 +0 -1
  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/availability.d.ts +3 -4
  10. package/dist/errors/availability.js +4 -5
  11. package/dist/errors/classify.d.ts +2 -3
  12. package/dist/errors/classify.js +4 -217
  13. package/dist/errors/index.d.ts +1 -2
  14. package/dist/errors/index.js +1 -2
  15. package/dist/errors/request-body.d.ts +0 -1
  16. package/dist/errors/request-body.js +0 -1
  17. package/dist/errors/response-body.d.ts +0 -1
  18. package/dist/errors/response-body.js +0 -1
  19. package/dist/index.d.ts +3 -3
  20. package/dist/index.js +2 -2
  21. package/dist/invocation/context.d.ts +2 -3
  22. package/dist/invocation/context.js +2 -4
  23. package/dist/invocation/identity.d.ts +9 -0
  24. package/dist/invocation/identity.js +11 -0
  25. package/dist/invocation/index.d.ts +3 -2
  26. package/dist/invocation/index.js +2 -1
  27. package/dist/invocation/publication-route.d.ts +13 -0
  28. package/dist/invocation/publication-route.js +44 -0
  29. package/dist/invocation/types.d.ts +38 -10
  30. package/dist/invocation/types.js +0 -1
  31. package/dist/issuer/exchange.d.ts +12 -0
  32. package/dist/issuer/exchange.js +136 -0
  33. package/dist/issuer/index.d.ts +1 -1
  34. package/dist/issuer/index.js +0 -1
  35. package/dist/issuer/routes.d.ts +3 -3
  36. package/dist/issuer/routes.js +25 -14
  37. package/dist/issuer/types.d.ts +2 -2
  38. package/dist/issuer/types.js +0 -1
  39. package/dist/lifecycle/active.d.ts +0 -1
  40. package/dist/lifecycle/active.js +0 -1
  41. package/dist/lifecycle/index.d.ts +0 -1
  42. package/dist/lifecycle/index.js +0 -1
  43. package/dist/publication/delivery/handler.d.ts +9 -0
  44. package/dist/{installation → publication/delivery}/handler.js +29 -28
  45. package/dist/publication/delivery/index.d.ts +2 -0
  46. package/dist/publication/delivery/index.js +1 -0
  47. package/dist/publication/delivery/types.d.ts +11 -0
  48. package/dist/publication/delivery/types.js +1 -0
  49. package/dist/publication/index.d.ts +1 -1
  50. package/dist/publication/index.js +1 -1
  51. package/dist/publication/snapshot.d.ts +5 -3
  52. package/dist/publication/snapshot.js +14 -7
  53. package/dist/publication/table.d.ts +4 -0
  54. package/dist/publication/table.js +16 -0
  55. package/dist/publication/types.d.ts +5 -2
  56. package/dist/publication/types.js +0 -1
  57. package/dist/routes/index.d.ts +0 -1
  58. package/dist/routes/index.js +0 -1
  59. package/dist/routes/routes.d.ts +6 -5
  60. package/dist/routes/routes.js +51 -41
  61. package/dist/server.d.ts +0 -1
  62. package/dist/server.js +56 -16
  63. package/dist/transport/body.d.ts +0 -1
  64. package/dist/transport/body.js +0 -1
  65. package/dist/transport/codecs.d.ts +1 -2
  66. package/dist/transport/codecs.js +1 -2
  67. package/dist/transport/credential.d.ts +1 -2
  68. package/dist/transport/credential.js +1 -2
  69. package/dist/transport/http/handler.d.ts +2 -1
  70. package/dist/transport/http/handler.js +47 -37
  71. package/dist/transport/http/index.d.ts +0 -1
  72. package/dist/transport/http/index.js +0 -1
  73. package/dist/transport/http/render.d.ts +13 -11
  74. package/dist/transport/http/render.js +50 -39
  75. package/dist/transport/index.d.ts +0 -1
  76. package/dist/transport/index.js +0 -1
  77. package/dist/transport/router.d.ts +0 -1
  78. package/dist/transport/router.js +0 -1
  79. package/dist/transport/stream-error.d.ts +2 -3
  80. package/dist/transport/stream-error.js +3 -4
  81. package/dist/transport/types.d.ts +1 -2
  82. package/dist/transport/types.js +0 -1
  83. package/dist/transport/websocket/index.d.ts +0 -1
  84. package/dist/transport/websocket/index.js +0 -1
  85. package/dist/transport/websocket/session.d.ts +4 -3
  86. package/dist/transport/websocket/session.js +46 -39
  87. package/dist/transport/websocket/upgrade.d.ts +2 -1
  88. package/dist/transport/websocket/upgrade.js +2 -2
  89. package/dist/types.d.ts +13 -10
  90. package/dist/types.js +0 -1
  91. package/package.json +23 -11
  92. package/dist/capture.d.ts.map +0 -1
  93. package/dist/capture.js.map +0 -1
  94. package/dist/cors/cors.d.ts.map +0 -1
  95. package/dist/cors/cors.js.map +0 -1
  96. package/dist/cors/index.d.ts.map +0 -1
  97. package/dist/cors/index.js.map +0 -1
  98. package/dist/cors/types.d.ts.map +0 -1
  99. package/dist/cors/types.js.map +0 -1
  100. package/dist/errors/availability.d.ts.map +0 -1
  101. package/dist/errors/availability.js.map +0 -1
  102. package/dist/errors/classify.d.ts.map +0 -1
  103. package/dist/errors/classify.js.map +0 -1
  104. package/dist/errors/index.d.ts.map +0 -1
  105. package/dist/errors/index.js.map +0 -1
  106. package/dist/errors/request-body.d.ts.map +0 -1
  107. package/dist/errors/request-body.js.map +0 -1
  108. package/dist/errors/response-body.d.ts.map +0 -1
  109. package/dist/errors/response-body.js.map +0 -1
  110. package/dist/index.d.ts.map +0 -1
  111. package/dist/index.js.map +0 -1
  112. package/dist/installation/handler.d.ts +0 -10
  113. package/dist/installation/handler.d.ts.map +0 -1
  114. package/dist/installation/handler.js.map +0 -1
  115. package/dist/installation/index.d.ts +0 -3
  116. package/dist/installation/index.d.ts.map +0 -1
  117. package/dist/installation/index.js +0 -2
  118. package/dist/installation/index.js.map +0 -1
  119. package/dist/installation/types.d.ts +0 -12
  120. package/dist/installation/types.d.ts.map +0 -1
  121. package/dist/installation/types.js +0 -2
  122. package/dist/installation/types.js.map +0 -1
  123. package/dist/invocation/context.d.ts.map +0 -1
  124. package/dist/invocation/context.js.map +0 -1
  125. package/dist/invocation/index.d.ts.map +0 -1
  126. package/dist/invocation/index.js.map +0 -1
  127. package/dist/invocation/types.d.ts.map +0 -1
  128. package/dist/invocation/types.js.map +0 -1
  129. package/dist/issuer/index.d.ts.map +0 -1
  130. package/dist/issuer/index.js.map +0 -1
  131. package/dist/issuer/routes.d.ts.map +0 -1
  132. package/dist/issuer/routes.js.map +0 -1
  133. package/dist/issuer/types.d.ts.map +0 -1
  134. package/dist/issuer/types.js.map +0 -1
  135. package/dist/lifecycle/active.d.ts.map +0 -1
  136. package/dist/lifecycle/active.js.map +0 -1
  137. package/dist/lifecycle/index.d.ts.map +0 -1
  138. package/dist/lifecycle/index.js.map +0 -1
  139. package/dist/publication/index.d.ts.map +0 -1
  140. package/dist/publication/index.js.map +0 -1
  141. package/dist/publication/snapshot.d.ts.map +0 -1
  142. package/dist/publication/snapshot.js.map +0 -1
  143. package/dist/publication/types.d.ts.map +0 -1
  144. package/dist/publication/types.js.map +0 -1
  145. package/dist/routes/index.d.ts.map +0 -1
  146. package/dist/routes/index.js.map +0 -1
  147. package/dist/routes/routes.d.ts.map +0 -1
  148. package/dist/routes/routes.js.map +0 -1
  149. package/dist/server.d.ts.map +0 -1
  150. package/dist/server.js.map +0 -1
  151. package/dist/transport/body.d.ts.map +0 -1
  152. package/dist/transport/body.js.map +0 -1
  153. package/dist/transport/codecs.d.ts.map +0 -1
  154. package/dist/transport/codecs.js.map +0 -1
  155. package/dist/transport/credential.d.ts.map +0 -1
  156. package/dist/transport/credential.js.map +0 -1
  157. package/dist/transport/http/handler.d.ts.map +0 -1
  158. package/dist/transport/http/handler.js.map +0 -1
  159. package/dist/transport/http/index.d.ts.map +0 -1
  160. package/dist/transport/http/index.js.map +0 -1
  161. package/dist/transport/http/render.d.ts.map +0 -1
  162. package/dist/transport/http/render.js.map +0 -1
  163. package/dist/transport/index.d.ts.map +0 -1
  164. package/dist/transport/index.js.map +0 -1
  165. package/dist/transport/router.d.ts.map +0 -1
  166. package/dist/transport/router.js.map +0 -1
  167. package/dist/transport/stream-error.d.ts.map +0 -1
  168. package/dist/transport/stream-error.js.map +0 -1
  169. package/dist/transport/types.d.ts.map +0 -1
  170. package/dist/transport/types.js.map +0 -1
  171. package/dist/transport/websocket/index.d.ts.map +0 -1
  172. package/dist/transport/websocket/index.js.map +0 -1
  173. package/dist/transport/websocket/session.d.ts.map +0 -1
  174. package/dist/transport/websocket/session.js.map +0 -1
  175. package/dist/transport/websocket/upgrade.d.ts.map +0 -1
  176. package/dist/transport/websocket/upgrade.js.map +0 -1
  177. package/dist/types.d.ts.map +0 -1
  178. package/dist/types.js.map +0 -1
@@ -1,17 +1,15 @@
1
- import { codecs, errors, invocation as protocol, publication as publicationProtocol, } from '@astrale-os/kernel-protocol';
1
+ import * as codecs from '@astrale-os/kernel-protocol/codecs';
2
+ import * as errors from '@astrale-os/kernel-protocol/errors';
3
+ import * as protocol from '@astrale-os/kernel-protocol/invocation';
2
4
  import { classifyError, RequestBodyInvalidError, RequestBodyTooLargeError, } from '../../errors/index.js';
3
- import { invocationContext } from '../../invocation/index.js';
5
+ import { invocationContext, publicationRouteDecision, } from '../../invocation/index.js';
4
6
  import { readBoundedBody } from '../body.js';
5
7
  import { loadCodecs } from '../codecs.js';
6
8
  import { resolveCredential } from '../credential.js';
7
- import { renderHttpError, renderHttpResult, renderHttpStale, } from './render.js';
9
+ import { renderHttpError, renderHttpResult } from './render.js';
8
10
  export function createHttpHandler(config) {
9
11
  return async (request, host) => {
10
12
  const cors = (exposedHeaders) => config.cors.response(request, exposedHeaders);
11
- const renderError = (id, error, codec, options = {}) => renderHttpError(id, error, codec, cors, {
12
- ...options,
13
- maximumResponseBytes: config.maximumResponseBytes,
14
- });
15
13
  const allow = [
16
14
  ...(config.websocket ? ['GET'] : []),
17
15
  'POST',
@@ -20,7 +18,12 @@ export function createHttpHandler(config) {
20
18
  if (request.method === 'OPTIONS' && config.cors.enabled) {
21
19
  return noStore(config.cors.preflight(request, {
22
20
  methods: ['POST'],
23
- headers: ['authorization', 'content-type'],
21
+ headers: [
22
+ 'authorization',
23
+ 'content-type',
24
+ protocol.http.TRACEPARENT_FIELD,
25
+ protocol.http.TRACESTATE_FIELD,
26
+ ],
24
27
  }));
25
28
  }
26
29
  if (request.method !== 'POST') {
@@ -29,8 +32,13 @@ export function createHttpHandler(config) {
29
32
  headers: { ...cors(), allow: allow.join(', '), 'cache-control': 'no-store' },
30
33
  });
31
34
  }
32
- const operation = config.active.begin(config.invocationTimeoutMs, request.signal);
33
- if (operation === undefined) {
35
+ const assigned = config.invocation();
36
+ const renderError = (requestId, error, codec, options = {}) => renderHttpError(requestId, assigned, error, codec, cors, {
37
+ ...options,
38
+ maximumResponseBytes: config.maximumResponseBytes,
39
+ });
40
+ const active = config.active.begin(config.invocationTimeoutMs, request.signal);
41
+ if (active === undefined) {
34
42
  return renderError(null, {
35
43
  code: errors.CODES.BACKEND_UNAVAILABLE,
36
44
  message: 'server is unavailable.',
@@ -58,19 +66,19 @@ export function createHttpHandler(config) {
58
66
  }
59
67
  let body;
60
68
  try {
61
- body = await readBoundedBody(request, config.maximumRequestBytes, operation.signal);
69
+ body = await readBoundedBody(request, config.maximumRequestBytes, active.signal);
62
70
  }
63
71
  catch (input) {
64
72
  const payload = input instanceof RequestBodyTooLargeError
65
73
  ? classifyError(input)
66
74
  : input instanceof RequestBodyInvalidError
67
75
  ? { code: errors.CODES.PARSE_ERROR, message: 'Request body is invalid.' }
68
- : operation.timedOut
76
+ : active.timedOut
69
77
  ? {
70
78
  code: errors.CODES.DEADLINE_EXCEEDED,
71
79
  message: 'Invocation deadline exceeded.',
72
80
  }
73
- : operation.signal.aborted
81
+ : active.signal.aborted
74
82
  ? { code: errors.CODES.CANCELLED, message: 'Invocation was cancelled.' }
75
83
  : undefined;
76
84
  if (payload === undefined)
@@ -88,67 +96,70 @@ export function createHttpHandler(config) {
88
96
  throw input;
89
97
  return renderError(null, { code: errors.CODES.PARSE_ERROR, message: 'Request body is invalid.' }, outgoing);
90
98
  }
91
- let invocation;
99
+ let envelope;
92
100
  try {
93
- invocation = protocol.decodeRequest(decoded);
101
+ envelope = protocol.decodeRequest(decoded);
94
102
  }
95
103
  catch (input) {
96
104
  return renderError(null, classifyError(input), outgoing);
97
105
  }
98
106
  const publication = config.currentPublication?.(request);
99
107
  if (config.currentPublication !== undefined && publication === undefined) {
100
- return renderError(invocation.id, {
108
+ return renderError(envelope.requestId, {
101
109
  code: errors.CODES.BACKEND_UNAVAILABLE,
102
110
  message: 'Publication is unavailable.',
103
111
  }, outgoing, { status: 503 });
104
112
  }
105
- if (invocation.routing?.kind === 'via') {
113
+ if (envelope.routing?.kind === 'via') {
106
114
  if (publication === undefined) {
107
- return renderError(invocation.id, {
115
+ return renderError(envelope.requestId, {
108
116
  code: errors.CODES.INVALID_REQUEST,
109
117
  message: 'Publication routing requires a Publication-backed destination.',
110
118
  }, outgoing);
111
119
  }
112
- if (!publicationProtocol.matchesReference(publication.publication, invocation.routing.publication)) {
113
- return renderHttpStale(invocation.id, publication.publication.etag, outgoing, cors, config.maximumResponseBytes);
120
+ const decision = publicationRouteDecision(publication.publication, envelope.routing.publication);
121
+ if (decision.kind === 'rejected') {
122
+ return renderError(envelope.requestId, decision.error, outgoing);
114
123
  }
115
124
  }
116
- const credential = resolveCredential(invocation.credential, request.headers.get('authorization'));
125
+ const credential = resolveCredential(envelope.credential, request.headers.get('authorization'));
117
126
  if (!credential.ok) {
118
- return renderError(invocation.id, credential.error, outgoing);
127
+ return renderError(envelope.requestId, credential.error, outgoing);
119
128
  }
129
+ const trace = protocol.http.decodeTraceHeaders(request.headers.get(protocol.http.TRACEPARENT_FIELD), request.headers.get(protocol.http.TRACESTATE_FIELD));
120
130
  try {
121
131
  const result = await config.handler.dispatch(Object.freeze({
122
- call: invocation.call,
132
+ call: envelope.call,
133
+ ...(trace === undefined ? {} : { trace }),
123
134
  ...(credential.credential === undefined ? {} : { credential: credential.credential }),
124
- ...(invocation.delegate === undefined ? {} : { delegate: invocation.delegate }),
125
- ...(invocation.routing?.kind === 'via' ? { via: invocation.routing } : {}),
135
+ ...(envelope.delegate === undefined ? {} : { delegate: envelope.delegate }),
136
+ ...(envelope.routing?.kind === 'via' ? { via: envelope.routing } : {}),
137
+ ...(envelope.schema === undefined ? {} : { schema: envelope.schema }),
126
138
  ...(publication === undefined ? {} : { publication }),
127
- context: invocationContext(operation, config.active, host, undefined, invocation.idempotencyKey, invocation.routing?.kind === 'refresh'
128
- ? { staleEtag: invocation.routing.stale }
129
- : undefined),
139
+ context: invocationContext(assigned, active, config.active, host, undefined, envelope.idempotencyKey),
130
140
  }));
131
141
  const response = renderHttpResult(result, {
132
- id: invocation.id,
142
+ requestId: envelope.requestId,
133
143
  codec: outgoing,
134
144
  cors,
135
- operation,
145
+ invocation: assigned,
146
+ active,
136
147
  maximumResponseBytes: config.maximumResponseBytes,
137
148
  });
138
149
  handedOff = result.kind === 'stream';
139
150
  return response;
140
151
  }
141
152
  catch (input) {
142
- if (operation.timedOut) {
143
- return renderError(invocation.id, {
153
+ if (active.timedOut) {
154
+ return renderError(envelope.requestId, {
144
155
  code: errors.CODES.DEADLINE_EXCEEDED,
145
156
  message: 'Invocation deadline exceeded.',
146
157
  }, outgoing, { status: 504 });
147
158
  }
148
- if (operation.signal.aborted) {
149
- return renderError(invocation.id, { code: errors.CODES.CANCELLED, message: 'Invocation was cancelled.' }, outgoing, { status: 408 });
159
+ if (active.signal.aborted) {
160
+ return renderError(envelope.requestId, { code: errors.CODES.CANCELLED, message: 'Invocation was cancelled.' }, outgoing, { status: 408 });
150
161
  }
151
- return renderError(invocation.id, classifyError(input), outgoing);
162
+ return renderError(envelope.requestId, classifyError(input), outgoing);
152
163
  }
153
164
  }
154
165
  catch (input) {
@@ -158,7 +169,7 @@ export function createHttpHandler(config) {
158
169
  }
159
170
  finally {
160
171
  if (!handedOff)
161
- operation.settle();
172
+ active.settle();
162
173
  }
163
174
  };
164
175
  }
@@ -167,4 +178,3 @@ function noStore(response) {
167
178
  headers.set('cache-control', 'no-store');
168
179
  return new Response(response.body, { status: response.status, headers });
169
180
  }
170
- //# sourceMappingURL=handler.js.map
@@ -1,3 +1,2 @@
1
1
  export { createHttpHandler, type HttpHandlerConfig } from './handler.js';
2
2
  export { encodeEnvelope, renderBinary, renderHttpError, renderHttpResult, renderHttpStale, renderRedirect, type CorsHeaders, type ErrorRenderOptions, type RenderContext, } from './render.js';
3
- //# sourceMappingURL=index.d.ts.map
@@ -1,3 +1,2 @@
1
1
  export { createHttpHandler } from './handler.js';
2
2
  export { encodeEnvelope, renderBinary, renderHttpError, renderHttpResult, renderHttpStale, renderRedirect, } from './render.js';
3
- //# sourceMappingURL=index.js.map
@@ -1,11 +1,14 @@
1
- import { errors, invocation as protocol, type codecs } from '@astrale-os/kernel-protocol';
1
+ import type { Codec } from '@astrale-os/kernel-protocol/codecs';
2
+ import * as errors from '@astrale-os/kernel-protocol/errors';
3
+ import * as protocol from '@astrale-os/kernel-protocol/invocation';
2
4
  import type { Handler } from '../../invocation/index.js';
3
5
  import type { ActiveOperation } from '../../lifecycle/index.js';
4
6
  export interface RenderContext {
5
- readonly id: protocol.RequestId;
6
- readonly codec: codecs.Codec;
7
+ readonly requestId: protocol.RequestId;
8
+ readonly codec: Codec;
7
9
  readonly cors: CorsHeaders;
8
- readonly operation: ActiveOperation;
10
+ readonly invocation: protocol.InvocationId;
11
+ readonly active: ActiveOperation;
9
12
  readonly maximumResponseBytes: number;
10
13
  }
11
14
  export type CorsHeaders = (exposedHeaders?: readonly string[]) => Readonly<Record<string, string>>;
@@ -16,14 +19,13 @@ export interface ErrorRenderOptions {
16
19
  }
17
20
  type HandlerResult = Awaited<ReturnType<Handler['dispatch']>>;
18
21
  export declare function renderHttpResult(result: HandlerResult, context: RenderContext): Response;
19
- export declare function renderBinary(id: protocol.RequestId, binary: Extract<HandlerResult, {
22
+ export declare function renderBinary(requestId: protocol.RequestId, invocation: protocol.InvocationId, binary: Extract<HandlerResult, {
20
23
  readonly kind: 'binary';
21
24
  }>['value']): protocol.BinaryResponse;
22
- export declare function renderRedirect(id: protocol.RequestId, redirect: Extract<HandlerResult, {
25
+ export declare function renderRedirect(requestId: protocol.RequestId, invocation: protocol.InvocationId, redirect: Extract<HandlerResult, {
23
26
  readonly kind: 'redirect';
24
- }>['redirect']): protocol.Redirect;
25
- export declare function renderHttpError(id: protocol.RequestId, error: errors.ErrorPayload, codec: codecs.Codec, cors: CorsHeaders, options?: ErrorRenderOptions): Response;
26
- export declare function renderHttpStale(id: protocol.RequestId, current: protocol.Stale['current'], codec: codecs.Codec, cors: CorsHeaders, maximumResponseBytes?: number): Response;
27
- export declare function encodeEnvelope(codec: codecs.Codec, input: unknown): string | Uint8Array;
27
+ }>['redirect']): protocol.RedirectResponse;
28
+ export declare function renderHttpError(requestId: protocol.RequestId, invocation: protocol.InvocationId, error: errors.ErrorPayload, codec: Codec, cors: CorsHeaders, options?: ErrorRenderOptions): Response;
29
+ export declare function renderHttpStale(requestId: protocol.RequestId, invocation: protocol.InvocationId, current: protocol.Stale['current'], codec: Codec, cors: CorsHeaders, maximumResponseBytes?: number): Response;
30
+ export declare function encodeEnvelope(codec: Codec, input: unknown): string | Uint8Array;
28
31
  export {};
29
- //# sourceMappingURL=render.d.ts.map
@@ -1,55 +1,64 @@
1
- import { errors, invocation as protocol, routes } from '@astrale-os/kernel-protocol';
1
+ import * as errors from '@astrale-os/kernel-protocol/errors';
2
+ import * as protocol from '@astrale-os/kernel-protocol/invocation';
3
+ import { HTTP_ROUTE_MISS, HTTP_ROUTE_STALE } from '@astrale-os/kernel-protocol/routes/routing';
2
4
  import { classifyError } from '../../errors/index.js';
3
5
  import { ResponseBodyTooLargeError } from '../../errors/index.js';
4
6
  import { interruptedStreamError } from '../stream-error.js';
5
7
  export function renderHttpResult(result, context) {
6
8
  switch (result.kind) {
7
9
  case 'value':
8
- return settled(context.operation, envelopeResponse(context.codec, { result: result.value, id: context.id }, context.cors(), 200, true, context.maximumResponseBytes));
10
+ return settled(context.active, envelopeResponse(context.codec, {
11
+ result: result.value,
12
+ requestId: context.requestId,
13
+ invocation: context.invocation,
14
+ }, context.cors(), 200, true, context.maximumResponseBytes));
9
15
  case 'redirect': {
10
- const response = renderRedirect(context.id, result.redirect);
11
- return settled(context.operation, envelopeResponse(context.codec, response, context.cors(), 200, true, context.maximumResponseBytes));
16
+ const response = renderRedirect(context.requestId, context.invocation, result.redirect);
17
+ return settled(context.active, envelopeResponse(context.codec, response, context.cors(), 200, true, context.maximumResponseBytes));
12
18
  }
13
19
  case 'miss':
14
- return settled(context.operation, envelopeResponse(context.codec, protocol.miss(context.id), context.cors(), 200, true, context.maximumResponseBytes));
20
+ return settled(context.active, envelopeResponse(context.codec, protocol.miss(context.requestId, context.invocation), context.cors(), 200, true, context.maximumResponseBytes));
15
21
  case 'binary': {
16
- const binary = renderBinary(context.id, result.value);
17
- return settled(context.operation, binaryHttpResponse(binary, context.cors, context.maximumResponseBytes));
22
+ const binary = renderBinary(context.requestId, context.invocation, result.value);
23
+ return settled(context.active, binaryHttpResponse(binary, context.cors, context.maximumResponseBytes));
18
24
  }
19
25
  case 'stream':
20
26
  return streamHttpResponse(result.stream, context);
21
27
  }
22
28
  }
23
- export function renderBinary(id, binary) {
24
- if (Object.keys(binary.headers ?? {}).some((name) => {
25
- const lower = name.toLowerCase();
26
- return lower === routes.HTTP_ROUTE_STALE || lower === routes.HTTP_ROUTE_MISS;
27
- })) {
28
- throw new TypeError(`${routes.HTTP_ROUTE_STALE} is reserved for stale-route control.`);
29
- }
29
+ export function renderBinary(requestId, invocation, binary) {
30
+ const reserved = Object.keys(binary.headers ?? {}).find((name) => {
31
+ const normalized = name.toLowerCase();
32
+ return (normalized === protocol.http.INVOCATION_FIELD ||
33
+ normalized === HTTP_ROUTE_STALE ||
34
+ normalized === HTTP_ROUTE_MISS);
35
+ });
36
+ if (reserved !== undefined)
37
+ throw new TypeError(`${reserved} is reserved by Protocol.`);
30
38
  return protocol.decodeBinaryResponse({
31
39
  kind: 'binary',
32
- id,
40
+ requestId,
41
+ invocation,
33
42
  body: binary.body,
34
43
  mediaType: binary.mediaType,
35
44
  ...(binary.headers === undefined ? {} : { headers: binary.headers }),
36
45
  });
37
46
  }
38
- export function renderRedirect(id, redirect) {
39
- return protocol.decodeRedirect({
47
+ export function renderRedirect(requestId, invocation, redirect) {
48
+ return protocol.decodeRedirectResponse({
40
49
  kind: 'redirect',
41
- id,
42
- route: redirect.route,
43
- ...(redirect.credential === undefined ? {} : { credential: redirect.credential }),
50
+ requestId,
51
+ invocation,
52
+ redirect,
44
53
  });
45
54
  }
46
- export function renderHttpError(id, error, codec, cors, options = {}) {
55
+ export function renderHttpError(requestId, invocation, error, codec, cors, options = {}) {
47
56
  const status = options.status ?? errors.httpStatusOf(error);
48
57
  const extra = status === 401 ? { 'www-authenticate': 'Bearer realm="astrale-invocation"' } : {};
49
- return errorEnvelopeResponse(codec, { error, id }, { ...cors(), ...extra }, status, options.negotiated ?? true, options.maximumResponseBytes);
58
+ return errorEnvelopeResponse(codec, { error, requestId, invocation }, { ...cors(), ...extra }, status, options.negotiated ?? true, options.maximumResponseBytes);
50
59
  }
51
- export function renderHttpStale(id, current, codec, cors, maximumResponseBytes) {
52
- return envelopeResponse(codec, protocol.stale(id, current), cors(), 200, true, maximumResponseBytes);
60
+ export function renderHttpStale(requestId, invocation, current, codec, cors, maximumResponseBytes) {
61
+ return envelopeResponse(codec, protocol.stale(requestId, invocation, current), cors(), 200, true, maximumResponseBytes);
53
62
  }
54
63
  export function encodeEnvelope(codec, input) {
55
64
  return codec.encode(input);
@@ -69,6 +78,7 @@ function binaryHttpResponse(binary, cors, maximumResponseBytes) {
69
78
  const applicationHeaders = Object.keys(binary.headers ?? {}).filter((name) => protocol.http.isApplicationBinaryHeader(name));
70
79
  const headers = new Headers(cors([
71
80
  protocol.http.REQUEST_ID_FIELD,
81
+ protocol.http.INVOCATION_FIELD,
72
82
  protocol.http.BINARY_HEADERS_FIELD,
73
83
  ...applicationHeaders,
74
84
  ]));
@@ -78,14 +88,15 @@ function binaryHttpResponse(binary, cors, maximumResponseBytes) {
78
88
  }
79
89
  headers.set('content-type', binary.mediaType);
80
90
  headers.set(protocol.http.BINARY_HEADERS_FIELD, protocol.http.encodeBinaryHeaderNames(binary.headers));
81
- headers.set(protocol.http.REQUEST_ID_FIELD, String(binary.id));
91
+ headers.set(protocol.http.REQUEST_ID_FIELD, String(binary.requestId));
92
+ headers.set(protocol.http.INVOCATION_FIELD, protocol.http.encodeInvocationId(binary.invocation));
82
93
  headers.set('cache-control', 'no-store');
83
94
  appendVary(headers, 'accept');
84
95
  return new Response(toBody(binary.body), { status: 200, headers });
85
96
  }
86
97
  function streamHttpResponse(stream, context) {
87
98
  const iterator = stream[Symbol.asyncIterator]();
88
- const startFrame = encodeBoundedStreamFrame(context.codec, { kind: 'stream.start', id: context.id }, context.maximumResponseBytes);
99
+ const startFrame = encodeBoundedStreamFrame(context.codec, { kind: 'stream.start', requestId: context.requestId, invocation: context.invocation }, context.maximumResponseBytes);
89
100
  let count = 0;
90
101
  let terminal = false;
91
102
  let controller;
@@ -121,7 +132,7 @@ function streamHttpResponse(stream, context) {
121
132
  ]);
122
133
  }
123
134
  finally {
124
- context.operation.settle();
135
+ context.active.settle();
125
136
  }
126
137
  }
127
138
  const body = new ReadableStream({
@@ -140,16 +151,16 @@ function streamHttpResponse(stream, context) {
140
151
  terminal = true;
141
152
  output.enqueue(encodeBoundedStreamFrame(context.codec, {
142
153
  kind: 'stream.end',
143
- id: context.id,
154
+ requestId: context.requestId,
144
155
  count,
145
156
  }, context.maximumResponseBytes));
146
157
  output.close();
147
- context.operation.settle();
158
+ context.active.settle();
148
159
  return;
149
160
  }
150
161
  const frame = protocol.decodeStreamFrame({
151
162
  kind: 'stream.item',
152
- id: context.id,
163
+ requestId: context.requestId,
153
164
  index: count,
154
165
  value: next.value,
155
166
  });
@@ -160,11 +171,11 @@ function streamHttpResponse(stream, context) {
160
171
  if (terminal)
161
172
  return;
162
173
  terminal = true;
163
- if (!context.operation.signal.aborted) {
174
+ if (!context.active.signal.aborted) {
164
175
  try {
165
176
  output.enqueue(encodeBoundedStreamFrame(context.codec, {
166
177
  kind: 'stream.error',
167
- id: context.id,
178
+ requestId: context.requestId,
168
179
  error: classifyError(input),
169
180
  }, context.maximumResponseBytes));
170
181
  }
@@ -177,16 +188,16 @@ function streamHttpResponse(stream, context) {
177
188
  Promise.resolve().then(() => stream.cancel('stream failed')),
178
189
  Promise.resolve().then(() => iterator.return?.()),
179
190
  ]);
180
- context.operation.settle();
191
+ context.active.settle();
181
192
  }
182
193
  },
183
194
  async cancel(reason) {
184
195
  const message = typeof reason === 'string' ? reason : 'response consumer cancelled';
185
- context.operation.cancel(message);
196
+ context.active.cancel(message);
186
197
  await stop(message);
187
198
  },
188
199
  });
189
- context.operation.onCancel(stop);
200
+ context.active.onCancel(stop);
190
201
  return new Response(body, {
191
202
  status: 200,
192
203
  headers: {
@@ -213,7 +224,8 @@ function errorEnvelopeResponse(codec, response, cors, status, negotiated, maximu
213
224
  if (!(error instanceof ResponseBodyTooLargeError))
214
225
  throw error;
215
226
  const fallback = {
216
- id: response.id,
227
+ requestId: response.requestId,
228
+ invocation: response.invocation,
217
229
  error: {
218
230
  code: errors.CODES.LIMIT_EXCEEDED,
219
231
  message: 'Response body exceeds the configured limit.',
@@ -264,8 +276,8 @@ function mergeVary(headers, value) {
264
276
  function cancellationFrame(context) {
265
277
  return {
266
278
  kind: 'stream.error',
267
- id: context.id,
268
- error: interruptedStreamError(context.operation.timedOut),
279
+ requestId: context.requestId,
280
+ error: interruptedStreamError(context.active.timedOut),
269
281
  };
270
282
  }
271
283
  function toBody(input) {
@@ -274,4 +286,3 @@ function toBody(input) {
274
286
  const copy = new Uint8Array(input);
275
287
  return copy.buffer;
276
288
  }
277
- //# sourceMappingURL=render.js.map
@@ -7,4 +7,3 @@ export { interruptedStreamError } from './stream-error.js';
7
7
  export { createServerRouter, type ServerRouter } from './router.js';
8
8
  export { createWebSocketSession, handleWebSocketUpgrade, type WebSocketHandlerConfig, type WebSocketSessionConfig, } from './websocket/index.js';
9
9
  export type { Application, WebSocketAdapter, WebSocketHandlers, WebSocketLike, WebSocketUpgradeOptions, } from './types.js';
10
- //# sourceMappingURL=index.d.ts.map
@@ -6,4 +6,3 @@ export { encodeEnvelope, renderBinary, renderHttpError, renderHttpResult, render
6
6
  export { interruptedStreamError } from './stream-error.js';
7
7
  export { createServerRouter } from './router.js';
8
8
  export { createWebSocketSession, handleWebSocketUpgrade, } from './websocket/index.js';
9
- //# sourceMappingURL=index.js.map
@@ -2,4 +2,3 @@ import { type Hono as HonoType } from 'hono';
2
2
  /** Private Web-standard router capability shared by Server route-owning children. */
3
3
  export type ServerRouter = HonoType;
4
4
  export declare function createServerRouter(): ServerRouter;
5
- //# sourceMappingURL=router.d.ts.map
@@ -2,4 +2,3 @@ import { Hono } from 'hono';
2
2
  export function createServerRouter() {
3
3
  return new Hono();
4
4
  }
5
- //# sourceMappingURL=router.js.map
@@ -1,4 +1,3 @@
1
- import { type errors } from '@astrale-os/kernel-protocol';
1
+ import type { ErrorPayload } from '@astrale-os/kernel-protocol/errors';
2
2
  /** A transport cancellation after stream.start necessarily follows the Function effect boundary. */
3
- export declare function interruptedStreamError(timedOut: boolean): errors.ErrorPayload;
4
- //# sourceMappingURL=stream-error.d.ts.map
3
+ export declare function interruptedStreamError(timedOut: boolean): ErrorPayload;
@@ -1,14 +1,13 @@
1
- import { errors as protocolErrors } from '@astrale-os/kernel-protocol';
1
+ import { CODES } from '@astrale-os/kernel-protocol/errors';
2
2
  /** A transport cancellation after stream.start necessarily follows the Function effect boundary. */
3
3
  export function interruptedStreamError(timedOut) {
4
4
  return timedOut
5
5
  ? {
6
- code: protocolErrors.CODES.OUTCOME_UNKNOWN,
6
+ code: CODES.OUTCOME_UNKNOWN,
7
7
  message: 'Invocation deadline elapsed after the Function stream began; outcome is unknown.',
8
8
  }
9
9
  : {
10
- code: protocolErrors.CODES.OUTCOME_UNKNOWN,
10
+ code: CODES.OUTCOME_UNKNOWN,
11
11
  message: 'Function stream was cancelled after execution began; outcome is unknown.',
12
12
  };
13
13
  }
14
- //# sourceMappingURL=stream-error.js.map
@@ -1,4 +1,4 @@
1
- import type { invocation as protocol } from '@astrale-os/kernel-protocol';
1
+ import type * as protocol from '@astrale-os/kernel-protocol/invocation';
2
2
  import type { ApplicationHost } from '../invocation/index.js';
3
3
  /** Portable Fetch application; framework and listener APIs are adapter-owned. */
4
4
  export interface Application {
@@ -26,4 +26,3 @@ export interface WebSocketUpgradeOptions {
26
26
  export interface WebSocketAdapter {
27
27
  upgrade(request: Request, options: WebSocketUpgradeOptions): Response | Promise<Response>;
28
28
  }
29
- //# sourceMappingURL=types.d.ts.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=types.js.map
@@ -1,3 +1,2 @@
1
1
  export { createWebSocketSession, type WebSocketSessionConfig } from './session.js';
2
2
  export { handleWebSocketUpgrade, type WebSocketHandlerConfig } from './upgrade.js';
3
- //# sourceMappingURL=index.d.ts.map
@@ -1,3 +1,2 @@
1
1
  export { createWebSocketSession } from './session.js';
2
2
  export { handleWebSocketUpgrade } from './upgrade.js';
3
- //# sourceMappingURL=index.js.map
@@ -1,13 +1,15 @@
1
- import { type codecs } from '@astrale-os/kernel-protocol';
1
+ import type { Codec } from '@astrale-os/kernel-protocol/codecs';
2
+ import type { NextInvocationId } from '../../invocation/index.js';
2
3
  import type { ActiveOperations } from '../../lifecycle/index.js';
3
4
  import type { PublicationSnapshot } from '../../publication/index.js';
4
5
  import type { WebSocketHandlers } from '../types.js';
5
6
  import { type ApplicationHost, type Handler } from '../../invocation/index.js';
6
7
  export interface WebSocketSessionConfig {
7
- readonly codec: codecs.Codec;
8
+ readonly codec: Codec;
8
9
  readonly authorization: string | null;
9
10
  readonly handler: Handler;
10
11
  readonly active: ActiveOperations;
12
+ readonly invocation: NextInvocationId;
11
13
  readonly maximumRequestBytes: number;
12
14
  readonly maximumResponseBytes: number;
13
15
  readonly invocationTimeoutMs: number;
@@ -16,4 +18,3 @@ export interface WebSocketSessionConfig {
16
18
  }
17
19
  /** Build one socket-pinned transport session. */
18
20
  export declare function createWebSocketSession(config: WebSocketSessionConfig): WebSocketHandlers;
19
- //# sourceMappingURL=session.d.ts.map