@astrale-os/kernel-client 0.6.0-beta.72 → 0.6.0-beta.75

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 (44) hide show
  1. package/dist/auth/credential.d.ts +1 -0
  2. package/dist/auth/credential.js +2 -2
  3. package/dist/errors/exchange-error.d.ts +19 -0
  4. package/dist/errors/exchange-error.js +9 -0
  5. package/dist/errors/index.d.ts +1 -0
  6. package/dist/errors/index.js +1 -0
  7. package/dist/schema/introspection.js +4 -0
  8. package/dist/session/admission.d.ts +3 -15
  9. package/dist/session/admission.js +16 -74
  10. package/dist/session/credential/index.d.ts +1 -1
  11. package/dist/session/credential/index.js +1 -1
  12. package/dist/session/credential/provider.d.ts +5 -0
  13. package/dist/session/credential/provider.js +8 -1
  14. package/dist/session/exchange/domain.d.ts +27 -0
  15. package/dist/session/exchange/domain.js +63 -0
  16. package/dist/session/exchange/exchange.d.ts +54 -0
  17. package/dist/session/exchange/exchange.js +58 -0
  18. package/dist/session/exchange/index.d.ts +5 -0
  19. package/dist/session/exchange/index.js +5 -0
  20. package/dist/session/exchange/issuer.d.ts +18 -0
  21. package/dist/session/exchange/issuer.js +132 -0
  22. package/dist/session/exchange/limits.d.ts +10 -0
  23. package/dist/session/exchange/limits.js +10 -0
  24. package/dist/session/exchange/options.d.ts +29 -0
  25. package/dist/session/exchange/options.js +57 -0
  26. package/dist/session/exchange/presentation.d.ts +18 -0
  27. package/dist/session/exchange/presentation.js +73 -0
  28. package/dist/session/exchange/source.d.ts +32 -0
  29. package/dist/session/exchange/source.js +78 -0
  30. package/dist/session/execution.d.ts +65 -0
  31. package/dist/session/execution.js +35 -0
  32. package/dist/session/index.d.ts +2 -0
  33. package/dist/session/index.js +1 -0
  34. package/dist/session/reference.d.ts +7 -1
  35. package/dist/session/routing/auth.d.ts +10 -0
  36. package/dist/session/routing/auth.js +8 -1
  37. package/dist/session/routing/dispatch.d.ts +2 -1
  38. package/dist/session/routing/dispatch.js +5 -2
  39. package/dist/session/routing/index.d.ts +1 -1
  40. package/dist/session/session.d.ts +16 -0
  41. package/dist/session/session.js +24 -4
  42. package/dist/session/session.typecheck.js +32 -1
  43. package/dist/transport/http/transport.js +0 -1
  44. package/package.json +5 -5
@@ -14,6 +14,7 @@ import { admitFunction } from './admission.js';
14
14
  import { createContentApi } from './content.js';
15
15
  import { admitControlOptions, admitPolicy, createSessionOperation, DEFAULT_MAXIMUM_BUNDLE_BYTES, DEFAULT_MAXIMUM_PUBLICATION_BYTES, DEFAULT_MAXIMUM_RESPONSE_BYTES, DEFAULT_TIMEOUT_MS, admitKernel, allowEndpoint, kernelInvocationEndpoint, platformDuration, positive, } from './context/index.js';
16
16
  import { createSessionDiscovery } from './discovery/index.js';
17
+ import { acquireDomainCredential, admitExchangeOptions, admitExchangeRequest, createSessionExchange, } from './exchange/index.js';
17
18
  import { admitReference } from './reference.js';
18
19
  import { admitEnvelopeTransport, admitInvocationOptions, admitSessionAuth, requireResultKind, RouteCache, SessionDispatcher, } from './routing/index.js';
19
20
  import { resolveViewsFor, targetViewCatalog } from './views/index.js';
