@astrale-os/sdk 0.6.0-beta.36 → 0.6.0-beta.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/application/action/context.d.ts +14 -11
- package/dist/application/action/index.d.ts +1 -1
- package/dist/application/dependency/invoker.d.ts +10 -4
- package/dist/application/integration/define.d.ts +8 -1
- package/dist/application/integration/index.d.ts +2 -2
- package/dist/application/integration/integration.d.ts +13 -1
- package/dist/application/integration/operation.d.ts +14 -1
- package/dist/application/mutation/execution/execute.js +1 -1
- package/dist/application/mutation/failure.d.ts +6 -0
- package/dist/application/mutation/failure.js +24 -18
- package/dist/application/query/collection/union.js +11 -4
- package/dist/application/query/conformance.d.ts +15 -0
- package/dist/application/query/conformance.js +46 -0
- package/dist/application/query/define.js +4 -3
- package/dist/application/query/execution/execute.d.ts +0 -1
- package/dist/application/query/execution/execute.js +7 -1
- package/dist/application/query/failure.d.ts +8 -0
- package/dist/application/query/failure.js +8 -0
- package/dist/application/query/index.d.ts +1 -1
- package/dist/application/query/index.js +1 -1
- package/dist/application/workflow/authoring.d.ts +1 -1
- package/dist/application/workflow/context.d.ts +1 -1
- package/dist/application/workflow/durable.d.ts +55 -20
- package/dist/application/workflow/index.d.ts +1 -1
- package/dist/execution/identity/authentication.js +12 -6
- package/dist/execution/identity/callback.d.ts +7 -8
- package/dist/execution/identity/callback.js +17 -14
- package/dist/execution/invocation/capabilities/bind.d.ts +11 -0
- package/dist/execution/invocation/capabilities/bind.js +25 -0
- package/dist/execution/invocation/capabilities/index.d.ts +1 -0
- package/dist/execution/invocation/capabilities/index.js +1 -0
- package/dist/execution/invocation/dispatch/context.js +2 -21
- package/dist/execution/invocation/integration/authentication.d.ts +3 -3
- package/dist/execution/invocation/integration/authentication.js +7 -7
- package/dist/execution/invocation/integration/call.js +2 -2
- package/dist/execution/invocation/integration/index.d.ts +1 -0
- package/dist/execution/invocation/integration/index.js +1 -0
- package/dist/execution/invocation/invocation.js +2 -2
- package/dist/execution/invocation/lifecycle/active.d.ts +8 -2
- package/dist/execution/invocation/lifecycle/active.js +3 -3
- package/dist/execution/invocation/lifecycle/index.d.ts +1 -1
- package/dist/execution/service/create.js +1 -0
- package/dist/execution/workflows/engine.d.ts +12 -2
- package/dist/execution/workflows/index.d.ts +1 -1
- package/dist/execution/workflows/integrations.d.ts +13 -0
- package/dist/execution/workflows/integrations.js +25 -0
- package/dist/execution/workflows/options.js +3 -1
- package/dist/execution/workflows/receiver.d.ts +3 -0
- package/dist/execution/workflows/receiver.js +7 -2
- package/dist/execution/workflows/run.d.ts +3 -4
- package/dist/execution/workflows/run.js +32 -60
- package/dist/execution/workflows/steps.d.ts +42 -0
- package/dist/execution/workflows/steps.js +67 -0
- package/dist/testing/durable/engine.d.ts +111 -0
- package/dist/testing/durable/engine.js +540 -0
- package/dist/testing/durable/index.d.ts +3 -0
- package/dist/testing/durable/index.js +1 -0
- package/dist/testing/durable/steps.d.ts +30 -0
- package/dist/testing/durable/steps.js +40 -0
- package/dist/testing/index.d.ts +6 -1
- package/dist/testing/index.js +5 -1
- package/dist/tooling/cli/dotenv.d.ts +3 -3
- package/dist/tooling/cli/dotenv.js +3 -3
- package/dist/tooling/cli/log.d.ts +0 -2
- package/dist/tooling/cli/log.js +0 -2
- package/dist/tooling/linter/adapters/typescript/imports.d.ts +0 -1
- package/dist/tooling/linter/adapters/typescript/imports.js +1 -5
- package/dist/tooling/linter/adapters/typescript/index.d.ts +1 -1
- package/dist/tooling/linter/adapters/typescript/index.js +1 -1
- package/dist/tooling/linter/adapters/typescript/syntax.d.ts +3 -3
- package/dist/tooling/linter/adapters/typescript/syntax.js +13 -25
- package/dist/tooling/linter/implementations/source/callable-requirements.d.ts +0 -1
- package/dist/tooling/linter/implementations/source/callable-requirements.js +1 -6
- package/dist/tooling/linter/implementations/source/dependencies.js +1 -62
- package/dist/tooling/linter/implementations/source/mutations.js +1 -12
- package/dist/tooling/linter/implementations/source/queries.js +1 -17
- package/dist/tooling/linter/implementations/source/shared.d.ts +7 -4
- package/dist/tooling/linter/implementations/source/shared.js +93 -46
- package/dist/tooling/linter/implementations/source/workflows.js +406 -16
- package/dist/tooling/linter/policy/generated.js +2 -2
- package/dist/tooling/linter/requirements/registry.js +3 -1
- package/package.json +6 -6
|
@@ -50,20 +50,23 @@ export interface DomainGraphExecutor<DomainValue extends Domain = Domain> {
|
|
|
50
50
|
/** Whose authority one Kernel call exercises: the incoming caller's or the installed Domain's. */
|
|
51
51
|
export type AuthorityMode = 'caller' | 'self';
|
|
52
52
|
/**
|
|
53
|
-
* One value per
|
|
54
|
-
* the call carried a credential, so it is absent from a call that carried none.
|
|
53
|
+
* One value per authority the code may act under. `self` exists in every invocation; `caller`
|
|
54
|
+
* exists only when the call carried a credential, so it is absent from a call that carried none.
|
|
55
55
|
*/
|
|
56
|
-
export type AuthoritySelection<Value,
|
|
57
|
-
readonly [Absent in Exclude<AuthorityMode,
|
|
56
|
+
export type AuthoritySelection<Value, Authority extends AuthorityMode = AuthorityMode> = Readonly<Record<Authority, Value> & {
|
|
57
|
+
readonly [Absent in Exclude<AuthorityMode, Authority>]?: never;
|
|
58
58
|
}>;
|
|
59
|
-
export type DomainGraphExecutors<DomainValue extends Domain = Domain,
|
|
59
|
+
export type DomainGraphExecutors<DomainValue extends Domain = Domain, Authority extends AuthorityMode = AuthorityMode> = Readonly<DomainGraphExecutor<DomainValue> & AuthoritySelection<DomainGraphExecutor<DomainValue>, Authority>>;
|
|
60
60
|
/** Self-default Kernel session with one level of explicit authority selection. */
|
|
61
|
-
export type DomainKernelSessions<
|
|
62
|
-
/**
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
export type DomainKernelSessions<Authority extends AuthorityMode = AuthorityMode> = Readonly<BoundClientSession & AuthoritySelection<BoundClientSession, Authority>>;
|
|
62
|
+
/**
|
|
63
|
+
* What code acting under `Authority` holds toward the Kernel and its dependencies, with the
|
|
64
|
+
* installed Domain authority by default. An Action and a durable Step receive the same capabilities.
|
|
65
|
+
*/
|
|
66
|
+
export interface DomainCapabilities<DomainValue extends Domain = Domain, Authority extends AuthorityMode = AuthorityMode> {
|
|
67
|
+
readonly dependencies: HandlerDependencies<DomainValue, Authority>;
|
|
68
|
+
readonly kernel: DomainKernelSessions<Authority>;
|
|
69
|
+
readonly graph: DomainGraphExecutors<DomainValue, Authority>;
|
|
67
70
|
/** Convenience executor using the installed Domain authority (`graph.self`). */
|
|
68
71
|
readonly query: QueryExecutor<DomainValue>;
|
|
69
72
|
/** 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, ActionBinaryInput, ActionExecution, AnonymousCaller, AuthenticatedCaller, AuthorityMode, AuthoritySelection, Caller, DomainGraphExecutor, DomainGraphExecutors, DomainKernelSessions, ResolvedCallable, } from './context.js';
|
|
3
|
+
export type { ActionContext, ActionBinaryInput, ActionExecution, AnonymousCaller, AuthenticatedCaller, AuthorityMode, AuthoritySelection, Caller, DomainCapabilities, 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';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Binary, Input } from '../../platform/client/index.js';
|
|
2
|
-
import type { SessionRequestOptions, SessionRequestOptionsWithBody } from '../../platform/client/session/index.js';
|
|
2
|
+
import type { ExecutionRef, SessionRequestOptions, SessionRequestOptionsWithBody } from '../../platform/client/session/index.js';
|
|
3
3
|
import type { NodeId } from '../../platform/graph/node/index.js';
|
|
4
4
|
import type { CallableInputOf, CallableInputModeOf, CallableOutputOf, CallableResultOf, Domain, ResolvedFunction, ResolvedMethod, KernelSchema, schema } from '../../platform/schema/index.js';
|
|
5
5
|
import type { AuthorityMode, AuthoritySelection, LocalCallable } from '../action/index.js';
|
|
@@ -11,7 +11,13 @@ type WithInputMode<C, Mode extends 'value' | 'binary'> = C extends unknown ? Cal
|
|
|
11
11
|
type ValueFunctionOrStaticMethodOf<D extends Domain> = WithInputMode<FunctionOrStaticMethodOf<D>, 'value'>;
|
|
12
12
|
type BinaryFunctionOf<D extends Domain> = WithInputMode<Extract<LocalCallable<D>, ResolvedFunction>, 'binary'>;
|
|
13
13
|
type DependencyInputOf<C> = C extends unknown ? unknown extends CallableInputOf<C> ? Input : [CallableInputOf<C>] extends [void] ? undefined : CallableInputOf<C> : never;
|
|
14
|
-
type
|
|
14
|
+
type HandlerResultOf<C> = unknown extends CallableOutputOf<C> ? unknown : CallableResultOf<C, Binary>;
|
|
15
|
+
/** A durable callable answers with its Execution, as the Kernel Client's typed reference does. */
|
|
16
|
+
type DependencyResultOf<C> = C extends {
|
|
17
|
+
readonly execution: {
|
|
18
|
+
readonly durable: true;
|
|
19
|
+
};
|
|
20
|
+
} ? ExecutionRef<HandlerResultOf<C>> : HandlerResultOf<C>;
|
|
15
21
|
/** One declared dependency, bound to one explicitly selected invocation authority. */
|
|
16
22
|
export interface DependencyInvoker<D extends Domain> {
|
|
17
23
|
readonly invoke: {
|
|
@@ -25,7 +31,7 @@ export interface DependencyInvoker<D extends Domain> {
|
|
|
25
31
|
* self is the executing Domain; caller forwards the incoming caller Identity, and is absent from a
|
|
26
32
|
* call that carried no credential. The canonical Kernel is exposed through context.kernel.
|
|
27
33
|
*/
|
|
28
|
-
export type HandlerDependencies<D extends Domain,
|
|
29
|
-
[Alias in keyof D['dependencies'] as D['dependencies'][Alias] extends schema.DomainOf<KernelSchema> ? never : Alias]: AuthoritySelection<DependencyInvoker<Extract<D['dependencies'][Alias], Domain>>,
|
|
34
|
+
export type HandlerDependencies<D extends Domain, Authority extends AuthorityMode = AuthorityMode> = Readonly<{
|
|
35
|
+
[Alias in keyof D['dependencies'] as D['dependencies'][Alias] extends schema.DomainOf<KernelSchema> ? never : Alias]: AuthoritySelection<DependencyInvoker<Extract<D['dependencies'][Alias], Domain>>, Authority>;
|
|
30
36
|
}>;
|
|
31
37
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IntegrationDefinition, Integrations } from './integration.js';
|
|
2
|
-
import type { IntegrationOperation, IntegrationOperations, IntegrationReplay } from './operation.js';
|
|
2
|
+
import type { IntegrationOperation, IntegrationOperations, IntegrationReplay, ReplayableIntegrationDecision } from './operation.js';
|
|
3
3
|
import type { Provider, ProviderImplementation } from './provider.js';
|
|
4
4
|
type RuntimeDefinition = IntegrationDefinition<string, IntegrationOperations>;
|
|
5
5
|
type ProviderOperations = Readonly<Record<string, (...input: readonly unknown[]) => unknown>>;
|
|
@@ -12,6 +12,13 @@ export interface DefineIntegration {
|
|
|
12
12
|
readonly id: Id;
|
|
13
13
|
readonly operations: Operations;
|
|
14
14
|
}): IntegrationDefinition<Id, Operations>;
|
|
15
|
+
/**
|
|
16
|
+
* One operation and what another attempt of it may do. A decision that is never `unsafe` keeps
|
|
17
|
+
* the operation available to code that may run more than once, such as a durable Step.
|
|
18
|
+
*/
|
|
19
|
+
operation<Input = void, Output = void>(input: {
|
|
20
|
+
readonly replay: ReplayableIntegrationDecision | ((input: Input) => ReplayableIntegrationDecision);
|
|
21
|
+
}): IntegrationOperation<Input, Output, ReplayableIntegrationDecision['kind']>;
|
|
15
22
|
operation<Input = void, Output = void>(input: {
|
|
16
23
|
readonly replay: IntegrationReplay<Input>;
|
|
17
24
|
}): IntegrationOperation<Input, Output>;
|
|
@@ -2,7 +2,7 @@ export { createIntegrationClients, bindProviders } from './client.js';
|
|
|
2
2
|
export type { IntegrationAttempt, IntegrationCallCoordinates, IntegrationClientFactory, IntegrationInvocationOwner, } from './client.js';
|
|
3
3
|
export { admitIntegrations, defineIntegration, defineProvider, requireIntegration, requireProvider, } from './define.js';
|
|
4
4
|
export type { DefineIntegration, ProviderBinding } from './define.js';
|
|
5
|
-
export type { IntegrationClient, IntegrationClients, IntegrationDefinition, Integrations, } from './integration.js';
|
|
6
|
-
export type { IntegrationExecution, IntegrationInput, IntegrationOperation, IntegrationOperations, IntegrationOutput, IntegrationReplay, IntegrationReplayDecision, } from './operation.js';
|
|
5
|
+
export type { IntegrationClient, IntegrationClients, IntegrationDefinition, Integrations, ReplayableIntegrationClient, ReplayableIntegrationClients, } from './integration.js';
|
|
6
|
+
export type { IntegrationExecution, IntegrationInput, IntegrationOperation, IntegrationOperations, IntegrationOutput, IntegrationReplay, IntegrationReplayDecision, IntegrationReplayKind, IntegrationReplayOf, ReplayableIntegrationDecision, } from './operation.js';
|
|
7
7
|
export type { Provider, ProviderImplementation, Providers } from './provider.js';
|
|
8
8
|
export type { IntegrationAuthentication, IntegrationMintInput } from './authentication.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IntegrationOperation, IntegrationOperations } from './operation.js';
|
|
1
|
+
import type { IntegrationOperation, IntegrationOperations, IntegrationReplayOf } from './operation.js';
|
|
2
2
|
declare const INTEGRATION_DEFINITION: unique symbol;
|
|
3
3
|
export interface IntegrationDefinition<Id extends string = string, Operations extends IntegrationOperations = IntegrationOperations> {
|
|
4
4
|
readonly kind: 'integration';
|
|
@@ -16,4 +16,16 @@ export type IntegrationClient<Definition extends IntegrationDefinition> = Readon
|
|
|
16
16
|
export type IntegrationClients<Definitions extends Integrations> = Readonly<{
|
|
17
17
|
[Name in keyof Definitions]: IntegrationClient<Definitions[Name]>;
|
|
18
18
|
}>;
|
|
19
|
+
type ReplayableOperationName<Definition extends IntegrationDefinition> = {
|
|
20
|
+
[Name in keyof Definition['operations']]: 'unsafe' extends IntegrationReplayOf<Definition['operations'][Name]> ? never : Name;
|
|
21
|
+
}[keyof Definition['operations']];
|
|
22
|
+
/** The operations of one Integration that may be attempted again: each is `safe` or keyed. */
|
|
23
|
+
export type ReplayableIntegrationClient<Definition extends IntegrationDefinition> = Pick<IntegrationClient<Definition>, ReplayableOperationName<Definition>>;
|
|
24
|
+
/**
|
|
25
|
+
* Integration clients of code that may run more than once, such as a durable Step. An operation
|
|
26
|
+
* whose replay decision may be `unsafe` is absent: another attempt could repeat its effect.
|
|
27
|
+
*/
|
|
28
|
+
export type ReplayableIntegrationClients<Definitions extends Integrations> = Readonly<{
|
|
29
|
+
[Name in keyof Definitions]: ReplayableIntegrationClient<Definitions[Name]>;
|
|
30
|
+
}>;
|
|
19
31
|
export {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { BoundClientSession } from '../../platform/client/session/index.js';
|
|
2
2
|
import type { IntegrationAuthentication } from './authentication.js';
|
|
3
3
|
declare const INTEGRATION_OPERATION: unique symbol;
|
|
4
|
+
declare const INTEGRATION_REPLAY: unique symbol;
|
|
4
5
|
export type IntegrationReplayDecision = {
|
|
5
6
|
readonly kind: 'safe';
|
|
6
7
|
} | {
|
|
@@ -13,6 +14,12 @@ export type IntegrationReplayDecision = {
|
|
|
13
14
|
} | {
|
|
14
15
|
readonly kind: 'unsafe';
|
|
15
16
|
};
|
|
17
|
+
/** What another attempt of an operation may do: anything, once per key, or nothing. */
|
|
18
|
+
export type IntegrationReplayKind = IntegrationReplayDecision['kind'];
|
|
19
|
+
/** A decision that allows another attempt of the operation. */
|
|
20
|
+
export type ReplayableIntegrationDecision = Exclude<IntegrationReplayDecision, {
|
|
21
|
+
readonly kind: 'unsafe';
|
|
22
|
+
}>;
|
|
16
23
|
export type IntegrationReplay<Input> = IntegrationReplayDecision | ((input: Input) => IntegrationReplayDecision);
|
|
17
24
|
export interface IntegrationExecution {
|
|
18
25
|
readonly callId: string;
|
|
@@ -24,9 +31,11 @@ export interface IntegrationExecution {
|
|
|
24
31
|
/** Domain-self transport authentication; absent only outside a Kernel invocation. */
|
|
25
32
|
readonly auth?: IntegrationAuthentication;
|
|
26
33
|
}
|
|
27
|
-
export interface IntegrationOperation<Input = unknown, Output = unknown> {
|
|
34
|
+
export interface IntegrationOperation<Input = unknown, Output = unknown, Replay extends IntegrationReplayKind = IntegrationReplayKind> {
|
|
28
35
|
readonly replay: IntegrationReplay<Input>;
|
|
29
36
|
readonly [INTEGRATION_OPERATION]: (input: Input) => Output;
|
|
37
|
+
/** Every kind its replay decision may take, as its definition proves them. */
|
|
38
|
+
readonly [INTEGRATION_REPLAY]: Replay;
|
|
30
39
|
}
|
|
31
40
|
export type IntegrationOperations = Readonly<Record<string, IntegrationOperation<never, unknown>>>;
|
|
32
41
|
export type IntegrationInput<Operation> = Operation extends {
|
|
@@ -35,4 +44,8 @@ export type IntegrationInput<Operation> = Operation extends {
|
|
|
35
44
|
export type IntegrationOutput<Operation> = Operation extends {
|
|
36
45
|
readonly [INTEGRATION_OPERATION]: (input: never) => infer Output;
|
|
37
46
|
} ? Output : never;
|
|
47
|
+
/** The replay kinds an operation's definition proves; every kind when it proves none. */
|
|
48
|
+
export type IntegrationReplayOf<Operation> = Operation extends {
|
|
49
|
+
readonly [INTEGRATION_REPLAY]: infer Replay;
|
|
50
|
+
} ? Replay : IntegrationReplayKind;
|
|
38
51
|
export {};
|
|
@@ -10,7 +10,7 @@ export async function executeMutation(client, domain, definition, input) {
|
|
|
10
10
|
const operation = realizeMutation(definition, domain);
|
|
11
11
|
try {
|
|
12
12
|
const ast = MutationAST.build((builder) => operation.build(input, richMutationBuilder(builder)));
|
|
13
|
-
return projectMutation(operation, await client.mutate(ast
|
|
13
|
+
return projectMutation(operation, await client.mutate(ast), input);
|
|
14
14
|
}
|
|
15
15
|
catch (cause) {
|
|
16
16
|
const expected = mutationFailure(cause);
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
export interface KernelMutationFailure extends Error {
|
|
2
2
|
readonly code: `MUTATION_${string}`;
|
|
3
3
|
readonly outcomeKnown: boolean;
|
|
4
|
+
/**
|
|
5
|
+
* The post-state rule a `MUTATION_POST_STATE_INVALID` refusal names, such as `duplicate-key`
|
|
6
|
+
* for a value a Class key already holds. Absent when the Kernel names none, and for every other
|
|
7
|
+
* refusal.
|
|
8
|
+
*/
|
|
9
|
+
readonly rule?: string;
|
|
4
10
|
}
|
|
5
11
|
export interface StateTransitionFailure extends Error {
|
|
6
12
|
readonly code: 'STATE_TRANSITION_ILLEGAL';
|
|
@@ -13,9 +13,10 @@ export function stateTransitionFailure(from, event) {
|
|
|
13
13
|
export function mutationFailure(input) {
|
|
14
14
|
if (!(input instanceof Error))
|
|
15
15
|
return undefined;
|
|
16
|
-
const
|
|
17
|
-
if (
|
|
16
|
+
const reason = mutationReason(input);
|
|
17
|
+
if (reason === undefined)
|
|
18
18
|
return undefined;
|
|
19
|
+
const { code } = reason;
|
|
19
20
|
const explicit = input.outcomeKnown;
|
|
20
21
|
if (explicit !== undefined && typeof explicit !== 'boolean')
|
|
21
22
|
return undefined;
|
|
@@ -28,30 +29,35 @@ export function mutationFailure(input) {
|
|
|
28
29
|
return undefined;
|
|
29
30
|
return input;
|
|
30
31
|
}
|
|
32
|
+
const rule = code === 'MUTATION_POST_STATE_INVALID' ? reason.rule : undefined;
|
|
31
33
|
return Object.assign(new Error(input.message, { cause: input }), {
|
|
32
34
|
code,
|
|
33
35
|
outcomeKnown: explicit !== false && !UNKNOWN_OUTCOME_CODES.has(code),
|
|
36
|
+
...(rule === undefined ? {} : { rule }),
|
|
34
37
|
});
|
|
35
38
|
}
|
|
36
|
-
|
|
39
|
+
/**
|
|
40
|
+
* The Mutation refusal an error carries, on itself, as its Kernel reason, or as its protocol data:
|
|
41
|
+
* its code and, from the same carrier's details, the post-state rule it names.
|
|
42
|
+
*/
|
|
43
|
+
function mutationReason(input) {
|
|
37
44
|
const value = input;
|
|
38
45
|
if (value.code === 'STATE_TRANSITION_ILLEGAL')
|
|
39
|
-
return value.code;
|
|
40
|
-
for (const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
return { code: value.code };
|
|
47
|
+
for (const carrier of [value, value.reason, value.data]) {
|
|
48
|
+
const code = typeof carrier === 'string' ? carrier : field(carrier, 'code');
|
|
49
|
+
if (typeof code !== 'string' || !code.startsWith('MUTATION_'))
|
|
50
|
+
continue;
|
|
51
|
+
const rule = field(field(carrier, 'details'), 'rule');
|
|
52
|
+
return {
|
|
53
|
+
code: code,
|
|
54
|
+
...(typeof rule === 'string' ? { rule } : {}),
|
|
55
|
+
};
|
|
48
56
|
}
|
|
49
57
|
return undefined;
|
|
50
58
|
}
|
|
51
|
-
function
|
|
52
|
-
return typeof input === '
|
|
53
|
-
? input
|
|
54
|
-
:
|
|
55
|
-
? Reflect.get(input, 'code')
|
|
56
|
-
: undefined;
|
|
59
|
+
function field(input, key) {
|
|
60
|
+
return input !== null && typeof input === 'object' && !Array.isArray(input)
|
|
61
|
+
? Reflect.get(input, key)
|
|
62
|
+
: undefined;
|
|
57
63
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { definedClass } from '@astrale-os/kernel-client/graph';
|
|
1
2
|
import { Query, QueryAST as QueryDocument } from '@astrale-os/kernel-core/graph/query';
|
|
2
|
-
import { ClassKey } from '@astrale-os/kernel-dsl/v1/addressing';
|
|
3
3
|
import { QueryCompositionError } from '../composite/errors.js';
|
|
4
4
|
import { collectionIdentityOf } from './identity.js';
|
|
5
5
|
import { COLLECTION_QUERY_LIMITS } from './limits.js';
|
|
@@ -80,8 +80,13 @@ export function partitionCollectionUnion(domain, compiled, values, maximumLogica
|
|
|
80
80
|
if (identities.has(identity))
|
|
81
81
|
invalid(`Collection union returned duplicate identity ${identity}.`);
|
|
82
82
|
identities.add(identity);
|
|
83
|
-
const names = memberships.
|
|
83
|
+
const names = memberships.has(value.class)
|
|
84
|
+
? memberships.get(value.class)
|
|
85
|
+
: memberNames(domain, compiled, value);
|
|
84
86
|
memberships.set(value.class, names);
|
|
87
|
+
// A Class added after this client was built belongs to no member it can name.
|
|
88
|
+
if (names === undefined)
|
|
89
|
+
continue;
|
|
85
90
|
if (names.length === 0) {
|
|
86
91
|
invalid(`Collection union returned ${value.class} outside every member extent.`);
|
|
87
92
|
}
|
|
@@ -105,9 +110,11 @@ function realizeMember(definition, domain, outputPath, name) {
|
|
|
105
110
|
}
|
|
106
111
|
}
|
|
107
112
|
function memberNames(domain, compiled, value) {
|
|
108
|
-
const exact = domain
|
|
113
|
+
const exact = definedClass(domain, value.class);
|
|
114
|
+
if (exact === undefined)
|
|
115
|
+
return undefined;
|
|
109
116
|
const kind = valueKind(value);
|
|
110
|
-
if (exact
|
|
117
|
+
if (exact.kind !== kind || exact.abstract) {
|
|
111
118
|
invalid(`Collection union returned inactive ${kind} Class ${value.class}.`);
|
|
112
119
|
}
|
|
113
120
|
const names = compiled.members.flatMap((member) => {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { QueryResult } from '@astrale-os/kernel-core/graph/query';
|
|
2
|
+
import type { Edge } from '../../platform/graph/edge/index.js';
|
|
3
|
+
import type { Node } from '../../platform/graph/node/index.js';
|
|
4
|
+
import type { Domain } from '../../platform/schema/index.js';
|
|
5
|
+
/**
|
|
6
|
+
* The members of `values` whose Class `domain` defines, in order. The Kernel answers in its active
|
|
7
|
+
* Schema, so a result may hold values of a Class added after the client was built.
|
|
8
|
+
*/
|
|
9
|
+
export declare function definedValues<Value extends Node | Edge>(domain: Domain, values: readonly Value[]): readonly Value[];
|
|
10
|
+
/**
|
|
11
|
+
* Check every value of `result` against the Domain this client was built from, by the Kernel
|
|
12
|
+
* Client's rule: a value fails only when a Property its Class defines holds an invalid value or a
|
|
13
|
+
* required one is absent. Properties and Classes the client does not know pass.
|
|
14
|
+
*/
|
|
15
|
+
export declare function requireConformance(domain: Domain, result: QueryResult): void;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { definedClass, validateDefinedProperties } from '@astrale-os/kernel-client/graph';
|
|
2
|
+
import { collectionIdentityOf } from './collection/identity.js';
|
|
3
|
+
import { QueryValueMismatchError } from './failure.js';
|
|
4
|
+
/**
|
|
5
|
+
* The members of `values` whose Class `domain` defines, in order. The Kernel answers in its active
|
|
6
|
+
* Schema, so a result may hold values of a Class added after the client was built.
|
|
7
|
+
*/
|
|
8
|
+
export function definedValues(domain, values) {
|
|
9
|
+
const defined = values.filter((value) => definedClass(domain, value.class) !== undefined);
|
|
10
|
+
return defined.length === values.length ? values : Object.freeze(defined);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Check every value of `result` against the Domain this client was built from, by the Kernel
|
|
14
|
+
* Client's rule: a value fails only when a Property its Class defines holds an invalid value or a
|
|
15
|
+
* required one is absent. Properties and Classes the client does not know pass.
|
|
16
|
+
*/
|
|
17
|
+
export function requireConformance(domain, result) {
|
|
18
|
+
for (const value of valuesOf(result)) {
|
|
19
|
+
const exact = definedClass(domain, value.class);
|
|
20
|
+
if (exact === undefined)
|
|
21
|
+
continue;
|
|
22
|
+
const [diagnostic] = validateDefinedProperties(exact, value.props);
|
|
23
|
+
if (diagnostic !== undefined) {
|
|
24
|
+
throw new QueryValueMismatchError(`${collectionIdentityOf(value)} at ${diagnostic.pointer}: ${diagnostic.message}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function* valuesOf(result) {
|
|
29
|
+
if (result.kind === 'graph') {
|
|
30
|
+
yield* result.graph.nodes;
|
|
31
|
+
yield* result.graph.edges;
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (result.kind === 'nodes') {
|
|
35
|
+
for (const item of result.nodes)
|
|
36
|
+
if (item.kind === 'value')
|
|
37
|
+
yield item.value;
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
for (const item of result.edges) {
|
|
41
|
+
for (const component of [item.edge, item.source, item.target]) {
|
|
42
|
+
if (component.kind === 'value')
|
|
43
|
+
yield component.value;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -3,6 +3,7 @@ import { isDomain } from '@astrale-os/kernel-dsl/v1/domain';
|
|
|
3
3
|
import { requireUniqueCollectionValues } from './collection/identity.js';
|
|
4
4
|
import { COLLECTION_QUERY_LIMITS } from './collection/limits.js';
|
|
5
5
|
import { realizeCollectionQuery, registerCollectionQuery, } from './collection/metadata.js';
|
|
6
|
+
import { definedValues } from './conformance.js';
|
|
6
7
|
import { queryResult } from './single/index.js';
|
|
7
8
|
const DEFAULT_PAGE_SIZE = 256;
|
|
8
9
|
const MAXIMUM_PAGES = 1_024;
|
|
@@ -27,7 +28,7 @@ export function defineCollectionQuery() {
|
|
|
27
28
|
kind: 'nodes',
|
|
28
29
|
projection: { kind: 'value' },
|
|
29
30
|
}),
|
|
30
|
-
project: (pages) => requireUniqueCollectionValues(queryResult.completeNodeValues(pages, specification.id), `Collection Query ${specification.id}`),
|
|
31
|
+
project: (pages) => definedValues(domain, requireUniqueCollectionValues(queryResult.completeNodeValues(pages, specification.id), `Collection Query ${specification.id}`)),
|
|
31
32
|
};
|
|
32
33
|
}
|
|
33
34
|
return {
|
|
@@ -38,12 +39,12 @@ export function defineCollectionQuery() {
|
|
|
38
39
|
kind: 'edges',
|
|
39
40
|
projection: { edge: 'value', source: 'reference', target: 'reference' },
|
|
40
41
|
}),
|
|
41
|
-
project: (pages) => requireUniqueCollectionValues(Object.freeze(pages.flatMap((page) => queryResult.edgeItems(page, specification.id).map((item) => {
|
|
42
|
+
project: (pages) => definedValues(domain, requireUniqueCollectionValues(Object.freeze(pages.flatMap((page) => queryResult.edgeItems(page, specification.id).map((item) => {
|
|
42
43
|
if (item.edge.kind !== 'value') {
|
|
43
44
|
throw new TypeError(`Collection Query ${specification.id} must project Edge values.`);
|
|
44
45
|
}
|
|
45
46
|
return item.edge.value;
|
|
46
|
-
}))), `Collection Query ${specification.id}`),
|
|
47
|
+
}))), `Collection Query ${specification.id}`)),
|
|
47
48
|
};
|
|
48
49
|
});
|
|
49
50
|
registerCollectionQuery(definition, project);
|
|
@@ -6,7 +6,6 @@ import type { QueryDefinition } from '../query.js';
|
|
|
6
6
|
export interface QueryClient {
|
|
7
7
|
query<Ast extends QueryAST>(ast: Ast, options: {
|
|
8
8
|
readonly page: QueryPageRequest;
|
|
9
|
-
readonly expected?: Domain['closure'];
|
|
10
9
|
}): Promise<QueryResponse<QueryResultFor<Ast>>>;
|
|
11
10
|
}
|
|
12
11
|
export declare function executeQuery<DomainValue extends Domain, Output>(client: QueryClient, domain: DomainValue, query: QueryDefinition<DomainValue, void, Output>): Promise<Output>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { COLLECTION_QUERY_LIMITS } from '../collection/limits.js';
|
|
2
2
|
import { compileCollectionUnion, partitionCollectionUnion } from '../collection/union.js';
|
|
3
3
|
import { createQueryComposition, executeQueryPlan } from '../composite/index.js';
|
|
4
|
+
import { requireConformance } from '../conformance.js';
|
|
4
5
|
import { realizeQuery } from '../define.js';
|
|
5
6
|
import { queryFailure } from '../failure.js';
|
|
6
7
|
import { completeSelection, queryResult } from '../single/index.js';
|
|
@@ -9,7 +10,12 @@ export async function executeQuery(client, domain, query, input) {
|
|
|
9
10
|
if (client === null || typeof client !== 'object' || typeof client.query !== 'function') {
|
|
10
11
|
throw new TypeError('Query execution requires a Client query capability.');
|
|
11
12
|
}
|
|
12
|
-
|
|
13
|
+
// The Kernel answers in its active Schema; each value is checked against this client's Domain.
|
|
14
|
+
const execute = async (ast, options) => {
|
|
15
|
+
const response = await client.query(ast, options);
|
|
16
|
+
requireConformance(domain, response.result);
|
|
17
|
+
return response;
|
|
18
|
+
};
|
|
13
19
|
const operation = realizeQuery(query, domain);
|
|
14
20
|
try {
|
|
15
21
|
if (operation.kind === 'single') {
|
|
@@ -7,4 +7,12 @@ export declare class QueryPaginationError extends Error implements QueryFailure
|
|
|
7
7
|
readonly name = "QueryPaginationError";
|
|
8
8
|
constructor(code: QueryPaginationErrorCode, message: string);
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* A value the Kernel returned does not have the shape its Class has in the Domain this client was
|
|
12
|
+
* built from: one of its Properties changed type, or a Property the client requires is absent.
|
|
13
|
+
*/
|
|
14
|
+
export declare class QueryValueMismatchError extends Error implements QueryFailure {
|
|
15
|
+
readonly name = "QueryValueMismatchError";
|
|
16
|
+
readonly code = "QUERY_VALUE_MISMATCH";
|
|
17
|
+
}
|
|
10
18
|
export declare function queryFailure(input: unknown): QueryFailure | undefined;
|
|
@@ -6,6 +6,14 @@ export class QueryPaginationError extends Error {
|
|
|
6
6
|
this.code = code;
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* A value the Kernel returned does not have the shape its Class has in the Domain this client was
|
|
11
|
+
* built from: one of its Properties changed type, or a Property the client requires is absent.
|
|
12
|
+
*/
|
|
13
|
+
export class QueryValueMismatchError extends Error {
|
|
14
|
+
name = 'QueryValueMismatchError';
|
|
15
|
+
code = 'QUERY_VALUE_MISMATCH';
|
|
16
|
+
}
|
|
9
17
|
export function queryFailure(input) {
|
|
10
18
|
if (!(input instanceof Error))
|
|
11
19
|
return undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { defineCollectionQuery, defineCompositeQuery, defineQuery, realizeQuery } from './define.js';
|
|
2
2
|
export type { CollectionQuerySpec } from './collection/metadata.js';
|
|
3
3
|
export { executeQuery, type QueryClient, type QueryExecutor } from './execution/index.js';
|
|
4
|
-
export { QueryPaginationError, type QueryFailure, type QueryPaginationErrorCode, } from './failure.js';
|
|
4
|
+
export { QueryPaginationError, QueryValueMismatchError, type QueryFailure, type QueryPaginationErrorCode, } from './failure.js';
|
|
5
5
|
export type { CollectionQueryDefinition, CollectionValue, CompositeQueryDefinition, QueryAstOf, QueryDefinition, QueryInputOf, QueryOutputOf, SingleQueryDefinition, } from './query.js';
|
|
6
6
|
export { queryResult } from './single/index.js';
|
|
7
7
|
export type { CompleteQueryProjectionContext, PaginatedQuery, ProjectedQuery, QueryPages, QueryPagination, QueryProjectionContext, RawQuery, SingleQuery, } from './single/index.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { defineCollectionQuery, defineCompositeQuery, defineQuery, realizeQuery } from './define.js';
|
|
2
2
|
export { executeQuery } from './execution/index.js';
|
|
3
|
-
export { QueryPaginationError, } from './failure.js';
|
|
3
|
+
export { QueryPaginationError, QueryValueMismatchError, } from './failure.js';
|
|
4
4
|
export { queryResult } from './single/index.js';
|
|
5
5
|
/** Canonical Query language and authoring values accept DSL ResolvedClass directly. */
|
|
6
6
|
export * from '@astrale-os/kernel-core/graph/query';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { defineWorkflow } from './define.js';
|
|
2
2
|
export type { InlineWorkflowContext, WorkflowContext } from './context.js';
|
|
3
|
-
export type { DurableCallable, DurableExecution, DurableStep, DurableStepAuthority, DurableWorkflowContext, } from './durable.js';
|
|
3
|
+
export type { DurableCallable, DurableExecution, DurableStep, DurableStepAuthority, DurableWorkflowContext, SignalOutcome, } from './durable.js';
|
|
4
4
|
export type { Workflow, WorkflowAddress, WorkflowDefinition, WorkflowOptions } from './workflow.js';
|
|
5
5
|
export type { DeclaredErrorDefinition, DeclaredErrorFactory, DeclaredErrorFamily, DeclaredErrorOptions, DeclaredErrors, } from '../error/index.js';
|
|
@@ -12,4 +12,4 @@ export type InlineWorkflowContext<Callable extends ResolvedCallable, DomainValue
|
|
|
12
12
|
* Exact Workflow context for one callable: engine-journaled when its Schema declares
|
|
13
13
|
* `execution: { durable: true }`, otherwise run inside its invocation.
|
|
14
14
|
*/
|
|
15
|
-
export type WorkflowContext<Callable extends ResolvedCallable, DomainValue extends Domain = Domain, Definitions extends Integrations = Readonly<Record<never, never>>, Errors extends DeclaredErrors = NoDeclaredErrors> = Callable extends DurableCallable ? DurableWorkflowContext<Callable, DomainValue, Errors> : InlineWorkflowContext<Callable, DomainValue, Definitions, Errors>;
|
|
15
|
+
export type WorkflowContext<Callable extends ResolvedCallable, DomainValue extends Domain = Domain, Definitions extends Integrations = Readonly<Record<never, never>>, Errors extends DeclaredErrors = NoDeclaredErrors> = Callable extends DurableCallable ? DurableWorkflowContext<Callable, DomainValue, Definitions, Errors> : InlineWorkflowContext<Callable, DomainValue, Definitions, Errors>;
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type { IssuerId } from '../../platform/auth/index.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ExecutionOutcome, ExecutionRef } from '../../platform/client/session/index.js';
|
|
3
3
|
import type { NodeId } from '../../platform/graph/node/index.js';
|
|
4
4
|
import type { CallableInputOf, Domain, ResolvedMethod } from '../../platform/schema/index.js';
|
|
5
5
|
import type { Value } from '../../platform/value/index.js';
|
|
6
|
+
import type { DomainCapabilities, DomainKernelSessions } from '../action/index.js';
|
|
7
|
+
import type { HandlerDependencies } from '../dependency/index.js';
|
|
6
8
|
import type { DeclaredErrorFactory, DeclaredErrors, NoDeclaredErrors } from '../error/index.js';
|
|
9
|
+
import type { Integrations, ReplayableIntegrationClients } from '../integration/index.js';
|
|
7
10
|
import type { Mutation, MutationExecutor } from '../mutation/index.js';
|
|
8
|
-
import type {
|
|
11
|
+
import type { QueryDefinition } from '../query/index.js';
|
|
9
12
|
/** A callable whose Schema declares `execution: { durable: true }`. */
|
|
10
13
|
export interface DurableCallable {
|
|
11
14
|
readonly execution: {
|
|
@@ -31,31 +34,46 @@ export interface DurableExecution {
|
|
|
31
34
|
readonly receiver?: NodeId;
|
|
32
35
|
}
|
|
33
36
|
/**
|
|
34
|
-
*
|
|
35
|
-
* belongs to a journaled Step and a replay never repeats it.
|
|
37
|
+
* What one Step holds: the capabilities of an Action, acting as the Domain alone. Kernel access
|
|
38
|
+
* exists only here, so every Kernel call belongs to a journaled Step and a replay never repeats it.
|
|
39
|
+
* Every key below comes from one sequence derived from the Execution, the Step and the position of
|
|
40
|
+
* the call, which restarts with each attempt: a retried Step sends the same keys again.
|
|
36
41
|
*/
|
|
37
|
-
export interface DurableStepAuthority<DomainValue extends Domain = Domain> {
|
|
42
|
+
export interface DurableStepAuthority<DomainValue extends Domain = Domain, Definitions extends Integrations = Readonly<Record<never, never>>> extends DomainCapabilities<DomainValue, 'self'> {
|
|
38
43
|
/**
|
|
39
44
|
* Kernel Session acting as the Domain. Each `invoke` of a durable callable without an explicit
|
|
40
|
-
* `idempotencyKey` carries
|
|
41
|
-
*
|
|
42
|
-
*
|
|
45
|
+
* `idempotencyKey` carries the next derived key, so a retried Step reaches the same durable child
|
|
46
|
+
* Execution. An `invoke` of any other callable carries no key, which the Kernel would refuse, and
|
|
47
|
+
* runs again when the Step is retried.
|
|
43
48
|
*/
|
|
44
|
-
readonly kernel:
|
|
45
|
-
|
|
49
|
+
readonly kernel: DomainKernelSessions<'self'>;
|
|
50
|
+
/** Dependency invokers acting as the Domain, keyed like `kernel.invoke`. */
|
|
51
|
+
readonly dependencies: HandlerDependencies<DomainValue, 'self'>;
|
|
46
52
|
/**
|
|
47
|
-
* Each Mutation carries
|
|
48
|
-
*
|
|
53
|
+
* Each Mutation carries the next derived key. The Kernel commits a receipt with the write and
|
|
54
|
+
* answers a retried Step with its first result.
|
|
49
55
|
*/
|
|
50
56
|
readonly mutate: MutationExecutor<DomainValue>;
|
|
57
|
+
/**
|
|
58
|
+
* Operations a retried Step may attempt again. A keyed operation of source `execution` receives
|
|
59
|
+
* the next derived key as its idempotency key. An operation whose decision may be `unsafe` is
|
|
60
|
+
* absent, and refused before its Provider runs if its decision is `unsafe` anyway.
|
|
61
|
+
*/
|
|
62
|
+
readonly integrations: ReplayableIntegrationClients<Definitions>;
|
|
51
63
|
}
|
|
52
|
-
export interface DurableStep<DomainValue extends Domain = Domain
|
|
64
|
+
export interface DurableStep<DomainValue extends Domain = Domain, Definitions extends Integrations = Readonly<Record<never, never>>> {
|
|
53
65
|
/**
|
|
54
66
|
* Run `execute` once and journal its portable output; a replay returns the journaled output. A
|
|
55
|
-
* Step may run again when its outcome was not journaled: its Mutations
|
|
56
|
-
* answered from their keys, and any other effect must be idempotent.
|
|
67
|
+
* Step may run again when its outcome was not journaled: its Mutations, durable calls and keyed
|
|
68
|
+
* Integration operations are answered from their keys, and any other effect must be idempotent.
|
|
57
69
|
*/
|
|
58
|
-
run<Output>(id: string, execute: (authority: DurableStepAuthority<DomainValue>) => Output | Promise<Output>): Promise<Output>;
|
|
70
|
+
run<Output>(id: string, execute: (authority: DurableStepAuthority<DomainValue, Definitions>) => Output | Promise<Output>): Promise<Output>;
|
|
71
|
+
/**
|
|
72
|
+
* One journaled Query. A replay returns the result of its first run, so a later Step that depends
|
|
73
|
+
* on it resends the same request whenever it is retried.
|
|
74
|
+
*/
|
|
75
|
+
query<Output>(id: string, query: QueryDefinition<DomainValue, void, Output>): Promise<Output>;
|
|
76
|
+
query<Input, Output>(id: string, query: QueryDefinition<DomainValue, Input, Output>, input: Input): Promise<Output>;
|
|
59
77
|
/**
|
|
60
78
|
* One journaled Mutation. A Step replayed after its commit receives the result of that commit
|
|
61
79
|
* from the Kernel's receipt instead of writing again.
|
|
@@ -67,18 +85,35 @@ type DurableSelfOf<Callable> = Callable extends ResolvedMethod<unknown, unknown,
|
|
|
67
85
|
} : {
|
|
68
86
|
readonly self?: never;
|
|
69
87
|
};
|
|
88
|
+
/** What a bounded wait for a signal ended with: the signal's value, or its timeout. */
|
|
89
|
+
export type SignalOutcome<Signal extends Value = Value> = {
|
|
90
|
+
readonly kind: 'signal';
|
|
91
|
+
readonly value: Signal;
|
|
92
|
+
} | {
|
|
93
|
+
readonly kind: 'timeout';
|
|
94
|
+
};
|
|
70
95
|
/** Context of a durable Workflow: engine-journaled, acting as its Domain. */
|
|
71
|
-
export type DurableWorkflowContext<Callable, DomainValue extends Domain = Domain, Errors extends DeclaredErrors = NoDeclaredErrors> = {
|
|
96
|
+
export type DurableWorkflowContext<Callable, DomainValue extends Domain = Domain, Definitions extends Integrations = Readonly<Record<never, never>>, Errors extends DeclaredErrors = NoDeclaredErrors> = {
|
|
72
97
|
readonly domain: DomainValue;
|
|
73
98
|
readonly input: CallableInputOf<Callable>;
|
|
74
99
|
readonly execution: DurableExecution;
|
|
75
100
|
/** Construct one implementation-declared safe business error for `throw error(...)`. */
|
|
76
101
|
readonly error: DeclaredErrorFactory<Errors>;
|
|
77
|
-
readonly step: DurableStep<DomainValue>;
|
|
102
|
+
readonly step: DurableStep<DomainValue, Definitions>;
|
|
78
103
|
/** Durable timer kept by the engine, even while the Domain is idle or down. */
|
|
79
104
|
sleep(durationMs: number): Promise<void>;
|
|
80
|
-
/**
|
|
81
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Wait for the value `Execution.signal({ name, value })` delivers once under `name`, whether it
|
|
107
|
+
* was sent before or during the wait.
|
|
108
|
+
*/
|
|
109
|
+
awaitSignal<Signal extends Value = Value>(name: string): Promise<Signal>;
|
|
110
|
+
/**
|
|
111
|
+
* Wait at most `timeoutMs` for the signal `name`. The engine journals which came first, so a
|
|
112
|
+
* replay answers the same. A signal sent after the timeout is kept for a later wait.
|
|
113
|
+
*/
|
|
114
|
+
awaitSignal<Signal extends Value = Value>(name: string, options: {
|
|
115
|
+
readonly timeoutMs: number;
|
|
116
|
+
}): Promise<SignalOutcome<Signal>>;
|
|
82
117
|
/** Whether `error` is the engine's cooperative cancellation, which the Workflow may compensate. */
|
|
83
118
|
cancelled(error: unknown): boolean;
|
|
84
119
|
/** Wait durably for another Execution to end, by journaled polling of its `result`. */
|