@cnstra/types 0.2.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 +120 -52
- package/dist/index.d.ts +120 -52
- package/dist/index.js.map +1 -1
- package/package.json +6 -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,14 +39,35 @@ 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 TCNSNeuronResponseReturn<TAxon extends TCNSAxon> =
|
|
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>;
|
|
46
68
|
|
|
47
69
|
type TCNSNeuron<TAxonType extends TCNSAxon = TCNSAxon> = {
|
|
70
|
+
readonly index: number;
|
|
48
71
|
axon: TAxonType;
|
|
49
72
|
/** Optional per-neuron concurrency limit. If undefined or <= 0, no limit is applied. */
|
|
50
73
|
concurrency?: number;
|
|
@@ -62,6 +85,7 @@ type TCNSNeuron<TAxonType extends TCNSAxon = TCNSAxon> = {
|
|
|
62
85
|
type TCNSOptions = Record<never, never>;
|
|
63
86
|
|
|
64
87
|
type TCNSModality = {
|
|
88
|
+
readonly index: number;
|
|
65
89
|
afferentPaths: Record<string | number, TCNSAfferentPath>;
|
|
66
90
|
};
|
|
67
91
|
|
|
@@ -69,6 +93,20 @@ type TCNSNeuronActivationTask<TNeuron extends object = object, TCollateral exten
|
|
|
69
93
|
neuron: TNeuron;
|
|
70
94
|
dendriteCollateral: TCollateral;
|
|
71
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;
|
|
72
110
|
};
|
|
73
111
|
|
|
74
112
|
type TCNSNeuronActivationTaskFailure<TNeuron extends object = object> = {
|
|
@@ -98,42 +136,29 @@ interface ICNSStimulation<TNeuron extends TCNSNeuron<any>, TDendrite extends TCN
|
|
|
98
136
|
}
|
|
99
137
|
|
|
100
138
|
/**
|
|
101
|
-
* Announced when a stimulation's synchronous turn ends
|
|
102
|
-
* without yielding to the event loop has run, and what remains (if anything) is
|
|
103
|
-
* waiting on a promise or blocked by a concurrency limit.
|
|
139
|
+
* Announced when a stimulation's synchronous turn ends — the batch boundary — or, for a turn inside `cns.batch`, when that batch ends.
|
|
104
140
|
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
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.
|
|
109
146
|
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* 4. the stimulation was aborted
|
|
114
|
-
* 5. subscribers are parked behind an async `onResponse` listener
|
|
115
|
-
* 6. a per-neuron `setConcurrency` gate forced an activation onto a promise
|
|
116
|
-
*
|
|
117
|
-
* Fires exactly once per turn, including the final one - so a listener that
|
|
118
|
-
* flushes on every drain needs no separate completion handling.
|
|
119
|
-
*
|
|
120
|
-
* The counters carry the same meaning as on `TCNSStimulationResponse`, but they
|
|
121
|
-
* are measured *after* the loop exhausted rather than before the work runs. On a
|
|
122
|
-
* response `pendingActivations` is a forecast; here it is a fact, and a non-zero
|
|
123
|
-
* value can only mean blocked - by a concurrency limit or by an abort - never
|
|
124
|
-
* "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.
|
|
125
150
|
*/
|
|
126
151
|
type TCNSStimulationDrain = {
|
|
127
152
|
stimulation: ICNSStimulation<any, any>;
|
|
128
153
|
/** `pendingActivations + activeActivations`. Zero means the stimulation is finished. */
|
|
129
154
|
queueLength: number;
|
|
130
|
-
/** Activations whose dendrite
|
|
155
|
+
/** Activations whose dendrite response has not been invoked. Non-zero here means blocked. */
|
|
131
156
|
pendingActivations: number;
|
|
132
157
|
/** Activations awaiting an unsettled promise. Non-zero means another drain is coming. */
|
|
133
158
|
activeActivations: number;
|
|
134
159
|
};
|
|
135
160
|
|
|
136
|
-
type TCNSStimulationOptions<TResponse
|
|
161
|
+
type TCNSStimulationOptions<TResponse> = {
|
|
137
162
|
maxNeuronHops?: number;
|
|
138
163
|
onResponse?: (response: TResponse) => void | Promise<void>;
|
|
139
164
|
/**
|
|
@@ -157,7 +182,14 @@ type TCNSStimulationOptions<TResponse, TStimulationContext extends Object = {}>
|
|
|
157
182
|
concurrency?: number;
|
|
158
183
|
modality?: TCNSModality;
|
|
159
184
|
afferentPath?: TCNSAfferentPath;
|
|
160
|
-
|
|
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;
|
|
161
193
|
};
|
|
162
194
|
|
|
163
195
|
type TCNSStimulationResponse<TInputCollateral extends ICNSCollateral<unknown> = ICNSCollateral<unknown>, TOutputCollateral extends ICNSCollateral<unknown> = ICNSCollateral<unknown>> = {
|
|
@@ -188,17 +220,17 @@ type TCNSStimulationResponse<TInputCollateral extends ICNSCollateral<unknown> =
|
|
|
188
220
|
*/
|
|
189
221
|
queueLength: number;
|
|
190
222
|
/**
|
|
191
|
-
* Activations that exist (or are reserved) but whose dendrite
|
|
192
|
-
* 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
|
|
193
225
|
* enqueued, or reserved by an array fan-out that is still mid-dispatch.
|
|
194
226
|
*
|
|
195
227
|
* Subscribers parked behind an async `onResponse` listener are counted here,
|
|
196
228
|
* not in {@link activeActivations}: the split is by lifecycle stage - whether
|
|
197
|
-
* the
|
|
229
|
+
* the response has started - not by whether something is being awaited.
|
|
198
230
|
*/
|
|
199
231
|
pendingActivations: number;
|
|
200
232
|
/**
|
|
201
|
-
* Activations whose dendrite
|
|
233
|
+
* Activations whose dendrite response has been invoked and returned a promise
|
|
202
234
|
* that has not settled.
|
|
203
235
|
*
|
|
204
236
|
* A synchronous body passes through this state within a single pump
|
|
@@ -216,6 +248,46 @@ type TCNSStimulationResponse<TInputCollateral extends ICNSCollateral<unknown> =
|
|
|
216
248
|
neuron?: TCNSNeuron<any>;
|
|
217
249
|
error?: Error;
|
|
218
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;
|
|
219
291
|
};
|
|
220
292
|
|
|
221
293
|
type TCNSSubscriber<TNeuron extends TCNSNeuron<any>, TDendrite extends TCNSDendrite<any, any>> = {
|
|
@@ -248,10 +320,11 @@ interface ICNS<TNeuron extends TCNSNeuron<any>, TDendrite extends TCNSDendrite<a
|
|
|
248
320
|
addResponseListener(listener: (response: TCNSStimulationResponse) => void): () => void;
|
|
249
321
|
/**
|
|
250
322
|
* Add a global batch-boundary listener applied to all stimulations, called
|
|
251
|
-
* once at the end of every synchronous turn.
|
|
323
|
+
* once at the end of every synchronous turn (inside `batch`, when the batch ends).
|
|
252
324
|
* Returns an unsubscribe function.
|
|
253
325
|
*/
|
|
254
326
|
addDrainListener(listener: (drain: TCNSStimulationDrain) => void): () => void;
|
|
327
|
+
batch<TResult>(run: () => TResult): TResult;
|
|
255
328
|
stimulate(signalOrSignals: TCNSSignal<ICNSCollateral<unknown>> | TCNSSignal<ICNSCollateral<unknown>>[], options?: TCNSStimulationOptions<TCNSStimulationResponse>): ICNSStimulation<TNeuron, TDendrite>;
|
|
256
329
|
/**
|
|
257
330
|
* Resume a run from a set of activation tasks (e.g. an outstanding frontier
|
|
@@ -276,14 +349,22 @@ type TCNSHandlerContextBase = {
|
|
|
276
349
|
cns?: ICNS<any, any>;
|
|
277
350
|
stimulation?: any;
|
|
278
351
|
/**
|
|
279
|
-
* The
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
* `unknown
|
|
284
|
-
* 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.
|
|
285
357
|
*/
|
|
286
|
-
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;
|
|
287
368
|
};
|
|
288
369
|
/**
|
|
289
370
|
* The `ctx` a dendrite handler receives. `TExt` is whatever the factory layers
|
|
@@ -301,17 +382,4 @@ type TCNSDendrite<TSenderCollateral extends ICNSCollateral<unknown>, TAxonType e
|
|
|
301
382
|
response: (payload: TSenderCollateral extends ICNSCollateral<infer P> ? P : never, axon: TAxonType, ctx: TCNSHandlerContext<TExt>) => TCNSNeuronResponseReturn<TAxonType>;
|
|
302
383
|
};
|
|
303
384
|
|
|
304
|
-
type
|
|
305
|
-
type TCNSNeuronPersistOptions<TNeuron extends TCNSNeuron<any> = TCNSNeuron<any>> = {
|
|
306
|
-
name: string;
|
|
307
|
-
neuron: TNeuron;
|
|
308
|
-
};
|
|
309
|
-
type TCNSCollateralPersistOptions<TCollateral extends CNSCollateralLike = CNSCollateralLike> = {
|
|
310
|
-
name: string;
|
|
311
|
-
collateral: TCollateral;
|
|
312
|
-
};
|
|
313
|
-
type TCNSStimulationPersistOptions = {
|
|
314
|
-
stimulationId: string;
|
|
315
|
-
};
|
|
316
|
-
|
|
317
|
-
export type { ICNS, ICNSCollateral, ICNSNetwork, ICNSStimulation, TCNSAfferentPath, TCNSAxon, TCNSCollateralPersistOptions, TCNSDendrite, TCNSHandlerContext, TCNSModality, TCNSNeuron, TCNSNeuronActivationTask, TCNSNeuronActivationTaskFailure, TCNSNeuronPersistOptions, TCNSNeuronResponseReturn, TCNSOptions, TCNSSignal, TCNSStimulationDrain, TCNSStimulationOptions, TCNSStimulationPersistOptions, TCNSStimulationResponse, TCNSSubscriber };
|
|
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,14 +39,35 @@ 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 TCNSNeuronResponseReturn<TAxon extends TCNSAxon> =
|
|
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>;
|
|
46
68
|
|
|
47
69
|
type TCNSNeuron<TAxonType extends TCNSAxon = TCNSAxon> = {
|
|
70
|
+
readonly index: number;
|
|
48
71
|
axon: TAxonType;
|
|
49
72
|
/** Optional per-neuron concurrency limit. If undefined or <= 0, no limit is applied. */
|
|
50
73
|
concurrency?: number;
|
|
@@ -62,6 +85,7 @@ type TCNSNeuron<TAxonType extends TCNSAxon = TCNSAxon> = {
|
|
|
62
85
|
type TCNSOptions = Record<never, never>;
|
|
63
86
|
|
|
64
87
|
type TCNSModality = {
|
|
88
|
+
readonly index: number;
|
|
65
89
|
afferentPaths: Record<string | number, TCNSAfferentPath>;
|
|
66
90
|
};
|
|
67
91
|
|
|
@@ -69,6 +93,20 @@ type TCNSNeuronActivationTask<TNeuron extends object = object, TCollateral exten
|
|
|
69
93
|
neuron: TNeuron;
|
|
70
94
|
dendriteCollateral: TCollateral;
|
|
71
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;
|
|
72
110
|
};
|
|
73
111
|
|
|
74
112
|
type TCNSNeuronActivationTaskFailure<TNeuron extends object = object> = {
|
|
@@ -98,42 +136,29 @@ interface ICNSStimulation<TNeuron extends TCNSNeuron<any>, TDendrite extends TCN
|
|
|
98
136
|
}
|
|
99
137
|
|
|
100
138
|
/**
|
|
101
|
-
* Announced when a stimulation's synchronous turn ends
|
|
102
|
-
* without yielding to the event loop has run, and what remains (if anything) is
|
|
103
|
-
* waiting on a promise or blocked by a concurrency limit.
|
|
139
|
+
* Announced when a stimulation's synchronous turn ends — the batch boundary — or, for a turn inside `cns.batch`, when that batch ends.
|
|
104
140
|
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
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.
|
|
109
146
|
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* 4. the stimulation was aborted
|
|
114
|
-
* 5. subscribers are parked behind an async `onResponse` listener
|
|
115
|
-
* 6. a per-neuron `setConcurrency` gate forced an activation onto a promise
|
|
116
|
-
*
|
|
117
|
-
* Fires exactly once per turn, including the final one - so a listener that
|
|
118
|
-
* flushes on every drain needs no separate completion handling.
|
|
119
|
-
*
|
|
120
|
-
* The counters carry the same meaning as on `TCNSStimulationResponse`, but they
|
|
121
|
-
* are measured *after* the loop exhausted rather than before the work runs. On a
|
|
122
|
-
* response `pendingActivations` is a forecast; here it is a fact, and a non-zero
|
|
123
|
-
* value can only mean blocked - by a concurrency limit or by an abort - never
|
|
124
|
-
* "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.
|
|
125
150
|
*/
|
|
126
151
|
type TCNSStimulationDrain = {
|
|
127
152
|
stimulation: ICNSStimulation<any, any>;
|
|
128
153
|
/** `pendingActivations + activeActivations`. Zero means the stimulation is finished. */
|
|
129
154
|
queueLength: number;
|
|
130
|
-
/** Activations whose dendrite
|
|
155
|
+
/** Activations whose dendrite response has not been invoked. Non-zero here means blocked. */
|
|
131
156
|
pendingActivations: number;
|
|
132
157
|
/** Activations awaiting an unsettled promise. Non-zero means another drain is coming. */
|
|
133
158
|
activeActivations: number;
|
|
134
159
|
};
|
|
135
160
|
|
|
136
|
-
type TCNSStimulationOptions<TResponse
|
|
161
|
+
type TCNSStimulationOptions<TResponse> = {
|
|
137
162
|
maxNeuronHops?: number;
|
|
138
163
|
onResponse?: (response: TResponse) => void | Promise<void>;
|
|
139
164
|
/**
|
|
@@ -157,7 +182,14 @@ type TCNSStimulationOptions<TResponse, TStimulationContext extends Object = {}>
|
|
|
157
182
|
concurrency?: number;
|
|
158
183
|
modality?: TCNSModality;
|
|
159
184
|
afferentPath?: TCNSAfferentPath;
|
|
160
|
-
|
|
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;
|
|
161
193
|
};
|
|
162
194
|
|
|
163
195
|
type TCNSStimulationResponse<TInputCollateral extends ICNSCollateral<unknown> = ICNSCollateral<unknown>, TOutputCollateral extends ICNSCollateral<unknown> = ICNSCollateral<unknown>> = {
|
|
@@ -188,17 +220,17 @@ type TCNSStimulationResponse<TInputCollateral extends ICNSCollateral<unknown> =
|
|
|
188
220
|
*/
|
|
189
221
|
queueLength: number;
|
|
190
222
|
/**
|
|
191
|
-
* Activations that exist (or are reserved) but whose dendrite
|
|
192
|
-
* 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
|
|
193
225
|
* enqueued, or reserved by an array fan-out that is still mid-dispatch.
|
|
194
226
|
*
|
|
195
227
|
* Subscribers parked behind an async `onResponse` listener are counted here,
|
|
196
228
|
* not in {@link activeActivations}: the split is by lifecycle stage - whether
|
|
197
|
-
* the
|
|
229
|
+
* the response has started - not by whether something is being awaited.
|
|
198
230
|
*/
|
|
199
231
|
pendingActivations: number;
|
|
200
232
|
/**
|
|
201
|
-
* Activations whose dendrite
|
|
233
|
+
* Activations whose dendrite response has been invoked and returned a promise
|
|
202
234
|
* that has not settled.
|
|
203
235
|
*
|
|
204
236
|
* A synchronous body passes through this state within a single pump
|
|
@@ -216,6 +248,46 @@ type TCNSStimulationResponse<TInputCollateral extends ICNSCollateral<unknown> =
|
|
|
216
248
|
neuron?: TCNSNeuron<any>;
|
|
217
249
|
error?: Error;
|
|
218
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;
|
|
219
291
|
};
|
|
220
292
|
|
|
221
293
|
type TCNSSubscriber<TNeuron extends TCNSNeuron<any>, TDendrite extends TCNSDendrite<any, any>> = {
|
|
@@ -248,10 +320,11 @@ interface ICNS<TNeuron extends TCNSNeuron<any>, TDendrite extends TCNSDendrite<a
|
|
|
248
320
|
addResponseListener(listener: (response: TCNSStimulationResponse) => void): () => void;
|
|
249
321
|
/**
|
|
250
322
|
* Add a global batch-boundary listener applied to all stimulations, called
|
|
251
|
-
* once at the end of every synchronous turn.
|
|
323
|
+
* once at the end of every synchronous turn (inside `batch`, when the batch ends).
|
|
252
324
|
* Returns an unsubscribe function.
|
|
253
325
|
*/
|
|
254
326
|
addDrainListener(listener: (drain: TCNSStimulationDrain) => void): () => void;
|
|
327
|
+
batch<TResult>(run: () => TResult): TResult;
|
|
255
328
|
stimulate(signalOrSignals: TCNSSignal<ICNSCollateral<unknown>> | TCNSSignal<ICNSCollateral<unknown>>[], options?: TCNSStimulationOptions<TCNSStimulationResponse>): ICNSStimulation<TNeuron, TDendrite>;
|
|
256
329
|
/**
|
|
257
330
|
* Resume a run from a set of activation tasks (e.g. an outstanding frontier
|
|
@@ -276,14 +349,22 @@ type TCNSHandlerContextBase = {
|
|
|
276
349
|
cns?: ICNS<any, any>;
|
|
277
350
|
stimulation?: any;
|
|
278
351
|
/**
|
|
279
|
-
* The
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
* `unknown
|
|
284
|
-
* 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.
|
|
285
357
|
*/
|
|
286
|
-
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;
|
|
287
368
|
};
|
|
288
369
|
/**
|
|
289
370
|
* The `ctx` a dendrite handler receives. `TExt` is whatever the factory layers
|
|
@@ -301,17 +382,4 @@ type TCNSDendrite<TSenderCollateral extends ICNSCollateral<unknown>, TAxonType e
|
|
|
301
382
|
response: (payload: TSenderCollateral extends ICNSCollateral<infer P> ? P : never, axon: TAxonType, ctx: TCNSHandlerContext<TExt>) => TCNSNeuronResponseReturn<TAxonType>;
|
|
302
383
|
};
|
|
303
384
|
|
|
304
|
-
type
|
|
305
|
-
type TCNSNeuronPersistOptions<TNeuron extends TCNSNeuron<any> = TCNSNeuron<any>> = {
|
|
306
|
-
name: string;
|
|
307
|
-
neuron: TNeuron;
|
|
308
|
-
};
|
|
309
|
-
type TCNSCollateralPersistOptions<TCollateral extends CNSCollateralLike = CNSCollateralLike> = {
|
|
310
|
-
name: string;
|
|
311
|
-
collateral: TCollateral;
|
|
312
|
-
};
|
|
313
|
-
type TCNSStimulationPersistOptions = {
|
|
314
|
-
stimulationId: string;
|
|
315
|
-
};
|
|
316
|
-
|
|
317
|
-
export type { ICNS, ICNSCollateral, ICNSNetwork, ICNSStimulation, TCNSAfferentPath, TCNSAxon, TCNSCollateralPersistOptions, TCNSDendrite, TCNSHandlerContext, TCNSModality, TCNSNeuron, TCNSNeuronActivationTask, TCNSNeuronActivationTaskFailure, TCNSNeuronPersistOptions, TCNSNeuronResponseReturn, TCNSOptions, TCNSSignal, TCNSStimulationDrain, TCNSStimulationOptions, TCNSStimulationPersistOptions, TCNSStimulationResponse, TCNSSubscriber };
|
|
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.2.
|
|
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",
|