@astrale-os/sdk 0.5.0-beta.118 → 0.5.0-beta.119
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/CHANGELOG.md +16 -0
- package/README.md +7 -0
- package/dist/application/action/authoring.d.ts +1 -1
- package/dist/application/action/context.d.ts +7 -8
- package/dist/application/action/index.d.ts +1 -1
- package/dist/application/dependency/index.d.ts +1 -0
- package/dist/application/dependency/index.js +1 -0
- package/dist/application/dependency/invoker.d.ts +22 -0
- package/dist/application/dependency/invoker.js +1 -0
- package/dist/execution/identity/authentication.js +0 -1
- package/dist/execution/invocation/admission/authentication.d.ts +0 -1
- package/dist/execution/invocation/admission/authentication.js +2 -5
- package/dist/execution/invocation/admission/authority.d.ts +0 -1
- package/dist/execution/invocation/dependency/bind.d.ts +5 -0
- package/dist/execution/invocation/dependency/bind.js +62 -0
- package/dist/execution/invocation/dependency/index.d.ts +1 -0
- package/dist/execution/invocation/dependency/index.js +1 -0
- package/dist/execution/invocation/dispatch/context.d.ts +4 -4
- package/dist/execution/invocation/dispatch/context.js +13 -4
- package/dist/execution/invocation/dispatch/workflow.js +1 -2
- package/dist/execution/invocation/lifecycle/active.js +30 -5
- package/dist/tooling/linter/implementations/source/callable-requirements.d.ts +28 -0
- package/dist/tooling/linter/implementations/source/callable-requirements.js +234 -0
- package/dist/tooling/linter/implementations/source/dependencies.d.ts +2 -0
- package/dist/tooling/linter/implementations/source/dependencies.js +219 -0
- package/dist/tooling/linter/implementations/source/providers.js +19 -164
- package/dist/tooling/linter/implementations/source/verifiers.js +2 -0
- package/dist/tooling/linter/implementations/source/workflows.js +2 -34
- package/dist/tooling/linter/policy/generated.js +2 -2
- package/dist/tooling/linter/requirements/registry.js +3 -2
- package/package.json +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.5.0-beta.119](https://github.com/astrale-os/sdk/compare/sdk-v0.5.0-beta.118...sdk-v0.5.0-beta.119) (2026-09-06)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### ⚠ BREAKING CHANGES
|
|
7
|
+
|
|
8
|
+
* **action:** add self-default capabilities and dependency invocation ([#438](https://github.com/astrale-os/sdk/issues/438))
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
|
|
12
|
+
* **action:** add self-default capabilities and dependency invocation ([#438](https://github.com/astrale-os/sdk/issues/438)) ([7daca62](https://github.com/astrale-os/sdk/commit/7daca6224e1532a2843f8d4bdc83ad93d8bccaa5))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* **linter:** resolve requirements through schema dependencies ([#440](https://github.com/astrale-os/sdk/issues/440)) ([096b037](https://github.com/astrale-os/sdk/commit/096b03774c09e04cd04380c4625e437a3be905aa))
|
|
18
|
+
|
|
3
19
|
## [0.5.0-beta.118](https://github.com/astrale-os/sdk/compare/sdk-v0.5.0-beta.117...sdk-v0.5.0-beta.118) (2026-09-06)
|
|
4
20
|
|
|
5
21
|
|
package/README.md
CHANGED
|
@@ -31,6 +31,13 @@ npx -y create-astrale-domain@beta my-domain --yes
|
|
|
31
31
|
See [the release lifecycle](docs/release.md) for package-set versioning, verification, and stable
|
|
32
32
|
promotion.
|
|
33
33
|
|
|
34
|
+
## Handler authority and dependencies
|
|
35
|
+
|
|
36
|
+
Authenticated handlers use Domain self authority for `kernel`, `graph`, `query`, and `mutate`.
|
|
37
|
+
`dependencies.directory.invoke(d => d.functions.lookup, input)` calls a direct declared dependency
|
|
38
|
+
with the incoming caller Grant. Explicit authority remains on `kernel` and `graph`; the former
|
|
39
|
+
handler `client` is removed. See [the API and migration guide](docs/handler-dependencies.md).
|
|
40
|
+
|
|
34
41
|
## Node Class icons
|
|
35
42
|
|
|
36
43
|
Every Node Class authored through the SDK must explicitly declare a self-contained SVG icon.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { defineAction } from './define.js';
|
|
2
2
|
export type { Action, ActionDefinition } from './action.js';
|
|
3
|
-
export type { ActionContext, ActionExecution, Caller, DomainGraphExecutor, DomainGraphExecutors, } from './context.js';
|
|
3
|
+
export type { ActionContext, ActionExecution, Caller, DomainGraphExecutor, DomainGraphExecutors, DomainKernelSessions, } from './context.js';
|
|
4
4
|
export type { ActionBinary, ActionOutputOf } from './output.js';
|
|
5
5
|
export type { DeclaredErrorDefinition, DeclaredErrorFactory, DeclaredErrorFamily, DeclaredErrorOptions, DeclaredErrors, } from '../error/index.js';
|
|
@@ -2,6 +2,7 @@ import type { AuthenticationEvidence, Grant, IdentityId } from '../../platform/a
|
|
|
2
2
|
import type { BoundClientSession } from '../../platform/client/session/index.js';
|
|
3
3
|
import type { NodeId } from '../../platform/graph/node/index.js';
|
|
4
4
|
import type { CallableInputOf, Domain, ResolvedFunction, ResolvedMethod } from '../../platform/schema/index.js';
|
|
5
|
+
import type { HandlerDependencies } from '../dependency/index.js';
|
|
5
6
|
import type { DeclaredErrorFactory, DeclaredErrors, NoDeclaredErrors } from '../error/index.js';
|
|
6
7
|
import type { IntegrationClients, Integrations } from '../integration/index.js';
|
|
7
8
|
import type { MutationExecutor } from '../mutation/index.js';
|
|
@@ -37,22 +38,21 @@ export interface DomainGraphExecutor<DomainValue extends Domain = Domain> {
|
|
|
37
38
|
readonly query: QueryExecutor<DomainValue>;
|
|
38
39
|
readonly mutate: MutationExecutor<DomainValue>;
|
|
39
40
|
}
|
|
40
|
-
export type DomainGraphExecutors<DomainValue extends Domain = Domain> = Readonly<Record<'caller' | 'self' | 'union', DomainGraphExecutor<DomainValue>>>;
|
|
41
|
-
/**
|
|
42
|
-
export type DomainKernelSessions = Readonly<Record<'caller' | 'self' | 'union', BoundClientSession>>;
|
|
41
|
+
export type DomainGraphExecutors<DomainValue extends Domain = Domain> = Readonly<DomainGraphExecutor<DomainValue> & Record<'caller' | 'self' | 'union', DomainGraphExecutor<DomainValue>>>;
|
|
42
|
+
/** Self-default Kernel session with one level of explicit authority selection. */
|
|
43
|
+
export type DomainKernelSessions = Readonly<BoundClientSession & Record<'caller' | 'self' | 'union', BoundClientSession>>;
|
|
43
44
|
type AuthorityOf<Callable, DomainValue extends Domain> = Callable extends {
|
|
44
45
|
readonly auth: 'anonymous';
|
|
45
46
|
} ? {
|
|
46
47
|
readonly caller: AnonymousCaller;
|
|
47
|
-
readonly
|
|
48
|
+
readonly dependencies: null;
|
|
48
49
|
readonly kernel: null;
|
|
49
50
|
readonly graph: null;
|
|
50
51
|
readonly query?: never;
|
|
51
52
|
readonly mutate?: never;
|
|
52
53
|
} | {
|
|
53
54
|
readonly caller: AuthenticatedCaller;
|
|
54
|
-
|
|
55
|
-
readonly client: BoundClientSession;
|
|
55
|
+
readonly dependencies: HandlerDependencies<DomainValue>;
|
|
56
56
|
readonly kernel: DomainKernelSessions;
|
|
57
57
|
readonly graph: DomainGraphExecutors<DomainValue>;
|
|
58
58
|
/** Convenience executor using the installed Domain authority (`graph.self`). */
|
|
@@ -61,8 +61,7 @@ type AuthorityOf<Callable, DomainValue extends Domain> = Callable extends {
|
|
|
61
61
|
readonly mutate: MutationExecutor<DomainValue>;
|
|
62
62
|
} : {
|
|
63
63
|
readonly caller: AuthenticatedCaller;
|
|
64
|
-
|
|
65
|
-
readonly client: BoundClientSession;
|
|
64
|
+
readonly dependencies: HandlerDependencies<DomainValue>;
|
|
66
65
|
readonly kernel: DomainKernelSessions;
|
|
67
66
|
readonly graph: DomainGraphExecutors<DomainValue>;
|
|
68
67
|
/** Convenience executor using the installed Domain authority (`graph.self`). */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { defineAction, isAction } from './define.js';
|
|
2
2
|
export type { Action, ActionAddress, ActionAddressOf, ActionDefinition, CallableAtAddress, LocalCallable, ResolvedDomainOf, } from './action.js';
|
|
3
|
-
export type { ActionContext, ActionExecution, AnonymousCaller, AuthenticatedCaller, Caller, DomainGraphExecutor, DomainGraphExecutors, ResolvedCallable, } from './context.js';
|
|
3
|
+
export type { ActionContext, ActionExecution, AnonymousCaller, AuthenticatedCaller, Caller, DomainGraphExecutor, DomainGraphExecutors, DomainKernelSessions, ResolvedCallable, } from './context.js';
|
|
4
4
|
export type { ActionBinary, ActionOutputOf } from './output.js';
|
|
5
5
|
export type { DeclaredErrorDefinition, DeclaredErrorFactory, DeclaredErrorFamily, DeclaredErrorOptions, DeclaredErrors, } from '../error/index.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { DependencyCallOptions, DependencyInvoker, HandlerDependencies } from './invoker.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Binary, Input } from '../../platform/client/index.js';
|
|
2
|
+
import type { SessionRequestOptions } from '../../platform/client/session/index.js';
|
|
3
|
+
import type { NodeId } from '../../platform/graph/node/index.js';
|
|
4
|
+
import type { CallableInputOf, CallableOutputOf, CallableResultOf, Domain, ResolvedMethod, KernelSchema, schema } from '../../platform/schema/index.js';
|
|
5
|
+
import type { LocalCallable } from '../action/index.js';
|
|
6
|
+
export type DependencyCallOptions = Pick<SessionRequestOptions, 'timeoutMs' | 'idempotencyKey'>;
|
|
7
|
+
type InstanceMethodOf<D extends Domain> = Extract<LocalCallable<D>, ResolvedMethod<unknown, unknown, false>>;
|
|
8
|
+
type FunctionOrStaticMethodOf<D extends Domain> = Exclude<LocalCallable<D>, ResolvedMethod<unknown, unknown, false>>;
|
|
9
|
+
type DependencyInputOf<C> = C extends unknown ? unknown extends CallableInputOf<C> ? Input : [CallableInputOf<C>] extends [void] ? undefined : Extract<CallableInputOf<C>, Input> : never;
|
|
10
|
+
type DependencyResultOf<C> = unknown extends CallableOutputOf<C> ? unknown : CallableResultOf<C, Binary>;
|
|
11
|
+
/** One declared dependency, bound to the incoming caller Grant for this invocation. */
|
|
12
|
+
export interface DependencyInvoker<D extends Domain> {
|
|
13
|
+
readonly invoke: {
|
|
14
|
+
<const C extends FunctionOrStaticMethodOf<D>>(select: (domain: D) => C, input: NoInfer<DependencyInputOf<C>>, options?: DependencyCallOptions): Promise<DependencyResultOf<C>>;
|
|
15
|
+
<const C extends InstanceMethodOf<D>>(select: (domain: D) => C, instance: NodeId, input: NoInfer<DependencyInputOf<C>>, options?: DependencyCallOptions): Promise<DependencyResultOf<C>>;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/** Direct Schema aliases only; the canonical Kernel is exposed through context.kernel. */
|
|
19
|
+
export type HandlerDependencies<D extends Domain> = Readonly<{
|
|
20
|
+
[Alias in keyof D['dependencies'] as D['dependencies'][Alias] extends schema.DomainOf<KernelSchema> ? never : Alias]: DependencyInvoker<Extract<D['dependencies'][Alias], Domain>>;
|
|
21
|
+
}>;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -5,7 +5,6 @@ import type { Domain } from '../../../platform/schema/index.js';
|
|
|
5
5
|
import type { AuthenticatedInvocation, InvocationAuthority } from './authority.js';
|
|
6
6
|
export interface AnonymousInvocation {
|
|
7
7
|
readonly caller: AnonymousCaller;
|
|
8
|
-
readonly client: null;
|
|
9
8
|
readonly kernel: null;
|
|
10
9
|
readonly graph: null;
|
|
11
10
|
close(): void;
|
|
@@ -5,7 +5,6 @@ import { protocolError } from '../result/index.js';
|
|
|
5
5
|
import { requireVia } from './authority.js';
|
|
6
6
|
const ANONYMOUS = Object.freeze({
|
|
7
7
|
caller: Object.freeze({ kind: 'anonymous' }),
|
|
8
|
-
client: null,
|
|
9
8
|
kernel: null,
|
|
10
9
|
graph: null,
|
|
11
10
|
close() { },
|
|
@@ -32,20 +31,18 @@ export async function authentication(callable, request, release, domain, authori
|
|
|
32
31
|
if (authenticated === null ||
|
|
33
32
|
typeof authenticated !== 'object' ||
|
|
34
33
|
Array.isArray(authenticated) ||
|
|
35
|
-
Reflect.ownKeys(authenticated).some((key) => key !== 'caller' && key !== '
|
|
34
|
+
Reflect.ownKeys(authenticated).some((key) => key !== 'caller' && key !== 'graph' && key !== 'close') ||
|
|
36
35
|
close === undefined) {
|
|
37
36
|
invalid();
|
|
38
37
|
}
|
|
39
38
|
const caller = admitCaller(authenticated.caller);
|
|
40
39
|
const graphInput = admitGraph(authenticated.graph);
|
|
41
|
-
if (authenticated.client !== graphInput.caller)
|
|
42
|
-
invalid();
|
|
43
40
|
const graph = Object.freeze({
|
|
44
41
|
caller: bindSession(graphInput.caller),
|
|
45
42
|
self: bindSession(graphInput.self),
|
|
46
43
|
union: bindSession(graphInput.union),
|
|
47
44
|
});
|
|
48
|
-
return Object.freeze({ caller,
|
|
45
|
+
return Object.freeze({ caller, graph, close });
|
|
49
46
|
}
|
|
50
47
|
catch (cause) {
|
|
51
48
|
if (close === undefined)
|
|
@@ -22,7 +22,6 @@ export interface InvocationAuthenticationInput {
|
|
|
22
22
|
/** Authenticated capabilities before the SDK admits and derives application caller context. */
|
|
23
23
|
export interface AuthenticatedInvocation {
|
|
24
24
|
readonly caller: Omit<AuthenticatedCaller, 'identity'>;
|
|
25
|
-
readonly client: BoundClientSession;
|
|
26
25
|
readonly graph: Readonly<Record<'caller' | 'self' | 'union', BoundClientSession>>;
|
|
27
26
|
close(): void;
|
|
28
27
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { HandlerDependencies } from '../../../application/dependency/index.js';
|
|
2
|
+
import type { BoundClientSession } from '../../../platform/client/session/index.js';
|
|
3
|
+
import type { Domain } from '../../../platform/schema/index.js';
|
|
4
|
+
/** Capture only the admitted caller session; schema metadata never acquires capabilities. */
|
|
5
|
+
export declare function bindDependencies<D extends Domain>(domain: D, caller: BoundClientSession): HandlerDependencies<D>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Key } from '@astrale-os/kernel-dsl/v1/addressing';
|
|
2
|
+
import { reference } from '../../../platform/client/session/index.js';
|
|
3
|
+
import { NodeId } from '../../../platform/graph/node/index.js';
|
|
4
|
+
import { Path } from '../../../platform/graph/path/index.js';
|
|
5
|
+
/** Capture only the admitted caller session; schema metadata never acquires capabilities. */
|
|
6
|
+
export function bindDependencies(domain, caller) {
|
|
7
|
+
const invoke = caller.invoke.bind(caller);
|
|
8
|
+
const dependencies = Object.create(null);
|
|
9
|
+
for (const [alias, dependency] of Object.entries(domain.dependencies)) {
|
|
10
|
+
if (dependency.origin === 'kernel.astrale.ai')
|
|
11
|
+
continue;
|
|
12
|
+
dependencies[alias] = Object.freeze({
|
|
13
|
+
async invoke(select, ...args) {
|
|
14
|
+
if (typeof select !== 'function')
|
|
15
|
+
invalid();
|
|
16
|
+
const selected = select(dependency);
|
|
17
|
+
if (selected === null ||
|
|
18
|
+
typeof selected !== 'object' ||
|
|
19
|
+
!('key' in selected) ||
|
|
20
|
+
typeof selected.key !== 'string')
|
|
21
|
+
invalid();
|
|
22
|
+
const callable = dependency.callable(selected.key);
|
|
23
|
+
if (callable !== selected || Key.origin(callable.key) !== dependency.origin)
|
|
24
|
+
invalid();
|
|
25
|
+
if ('owner' in callable &&
|
|
26
|
+
(callable.inheritance === 'abstract' || !ownMethod(dependency, callable)))
|
|
27
|
+
invalid();
|
|
28
|
+
if ('owner' in callable && !callable.static) {
|
|
29
|
+
if (args.length < 2 || args.length > 3 || typeof args[0] !== 'string')
|
|
30
|
+
invalid();
|
|
31
|
+
const instance = Path.id(NodeId(args[0]));
|
|
32
|
+
return invoke(reference(dependency, callable)(instance), args[1], options(args[2]));
|
|
33
|
+
}
|
|
34
|
+
if (args.length < 1 || args.length > 2)
|
|
35
|
+
invalid();
|
|
36
|
+
return invoke(reference(dependency, callable), args[0], options(args[1]));
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return Object.freeze(dependencies);
|
|
41
|
+
}
|
|
42
|
+
function ownMethod(domain, callable) {
|
|
43
|
+
const owner = Object.values(domain.classes).find((value) => value === callable.owner);
|
|
44
|
+
if (owner === undefined)
|
|
45
|
+
return false;
|
|
46
|
+
const methods = callable.static ? owner.self.static.methods : owner.self.methods;
|
|
47
|
+
return methods.get(callable.key) === callable;
|
|
48
|
+
}
|
|
49
|
+
function options(value) {
|
|
50
|
+
if (value === undefined)
|
|
51
|
+
return undefined;
|
|
52
|
+
if (value === null ||
|
|
53
|
+
typeof value !== 'object' ||
|
|
54
|
+
Array.isArray(value) ||
|
|
55
|
+
Reflect.ownKeys(value).some((key) => key !== 'timeoutMs' && key !== 'idempotencyKey'))
|
|
56
|
+
invalid();
|
|
57
|
+
// Canonical ClientSession admits option values and clamps them to the parent lifetime.
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
function invalid() {
|
|
61
|
+
throw new TypeError('Dependency invocation requires one owned concrete callable, its input, and valid instance/options.');
|
|
62
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { bindDependencies } from './bind.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { bindDependencies } from './bind.js';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { HandlerRequest } from '@astrale-os/kernel-server';
|
|
2
|
-
import type { ActionExecution, Caller, DomainGraphExecutors } from '../../../application/action/index.js';
|
|
2
|
+
import type { ActionExecution, Caller, DomainGraphExecutors, DomainKernelSessions } from '../../../application/action/index.js';
|
|
3
|
+
import type { HandlerDependencies } from '../../../application/dependency/index.js';
|
|
3
4
|
import type { MutationExecutor } from '../../../application/mutation/index.js';
|
|
4
5
|
import type { QueryExecutor } from '../../../application/query/index.js';
|
|
5
|
-
import type { BoundClientSession } from '../../../platform/client/session/index.js';
|
|
6
6
|
import type { NodeId } from '../../../platform/graph/node/index.js';
|
|
7
7
|
import type { Domain } from '../../../platform/schema/index.js';
|
|
8
8
|
import type { InitializedRuntime } from '../../runtime/index.js';
|
|
@@ -11,8 +11,8 @@ export interface DispatchContext {
|
|
|
11
11
|
readonly domain: Domain;
|
|
12
12
|
readonly input: unknown;
|
|
13
13
|
readonly caller: Caller;
|
|
14
|
-
readonly
|
|
15
|
-
readonly kernel:
|
|
14
|
+
readonly dependencies: HandlerDependencies<Domain> | null;
|
|
15
|
+
readonly kernel: DomainKernelSessions | null;
|
|
16
16
|
readonly graph: DomainGraphExecutors | null;
|
|
17
17
|
readonly query?: QueryExecutor;
|
|
18
18
|
readonly mutate?: MutationExecutor;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { bindMutation } from '../../../application/mutation/execution/executor.js';
|
|
2
2
|
import { bindQuery } from '../../../application/query/execution/executor.js';
|
|
3
|
+
import { bindDependencies } from '../dependency/index.js';
|
|
3
4
|
import { clients } from '../integration/index.js';
|
|
4
5
|
export function context(request, runtime, authentication, self) {
|
|
5
|
-
const client = authentication.client;
|
|
6
6
|
const graph = authentication.graph === null ? null : bindGraph(authentication.graph, runtime.loaded.domain);
|
|
7
7
|
const execution = Object.freeze({
|
|
8
8
|
signal: request.context.execution.signal,
|
|
@@ -18,8 +18,15 @@ export function context(request, runtime, authentication, self) {
|
|
|
18
18
|
domain: runtime.loaded.domain,
|
|
19
19
|
input: request.call.input,
|
|
20
20
|
caller: authentication.caller,
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
kernel: authentication.graph === null
|
|
22
|
+
? null
|
|
23
|
+
: Object.freeze({
|
|
24
|
+
...authentication.graph.self,
|
|
25
|
+
...authentication.graph,
|
|
26
|
+
}),
|
|
27
|
+
dependencies: authentication.graph === null
|
|
28
|
+
? null
|
|
29
|
+
: bindDependencies(runtime.loaded.domain, authentication.graph.caller),
|
|
23
30
|
graph,
|
|
24
31
|
...(graph === null
|
|
25
32
|
? {}
|
|
@@ -47,9 +54,11 @@ function bindGraph(clients, domain) {
|
|
|
47
54
|
query: bindQuery(client, domain),
|
|
48
55
|
mutate: bindMutation(client, domain),
|
|
49
56
|
});
|
|
57
|
+
const self = bind(clients.self);
|
|
50
58
|
return Object.freeze({
|
|
59
|
+
...self,
|
|
51
60
|
caller: bind(clients.caller),
|
|
52
|
-
self
|
|
61
|
+
self,
|
|
53
62
|
union: bind(clients.union),
|
|
54
63
|
});
|
|
55
64
|
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { declaredErrorFactory, declaredErrorOf } from '../../../application/error/index.js';
|
|
2
2
|
import { protocolError } from '../result/index.js';
|
|
3
3
|
export async function workflow(selected, context, runner) {
|
|
4
|
-
if (context.caller.kind !== 'authenticated' || context.
|
|
4
|
+
if (context.caller.kind !== 'authenticated' || context.kernel === null) {
|
|
5
5
|
throw protocolError('AUTH_MISSING', 'Workflow authentication is required.');
|
|
6
6
|
}
|
|
7
7
|
const complete = Object.freeze({
|
|
8
8
|
...context,
|
|
9
9
|
caller: context.caller,
|
|
10
|
-
client: context.client,
|
|
11
10
|
error: declaredErrorFactory(selected.definition),
|
|
12
11
|
});
|
|
13
12
|
try {
|
|
@@ -9,11 +9,17 @@ export function active(context) {
|
|
|
9
9
|
}
|
|
10
10
|
/** Close authenticated resources after finite results or stream settlement. */
|
|
11
11
|
export function settle(result, close) {
|
|
12
|
-
if (result.kind
|
|
13
|
-
close
|
|
14
|
-
|
|
12
|
+
if (result.kind === 'stream') {
|
|
13
|
+
return Object.freeze({ kind: 'stream', stream: settledStream(result.stream, close) });
|
|
14
|
+
}
|
|
15
|
+
if (result.kind === 'binary' && !(result.value.body instanceof Uint8Array)) {
|
|
16
|
+
return Object.freeze({
|
|
17
|
+
kind: 'binary',
|
|
18
|
+
value: Object.freeze({ ...result.value, body: settledIterable(result.value.body, close) }),
|
|
19
|
+
});
|
|
15
20
|
}
|
|
16
|
-
|
|
21
|
+
close();
|
|
22
|
+
return result;
|
|
17
23
|
}
|
|
18
24
|
function settledStream(stream, close) {
|
|
19
25
|
let settled = false;
|
|
@@ -24,6 +30,7 @@ function settledStream(stream, close) {
|
|
|
24
30
|
close();
|
|
25
31
|
};
|
|
26
32
|
return Object.freeze({
|
|
33
|
+
...settledIterable(stream, finish),
|
|
27
34
|
async cancel(reason) {
|
|
28
35
|
try {
|
|
29
36
|
await stream.cancel(reason);
|
|
@@ -32,8 +39,26 @@ function settledStream(stream, close) {
|
|
|
32
39
|
finish();
|
|
33
40
|
}
|
|
34
41
|
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function settledIterable(stream, close) {
|
|
45
|
+
let settled = false;
|
|
46
|
+
const finish = () => {
|
|
47
|
+
if (settled)
|
|
48
|
+
return;
|
|
49
|
+
settled = true;
|
|
50
|
+
close();
|
|
51
|
+
};
|
|
52
|
+
return Object.freeze({
|
|
35
53
|
[Symbol.asyncIterator]() {
|
|
36
|
-
|
|
54
|
+
let iterator;
|
|
55
|
+
try {
|
|
56
|
+
iterator = stream[Symbol.asyncIterator]();
|
|
57
|
+
}
|
|
58
|
+
catch (cause) {
|
|
59
|
+
finish();
|
|
60
|
+
throw cause;
|
|
61
|
+
}
|
|
37
62
|
return Object.freeze({
|
|
38
63
|
async next() {
|
|
39
64
|
try {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import { type SourceFile, type SourceProject } from '../../adapters/typescript/index.js';
|
|
3
|
+
export interface RemoteCallable {
|
|
4
|
+
readonly file: SourceFile;
|
|
5
|
+
readonly node: ts.CallExpression;
|
|
6
|
+
readonly module: string;
|
|
7
|
+
readonly selector: readonly string[];
|
|
8
|
+
}
|
|
9
|
+
export interface FunctionRequirements {
|
|
10
|
+
readonly keys: ReadonlySet<string>;
|
|
11
|
+
readonly indeterminate: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function applicationFunctionRequirements(project: SourceProject): FunctionRequirements;
|
|
14
|
+
export declare function requiredCallable(project: SourceProject, file: SourceFile, input: ts.Expression): Pick<RemoteCallable, 'module' | 'selector'> | undefined;
|
|
15
|
+
export declare function declaredDomainDependencies(project: SourceProject): {
|
|
16
|
+
readonly aliases: ReadonlyMap<string, string>;
|
|
17
|
+
readonly indeterminate: boolean;
|
|
18
|
+
};
|
|
19
|
+
export declare function callableSelector(selector: readonly string[]): boolean;
|
|
20
|
+
export declare function externalFacade(module: string): boolean;
|
|
21
|
+
export declare function remoteCallableKey(input: Pick<RemoteCallable, 'module' | 'selector'>): string;
|
|
22
|
+
export declare function callableReference(expression: ts.Expression): {
|
|
23
|
+
readonly expression: ts.Expression;
|
|
24
|
+
readonly resolved: boolean;
|
|
25
|
+
};
|
|
26
|
+
/** Resolve only one immutable lexical alias; the linter does not emulate program execution. */
|
|
27
|
+
export declare function lexicalConstInitializer(identifier: ts.Identifier): ts.Expression | undefined;
|
|
28
|
+
export declare function bindingContains(binding: ts.BindingName, name: string): boolean;
|