@@ -31,6 +32,8 @@ export class ClientSession {
31
32
  lifecycle = new AbortController();
32
33
  timeoutMs;
33
34
  routes;
35
+ exchangeDependencies;
36
+ callExchange;
34
37
  admitTargetViews;
35
38
  closed = false;
36
39
  constructor(options) {
@@ -86,24 +89,31 @@ export class ClientSession {
86
89
  });
87
90
  this.routes = new RouteCache(policy.maximumRouteAgeMs, undefined, options.routeStore);
88
91
  const auth = admitSessionAuth(options.auth);
89
- const admission = {
92
+ const exchange = admitExchangeOptions(options.exchange, auth);
93
+ this.exchangeDependencies = Object.freeze({
90
94
  kernel: this.kernel,
91
- auth,
92
95
  source: () => {
93
96
  allowEndpoint(sourceEndpoint, policy);
94
97
  return pool.clientFor({ transport: 'http', url: sourceEndpoint });
95
98
  },
99
+ ...(auth === undefined ? {} : { auth }),
96
100
  fetch: fetchImpl,
97
101
  policy,
98
102
  limits: { maximumPublicationBytes, maximumBundleBytes },
99
103
  maximumResponseBytes,
100
- };
104
+ operation: (signal) => this.operation(signal === undefined ? undefined : { signal }),
105
+ });
106
+ this.callExchange =
107
+ exchange === undefined || auth === undefined
108
+ ? undefined
109
+ : createSessionExchange({ ...this.exchangeDependencies, auth }, exchange);
101
110
  this.dispatcher = new SessionDispatcher({
102
111
  kernel: this.kernel,
103
112
  sourceEndpoint,
104
113
  pool,
105
114
  websocketAvailable,
106
115
  auth,
116
+ ...(this.callExchange === undefined ? {} : { exchange: this.callExchange }),
107
117
  cache: this.routes,
108
118
  policy,
109
119
  envelopeTransport: admitEnvelopeTransport(options.envelopeTransport ?? 'http'),
@@ -127,13 +137,22 @@ export class ClientSession {
127
137
  this.graph = createGraph((call, options) => this.call(call, options));
128
138
  this.auth = createAuth((target, input, options) => this.call({ target, input }, options), (call, options) => {
129
139
  const operation = this.operation(admitControlOptions(options));
130
- return admitFunction(admission, acceptCall(call), options, operation);
140
+ return admitFunction(this.exchangeDependencies, acceptCall(call), options, operation);
131
141
  });
132
142
  }
133
143
  /** Bind one admitted DSL Domain to authenticated graph projection and Method dispatch. */
134
144
  bind(domain) {
135
145
  return createDomainBinding(domain, this.graph, (node, method, input) => this.invokeDomainMethod(domain, node, method, input));
136
146
  }
147
+ /**
148
+ * Delegate this Session's caller to one Domain issuer and exchange that delegation for the
149
+ * Domain's credential to this Kernel. Nothing is cached: hold the result, for example through
150
+ * `createSessionCredentialProvider`, for as long as it covers the calls it carries.
151
+ */
152
+ async exchange(domain, options) {
153
+ const request = admitExchangeRequest(domain, options);
154
+ return acquireDomainCredential(this.exchangeDependencies, request, this.operation(request.control));
155
+ }
137
156
  /** Revalidate the intrinsic Publication without acquiring its bundle or Views. */
138
157
  publication(options) {
139
158
  return this.discovery.publication(this.operation(admitControlOptions(options)));
@@ -208,6 +227,7 @@ export class ClientSession {
208
227
  this.ownedPool?.close();
209
228
  this.routes.clear();
210
229
  this.discovery.clear();
230
+ this.callExchange?.clear();
211
231
  }
212
232
  requireOpen() {
213
233
  if (this.closed)
@@ -4,7 +4,7 @@ import { K, KernelSchema } from '@astrale-os/kernel-core/schema';
4
4
  import { defineSchema, func, method, nodeClass, schema, valueSchema, } from '@astrale-os/kernel-dsl/v1';
5
5
  import { isBinaryInput } from '@astrale-os/kernel-dsl/v1/language';
6
6
  import { call } from '../client/index.js';
7
- import { ClientSession, createSessionCredentialProvider, reference } from './index.js';
7
+ import { ClientSession, createSessionCredentialProvider, execution, reference } from './index.js';
8
8
  void new ClientSession(options);
9
9
  void auth;
10
10
  void control;
@@ -136,6 +136,37 @@ const abstractDomain = schema.resolve(defineSchema('client.reference.typecheck',
136
136
  AbstractItem: nodeClass({ abstract: true, methods: { abstractMethod } }),
137
137
  },
138
138
  }));
139
+ const reminderOutput = valueSchema()({
140
+ type: 'object',
141
+ properties: { reminder: { type: 'string' } },
142
+ required: ['reminder'],
143
+ additionalProperties: false,
144
+ });
145
+ const durableDomain = schema.resolve(defineSchema('client.durable.typecheck', {
146
+ classes: {
147
+ Invoice: nodeClass({
148
+ methods: {
149
+ remind: method({
150
+ auth: 'authenticated',
151
+ input: renameInput,
152
+ output: reminderOutput,
153
+ execution: { durable: true },
154
+ }),
155
+ },
156
+ }),
157
+ },
158
+ }));
159
+ const remindReference = reference(durableDomain, durableDomain.classes.Invoice.methods.remind)(Path.id(NodeId('invoice-1')));
160
+ const durableReturnsExecution = true;
161
+ const outcomeIsTyped = true;
162
+ const statusIsTyped = true;
163
+ void session.invoke(execution.result(run), { waitMs: 1_000 });
164
+ void session.invoke(execution.signal(run), { name: 'approval', value: { by: 'billing' } });
165
+ // @ts-expect-error Force is the only cancellation option.
166
+ void session.invoke(execution.cancel(run), { waitMs: 1_000 });
167
+ void durableReturnsExecution;
168
+ void outcomeIsTyped;
169
+ void statusIsTyped;
139
170
  // @ts-expect-error Abstract Methods are declarations and cannot become Client references.
140
171
  reference(abstractDomain, abstractDomain.classes.AbstractItem.methods.abstractMethod);
141
172
  // @ts-expect-error Exact identity is derived internally, never supplied as a Session option.
@@ -163,7 +163,6 @@ export class HttpTransport {
163
163
  method: 'POST',
164
164
  redirect: 'manual',
165
165
  credentials: 'omit',
166
- cache: 'no-store',
167
166
  referrerPolicy: 'no-referrer',
168
167
  // Fetch owns Content-Length; the protocol carries Blob.size across Fetch runtimes.
169
168
  headers: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrale-os/kernel-client",
3
- "version": "0.6.0-beta.72",
3
+ "version": "0.6.0-beta.75",
4
4
  "description": "Universal Client — protocol-first, transport-agnostic",
5
5
  "keywords": [
6
6
  "astrale",
@@ -65,14 +65,14 @@
65
65
  "access": "public"
66
66
  },
67
67
  "dependencies": {
68
- "@astrale-os/kernel-core": "0.9.0-beta.55",
69
- "@astrale-os/kernel-dsl": "0.2.0-beta.40",
70
- "@astrale-os/kernel-protocol": "0.5.0-beta.61",
68
+ "@astrale-os/kernel-core": "0.9.0-beta.56",
69
+ "@astrale-os/kernel-dsl": "0.2.0-beta.41",
70
+ "@astrale-os/kernel-protocol": "0.5.0-beta.62",
71
71
  "@tanstack/pacer": "0.20.1",
72
72
  "msgpackr": "^2.0.5"
73
73
  },
74
74
  "devDependencies": {
75
- "@astrale-os/kernel-server": "0.5.0-beta.63",
75
+ "@astrale-os/kernel-server": "0.5.0-beta.64",
76
76
  "@astrale/typescript-config": "npm:@jsr/astrale__typescript-config@~1.1.0",
77
77
  "@types/node": "^22.0.0",
78
78
  "typescript": "7.0.2",