depa-actor 0.2.0 → 0.2.2
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/addressing.d.ts +100 -0
- package/dist/addressing.d.ts.map +1 -0
- package/dist/addressing.js +517 -0
- package/dist/addressing.js.map +1 -0
- package/dist/dispatch/ActorDispatchAdapter.d.ts +74 -17
- package/dist/dispatch/ActorDispatchAdapter.d.ts.map +1 -1
- package/dist/dispatch/ActorDispatchAdapter.js +109 -24
- package/dist/dispatch/ActorDispatchAdapter.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/pipeline/ActorPipeline.d.ts +35 -8
- package/dist/pipeline/ActorPipeline.d.ts.map +1 -1
- package/dist/pipeline/ActorPipeline.js +26 -16
- package/dist/pipeline/ActorPipeline.js.map +1 -1
- package/dist-cjs/addressing.cjs +532 -0
- package/dist-cjs/dispatch/ActorDispatchAdapter.cjs +109 -24
- package/dist-cjs/index.cjs +26 -1
- package/dist-cjs/pipeline/ActorPipeline.cjs +26 -16
- package/package.json +4 -1
- package/src/addressing.ts +976 -0
- package/src/dispatch/ActorDispatchAdapter.ts +218 -47
- package/src/index.ts +55 -2
- package/src/pipeline/ActorPipeline.ts +103 -57
|
@@ -1,11 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* depa-actor — Dispatch Bridge
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Drives the depa-processor `DispatchEngine` (all 7 strategies) from the actor
|
|
5
|
+
* side. The envelope → DispatchRequest adaptation and the actor `tag` overlay
|
|
6
|
+
* live HERE, in depa-actor — the generic `DispatchEngine` / `DispatchStrategyConfig`
|
|
7
|
+
* stay free of any actor (`envelope` / `tag` / `ActorSelf`) knowledge.
|
|
8
|
+
*
|
|
9
|
+
* Two orthogonal axes:
|
|
10
|
+
* 1. `tag` — actor's first-level route (which mailbox). Selecting a handler by
|
|
11
|
+
* tag is the actor system's job (`ActorDef.handlers[tag]`); a dispatch handler
|
|
12
|
+
* built here is slotted UNDER a tag, so tag selection happens upstream.
|
|
13
|
+
* `tag` is NOT a DispatchStrategyType — it is an orthogonal overlay dimension.
|
|
14
|
+
* 2. `strategy` — one of the 7 `DispatchStrategyType` values, used as the
|
|
15
|
+
* second-level resolution within the selected tag.
|
|
7
16
|
*/
|
|
8
17
|
|
|
18
|
+
import {
|
|
19
|
+
DispatchEngine,
|
|
20
|
+
DispatchStrategyConfig,
|
|
21
|
+
DispatchStrategyType,
|
|
22
|
+
createClassDispatchRequest,
|
|
23
|
+
createRouteKeyDispatchRequest,
|
|
24
|
+
createEnumDispatchRequest,
|
|
25
|
+
createRouteKeyToEnumDispatchRequest,
|
|
26
|
+
createCommandDispatchRequest,
|
|
27
|
+
createPathDispatchRequest,
|
|
28
|
+
createActionPathDispatchRequest,
|
|
29
|
+
} from 'depa-processor';
|
|
9
30
|
import type {
|
|
10
31
|
MailboxSchema,
|
|
11
32
|
ActorSelf,
|
|
@@ -13,71 +34,221 @@ import type {
|
|
|
13
34
|
ActorHandler,
|
|
14
35
|
} from '../core/types.js';
|
|
15
36
|
|
|
16
|
-
// ───
|
|
37
|
+
// ─── Actor sub-handler ───────────────────────────────────────────────
|
|
17
38
|
|
|
18
39
|
/**
|
|
19
|
-
* A
|
|
20
|
-
* This is
|
|
40
|
+
* A resolved actor sub-handler: receives `(self, envelope)` and performs side
|
|
41
|
+
* effects (write state / send messages). This is the `TResult = void | Promise<void>`
|
|
42
|
+
* shape the underlying DispatchEngine resolves to.
|
|
21
43
|
*/
|
|
22
|
-
export
|
|
44
|
+
export type ActorRouteHandler<
|
|
45
|
+
TRuntime,
|
|
46
|
+
TSchema extends MailboxSchema,
|
|
47
|
+
TState,
|
|
48
|
+
> = (
|
|
49
|
+
self: ActorSelf<TRuntime, TSchema, TState>,
|
|
50
|
+
envelope: ActorEnvelope<TSchema>,
|
|
51
|
+
) => void | Promise<void>;
|
|
52
|
+
|
|
53
|
+
// ─── Key extraction (envelope → dispatch coordinate) ─────────────────
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Maps an envelope to the dispatch coordinate consumed by the selected strategy.
|
|
57
|
+
* Defaults are provided per strategy; override to route by payload fields, etc.
|
|
58
|
+
*/
|
|
59
|
+
export interface DispatchKeyExtractors<TSchema extends MailboxSchema> {
|
|
60
|
+
/** ROUTE_KEY / ROUTE_KEY_TO_ENUM / COMMAND_TABLE — defaults to `envelope.tag`. */
|
|
61
|
+
routeKeyOf?: (envelope: ActorEnvelope<TSchema>) => string;
|
|
62
|
+
/** ENUM — defaults to `envelope.tag`. */
|
|
63
|
+
enumOf?: (envelope: ActorEnvelope<TSchema>) => string | number;
|
|
64
|
+
/** CLASS / key-based strategies' input — defaults to `envelope.payload`. */
|
|
65
|
+
inputOf?: (envelope: ActorEnvelope<TSchema>) => unknown;
|
|
66
|
+
/** PATH / ACTION_PATH — defaults to `envelope.tag`. */
|
|
67
|
+
pathOf?: (envelope: ActorEnvelope<TSchema>) => string;
|
|
68
|
+
/** ACTION_PATH action — defaults to `undefined`. */
|
|
69
|
+
actionOf?: (envelope: ActorEnvelope<TSchema>) => unknown;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ─── createDispatchHandler params (object-param, B2 composable) ───────
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Parameters for {@link createDispatchHandler}.
|
|
76
|
+
*
|
|
77
|
+
* `routes` is either:
|
|
78
|
+
* - a plain key → actor-sub-handler map (for the common key-based strategies
|
|
79
|
+
* CLASS-by-key is not applicable; use ROUTE_KEY / ENUM / COMMAND_TABLE), or
|
|
80
|
+
* - a fully-built `DispatchStrategyConfig<void | Promise<void>>` for advanced
|
|
81
|
+
* strategies (PATH / ACTION_PATH / CLASS / ROUTE_KEY_TO_ENUM) where the
|
|
82
|
+
* handler wiring is expressed in depa-processor terms.
|
|
83
|
+
*
|
|
84
|
+
* When a `DispatchStrategyConfig` is supplied, its handlers receive the raw
|
|
85
|
+
* dispatch `input` / `context` (already adapted from the envelope) and may
|
|
86
|
+
* close over `self` via the surrounding scope.
|
|
87
|
+
*/
|
|
88
|
+
export interface CreateDispatchHandlerParams<
|
|
23
89
|
TRuntime,
|
|
24
90
|
TSchema extends MailboxSchema,
|
|
25
91
|
TState,
|
|
26
92
|
> {
|
|
27
|
-
/** Which
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
93
|
+
/** Which of the 7 strategies to use for second-level resolution. */
|
|
94
|
+
strategy: DispatchStrategyType;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Route table. For key-based strategies (ROUTE_KEY / ENUM / COMMAND_TABLE)
|
|
98
|
+
* pass a `Record<key, ActorRouteHandler>`. For advanced strategies, pass a
|
|
99
|
+
* prebuilt `DispatchStrategyConfig` whose `TResult = void | Promise<void>`.
|
|
100
|
+
*/
|
|
101
|
+
routes:
|
|
102
|
+
| Record<string, ActorRouteHandler<TRuntime, TSchema, TState>>
|
|
103
|
+
| DispatchStrategyConfig<void | Promise<void>>;
|
|
104
|
+
|
|
105
|
+
/** Optional fallback when the strategy does not resolve a handler. */
|
|
106
|
+
defaultHandler?: ActorHandler<TRuntime, TSchema, TState>;
|
|
107
|
+
|
|
108
|
+
/** Optional envelope → dispatch-coordinate extractors. */
|
|
109
|
+
extractors?: DispatchKeyExtractors<TSchema>;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ─── Internal helpers ────────────────────────────────────────────────
|
|
113
|
+
|
|
114
|
+
function isStrategyConfig(
|
|
115
|
+
routes: unknown,
|
|
116
|
+
): routes is DispatchStrategyConfig<void | Promise<void>> {
|
|
117
|
+
return routes instanceof DispatchStrategyConfig;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Build a `DispatchStrategyConfig<void>` from a plain key → handler map for the
|
|
122
|
+
* supported key-based strategies. The map values are pre-bound to `(self, envelope)`
|
|
123
|
+
* by capturing the current dispatch's `self` / `envelope` via a thunk.
|
|
124
|
+
*/
|
|
125
|
+
function buildKeyBasedConfig<TRuntime, TSchema extends MailboxSchema, TState>(
|
|
126
|
+
strategy: DispatchStrategyType,
|
|
127
|
+
routes: Record<string, ActorRouteHandler<TRuntime, TSchema, TState>>,
|
|
128
|
+
self: ActorSelf<TRuntime, TSchema, TState>,
|
|
129
|
+
envelope: ActorEnvelope<TSchema>,
|
|
130
|
+
): DispatchStrategyConfig<void | Promise<void>> {
|
|
131
|
+
const handlerMap = new Map<
|
|
132
|
+
string | number,
|
|
133
|
+
(input: unknown) => void | Promise<void>
|
|
134
|
+
>();
|
|
135
|
+
for (const [key, handler] of Object.entries(routes)) {
|
|
136
|
+
handlerMap.set(key, () => handler(self, envelope));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
switch (strategy) {
|
|
140
|
+
case DispatchStrategyType.ROUTE_KEY:
|
|
141
|
+
return DispatchStrategyConfig.forRouteKeyStrategy<void | Promise<void>>({
|
|
142
|
+
handlerMap: handlerMap as Map<string, (input: unknown) => void | Promise<void>>,
|
|
143
|
+
});
|
|
144
|
+
case DispatchStrategyType.ENUM:
|
|
145
|
+
return DispatchStrategyConfig.forEnumStrategy<void | Promise<void>>({
|
|
146
|
+
handlerMap,
|
|
147
|
+
});
|
|
148
|
+
case DispatchStrategyType.COMMAND_TABLE:
|
|
149
|
+
return DispatchStrategyConfig.forCommandStrategy<void | Promise<void>>({
|
|
150
|
+
commandConverter: (command: string) =>
|
|
151
|
+
handlerMap.has(command) ? command : null,
|
|
152
|
+
handlerExtractor: (commandEnum: string | number) =>
|
|
153
|
+
handlerMap.get(commandEnum) ?? null,
|
|
154
|
+
});
|
|
155
|
+
default:
|
|
156
|
+
throw new Error(
|
|
157
|
+
`createDispatchHandler: strategy ${strategy} requires a prebuilt ` +
|
|
158
|
+
`DispatchStrategyConfig in 'routes' (plain key→handler maps support ` +
|
|
159
|
+
`ROUTE_KEY / ENUM / COMMAND_TABLE only).`,
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** Build the strategy-appropriate DispatchRequest from the envelope. */
|
|
165
|
+
function buildRequest<TSchema extends MailboxSchema>(
|
|
166
|
+
strategy: DispatchStrategyType,
|
|
167
|
+
envelope: ActorEnvelope<TSchema>,
|
|
168
|
+
extractors: DispatchKeyExtractors<TSchema> | undefined,
|
|
169
|
+
) {
|
|
170
|
+
const input = extractors?.inputOf ? extractors.inputOf(envelope) : envelope.payload;
|
|
171
|
+
const routeKey = extractors?.routeKeyOf
|
|
172
|
+
? extractors.routeKeyOf(envelope)
|
|
173
|
+
: envelope.tag;
|
|
174
|
+
const path = extractors?.pathOf ? extractors.pathOf(envelope) : envelope.tag;
|
|
175
|
+
|
|
176
|
+
switch (strategy) {
|
|
177
|
+
case DispatchStrategyType.CLASS:
|
|
178
|
+
return createClassDispatchRequest<void | Promise<void>>(input);
|
|
179
|
+
case DispatchStrategyType.ROUTE_KEY:
|
|
180
|
+
return createRouteKeyDispatchRequest<void | Promise<void>>(routeKey, input, false);
|
|
181
|
+
case DispatchStrategyType.ENUM:
|
|
182
|
+
return createEnumDispatchRequest<void | Promise<void>>(
|
|
183
|
+
extractors?.enumOf ? extractors.enumOf(envelope) : envelope.tag,
|
|
184
|
+
input,
|
|
185
|
+
);
|
|
186
|
+
case DispatchStrategyType.ROUTE_KEY_TO_ENUM:
|
|
187
|
+
return createRouteKeyToEnumDispatchRequest<void | Promise<void>>(routeKey, input);
|
|
188
|
+
case DispatchStrategyType.COMMAND_TABLE:
|
|
189
|
+
return createCommandDispatchRequest<void | Promise<void>>(routeKey, input);
|
|
190
|
+
case DispatchStrategyType.PATH:
|
|
191
|
+
return createPathDispatchRequest<void | Promise<void>, unknown, unknown>({
|
|
192
|
+
runtime: undefined,
|
|
193
|
+
request: input,
|
|
194
|
+
path,
|
|
195
|
+
});
|
|
196
|
+
case DispatchStrategyType.ACTION_PATH:
|
|
197
|
+
return createActionPathDispatchRequest<void | Promise<void>, unknown, unknown, unknown>({
|
|
198
|
+
runtime: undefined,
|
|
199
|
+
request: input,
|
|
200
|
+
action: extractors?.actionOf ? extractors.actionOf(envelope) : undefined,
|
|
201
|
+
path,
|
|
202
|
+
});
|
|
203
|
+
default:
|
|
204
|
+
throw new Error(`createDispatchHandler: unknown strategy ${String(strategy)}`);
|
|
205
|
+
}
|
|
45
206
|
}
|
|
46
207
|
|
|
47
208
|
// ─── createDispatchHandler ───────────────────────────────────────────
|
|
48
209
|
|
|
49
210
|
/**
|
|
50
|
-
* Creates an ActorHandler that
|
|
51
|
-
*
|
|
211
|
+
* Creates an ActorHandler that resolves an envelope to a sub-handler via one of
|
|
212
|
+
* the 7 depa-processor dispatch strategies (opt-in, per-handler — DX form C / B2).
|
|
213
|
+
*
|
|
214
|
+
* Object-param signature: `{ strategy, routes, defaultHandler?, extractors? }`.
|
|
215
|
+
*
|
|
216
|
+
* Composability:
|
|
217
|
+
* - slot the returned handler under a `tag` in `ActorDef.handlers` → `tag` overlay
|
|
218
|
+
* (first-level) + `strategy` (second-level), the two axes are orthogonal.
|
|
219
|
+
* - the resolved sub-handler may itself be a `createPipelineHandler(...)` result,
|
|
220
|
+
* so dispatch and pipeline nest freely.
|
|
221
|
+
*
|
|
222
|
+
* No declarative `ActorDef.dispatch` field and no global feature flag / enableXxx
|
|
223
|
+
* API exist — enabling rich dispatch is expressed purely by import + composition.
|
|
52
224
|
*/
|
|
53
225
|
export function createDispatchHandler<
|
|
54
226
|
TRuntime,
|
|
55
227
|
TSchema extends MailboxSchema,
|
|
56
228
|
TState,
|
|
57
229
|
>(
|
|
58
|
-
|
|
59
|
-
defaultHandler?: ActorHandler<TRuntime, TSchema, TState>,
|
|
230
|
+
params: CreateDispatchHandlerParams<TRuntime, TSchema, TState>,
|
|
60
231
|
): ActorHandler<TRuntime, TSchema, TState> {
|
|
61
|
-
|
|
62
|
-
const tagIndex = new Map<string, DispatchRoute<TRuntime, TSchema, TState>>();
|
|
63
|
-
for (const route of routes) {
|
|
64
|
-
for (const tag of route.tags) {
|
|
65
|
-
tagIndex.set(tag, route);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
232
|
+
const { strategy, routes, defaultHandler, extractors } = params;
|
|
68
233
|
|
|
69
234
|
return async (self, envelope) => {
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
235
|
+
const config = isStrategyConfig(routes)
|
|
236
|
+
? routes
|
|
237
|
+
: buildKeyBasedConfig(strategy, routes, self, envelope);
|
|
238
|
+
|
|
239
|
+
const engine = new DispatchEngine<void | Promise<void>>();
|
|
240
|
+
engine.registerStrategy(config);
|
|
241
|
+
|
|
242
|
+
const request = buildRequest(strategy, envelope, extractors);
|
|
243
|
+
const result = await engine.dispatch(request);
|
|
244
|
+
|
|
245
|
+
if (result.isHandled()) {
|
|
246
|
+
// Await the sub-handler's (possibly async) side effect.
|
|
247
|
+
await result.getResult();
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (defaultHandler) {
|
|
81
252
|
await defaultHandler(self, envelope);
|
|
82
253
|
}
|
|
83
254
|
};
|
package/src/index.ts
CHANGED
|
@@ -15,6 +15,46 @@ export type {
|
|
|
15
15
|
|
|
16
16
|
export { ActorSystem } from './core/ActorSystem.js';
|
|
17
17
|
|
|
18
|
+
// depa-actor — Stable local logical addressing
|
|
19
|
+
export type {
|
|
20
|
+
ActorAddress,
|
|
21
|
+
ActorSelector,
|
|
22
|
+
ActorOwnerSnapshotRegistration,
|
|
23
|
+
ActorOwnerSnapshot,
|
|
24
|
+
ActorRegistrationReceipt,
|
|
25
|
+
ActorAddressingErrorCode,
|
|
26
|
+
LocalActorEndpoint,
|
|
27
|
+
LocalActorAddressingRuntime,
|
|
28
|
+
LocalActorAddressingRuntimeConfig,
|
|
29
|
+
RegisterActorInput,
|
|
30
|
+
ActorProcessorConfig,
|
|
31
|
+
ResolveActorInvocation,
|
|
32
|
+
DispatchActorInvocation,
|
|
33
|
+
UnregisterActorInvocation,
|
|
34
|
+
ResolvedActor,
|
|
35
|
+
RebuildActorRegistrationsConfig,
|
|
36
|
+
DirectActorProcessor,
|
|
37
|
+
TargetedActorProcessor,
|
|
38
|
+
} from './addressing.js';
|
|
39
|
+
export {
|
|
40
|
+
ACTOR_ADDRESS_SCHEMA_VERSION,
|
|
41
|
+
ACTOR_OWNER_SNAPSHOT_SCHEMA_VERSION,
|
|
42
|
+
ACTOR_REGISTRATION_SCHEMA_VERSION,
|
|
43
|
+
ActorAddressingError,
|
|
44
|
+
actorAddressKey,
|
|
45
|
+
parseActorAddress,
|
|
46
|
+
parseActorSelector,
|
|
47
|
+
parseActorOwnerSnapshot,
|
|
48
|
+
parseActorRegistrationReceipt,
|
|
49
|
+
createLocalActorAddressingRuntime,
|
|
50
|
+
registerActor,
|
|
51
|
+
resolveActor,
|
|
52
|
+
dispatchActor,
|
|
53
|
+
unregisterActor,
|
|
54
|
+
rebuildActorRegistrations,
|
|
55
|
+
createActorRefEndpoint,
|
|
56
|
+
} from './addressing.js';
|
|
57
|
+
|
|
18
58
|
// depa-actor — Runtime
|
|
19
59
|
export type { ActorPlugin } from './runtime/ActorRuntime.js';
|
|
20
60
|
export { ActorRuntime } from './runtime/ActorRuntime.js';
|
|
@@ -108,10 +148,23 @@ export type {
|
|
|
108
148
|
} from './pipeline/ActorPipeline.js';
|
|
109
149
|
export { createPipelineHandler } from './pipeline/ActorPipeline.js';
|
|
110
150
|
|
|
111
|
-
// depa-actor — Dispatch bridge
|
|
112
|
-
export type {
|
|
151
|
+
// depa-actor — Dispatch bridge (drives depa-processor DispatchEngine, 7 strategies)
|
|
152
|
+
export type {
|
|
153
|
+
ActorRouteHandler,
|
|
154
|
+
DispatchKeyExtractors,
|
|
155
|
+
CreateDispatchHandlerParams,
|
|
156
|
+
} from './dispatch/ActorDispatchAdapter.js';
|
|
113
157
|
export { createDispatchHandler } from './dispatch/ActorDispatchAdapter.js';
|
|
114
158
|
|
|
159
|
+
// depa-actor — C3 re-export of the common depa-processor subset (single DX entry).
|
|
160
|
+
// Component core-logic seam:
|
|
161
|
+
export type { StdInnerLogic } from 'depa-processor';
|
|
162
|
+
// Dispatch strategy enum + the common-tier strategy config factories
|
|
163
|
+
// (ROUTE_KEY / ENUM / COMMAND_TABLE). Advanced strategies (PATH / ACTION_PATH +
|
|
164
|
+
// AntPathMatcher / PathActionMatchRule), manifest-* and router/ stay in
|
|
165
|
+
// depa-processor and are imported directly by users who need them.
|
|
166
|
+
export { DispatchStrategyType, DispatchStrategyConfig } from 'depa-processor';
|
|
167
|
+
|
|
115
168
|
// depa-actor — Orchestration (Fiber Scheduling)
|
|
116
169
|
export type {
|
|
117
170
|
FiberId,
|
|
@@ -1,16 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* depa-actor — ActorPipeline
|
|
3
3
|
*
|
|
4
|
-
* Adapts the DOP 6-step pipeline
|
|
4
|
+
* Adapts the DOP 6-step pipeline to actor context by REUSING the depa-processor
|
|
5
|
+
* `component` primitives (DEPA dimension chain Processor → Actor): the 6-step
|
|
6
|
+
* orchestration is delegated to `runByFuncStyleAdapter`, identity/null seams come
|
|
7
|
+
* from `stdMake*`, and the core-logic seam is `StdInnerLogic` verbatim — this module
|
|
8
|
+
* no longer re-implements a parallel copy of `component/types.ts`.
|
|
5
9
|
*
|
|
6
|
-
* Mapping:
|
|
10
|
+
* Mapping (outer dimension):
|
|
7
11
|
* OuterRuntime = ActorSelf
|
|
8
12
|
* OuterInput = envelope payload
|
|
9
13
|
* OuterConfig = actor state
|
|
10
14
|
*
|
|
15
|
+
* Step 6 (output) is adapted with `TOuterOutput = void`: actor output is a side
|
|
16
|
+
* effect (write `self.state` / `self.send`), not a returned value. This thinly
|
|
17
|
+
* adapts depa-processor's pure-function `StdOuterOutputAdapter` without leaking
|
|
18
|
+
* actor semantics back into the generic primitive.
|
|
19
|
+
*
|
|
11
20
|
* createPipelineHandler() wraps a pipeline definition into an ActorHandler.
|
|
12
21
|
*/
|
|
13
22
|
|
|
23
|
+
import { runByFuncStyleAdapter } from 'depa-processor';
|
|
24
|
+
import type {
|
|
25
|
+
StdOuterComputedAdapter,
|
|
26
|
+
StdInnerRuntimeAdapter,
|
|
27
|
+
StdInnerInputAdapter,
|
|
28
|
+
StdInnerConfigAdapter,
|
|
29
|
+
StdInnerLogic,
|
|
30
|
+
StdOuterOutputAdapter,
|
|
31
|
+
} from 'depa-processor';
|
|
14
32
|
import type {
|
|
15
33
|
MailboxSchema,
|
|
16
34
|
ActorSelf,
|
|
@@ -18,57 +36,71 @@ import type {
|
|
|
18
36
|
} from '../core/types.js';
|
|
19
37
|
|
|
20
38
|
// ─── Pipeline Adapter Types ──────────────────────────────────────────
|
|
39
|
+
// Thin actor-flavoured aliases over the depa-processor component adapters.
|
|
40
|
+
// Outer dimension = (ActorSelf, payload, state); the seam contracts are reused
|
|
41
|
+
// 1:1 from `depa-processor` rather than re-declared.
|
|
21
42
|
|
|
22
43
|
export type PipelineDerivedAdapter<
|
|
23
44
|
TRuntime, TSchema extends MailboxSchema, TState, TDerived,
|
|
24
|
-
> =
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
45
|
+
> = StdOuterComputedAdapter<
|
|
46
|
+
ActorSelf<TRuntime, TSchema, TState>,
|
|
47
|
+
TSchema[keyof TSchema & string],
|
|
48
|
+
TState,
|
|
49
|
+
TDerived
|
|
50
|
+
>;
|
|
29
51
|
|
|
30
52
|
export type PipelineInnerRuntimeAdapter<
|
|
31
53
|
TRuntime, TSchema extends MailboxSchema, TState, TDerived, TInnerRuntime,
|
|
32
|
-
> =
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
54
|
+
> = StdInnerRuntimeAdapter<
|
|
55
|
+
ActorSelf<TRuntime, TSchema, TState>,
|
|
56
|
+
TSchema[keyof TSchema & string],
|
|
57
|
+
TState,
|
|
58
|
+
TDerived,
|
|
59
|
+
TInnerRuntime
|
|
60
|
+
>;
|
|
38
61
|
|
|
39
62
|
export type PipelineInnerInputAdapter<
|
|
40
63
|
TRuntime, TSchema extends MailboxSchema, TState, TDerived, TInnerInput,
|
|
41
|
-
> =
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
64
|
+
> = StdInnerInputAdapter<
|
|
65
|
+
ActorSelf<TRuntime, TSchema, TState>,
|
|
66
|
+
TSchema[keyof TSchema & string],
|
|
67
|
+
TState,
|
|
68
|
+
TDerived,
|
|
69
|
+
TInnerInput
|
|
70
|
+
>;
|
|
47
71
|
|
|
48
72
|
export type PipelineInnerConfigAdapter<
|
|
49
73
|
TRuntime, TSchema extends MailboxSchema, TState, TDerived, TInnerConfig,
|
|
50
|
-
> =
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
74
|
+
> = StdInnerConfigAdapter<
|
|
75
|
+
ActorSelf<TRuntime, TSchema, TState>,
|
|
76
|
+
TSchema[keyof TSchema & string],
|
|
77
|
+
TState,
|
|
78
|
+
TDerived,
|
|
79
|
+
TInnerConfig
|
|
80
|
+
>;
|
|
56
81
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
82
|
+
/**
|
|
83
|
+
* Core business logic seam — reuses depa-processor `StdInnerLogic` verbatim:
|
|
84
|
+
* (runtime, input, config) => output | Promise<output>.
|
|
85
|
+
*/
|
|
86
|
+
export type PipelineCoreLogic<TInnerRuntime, TInnerInput, TInnerConfig, TInnerOutput> =
|
|
87
|
+
StdInnerLogic<TInnerRuntime, TInnerInput, TInnerConfig, TInnerOutput>;
|
|
62
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Step 6 output adapter — actor variant with `TOuterOutput = void`.
|
|
91
|
+
* The adapter performs side effects (write state / send messages) and returns
|
|
92
|
+
* nothing. This is the depa-processor `StdOuterOutputAdapter` specialised to void.
|
|
93
|
+
*/
|
|
63
94
|
export type PipelineOutputAdapter<
|
|
64
95
|
TRuntime, TSchema extends MailboxSchema, TState, TDerived, TInnerOutput,
|
|
65
|
-
> =
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
96
|
+
> = StdOuterOutputAdapter<
|
|
97
|
+
ActorSelf<TRuntime, TSchema, TState>,
|
|
98
|
+
TSchema[keyof TSchema & string],
|
|
99
|
+
TState,
|
|
100
|
+
TDerived,
|
|
101
|
+
TInnerOutput,
|
|
102
|
+
void | Promise<void>
|
|
103
|
+
>;
|
|
72
104
|
|
|
73
105
|
// ─── Pipeline Definition ─────────────────────────────────────────────
|
|
74
106
|
|
|
@@ -92,6 +124,14 @@ export interface ActorPipelineDef<
|
|
|
92
124
|
|
|
93
125
|
// ─── createPipelineHandler ───────────────────────────────────────────
|
|
94
126
|
|
|
127
|
+
/**
|
|
128
|
+
* Wrap a pipeline definition into an ActorHandler by delegating the 6-step
|
|
129
|
+
* orchestration to depa-processor `runByFuncStyleAdapter`.
|
|
130
|
+
*
|
|
131
|
+
* Outer dimension: runtime = self, input = payload, config = state.
|
|
132
|
+
* Step 6 produces `void` — `runByFuncStyleAdapter` runs the output adapter for its
|
|
133
|
+
* side effects and the (void) return value is discarded.
|
|
134
|
+
*/
|
|
95
135
|
export function createPipelineHandler<
|
|
96
136
|
TRuntime,
|
|
97
137
|
TSchema extends MailboxSchema,
|
|
@@ -108,25 +148,31 @@ export function createPipelineHandler<
|
|
|
108
148
|
>,
|
|
109
149
|
): ActorHandler<TRuntime, TSchema, TState> {
|
|
110
150
|
return async (self, envelope) => {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
//
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
151
|
+
// `runByFuncStyleAdapter` returns the output adapter's value verbatim (without
|
|
152
|
+
// awaiting it). Capture it and await so an async step-6 side effect (write
|
|
153
|
+
// state / send messages) is fully settled before the handler resolves —
|
|
154
|
+
// preserving the original `await pipeline.output(...)` semantics.
|
|
155
|
+
const outputResult = await runByFuncStyleAdapter<
|
|
156
|
+
ActorSelf<TRuntime, TSchema, TState>,
|
|
157
|
+
TSchema[keyof TSchema & string],
|
|
158
|
+
TState,
|
|
159
|
+
TDerived,
|
|
160
|
+
void | Promise<void>,
|
|
161
|
+
TInnerRuntime,
|
|
162
|
+
TInnerInput,
|
|
163
|
+
TInnerConfig,
|
|
164
|
+
TInnerOutput
|
|
165
|
+
>(
|
|
166
|
+
self,
|
|
167
|
+
envelope.payload,
|
|
168
|
+
self.state,
|
|
169
|
+
pipeline.computeDerived,
|
|
170
|
+
pipeline.innerRuntime,
|
|
171
|
+
pipeline.innerInput,
|
|
172
|
+
pipeline.innerConfig,
|
|
173
|
+
pipeline.coreLogic,
|
|
174
|
+
pipeline.output,
|
|
175
|
+
);
|
|
176
|
+
await outputResult;
|
|
131
177
|
};
|
|
132
178
|
}
|