@cnstra/types 0.1.0 → 0.2.1
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/index.d.mts +142 -102
- package/dist/index.d.ts +142 -102
- package/dist/index.js.map +1 -1
- package/package.json +7 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
type TCNSAfferentPath = {
|
|
2
|
+
readonly index: number;
|
|
2
3
|
parentAfferentPath?: TCNSAfferentPath;
|
|
3
4
|
};
|
|
4
5
|
|
|
@@ -8,6 +9,7 @@ type TCNSSignal<TCollateral extends ICNSCollateral<unknown>> = {
|
|
|
8
9
|
};
|
|
9
10
|
|
|
10
11
|
interface ICNSCollateral<TPayload> {
|
|
12
|
+
readonly index: number;
|
|
11
13
|
createSignal(): TCNSSignal<ICNSCollateral<TPayload>>;
|
|
12
14
|
createSignal(payload: TPayload): TCNSSignal<ICNSCollateral<TPayload>>;
|
|
13
15
|
}
|
|
@@ -37,48 +39,53 @@ type TCNSAxon<TCollaterals extends Record<string, ICNSCollateral<unknown>> = Rec
|
|
|
37
39
|
[K in keyof TCollaterals]: TCollaterals[K];
|
|
38
40
|
};
|
|
39
41
|
|
|
42
|
+
/**
|
|
43
|
+
* A context store: data attached to something the engine is running, in
|
|
44
|
+
* compartments.
|
|
45
|
+
*
|
|
46
|
+
* There are two of them, same shape, different life — the run's
|
|
47
|
+
* (`stimulationContext`, one per stimulation) and the activation's
|
|
48
|
+
* (`activationContext`, one per neuron activation). Same shape on purpose: they
|
|
49
|
+
* are used the same way, serialized the same way, and read the same way.
|
|
50
|
+
*
|
|
51
|
+
* A key is a namespace its writer owns, by convention the package name
|
|
52
|
+
* (`'@cnstra/persist-otel'`), so an integration and your own code cannot
|
|
53
|
+
* overwrite each other. A caller who owns their whole run does not need a prefix.
|
|
54
|
+
*
|
|
55
|
+
* Plain object with string keys rather than a `Map` because this crosses a
|
|
56
|
+
* process boundary: `JSON.stringify` turns a `Map` into `{}` and drops symbol
|
|
57
|
+
* keys entirely, so neither could carry anything. What is portable travels with
|
|
58
|
+
* the serialized frontier; a live handle stays where it was made.
|
|
59
|
+
*/
|
|
60
|
+
type TCNSContextStore = Record<string, unknown>;
|
|
61
|
+
|
|
40
62
|
/**
|
|
41
63
|
* Allowed return types from a neuron dendrite `response` function.
|
|
42
64
|
*
|
|
43
65
|
* Signals route by collateral object identity (not by name).
|
|
44
66
|
*/
|
|
45
|
-
type
|
|
46
|
-
|
|
47
|
-
type TCNSLocalContextValueStore<TContextValue> = {
|
|
48
|
-
get: () => TContextValue | undefined;
|
|
49
|
-
set: (value: TContextValue) => void;
|
|
50
|
-
delete: () => void;
|
|
51
|
-
};
|
|
67
|
+
type TCNSNeuronResponseReturn<TAxon extends TCNSAxon> = TCNSSignal<TAxon[keyof TAxon]> | TCNSSignal<TAxon[keyof TAxon]>[] | void | Promise<TCNSSignal<TAxon[keyof TAxon]> | TCNSSignal<TAxon[keyof TAxon]>[] | void>;
|
|
52
68
|
|
|
53
|
-
type TCNSNeuron<
|
|
69
|
+
type TCNSNeuron<TAxonType extends TCNSAxon = TCNSAxon> = {
|
|
70
|
+
readonly index: number;
|
|
54
71
|
axon: TAxonType;
|
|
55
72
|
/** Optional per-neuron concurrency limit. If undefined or <= 0, no limit is applied. */
|
|
56
73
|
concurrency?: number;
|
|
57
74
|
/** Optional per-neuron max processing duration in milliseconds. */
|
|
58
75
|
maxDuration?: number;
|
|
59
|
-
dendrites: TCNSDendrite<
|
|
76
|
+
dendrites: TCNSDendrite<ICNSCollateral<unknown>, TAxonType, any>[];
|
|
60
77
|
};
|
|
61
78
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
*/
|
|
70
|
-
autoCleanupContexts?: boolean;
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
interface ICNSStimulationContextStore {
|
|
74
|
-
get: (key: object) => unknown;
|
|
75
|
-
set: (key: object, value: unknown) => void;
|
|
76
|
-
getAll: () => Map<object, unknown>;
|
|
77
|
-
setAll: (values: Map<object, unknown>) => void;
|
|
78
|
-
delete: (key: object) => void;
|
|
79
|
-
}
|
|
79
|
+
/**
|
|
80
|
+
* Options bag for `new CNS(...)`. Currently empty — the former
|
|
81
|
+
* `autoCleanupContexts` flag was removed together with the per-neuron mutable
|
|
82
|
+
* context store. Kept as a named type so the constructor signature and future
|
|
83
|
+
* engine-level options have a stable home.
|
|
84
|
+
*/
|
|
85
|
+
type TCNSOptions = Record<never, never>;
|
|
80
86
|
|
|
81
87
|
type TCNSModality = {
|
|
88
|
+
readonly index: number;
|
|
82
89
|
afferentPaths: Record<string | number, TCNSAfferentPath>;
|
|
83
90
|
};
|
|
84
91
|
|
|
@@ -86,6 +93,20 @@ type TCNSNeuronActivationTask<TNeuron extends object = object, TCollateral exten
|
|
|
86
93
|
neuron: TNeuron;
|
|
87
94
|
dendriteCollateral: TCollateral;
|
|
88
95
|
input?: TCNSSignal<TCollateral>;
|
|
96
|
+
/**
|
|
97
|
+
* Data attached to THIS activation, in namespaced compartments — the
|
|
98
|
+
* per-activation sibling of `stimulationContext`.
|
|
99
|
+
*
|
|
100
|
+
* A response listener can write here before the activation runs (the engine
|
|
101
|
+
* builds these tasks first and hands them to the listener on the response),
|
|
102
|
+
* and the dendrite reads them back as `ctx.activationContext`.
|
|
103
|
+
*
|
|
104
|
+
* Compartment keys are strings, by convention the writer's package name, so
|
|
105
|
+
* an integration and your own code cannot overwrite each other. What is
|
|
106
|
+
* portable travels with the serialized frontier; a live handle does not —
|
|
107
|
+
* see `portable()` in `@cnstra/persist`.
|
|
108
|
+
*/
|
|
109
|
+
activationContext?: TCNSContextStore;
|
|
89
110
|
};
|
|
90
111
|
|
|
91
112
|
type TCNSNeuronActivationTaskFailure<TNeuron extends object = object> = {
|
|
@@ -100,7 +121,7 @@ type TCNSNeuronActivationTaskFailure<TNeuron extends object = object> = {
|
|
|
100
121
|
* `CNSStimulation` class in `@cnstra/core` implements it; internal enqueue/dispatch
|
|
101
122
|
* methods are intentionally not part of the public interface.
|
|
102
123
|
*/
|
|
103
|
-
interface ICNSStimulation<TNeuron extends TCNSNeuron<any
|
|
124
|
+
interface ICNSStimulation<TNeuron extends TCNSNeuron<any>, TDendrite extends TCNSDendrite<any, any> = TCNSDendrite<any, any>> {
|
|
104
125
|
/** Resolves when the run completes; rejects on failed tasks / abort. */
|
|
105
126
|
waitUntilComplete(): Promise<void>;
|
|
106
127
|
/** All activation tasks seen this run. */
|
|
@@ -112,47 +133,32 @@ interface ICNSStimulation<TNeuron extends TCNSNeuron<any, any>, TDendrite extend
|
|
|
112
133
|
* pending) plus failed/aborted ones. The set to persist for resume.
|
|
113
134
|
*/
|
|
114
135
|
getOutstandingTasks(): TCNSNeuronActivationTask<TNeuron>[];
|
|
115
|
-
/** The per-neuron context store for this run. */
|
|
116
|
-
getContext(): ICNSStimulationContextStore;
|
|
117
136
|
}
|
|
118
137
|
|
|
119
138
|
/**
|
|
120
|
-
* Announced when a stimulation's synchronous turn ends
|
|
121
|
-
* without yielding to the event loop has run, and what remains (if anything) is
|
|
122
|
-
* waiting on a promise or blocked by a concurrency limit.
|
|
123
|
-
*
|
|
124
|
-
* This is the batch boundary. It is a property of the scheduler loop exhausting,
|
|
125
|
-
* not of any individual activation starting or finishing - which is why it cannot
|
|
126
|
-
* be derived from `onResponse`. A turn ends in six ways, and a response is only
|
|
127
|
-
* emitted in the first:
|
|
139
|
+
* Announced when a stimulation's synchronous turn ends — the batch boundary — or, for a turn inside `cns.batch`, when that batch ends.
|
|
128
140
|
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* 6. a per-neuron `setConcurrency` gate forced an activation onto a promise
|
|
141
|
+
* It is a property of the scheduler loop exhausting, not of an activation
|
|
142
|
+
* finishing, so it cannot be derived from `onResponse`: a turn also ends when the
|
|
143
|
+
* last activation returned a promise, when a concurrency limit is reached, on
|
|
144
|
+
* abort, and behind an async listener. Fires once per turn, the final one
|
|
145
|
+
* included.
|
|
135
146
|
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
* The counters carry the same meaning as on `TCNSStimulationResponse`, but they
|
|
140
|
-
* are measured *after* the loop exhausted rather than before the work runs. On a
|
|
141
|
-
* response `pendingActivations` is a forecast; here it is a fact, and a non-zero
|
|
142
|
-
* value can only mean blocked - by a concurrency limit or by an abort - never
|
|
143
|
-
* "about to run".
|
|
147
|
+
* The counters mean what they do on `TCNSStimulationResponse`, but measured after
|
|
148
|
+
* the loop exhausted — so a non-zero `pendingActivations` here is blocked, not
|
|
149
|
+
* about to run.
|
|
144
150
|
*/
|
|
145
151
|
type TCNSStimulationDrain = {
|
|
146
152
|
stimulation: ICNSStimulation<any, any>;
|
|
147
153
|
/** `pendingActivations + activeActivations`. Zero means the stimulation is finished. */
|
|
148
154
|
queueLength: number;
|
|
149
|
-
/** Activations whose dendrite
|
|
155
|
+
/** Activations whose dendrite response has not been invoked. Non-zero here means blocked. */
|
|
150
156
|
pendingActivations: number;
|
|
151
157
|
/** Activations awaiting an unsettled promise. Non-zero means another drain is coming. */
|
|
152
158
|
activeActivations: number;
|
|
153
159
|
};
|
|
154
160
|
|
|
155
|
-
type TCNSStimulationOptions<TResponse
|
|
161
|
+
type TCNSStimulationOptions<TResponse> = {
|
|
156
162
|
maxNeuronHops?: number;
|
|
157
163
|
onResponse?: (response: TResponse) => void | Promise<void>;
|
|
158
164
|
/**
|
|
@@ -173,11 +179,17 @@ type TCNSStimulationOptions<TResponse, TStimulationContext extends Object = {}>
|
|
|
173
179
|
*/
|
|
174
180
|
onDrain?: (drain: TCNSStimulationDrain) => void;
|
|
175
181
|
abortSignal?: AbortSignal;
|
|
176
|
-
ctx?: ICNSStimulationContextStore;
|
|
177
182
|
concurrency?: number;
|
|
178
183
|
modality?: TCNSModality;
|
|
179
184
|
afferentPath?: TCNSAfferentPath;
|
|
180
|
-
|
|
185
|
+
/**
|
|
186
|
+
* Data attached to the whole run, in namespaced compartments — the same
|
|
187
|
+
* object on every hop. Its per-activation sibling is `activationContext`.
|
|
188
|
+
*
|
|
189
|
+
* What is portable travels with the serialized frontier, so a run resumed in
|
|
190
|
+
* another process reads back what the previous attempt left here.
|
|
191
|
+
*/
|
|
192
|
+
stimulationContext?: TCNSContextStore;
|
|
181
193
|
};
|
|
182
194
|
|
|
183
195
|
type TCNSStimulationResponse<TInputCollateral extends ICNSCollateral<unknown> = ICNSCollateral<unknown>, TOutputCollateral extends ICNSCollateral<unknown> = ICNSCollateral<unknown>> = {
|
|
@@ -185,7 +197,6 @@ type TCNSStimulationResponse<TInputCollateral extends ICNSCollateral<unknown> =
|
|
|
185
197
|
outputSignal?: TCNSSignal<TOutputCollateral>;
|
|
186
198
|
modality?: TCNSModality;
|
|
187
199
|
afferentPath?: TCNSAfferentPath;
|
|
188
|
-
contextValue: Map<object, unknown>;
|
|
189
200
|
/**
|
|
190
201
|
* Every activation this stimulation still owns, in any state:
|
|
191
202
|
* `pendingActivations + activeActivations`.
|
|
@@ -209,17 +220,17 @@ type TCNSStimulationResponse<TInputCollateral extends ICNSCollateral<unknown> =
|
|
|
209
220
|
*/
|
|
210
221
|
queueLength: number;
|
|
211
222
|
/**
|
|
212
|
-
* Activations that exist (or are reserved) but whose dendrite
|
|
213
|
-
* been invoked yet: waiting in the ring buffer, created and held before being
|
|
223
|
+
* Activations that exist (or are reserved) but whose dendrite response has
|
|
224
|
+
* not been invoked yet: waiting in the ring buffer, created and held before being
|
|
214
225
|
* enqueued, or reserved by an array fan-out that is still mid-dispatch.
|
|
215
226
|
*
|
|
216
227
|
* Subscribers parked behind an async `onResponse` listener are counted here,
|
|
217
228
|
* not in {@link activeActivations}: the split is by lifecycle stage - whether
|
|
218
|
-
* the
|
|
229
|
+
* the response has started - not by whether something is being awaited.
|
|
219
230
|
*/
|
|
220
231
|
pendingActivations: number;
|
|
221
232
|
/**
|
|
222
|
-
* Activations whose dendrite
|
|
233
|
+
* Activations whose dendrite response has been invoked and returned a promise
|
|
223
234
|
* that has not settled.
|
|
224
235
|
*
|
|
225
236
|
* A synchronous body passes through this state within a single pump
|
|
@@ -234,12 +245,52 @@ type TCNSStimulationResponse<TInputCollateral extends ICNSCollateral<unknown> =
|
|
|
234
245
|
* task's neuron reliably — including for sink/failed tasks that have no output
|
|
235
246
|
* collateral to trace an owner from.
|
|
236
247
|
*/
|
|
237
|
-
neuron?: TCNSNeuron<any
|
|
248
|
+
neuron?: TCNSNeuron<any>;
|
|
238
249
|
error?: Error;
|
|
239
250
|
hops?: number;
|
|
251
|
+
/**
|
|
252
|
+
* When the activation's dendrite response was invoked, in epoch milliseconds.
|
|
253
|
+
*
|
|
254
|
+
* Present for real neuron activations on every path — success, sync throw and
|
|
255
|
+
* async rejection alike. Absent on responses that are not an activation (the
|
|
256
|
+
* entry-signal injection, and the terminal signal emitted on abort).
|
|
257
|
+
*/
|
|
258
|
+
startedAt?: number;
|
|
259
|
+
/**
|
|
260
|
+
* How long the dendrite response took, in milliseconds: the span from
|
|
261
|
+
* {@link startedAt} to the moment the activation settled.
|
|
262
|
+
*
|
|
263
|
+
* This is the only place per-hop latency exists — it is what a trace needs to
|
|
264
|
+
* draw a waterfall and what a metrics layer needs for a latency histogram.
|
|
265
|
+
* Present exactly when {@link startedAt} is.
|
|
266
|
+
*/
|
|
267
|
+
duration?: number;
|
|
268
|
+
/**
|
|
269
|
+
* The activations this response is about to create — built, but not yet run.
|
|
270
|
+
*
|
|
271
|
+
* The engine resolves the subscribers of the output collateral and builds
|
|
272
|
+
* their tasks BEFORE handing the response to a listener, then enqueues those
|
|
273
|
+
* very objects afterwards — on the synchronous path, after an async listener
|
|
274
|
+
* settles, and even after a listener throws. So a listener can write into
|
|
275
|
+
* `task.activationContext` here and the dendrite will read it back as
|
|
276
|
+
* `ctx.activationContext`.
|
|
277
|
+
*
|
|
278
|
+
* Empty on a response that starts nothing: a sink neuron, a failure, the
|
|
279
|
+
* entry injection with no subscribers, the terminal abort signal.
|
|
280
|
+
*/
|
|
281
|
+
scheduledActivationTasks?: readonly TCNSNeuronActivationTask<any>[];
|
|
282
|
+
/**
|
|
283
|
+
* The context store of the activation that produced this response — the same
|
|
284
|
+
* object its own handler reads as `ctx.activationContext`.
|
|
285
|
+
*
|
|
286
|
+
* Here so a recorder can put it in the task's history row without holding the
|
|
287
|
+
* task itself. Undefined when nothing was attached, and on responses that are
|
|
288
|
+
* not an activation.
|
|
289
|
+
*/
|
|
290
|
+
activationContext?: TCNSContextStore;
|
|
240
291
|
};
|
|
241
292
|
|
|
242
|
-
type TCNSSubscriber<TNeuron extends TCNSNeuron<any
|
|
293
|
+
type TCNSSubscriber<TNeuron extends TCNSNeuron<any>, TDendrite extends TCNSDendrite<any, any>> = {
|
|
243
294
|
neuron: TNeuron;
|
|
244
295
|
dendrite: TDendrite;
|
|
245
296
|
};
|
|
@@ -248,7 +299,7 @@ type TCNSSubscriber<TNeuron extends TCNSNeuron<any, any>, TDendrite extends TCNS
|
|
|
248
299
|
* The public contract of the compiled neuron network, exposed on `ICNS.network`.
|
|
249
300
|
* The concrete `CNSNetwork` class in `@cnstra/core` implements it.
|
|
250
301
|
*/
|
|
251
|
-
interface ICNSNetwork<TNeuron extends TCNSNeuron<any
|
|
302
|
+
interface ICNSNetwork<TNeuron extends TCNSNeuron<any>, TDendrite extends TCNSDendrite<any, any> = TCNSDendrite<any, any>> {
|
|
252
303
|
readonly stronglyConnectedComponents: Set<TNeuron>[];
|
|
253
304
|
getSCCSetByNeuron(neuron: TNeuron): Set<TNeuron> | undefined;
|
|
254
305
|
getSccIndexByNeuron(neuron: TNeuron): number | undefined;
|
|
@@ -259,7 +310,7 @@ interface ICNSNetwork<TNeuron extends TCNSNeuron<any, any>, TDendrite extends TC
|
|
|
259
310
|
getSubscribers(collateral: ICNSCollateral<unknown>): TCNSSubscriber<TNeuron, TDendrite>[];
|
|
260
311
|
}
|
|
261
312
|
|
|
262
|
-
interface ICNS<TNeuron extends TCNSNeuron<any
|
|
313
|
+
interface ICNS<TNeuron extends TCNSNeuron<any>, TDendrite extends TCNSDendrite<any, any> = TCNSDendrite<any, any>> {
|
|
263
314
|
options?: TCNSOptions;
|
|
264
315
|
network: ICNSNetwork<TNeuron, TDendrite>;
|
|
265
316
|
/**
|
|
@@ -269,16 +320,18 @@ interface ICNS<TNeuron extends TCNSNeuron<any, any>, TDendrite extends TCNSDendr
|
|
|
269
320
|
addResponseListener(listener: (response: TCNSStimulationResponse) => void): () => void;
|
|
270
321
|
/**
|
|
271
322
|
* Add a global batch-boundary listener applied to all stimulations, called
|
|
272
|
-
* once at the end of every synchronous turn.
|
|
323
|
+
* once at the end of every synchronous turn (inside `batch`, when the batch ends).
|
|
273
324
|
* Returns an unsubscribe function.
|
|
274
325
|
*/
|
|
275
326
|
addDrainListener(listener: (drain: TCNSStimulationDrain) => void): () => void;
|
|
327
|
+
batch<TResult>(run: () => TResult): TResult;
|
|
276
328
|
stimulate(signalOrSignals: TCNSSignal<ICNSCollateral<unknown>> | TCNSSignal<ICNSCollateral<unknown>>[], options?: TCNSStimulationOptions<TCNSStimulationResponse>): ICNSStimulation<TNeuron, TDendrite>;
|
|
277
329
|
/**
|
|
278
330
|
* Resume a run from a set of activation tasks (e.g. an outstanding frontier
|
|
279
331
|
* hydrated from persisted progress, or `getFailedTasks()` for a partial
|
|
280
332
|
* retry). Unlike {@link stimulate}, no entry signal is derived — the given
|
|
281
|
-
* tasks are enqueued directly.
|
|
333
|
+
* tasks are enqueued directly. Each task carries its own input signal (with
|
|
334
|
+
* payload), so re-driving the frontier needs no extra state.
|
|
282
335
|
*/
|
|
283
336
|
activate(tasks: TCNSNeuronActivationTask<TNeuron>[], options?: TCNSStimulationOptions<TCNSStimulationResponse>): ICNSStimulation<TNeuron, TDendrite>;
|
|
284
337
|
}
|
|
@@ -288,20 +341,30 @@ interface ICNS<TNeuron extends TCNSNeuron<any, any>, TDendrite extends TCNSDendr
|
|
|
288
341
|
* lives here. Factory layers add their own fields via the `TExt` extension
|
|
289
342
|
* (see {@link TCNSHandlerContext}), so the base stays clean for neurons that
|
|
290
343
|
* don't opt into anything.
|
|
344
|
+
*
|
|
345
|
+
* Internal building block for {@link TCNSHandlerContext} — not part of the public API.
|
|
291
346
|
*/
|
|
292
|
-
type TCNSHandlerContextBase
|
|
347
|
+
type TCNSHandlerContextBase = {
|
|
293
348
|
abortSignal?: AbortSignal;
|
|
294
349
|
cns?: ICNS<any, any>;
|
|
295
350
|
stimulation?: any;
|
|
296
351
|
/**
|
|
297
|
-
* The
|
|
298
|
-
*
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
* `unknown
|
|
302
|
-
* the read site.
|
|
352
|
+
* The context store of the whole run — what the caller passed as
|
|
353
|
+
* `stimulate(sig, { stimulationContext })` plus whatever the run has written
|
|
354
|
+
* into it since, the same object on every hop in any environment (sync or
|
|
355
|
+
* async, node or browser). Keyed by namespace; the values inside are
|
|
356
|
+
* `unknown`, so cast at the read site.
|
|
303
357
|
*/
|
|
304
|
-
stimulationContext?:
|
|
358
|
+
stimulationContext?: TCNSContextStore;
|
|
359
|
+
/**
|
|
360
|
+
* The context store of the activation currently running — data a response
|
|
361
|
+
* listener attached to THIS activation before it started. Unset when nobody
|
|
362
|
+
* wrote anything.
|
|
363
|
+
*
|
|
364
|
+
* Same shape as {@link stimulationContext}, shorter life: this one is gone
|
|
365
|
+
* when the activation returns.
|
|
366
|
+
*/
|
|
367
|
+
activationContext?: TCNSContextStore;
|
|
305
368
|
};
|
|
306
369
|
/**
|
|
307
370
|
* The `ctx` a dendrite handler receives. `TExt` is whatever the factory layers
|
|
@@ -312,34 +375,11 @@ type TCNSHandlerContextBase<TContextValue> = TCNSLocalContextValueStore<TContext
|
|
|
312
375
|
* The handler signature stays `(payload, axon, ctx)` no matter how many layers
|
|
313
376
|
* you stack; each layer widens the type of `ctx`, never the argument list.
|
|
314
377
|
*/
|
|
315
|
-
type TCNSHandlerContext<
|
|
378
|
+
type TCNSHandlerContext<TExt = unknown> = TCNSHandlerContextBase & TExt;
|
|
316
379
|
|
|
317
|
-
type TCNSDendrite<
|
|
380
|
+
type TCNSDendrite<TSenderCollateral extends ICNSCollateral<unknown>, TAxonType extends TCNSAxon, TExt = unknown> = {
|
|
318
381
|
collateral: TSenderCollateral;
|
|
319
|
-
response: (payload: TSenderCollateral extends ICNSCollateral<infer P> ? P : never, axon: TAxonType, ctx: TCNSHandlerContext<
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
type CNSCollateralLike = ICNSCollateral<unknown>;
|
|
323
|
-
type TCNSNeuronPersistOptions<TNeuron extends TCNSNeuron<unknown, any> = TCNSNeuron<unknown, any>> = {
|
|
324
|
-
name: string;
|
|
325
|
-
neuron: TNeuron;
|
|
326
|
-
};
|
|
327
|
-
type TCNSCollateralPersistOptions<TCollateral extends CNSCollateralLike = CNSCollateralLike> = {
|
|
328
|
-
name: string;
|
|
329
|
-
collateral: TCollateral;
|
|
330
|
-
};
|
|
331
|
-
type TCNSStimulationPersistOptions = {
|
|
332
|
-
stimulationId: string;
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
type TCNSStimulationQueueItem<TNeuron extends TCNSNeuron<any, any>, TDendrite extends TCNSDendrite<any, any, any>, TInputCollateral extends ICNSCollateral<unknown> = ICNSCollateral<unknown>> = {
|
|
336
|
-
neuron: TNeuron;
|
|
337
|
-
subscriber: TCNSSubscriber<TNeuron, TDendrite>;
|
|
338
|
-
inputSignal?: TCNSSignal<TInputCollateral>;
|
|
339
|
-
};
|
|
340
|
-
|
|
341
|
-
type TCNSStimulationSerializedContextValue = {
|
|
342
|
-
[key: string]: unknown;
|
|
382
|
+
response: (payload: TSenderCollateral extends ICNSCollateral<infer P> ? P : never, axon: TAxonType, ctx: TCNSHandlerContext<TExt>) => TCNSNeuronResponseReturn<TAxonType>;
|
|
343
383
|
};
|
|
344
384
|
|
|
345
|
-
export type { ICNS, ICNSCollateral, ICNSNetwork, ICNSStimulation,
|
|
385
|
+
export type { ICNS, ICNSCollateral, ICNSNetwork, ICNSStimulation, TCNSAfferentPath, TCNSAxon, TCNSContextStore, TCNSDendrite, TCNSHandlerContext, TCNSModality, TCNSNeuron, TCNSNeuronActivationTask, TCNSNeuronActivationTaskFailure, TCNSNeuronResponseReturn, TCNSOptions, TCNSSignal, TCNSStimulationDrain, TCNSStimulationOptions, TCNSStimulationResponse, TCNSSubscriber };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
type TCNSAfferentPath = {
|
|
2
|
+
readonly index: number;
|
|
2
3
|
parentAfferentPath?: TCNSAfferentPath;
|
|
3
4
|
};
|
|
4
5
|
|
|
@@ -8,6 +9,7 @@ type TCNSSignal<TCollateral extends ICNSCollateral<unknown>> = {
|
|
|
8
9
|
};
|
|
9
10
|
|
|
10
11
|
interface ICNSCollateral<TPayload> {
|
|
12
|
+
readonly index: number;
|
|
11
13
|
createSignal(): TCNSSignal<ICNSCollateral<TPayload>>;
|
|
12
14
|
createSignal(payload: TPayload): TCNSSignal<ICNSCollateral<TPayload>>;
|
|
13
15
|
}
|
|
@@ -37,48 +39,53 @@ type TCNSAxon<TCollaterals extends Record<string, ICNSCollateral<unknown>> = Rec
|
|
|
37
39
|
[K in keyof TCollaterals]: TCollaterals[K];
|
|
38
40
|
};
|
|
39
41
|
|
|
42
|
+
/**
|
|
43
|
+
* A context store: data attached to something the engine is running, in
|
|
44
|
+
* compartments.
|
|
45
|
+
*
|
|
46
|
+
* There are two of them, same shape, different life — the run's
|
|
47
|
+
* (`stimulationContext`, one per stimulation) and the activation's
|
|
48
|
+
* (`activationContext`, one per neuron activation). Same shape on purpose: they
|
|
49
|
+
* are used the same way, serialized the same way, and read the same way.
|
|
50
|
+
*
|
|
51
|
+
* A key is a namespace its writer owns, by convention the package name
|
|
52
|
+
* (`'@cnstra/persist-otel'`), so an integration and your own code cannot
|
|
53
|
+
* overwrite each other. A caller who owns their whole run does not need a prefix.
|
|
54
|
+
*
|
|
55
|
+
* Plain object with string keys rather than a `Map` because this crosses a
|
|
56
|
+
* process boundary: `JSON.stringify` turns a `Map` into `{}` and drops symbol
|
|
57
|
+
* keys entirely, so neither could carry anything. What is portable travels with
|
|
58
|
+
* the serialized frontier; a live handle stays where it was made.
|
|
59
|
+
*/
|
|
60
|
+
type TCNSContextStore = Record<string, unknown>;
|
|
61
|
+
|
|
40
62
|
/**
|
|
41
63
|
* Allowed return types from a neuron dendrite `response` function.
|
|
42
64
|
*
|
|
43
65
|
* Signals route by collateral object identity (not by name).
|
|
44
66
|
*/
|
|
45
|
-
type
|
|
46
|
-
|
|
47
|
-
type TCNSLocalContextValueStore<TContextValue> = {
|
|
48
|
-
get: () => TContextValue | undefined;
|
|
49
|
-
set: (value: TContextValue) => void;
|
|
50
|
-
delete: () => void;
|
|
51
|
-
};
|
|
67
|
+
type TCNSNeuronResponseReturn<TAxon extends TCNSAxon> = TCNSSignal<TAxon[keyof TAxon]> | TCNSSignal<TAxon[keyof TAxon]>[] | void | Promise<TCNSSignal<TAxon[keyof TAxon]> | TCNSSignal<TAxon[keyof TAxon]>[] | void>;
|
|
52
68
|
|
|
53
|
-
type TCNSNeuron<
|
|
69
|
+
type TCNSNeuron<TAxonType extends TCNSAxon = TCNSAxon> = {
|
|
70
|
+
readonly index: number;
|
|
54
71
|
axon: TAxonType;
|
|
55
72
|
/** Optional per-neuron concurrency limit. If undefined or <= 0, no limit is applied. */
|
|
56
73
|
concurrency?: number;
|
|
57
74
|
/** Optional per-neuron max processing duration in milliseconds. */
|
|
58
75
|
maxDuration?: number;
|
|
59
|
-
dendrites: TCNSDendrite<
|
|
76
|
+
dendrites: TCNSDendrite<ICNSCollateral<unknown>, TAxonType, any>[];
|
|
60
77
|
};
|
|
61
78
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
*/
|
|
70
|
-
autoCleanupContexts?: boolean;
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
interface ICNSStimulationContextStore {
|
|
74
|
-
get: (key: object) => unknown;
|
|
75
|
-
set: (key: object, value: unknown) => void;
|
|
76
|
-
getAll: () => Map<object, unknown>;
|
|
77
|
-
setAll: (values: Map<object, unknown>) => void;
|
|
78
|
-
delete: (key: object) => void;
|
|
79
|
-
}
|
|
79
|
+
/**
|
|
80
|
+
* Options bag for `new CNS(...)`. Currently empty — the former
|
|
81
|
+
* `autoCleanupContexts` flag was removed together with the per-neuron mutable
|
|
82
|
+
* context store. Kept as a named type so the constructor signature and future
|
|
83
|
+
* engine-level options have a stable home.
|
|
84
|
+
*/
|
|
85
|
+
type TCNSOptions = Record<never, never>;
|
|
80
86
|
|
|
81
87
|
type TCNSModality = {
|
|
88
|
+
readonly index: number;
|
|
82
89
|
afferentPaths: Record<string | number, TCNSAfferentPath>;
|
|
83
90
|
};
|
|
84
91
|
|
|
@@ -86,6 +93,20 @@ type TCNSNeuronActivationTask<TNeuron extends object = object, TCollateral exten
|
|
|
86
93
|
neuron: TNeuron;
|
|
87
94
|
dendriteCollateral: TCollateral;
|
|
88
95
|
input?: TCNSSignal<TCollateral>;
|
|
96
|
+
/**
|
|
97
|
+
* Data attached to THIS activation, in namespaced compartments — the
|
|
98
|
+
* per-activation sibling of `stimulationContext`.
|
|
99
|
+
*
|
|
100
|
+
* A response listener can write here before the activation runs (the engine
|
|
101
|
+
* builds these tasks first and hands them to the listener on the response),
|
|
102
|
+
* and the dendrite reads them back as `ctx.activationContext`.
|
|
103
|
+
*
|
|
104
|
+
* Compartment keys are strings, by convention the writer's package name, so
|
|
105
|
+
* an integration and your own code cannot overwrite each other. What is
|
|
106
|
+
* portable travels with the serialized frontier; a live handle does not —
|
|
107
|
+
* see `portable()` in `@cnstra/persist`.
|
|
108
|
+
*/
|
|
109
|
+
activationContext?: TCNSContextStore;
|
|
89
110
|
};
|
|
90
111
|
|
|
91
112
|
type TCNSNeuronActivationTaskFailure<TNeuron extends object = object> = {
|
|
@@ -100,7 +121,7 @@ type TCNSNeuronActivationTaskFailure<TNeuron extends object = object> = {
|
|
|
100
121
|
* `CNSStimulation` class in `@cnstra/core` implements it; internal enqueue/dispatch
|
|
101
122
|
* methods are intentionally not part of the public interface.
|
|
102
123
|
*/
|
|
103
|
-
interface ICNSStimulation<TNeuron extends TCNSNeuron<any
|
|
124
|
+
interface ICNSStimulation<TNeuron extends TCNSNeuron<any>, TDendrite extends TCNSDendrite<any, any> = TCNSDendrite<any, any>> {
|
|
104
125
|
/** Resolves when the run completes; rejects on failed tasks / abort. */
|
|
105
126
|
waitUntilComplete(): Promise<void>;
|
|
106
127
|
/** All activation tasks seen this run. */
|
|
@@ -112,47 +133,32 @@ interface ICNSStimulation<TNeuron extends TCNSNeuron<any, any>, TDendrite extend
|
|
|
112
133
|
* pending) plus failed/aborted ones. The set to persist for resume.
|
|
113
134
|
*/
|
|
114
135
|
getOutstandingTasks(): TCNSNeuronActivationTask<TNeuron>[];
|
|
115
|
-
/** The per-neuron context store for this run. */
|
|
116
|
-
getContext(): ICNSStimulationContextStore;
|
|
117
136
|
}
|
|
118
137
|
|
|
119
138
|
/**
|
|
120
|
-
* Announced when a stimulation's synchronous turn ends
|
|
121
|
-
* without yielding to the event loop has run, and what remains (if anything) is
|
|
122
|
-
* waiting on a promise or blocked by a concurrency limit.
|
|
123
|
-
*
|
|
124
|
-
* This is the batch boundary. It is a property of the scheduler loop exhausting,
|
|
125
|
-
* not of any individual activation starting or finishing - which is why it cannot
|
|
126
|
-
* be derived from `onResponse`. A turn ends in six ways, and a response is only
|
|
127
|
-
* emitted in the first:
|
|
139
|
+
* Announced when a stimulation's synchronous turn ends — the batch boundary — or, for a turn inside `cns.batch`, when that batch ends.
|
|
128
140
|
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* 6. a per-neuron `setConcurrency` gate forced an activation onto a promise
|
|
141
|
+
* It is a property of the scheduler loop exhausting, not of an activation
|
|
142
|
+
* finishing, so it cannot be derived from `onResponse`: a turn also ends when the
|
|
143
|
+
* last activation returned a promise, when a concurrency limit is reached, on
|
|
144
|
+
* abort, and behind an async listener. Fires once per turn, the final one
|
|
145
|
+
* included.
|
|
135
146
|
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
* The counters carry the same meaning as on `TCNSStimulationResponse`, but they
|
|
140
|
-
* are measured *after* the loop exhausted rather than before the work runs. On a
|
|
141
|
-
* response `pendingActivations` is a forecast; here it is a fact, and a non-zero
|
|
142
|
-
* value can only mean blocked - by a concurrency limit or by an abort - never
|
|
143
|
-
* "about to run".
|
|
147
|
+
* The counters mean what they do on `TCNSStimulationResponse`, but measured after
|
|
148
|
+
* the loop exhausted — so a non-zero `pendingActivations` here is blocked, not
|
|
149
|
+
* about to run.
|
|
144
150
|
*/
|
|
145
151
|
type TCNSStimulationDrain = {
|
|
146
152
|
stimulation: ICNSStimulation<any, any>;
|
|
147
153
|
/** `pendingActivations + activeActivations`. Zero means the stimulation is finished. */
|
|
148
154
|
queueLength: number;
|
|
149
|
-
/** Activations whose dendrite
|
|
155
|
+
/** Activations whose dendrite response has not been invoked. Non-zero here means blocked. */
|
|
150
156
|
pendingActivations: number;
|
|
151
157
|
/** Activations awaiting an unsettled promise. Non-zero means another drain is coming. */
|
|
152
158
|
activeActivations: number;
|
|
153
159
|
};
|
|
154
160
|
|
|
155
|
-
type TCNSStimulationOptions<TResponse
|
|
161
|
+
type TCNSStimulationOptions<TResponse> = {
|
|
156
162
|
maxNeuronHops?: number;
|
|
157
163
|
onResponse?: (response: TResponse) => void | Promise<void>;
|
|
158
164
|
/**
|
|
@@ -173,11 +179,17 @@ type TCNSStimulationOptions<TResponse, TStimulationContext extends Object = {}>
|
|
|
173
179
|
*/
|
|
174
180
|
onDrain?: (drain: TCNSStimulationDrain) => void;
|
|
175
181
|
abortSignal?: AbortSignal;
|
|
176
|
-
ctx?: ICNSStimulationContextStore;
|
|
177
182
|
concurrency?: number;
|
|
178
183
|
modality?: TCNSModality;
|
|
179
184
|
afferentPath?: TCNSAfferentPath;
|
|
180
|
-
|
|
185
|
+
/**
|
|
186
|
+
* Data attached to the whole run, in namespaced compartments — the same
|
|
187
|
+
* object on every hop. Its per-activation sibling is `activationContext`.
|
|
188
|
+
*
|
|
189
|
+
* What is portable travels with the serialized frontier, so a run resumed in
|
|
190
|
+
* another process reads back what the previous attempt left here.
|
|
191
|
+
*/
|
|
192
|
+
stimulationContext?: TCNSContextStore;
|
|
181
193
|
};
|
|
182
194
|
|
|
183
195
|
type TCNSStimulationResponse<TInputCollateral extends ICNSCollateral<unknown> = ICNSCollateral<unknown>, TOutputCollateral extends ICNSCollateral<unknown> = ICNSCollateral<unknown>> = {
|
|
@@ -185,7 +197,6 @@ type TCNSStimulationResponse<TInputCollateral extends ICNSCollateral<unknown> =
|
|
|
185
197
|
outputSignal?: TCNSSignal<TOutputCollateral>;
|
|
186
198
|
modality?: TCNSModality;
|
|
187
199
|
afferentPath?: TCNSAfferentPath;
|
|
188
|
-
contextValue: Map<object, unknown>;
|
|
189
200
|
/**
|
|
190
201
|
* Every activation this stimulation still owns, in any state:
|
|
191
202
|
* `pendingActivations + activeActivations`.
|
|
@@ -209,17 +220,17 @@ type TCNSStimulationResponse<TInputCollateral extends ICNSCollateral<unknown> =
|
|
|
209
220
|
*/
|
|
210
221
|
queueLength: number;
|
|
211
222
|
/**
|
|
212
|
-
* Activations that exist (or are reserved) but whose dendrite
|
|
213
|
-
* been invoked yet: waiting in the ring buffer, created and held before being
|
|
223
|
+
* Activations that exist (or are reserved) but whose dendrite response has
|
|
224
|
+
* not been invoked yet: waiting in the ring buffer, created and held before being
|
|
214
225
|
* enqueued, or reserved by an array fan-out that is still mid-dispatch.
|
|
215
226
|
*
|
|
216
227
|
* Subscribers parked behind an async `onResponse` listener are counted here,
|
|
217
228
|
* not in {@link activeActivations}: the split is by lifecycle stage - whether
|
|
218
|
-
* the
|
|
229
|
+
* the response has started - not by whether something is being awaited.
|
|
219
230
|
*/
|
|
220
231
|
pendingActivations: number;
|
|
221
232
|
/**
|
|
222
|
-
* Activations whose dendrite
|
|
233
|
+
* Activations whose dendrite response has been invoked and returned a promise
|
|
223
234
|
* that has not settled.
|
|
224
235
|
*
|
|
225
236
|
* A synchronous body passes through this state within a single pump
|
|
@@ -234,12 +245,52 @@ type TCNSStimulationResponse<TInputCollateral extends ICNSCollateral<unknown> =
|
|
|
234
245
|
* task's neuron reliably — including for sink/failed tasks that have no output
|
|
235
246
|
* collateral to trace an owner from.
|
|
236
247
|
*/
|
|
237
|
-
neuron?: TCNSNeuron<any
|
|
248
|
+
neuron?: TCNSNeuron<any>;
|
|
238
249
|
error?: Error;
|
|
239
250
|
hops?: number;
|
|
251
|
+
/**
|
|
252
|
+
* When the activation's dendrite response was invoked, in epoch milliseconds.
|
|
253
|
+
*
|
|
254
|
+
* Present for real neuron activations on every path — success, sync throw and
|
|
255
|
+
* async rejection alike. Absent on responses that are not an activation (the
|
|
256
|
+
* entry-signal injection, and the terminal signal emitted on abort).
|
|
257
|
+
*/
|
|
258
|
+
startedAt?: number;
|
|
259
|
+
/**
|
|
260
|
+
* How long the dendrite response took, in milliseconds: the span from
|
|
261
|
+
* {@link startedAt} to the moment the activation settled.
|
|
262
|
+
*
|
|
263
|
+
* This is the only place per-hop latency exists — it is what a trace needs to
|
|
264
|
+
* draw a waterfall and what a metrics layer needs for a latency histogram.
|
|
265
|
+
* Present exactly when {@link startedAt} is.
|
|
266
|
+
*/
|
|
267
|
+
duration?: number;
|
|
268
|
+
/**
|
|
269
|
+
* The activations this response is about to create — built, but not yet run.
|
|
270
|
+
*
|
|
271
|
+
* The engine resolves the subscribers of the output collateral and builds
|
|
272
|
+
* their tasks BEFORE handing the response to a listener, then enqueues those
|
|
273
|
+
* very objects afterwards — on the synchronous path, after an async listener
|
|
274
|
+
* settles, and even after a listener throws. So a listener can write into
|
|
275
|
+
* `task.activationContext` here and the dendrite will read it back as
|
|
276
|
+
* `ctx.activationContext`.
|
|
277
|
+
*
|
|
278
|
+
* Empty on a response that starts nothing: a sink neuron, a failure, the
|
|
279
|
+
* entry injection with no subscribers, the terminal abort signal.
|
|
280
|
+
*/
|
|
281
|
+
scheduledActivationTasks?: readonly TCNSNeuronActivationTask<any>[];
|
|
282
|
+
/**
|
|
283
|
+
* The context store of the activation that produced this response — the same
|
|
284
|
+
* object its own handler reads as `ctx.activationContext`.
|
|
285
|
+
*
|
|
286
|
+
* Here so a recorder can put it in the task's history row without holding the
|
|
287
|
+
* task itself. Undefined when nothing was attached, and on responses that are
|
|
288
|
+
* not an activation.
|
|
289
|
+
*/
|
|
290
|
+
activationContext?: TCNSContextStore;
|
|
240
291
|
};
|
|
241
292
|
|
|
242
|
-
type TCNSSubscriber<TNeuron extends TCNSNeuron<any
|
|
293
|
+
type TCNSSubscriber<TNeuron extends TCNSNeuron<any>, TDendrite extends TCNSDendrite<any, any>> = {
|
|
243
294
|
neuron: TNeuron;
|
|
244
295
|
dendrite: TDendrite;
|
|
245
296
|
};
|
|
@@ -248,7 +299,7 @@ type TCNSSubscriber<TNeuron extends TCNSNeuron<any, any>, TDendrite extends TCNS
|
|
|
248
299
|
* The public contract of the compiled neuron network, exposed on `ICNS.network`.
|
|
249
300
|
* The concrete `CNSNetwork` class in `@cnstra/core` implements it.
|
|
250
301
|
*/
|
|
251
|
-
interface ICNSNetwork<TNeuron extends TCNSNeuron<any
|
|
302
|
+
interface ICNSNetwork<TNeuron extends TCNSNeuron<any>, TDendrite extends TCNSDendrite<any, any> = TCNSDendrite<any, any>> {
|
|
252
303
|
readonly stronglyConnectedComponents: Set<TNeuron>[];
|
|
253
304
|
getSCCSetByNeuron(neuron: TNeuron): Set<TNeuron> | undefined;
|
|
254
305
|
getSccIndexByNeuron(neuron: TNeuron): number | undefined;
|
|
@@ -259,7 +310,7 @@ interface ICNSNetwork<TNeuron extends TCNSNeuron<any, any>, TDendrite extends TC
|
|
|
259
310
|
getSubscribers(collateral: ICNSCollateral<unknown>): TCNSSubscriber<TNeuron, TDendrite>[];
|
|
260
311
|
}
|
|
261
312
|
|
|
262
|
-
interface ICNS<TNeuron extends TCNSNeuron<any
|
|
313
|
+
interface ICNS<TNeuron extends TCNSNeuron<any>, TDendrite extends TCNSDendrite<any, any> = TCNSDendrite<any, any>> {
|
|
263
314
|
options?: TCNSOptions;
|
|
264
315
|
network: ICNSNetwork<TNeuron, TDendrite>;
|
|
265
316
|
/**
|
|
@@ -269,16 +320,18 @@ interface ICNS<TNeuron extends TCNSNeuron<any, any>, TDendrite extends TCNSDendr
|
|
|
269
320
|
addResponseListener(listener: (response: TCNSStimulationResponse) => void): () => void;
|
|
270
321
|
/**
|
|
271
322
|
* Add a global batch-boundary listener applied to all stimulations, called
|
|
272
|
-
* once at the end of every synchronous turn.
|
|
323
|
+
* once at the end of every synchronous turn (inside `batch`, when the batch ends).
|
|
273
324
|
* Returns an unsubscribe function.
|
|
274
325
|
*/
|
|
275
326
|
addDrainListener(listener: (drain: TCNSStimulationDrain) => void): () => void;
|
|
327
|
+
batch<TResult>(run: () => TResult): TResult;
|
|
276
328
|
stimulate(signalOrSignals: TCNSSignal<ICNSCollateral<unknown>> | TCNSSignal<ICNSCollateral<unknown>>[], options?: TCNSStimulationOptions<TCNSStimulationResponse>): ICNSStimulation<TNeuron, TDendrite>;
|
|
277
329
|
/**
|
|
278
330
|
* Resume a run from a set of activation tasks (e.g. an outstanding frontier
|
|
279
331
|
* hydrated from persisted progress, or `getFailedTasks()` for a partial
|
|
280
332
|
* retry). Unlike {@link stimulate}, no entry signal is derived — the given
|
|
281
|
-
* tasks are enqueued directly.
|
|
333
|
+
* tasks are enqueued directly. Each task carries its own input signal (with
|
|
334
|
+
* payload), so re-driving the frontier needs no extra state.
|
|
282
335
|
*/
|
|
283
336
|
activate(tasks: TCNSNeuronActivationTask<TNeuron>[], options?: TCNSStimulationOptions<TCNSStimulationResponse>): ICNSStimulation<TNeuron, TDendrite>;
|
|
284
337
|
}
|
|
@@ -288,20 +341,30 @@ interface ICNS<TNeuron extends TCNSNeuron<any, any>, TDendrite extends TCNSDendr
|
|
|
288
341
|
* lives here. Factory layers add their own fields via the `TExt` extension
|
|
289
342
|
* (see {@link TCNSHandlerContext}), so the base stays clean for neurons that
|
|
290
343
|
* don't opt into anything.
|
|
344
|
+
*
|
|
345
|
+
* Internal building block for {@link TCNSHandlerContext} — not part of the public API.
|
|
291
346
|
*/
|
|
292
|
-
type TCNSHandlerContextBase
|
|
347
|
+
type TCNSHandlerContextBase = {
|
|
293
348
|
abortSignal?: AbortSignal;
|
|
294
349
|
cns?: ICNS<any, any>;
|
|
295
350
|
stimulation?: any;
|
|
296
351
|
/**
|
|
297
|
-
* The
|
|
298
|
-
*
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
* `unknown
|
|
302
|
-
* the read site.
|
|
352
|
+
* The context store of the whole run — what the caller passed as
|
|
353
|
+
* `stimulate(sig, { stimulationContext })` plus whatever the run has written
|
|
354
|
+
* into it since, the same object on every hop in any environment (sync or
|
|
355
|
+
* async, node or browser). Keyed by namespace; the values inside are
|
|
356
|
+
* `unknown`, so cast at the read site.
|
|
303
357
|
*/
|
|
304
|
-
stimulationContext?:
|
|
358
|
+
stimulationContext?: TCNSContextStore;
|
|
359
|
+
/**
|
|
360
|
+
* The context store of the activation currently running — data a response
|
|
361
|
+
* listener attached to THIS activation before it started. Unset when nobody
|
|
362
|
+
* wrote anything.
|
|
363
|
+
*
|
|
364
|
+
* Same shape as {@link stimulationContext}, shorter life: this one is gone
|
|
365
|
+
* when the activation returns.
|
|
366
|
+
*/
|
|
367
|
+
activationContext?: TCNSContextStore;
|
|
305
368
|
};
|
|
306
369
|
/**
|
|
307
370
|
* The `ctx` a dendrite handler receives. `TExt` is whatever the factory layers
|
|
@@ -312,34 +375,11 @@ type TCNSHandlerContextBase<TContextValue> = TCNSLocalContextValueStore<TContext
|
|
|
312
375
|
* The handler signature stays `(payload, axon, ctx)` no matter how many layers
|
|
313
376
|
* you stack; each layer widens the type of `ctx`, never the argument list.
|
|
314
377
|
*/
|
|
315
|
-
type TCNSHandlerContext<
|
|
378
|
+
type TCNSHandlerContext<TExt = unknown> = TCNSHandlerContextBase & TExt;
|
|
316
379
|
|
|
317
|
-
type TCNSDendrite<
|
|
380
|
+
type TCNSDendrite<TSenderCollateral extends ICNSCollateral<unknown>, TAxonType extends TCNSAxon, TExt = unknown> = {
|
|
318
381
|
collateral: TSenderCollateral;
|
|
319
|
-
response: (payload: TSenderCollateral extends ICNSCollateral<infer P> ? P : never, axon: TAxonType, ctx: TCNSHandlerContext<
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
type CNSCollateralLike = ICNSCollateral<unknown>;
|
|
323
|
-
type TCNSNeuronPersistOptions<TNeuron extends TCNSNeuron<unknown, any> = TCNSNeuron<unknown, any>> = {
|
|
324
|
-
name: string;
|
|
325
|
-
neuron: TNeuron;
|
|
326
|
-
};
|
|
327
|
-
type TCNSCollateralPersistOptions<TCollateral extends CNSCollateralLike = CNSCollateralLike> = {
|
|
328
|
-
name: string;
|
|
329
|
-
collateral: TCollateral;
|
|
330
|
-
};
|
|
331
|
-
type TCNSStimulationPersistOptions = {
|
|
332
|
-
stimulationId: string;
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
type TCNSStimulationQueueItem<TNeuron extends TCNSNeuron<any, any>, TDendrite extends TCNSDendrite<any, any, any>, TInputCollateral extends ICNSCollateral<unknown> = ICNSCollateral<unknown>> = {
|
|
336
|
-
neuron: TNeuron;
|
|
337
|
-
subscriber: TCNSSubscriber<TNeuron, TDendrite>;
|
|
338
|
-
inputSignal?: TCNSSignal<TInputCollateral>;
|
|
339
|
-
};
|
|
340
|
-
|
|
341
|
-
type TCNSStimulationSerializedContextValue = {
|
|
342
|
-
[key: string]: unknown;
|
|
382
|
+
response: (payload: TSenderCollateral extends ICNSCollateral<infer P> ? P : never, axon: TAxonType, ctx: TCNSHandlerContext<TExt>) => TCNSNeuronResponseReturn<TAxonType>;
|
|
343
383
|
};
|
|
344
384
|
|
|
345
|
-
export type { ICNS, ICNSCollateral, ICNSNetwork, ICNSStimulation,
|
|
385
|
+
export type { ICNS, ICNSCollateral, ICNSNetwork, ICNSStimulation, TCNSAfferentPath, TCNSAxon, TCNSContextStore, TCNSDendrite, TCNSHandlerContext, TCNSModality, TCNSNeuron, TCNSNeuronActivationTask, TCNSNeuronActivationTaskFailure, TCNSNeuronResponseReturn, TCNSOptions, TCNSSignal, TCNSStimulationDrain, TCNSStimulationOptions, TCNSStimulationResponse, TCNSSubscriber };
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./types/TCNSAfferentPath\";\nexport * from \"./types/TCNSAxon\";\nexport * from \"./types/
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./types/TCNSAfferentPath\";\nexport * from \"./types/TCNSAxon\";\nexport * from \"./types/TCNSContextStore\";\nexport * from \"./types/TCNSDendrite\";\nexport * from \"./types/TCNSHandlerContext\";\nexport * from \"./types/TCNSModality\";\nexport * from \"./types/TCNSNeuron\";\nexport * from \"./types/TCNSNeuronActivationTask\";\nexport * from \"./types/TCNSNeuronActivationTaskFailure\";\nexport * from \"./types/TCNSNeuronResponseReturn\";\nexport * from \"./types/TCNSOptions\";\nexport * from \"./types/TCNSSignal\";\nexport * from \"./types/TCNSStimulationDrain\";\nexport * from \"./types/TCNSStimulationOptions\";\nexport * from \"./types/TCNSStimulationResponse\";\nexport * from \"./types/TCNSSubscriber\";\nexport * from \"./interfaces/ICNS\";\nexport * from \"./interfaces/ICNSCollateral\";\nexport * from \"./interfaces/ICNSNetwork\";\nexport * from \"./interfaces/ICNSStimulation\";\n"],"mappings":";;;;;;;;;;;;;;;AAAA;;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cnstra/types",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Shared TypeScript contract for CNStra: signals, tasks, axons, neuron/collateral/stimulation/network interfaces. Zero runtime — the base package core and integrations build on.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/abaikov/cnstra.git",
|
|
8
|
+
"directory": "packages/types"
|
|
9
|
+
},
|
|
5
10
|
"keywords": ["cnstra", "types", "contract", "interfaces"],
|
|
6
11
|
"main": "dist/index.js",
|
|
7
12
|
"module": "dist/index.mjs",
|
|
@@ -16,6 +21,7 @@
|
|
|
16
21
|
"sideEffects": false,
|
|
17
22
|
"files": ["dist"],
|
|
18
23
|
"scripts": {
|
|
24
|
+
"prepublishOnly": "node ../../scripts/check-drift.mjs --gate",
|
|
19
25
|
"build": "tsup",
|
|
20
26
|
"test:types": "tsc --noEmit",
|
|
21
27
|
"clean": "rm -rf dist"
|