@cnstra/core 2.3.0 → 2.5.0
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/README.md +28 -6
- package/dist/CNS.d.ts +29 -1
- package/dist/CNS.d.ts.map +1 -1
- package/dist/CNSStimulation.d.ts +33 -1
- package/dist/CNSStimulation.d.ts.map +1 -1
- package/dist/factory/index.d.ts +94 -67
- package/dist/factory/index.d.ts.map +1 -1
- package/dist/index.cjs +241 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +239 -49
- package/dist/index.js.map +1 -1
- package/dist/interfaces/ICNS.d.ts +7 -0
- package/dist/interfaces/ICNS.d.ts.map +1 -1
- package/dist/types/TCNSDendrite.d.ts +3 -8
- package/dist/types/TCNSDendrite.d.ts.map +1 -1
- package/dist/types/TCNSHandlerContext.d.ts +24 -0
- package/dist/types/TCNSHandlerContext.d.ts.map +1 -0
- package/dist/types/TCNSNeuron.d.ts +1 -1
- package/dist/types/TCNSNeuron.d.ts.map +1 -1
- package/dist/types/TCNSStimulationDrain.d.ts +37 -0
- package/dist/types/TCNSStimulationDrain.d.ts.map +1 -0
- package/dist/types/TCNSStimulationOptions.d.ts +18 -0
- package/dist/types/TCNSStimulationOptions.d.ts.map +1 -1
- package/dist/types/TCNSStimulationResponse.d.ts +40 -0
- package/dist/types/TCNSStimulationResponse.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -33,6 +33,12 @@ var CNSDendriteContext = class {
|
|
|
33
33
|
this.abortSignal = abortSignal;
|
|
34
34
|
this.cns = cns;
|
|
35
35
|
}
|
|
36
|
+
// Prototype getter, not a constructor field: the per-activation allocation is
|
|
37
|
+
// unchanged (still 4 fields) and you only pay a single `cns.global` read on the
|
|
38
|
+
// dendrites that actually reach for it. Value getter, so `{ global }` destructuring is safe.
|
|
39
|
+
get global() {
|
|
40
|
+
return this.cns.global;
|
|
41
|
+
}
|
|
36
42
|
get() {
|
|
37
43
|
return this.stimulation.getContext().get(this.neuron);
|
|
38
44
|
}
|
|
@@ -44,12 +50,14 @@ var CNSDendriteContext = class {
|
|
|
44
50
|
}
|
|
45
51
|
};
|
|
46
52
|
var CNSStimulationResponseImpl = class {
|
|
47
|
-
constructor(stimulation, store, inputSignal, outputSignal, queueLength, hops, error) {
|
|
53
|
+
constructor(stimulation, store, inputSignal, outputSignal, queueLength, pendingActivations, activeActivations, hops, error) {
|
|
48
54
|
this.stimulation = stimulation;
|
|
49
55
|
this.store = store;
|
|
50
56
|
this.inputSignal = inputSignal;
|
|
51
57
|
this.outputSignal = outputSignal;
|
|
52
58
|
this.queueLength = queueLength;
|
|
59
|
+
this.pendingActivations = pendingActivations;
|
|
60
|
+
this.activeActivations = activeActivations;
|
|
53
61
|
this.hops = hops;
|
|
54
62
|
this.error = error;
|
|
55
63
|
}
|
|
@@ -58,7 +66,7 @@ var CNSStimulationResponseImpl = class {
|
|
|
58
66
|
}
|
|
59
67
|
};
|
|
60
68
|
var CNSStimulation = class {
|
|
61
|
-
constructor(cns, instanceNeuronQueue, options, onResponse) {
|
|
69
|
+
constructor(cns, instanceNeuronQueue, options, onResponse, onDrain) {
|
|
62
70
|
this.cns = cns;
|
|
63
71
|
this.options = options;
|
|
64
72
|
this.qHead = 0;
|
|
@@ -69,9 +77,20 @@ var CNSStimulation = class {
|
|
|
69
77
|
// Re-entrancy guard for the pump loop.
|
|
70
78
|
this.pumping = false;
|
|
71
79
|
this.needsPump = false;
|
|
80
|
+
// Nesting depth of the current synchronous turn. Only the outermost close
|
|
81
|
+
// announces a drain - see beginTurn/endTurn.
|
|
82
|
+
this.turnDepth = 0;
|
|
72
83
|
this.scheduledCount = 0;
|
|
84
|
+
// Activations belonging to signals of an in-progress array fan-out that have
|
|
85
|
+
// not been handed to processResponse yet, so the task objects do not exist.
|
|
86
|
+
// processResponse enqueues synchronously, so the first signal's whole subtree
|
|
87
|
+
// drains before the second signal is even looked at; without this counter
|
|
88
|
+
// that subtree's leaf sees an empty queue and reads as "all work done".
|
|
89
|
+
// Counted in activations, not signals, so every public counter shares a unit.
|
|
90
|
+
this.reservedActivations = 0;
|
|
73
91
|
this.isCompleted = false;
|
|
74
92
|
this.completionRejected = false;
|
|
93
|
+
this.onDrain = onDrain;
|
|
75
94
|
this.ctxStore = options?.ctx;
|
|
76
95
|
this.instanceNeuronQueue = instanceNeuronQueue;
|
|
77
96
|
this.onResponse = onResponse;
|
|
@@ -168,18 +187,28 @@ var CNSStimulation = class {
|
|
|
168
187
|
(cb) => {
|
|
169
188
|
this.activeOperations--;
|
|
170
189
|
this.activeTasks.delete(task);
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
if (
|
|
174
|
-
|
|
190
|
+
this.beginTurn();
|
|
191
|
+
try {
|
|
192
|
+
if (typeof cb === "function") cb();
|
|
193
|
+
if (this.qSize > 0 && this.canStartOperation) {
|
|
194
|
+
if (this.pumping) this.needsPump = true;
|
|
195
|
+
else this.pump();
|
|
196
|
+
}
|
|
197
|
+
} finally {
|
|
198
|
+
this.endTurn();
|
|
175
199
|
}
|
|
176
200
|
},
|
|
177
201
|
(err) => {
|
|
178
202
|
this.activeOperations--;
|
|
179
203
|
this.activeTasks.delete(task);
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
204
|
+
this.beginTurn();
|
|
205
|
+
try {
|
|
206
|
+
if (this.qSize > 0 && this.canStartOperation) {
|
|
207
|
+
if (this.pumping) this.needsPump = true;
|
|
208
|
+
else this.pump();
|
|
209
|
+
}
|
|
210
|
+
} finally {
|
|
211
|
+
this.endTurn();
|
|
183
212
|
}
|
|
184
213
|
throw err;
|
|
185
214
|
}
|
|
@@ -195,10 +224,54 @@ var CNSStimulation = class {
|
|
|
195
224
|
this.pump();
|
|
196
225
|
}
|
|
197
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* Open a synchronous turn. Turns nest: a drain is announced only when the
|
|
229
|
+
* outermost one closes, so an enqueue that happens while the pump is already
|
|
230
|
+
* running does not produce its own boundary.
|
|
231
|
+
*/
|
|
232
|
+
beginTurn() {
|
|
233
|
+
this.turnDepth++;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Close a synchronous turn and, if it was the outermost and nothing more can
|
|
237
|
+
* run without yielding to the event loop, announce the drain.
|
|
238
|
+
*
|
|
239
|
+
* This is the only place the synchronous frontier is observable. A response
|
|
240
|
+
* cannot serve the purpose: responses are emitted when an activation
|
|
241
|
+
* *finishes*, but a turn just as often ends when one *starts* and returns a
|
|
242
|
+
* promise - at which point there is nothing left to emit a response from.
|
|
243
|
+
*/
|
|
244
|
+
endTurn() {
|
|
245
|
+
if (--this.turnDepth > 0) return;
|
|
246
|
+
const onDrain = this.onDrain;
|
|
247
|
+
if (!onDrain) return;
|
|
248
|
+
if (this.pumping) return;
|
|
249
|
+
if (this.qSize > 0 && this.canStartOperation) return;
|
|
250
|
+
this.turnDepth++;
|
|
251
|
+
try {
|
|
252
|
+
onDrain({
|
|
253
|
+
stimulation: this,
|
|
254
|
+
queueLength: this.pendingActivations + this.activeOperations,
|
|
255
|
+
pendingActivations: this.pendingActivations,
|
|
256
|
+
activeActivations: this.activeOperations
|
|
257
|
+
});
|
|
258
|
+
} finally {
|
|
259
|
+
this.turnDepth--;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Activations that exist (or are reserved) but whose dendrite body has not
|
|
264
|
+
* been invoked yet: sitting in the ring buffer, created and held in
|
|
265
|
+
* pendingTasks, or reserved by an array fan-out mid-dispatch. Subscribers
|
|
266
|
+
* parked behind an async onResponse land here too - their body has not run.
|
|
267
|
+
*/
|
|
268
|
+
get pendingActivations() {
|
|
269
|
+
return this.qSize + this.scheduledCount + this.reservedActivations;
|
|
270
|
+
}
|
|
198
271
|
tryResolveCompleted() {
|
|
199
272
|
if (this.isCompleted) return;
|
|
200
273
|
const noActive = this.activeOperations === 0;
|
|
201
|
-
const noPending = this.
|
|
274
|
+
const noPending = this.pendingActivations === 0;
|
|
202
275
|
const aborted = !!this.options?.abortSignal?.aborted;
|
|
203
276
|
if (noPending && noActive || aborted && noActive && !noPending) {
|
|
204
277
|
if (aborted) {
|
|
@@ -270,10 +343,15 @@ var CNSStimulation = class {
|
|
|
270
343
|
* Enqueue activation tasks directly into the stimulation queue
|
|
271
344
|
*/
|
|
272
345
|
enqueueTasks(tasks) {
|
|
273
|
-
|
|
274
|
-
|
|
346
|
+
this.beginTurn();
|
|
347
|
+
try {
|
|
348
|
+
for (const task of tasks) {
|
|
349
|
+
this.qEnqueue(task);
|
|
350
|
+
}
|
|
351
|
+
this.tryResolveCompleted();
|
|
352
|
+
} finally {
|
|
353
|
+
this.endTurn();
|
|
275
354
|
}
|
|
276
|
-
this.tryResolveCompleted();
|
|
277
355
|
}
|
|
278
356
|
get concurrencyEnabled() {
|
|
279
357
|
return this.options?.concurrency !== void 0 && this.options?.concurrency > 0;
|
|
@@ -374,14 +452,19 @@ var CNSStimulation = class {
|
|
|
374
452
|
}
|
|
375
453
|
}
|
|
376
454
|
if (!subscriber) {
|
|
455
|
+
const error = new Error(`Subscriber not found for activation task`);
|
|
377
456
|
this.pushFailedTask({
|
|
378
457
|
task: neuronActivationTask,
|
|
379
|
-
error
|
|
380
|
-
`Subscriber not found for activation task`
|
|
381
|
-
),
|
|
458
|
+
error,
|
|
382
459
|
aborted: false
|
|
383
460
|
});
|
|
384
461
|
return () => {
|
|
462
|
+
this.processResponseOrResponses(
|
|
463
|
+
void 0,
|
|
464
|
+
neuronActivationTask.input,
|
|
465
|
+
void 0,
|
|
466
|
+
error
|
|
467
|
+
);
|
|
385
468
|
};
|
|
386
469
|
}
|
|
387
470
|
const neuron2 = subscriber.neuron;
|
|
@@ -428,13 +511,13 @@ var CNSStimulation = class {
|
|
|
428
511
|
error: error instanceof Error ? error : new Error(String(error)),
|
|
429
512
|
aborted: isAborted
|
|
430
513
|
});
|
|
431
|
-
this.processResponseOrResponses(
|
|
432
|
-
neuron2,
|
|
433
|
-
inputSignal,
|
|
434
|
-
void 0,
|
|
435
|
-
error
|
|
436
|
-
);
|
|
437
514
|
return () => {
|
|
515
|
+
this.processResponseOrResponses(
|
|
516
|
+
neuron2,
|
|
517
|
+
inputSignal,
|
|
518
|
+
void 0,
|
|
519
|
+
error
|
|
520
|
+
);
|
|
438
521
|
};
|
|
439
522
|
}
|
|
440
523
|
const maxDuration = neuron2.maxDuration;
|
|
@@ -504,8 +587,26 @@ var CNSStimulation = class {
|
|
|
504
587
|
this.processResponse(emitter, inputSignal, void 0, error);
|
|
505
588
|
return;
|
|
506
589
|
}
|
|
507
|
-
|
|
508
|
-
|
|
590
|
+
let perSignal;
|
|
591
|
+
if (!error) {
|
|
592
|
+
perSignal = new Array(outputSignalOrSignals.length);
|
|
593
|
+
let reserved = 0;
|
|
594
|
+
for (let i = 0; i < outputSignalOrSignals.length; i++) {
|
|
595
|
+
const c = outputSignalOrSignals[i]?.collateral;
|
|
596
|
+
const n = c ? this.cns.network.getSubscribers(c).length : 0;
|
|
597
|
+
perSignal[i] = n;
|
|
598
|
+
reserved += n;
|
|
599
|
+
}
|
|
600
|
+
this.reservedActivations += reserved;
|
|
601
|
+
}
|
|
602
|
+
for (let i = 0; i < outputSignalOrSignals.length; i++) {
|
|
603
|
+
if (perSignal) this.reservedActivations -= perSignal[i];
|
|
604
|
+
this.processResponse(
|
|
605
|
+
emitter,
|
|
606
|
+
inputSignal,
|
|
607
|
+
outputSignalOrSignals[i],
|
|
608
|
+
error
|
|
609
|
+
);
|
|
509
610
|
}
|
|
510
611
|
return;
|
|
511
612
|
}
|
|
@@ -559,7 +660,9 @@ var CNSStimulation = class {
|
|
|
559
660
|
this.ctxStore,
|
|
560
661
|
inputSignal,
|
|
561
662
|
outputSignal,
|
|
562
|
-
this.
|
|
663
|
+
this.pendingActivations + this.activeOperations,
|
|
664
|
+
this.pendingActivations,
|
|
665
|
+
this.activeOperations,
|
|
563
666
|
this.options?.maxNeuronHops && emitter ? this.neuronVisitMap?.get(emitter) ?? 0 : void 0,
|
|
564
667
|
error
|
|
565
668
|
)
|
|
@@ -577,21 +680,35 @@ var CNSStimulation = class {
|
|
|
577
680
|
if (maybePromise && typeof maybePromise.then === "function") {
|
|
578
681
|
maybePromise.then(
|
|
579
682
|
() => {
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
683
|
+
this.beginTurn();
|
|
684
|
+
try {
|
|
685
|
+
for (let i = 0; i < subscriberActivationTasks.length; i++) {
|
|
686
|
+
this.scheduledCount--;
|
|
687
|
+
this.pendingTasks?.delete(
|
|
688
|
+
subscriberActivationTasks[i]
|
|
689
|
+
);
|
|
690
|
+
this.qEnqueue(subscriberActivationTasks[i]);
|
|
691
|
+
}
|
|
692
|
+
this.tryResolveCompleted();
|
|
693
|
+
} finally {
|
|
694
|
+
this.endTurn();
|
|
584
695
|
}
|
|
585
|
-
this.tryResolveCompleted();
|
|
586
696
|
},
|
|
587
697
|
(error2) => {
|
|
588
698
|
this.onResponseError = error2 instanceof Error ? error2 : new Error(String(error2));
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
699
|
+
this.beginTurn();
|
|
700
|
+
try {
|
|
701
|
+
for (let i = 0; i < subscriberActivationTasks.length; i++) {
|
|
702
|
+
this.scheduledCount--;
|
|
703
|
+
this.pendingTasks?.delete(
|
|
704
|
+
subscriberActivationTasks[i]
|
|
705
|
+
);
|
|
706
|
+
this.qEnqueue(subscriberActivationTasks[i]);
|
|
707
|
+
}
|
|
708
|
+
this.tryResolveCompleted();
|
|
709
|
+
} finally {
|
|
710
|
+
this.endTurn();
|
|
593
711
|
}
|
|
594
|
-
this.tryResolveCompleted();
|
|
595
712
|
}
|
|
596
713
|
);
|
|
597
714
|
return;
|
|
@@ -604,12 +721,21 @@ var CNSStimulation = class {
|
|
|
604
721
|
this.tryResolveCompleted();
|
|
605
722
|
}
|
|
606
723
|
responseToSignal(signalOrSignals) {
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
724
|
+
this.beginTurn();
|
|
725
|
+
try {
|
|
726
|
+
if (Array.isArray(signalOrSignals)) {
|
|
727
|
+
this.processResponseOrResponses(
|
|
728
|
+
void 0,
|
|
729
|
+
void 0,
|
|
730
|
+
signalOrSignals
|
|
731
|
+
);
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
this.processResponse(void 0, void 0, signalOrSignals);
|
|
735
|
+
this.tryResolveCompleted();
|
|
736
|
+
} finally {
|
|
737
|
+
this.endTurn();
|
|
610
738
|
}
|
|
611
|
-
this.processResponse(void 0, void 0, signalOrSignals);
|
|
612
|
-
this.tryResolveCompleted();
|
|
613
739
|
}
|
|
614
740
|
};
|
|
615
741
|
|
|
@@ -944,7 +1070,7 @@ var CNSNetwork = class {
|
|
|
944
1070
|
|
|
945
1071
|
// src/CNS.ts
|
|
946
1072
|
var CNS = class {
|
|
947
|
-
constructor(neurons, options) {
|
|
1073
|
+
constructor(neurons, options, global) {
|
|
948
1074
|
this.neurons = neurons;
|
|
949
1075
|
this.options = options;
|
|
950
1076
|
/**
|
|
@@ -956,7 +1082,12 @@ var CNS = class {
|
|
|
956
1082
|
* Global response listeners applied to every stimulation.
|
|
957
1083
|
*/
|
|
958
1084
|
this.globalResponseListeners = [];
|
|
1085
|
+
/**
|
|
1086
|
+
* Global batch-boundary listeners applied to every stimulation.
|
|
1087
|
+
*/
|
|
1088
|
+
this.globalDrainListeners = [];
|
|
959
1089
|
this.network = new CNSNetwork(this.neurons);
|
|
1090
|
+
this.global = global;
|
|
960
1091
|
}
|
|
961
1092
|
addResponseListener(listener) {
|
|
962
1093
|
this.globalResponseListeners.push(listener);
|
|
@@ -968,6 +1099,50 @@ var CNS = class {
|
|
|
968
1099
|
if (idx >= 0) this.globalResponseListeners.splice(idx, 1);
|
|
969
1100
|
};
|
|
970
1101
|
}
|
|
1102
|
+
/**
|
|
1103
|
+
* Register a listener called once at the end of every synchronous turn of
|
|
1104
|
+
* every stimulation - see {@link TCNSStimulationDrain}. This is how an
|
|
1105
|
+
* integration (a state manager, an in-memory database) installs a single
|
|
1106
|
+
* commit point for the whole organism instead of passing `onDrain` per call.
|
|
1107
|
+
*
|
|
1108
|
+
* Returns an unsubscribe function.
|
|
1109
|
+
*/
|
|
1110
|
+
addDrainListener(listener) {
|
|
1111
|
+
this.globalDrainListeners.push(listener);
|
|
1112
|
+
let active = true;
|
|
1113
|
+
return () => {
|
|
1114
|
+
if (!active) return;
|
|
1115
|
+
active = false;
|
|
1116
|
+
const idx = this.globalDrainListeners.indexOf(listener);
|
|
1117
|
+
if (idx >= 0) this.globalDrainListeners.splice(idx, 1);
|
|
1118
|
+
};
|
|
1119
|
+
}
|
|
1120
|
+
/**
|
|
1121
|
+
* Fan a drain out to the local and global listeners, or return undefined when
|
|
1122
|
+
* there are none so the stimulation can skip the boundary check entirely.
|
|
1123
|
+
*
|
|
1124
|
+
* Listener errors are isolated: a drain is a notification, and one broken
|
|
1125
|
+
* flush must not stop the others or derail the stimulation that triggered it.
|
|
1126
|
+
*/
|
|
1127
|
+
wrapOnDrain(local) {
|
|
1128
|
+
if (this.globalDrainListeners.length === 0 && !local) return void 0;
|
|
1129
|
+
return (d) => {
|
|
1130
|
+
if (local) {
|
|
1131
|
+
try {
|
|
1132
|
+
local(d);
|
|
1133
|
+
} catch (error) {
|
|
1134
|
+
console.error("[CNS] onDrain listener threw", error);
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
for (let i = 0; i < this.globalDrainListeners.length; i++) {
|
|
1138
|
+
try {
|
|
1139
|
+
this.globalDrainListeners[i](d);
|
|
1140
|
+
} catch (error) {
|
|
1141
|
+
console.error("[CNS] drain listener threw", error);
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
971
1146
|
wrapOnResponse(local) {
|
|
972
1147
|
if (this.globalResponseListeners.length === 0 && !local) {
|
|
973
1148
|
return void 0;
|
|
@@ -1015,7 +1190,8 @@ var CNS = class {
|
|
|
1015
1190
|
this,
|
|
1016
1191
|
this.instanceNeuronQueue,
|
|
1017
1192
|
options,
|
|
1018
|
-
wrapped
|
|
1193
|
+
wrapped,
|
|
1194
|
+
this.wrapOnDrain(options?.onDrain)
|
|
1019
1195
|
);
|
|
1020
1196
|
stimulation.responseToSignal(signalOrSignals);
|
|
1021
1197
|
return stimulation;
|
|
@@ -1029,7 +1205,8 @@ var CNS = class {
|
|
|
1029
1205
|
this,
|
|
1030
1206
|
this.instanceNeuronQueue,
|
|
1031
1207
|
options,
|
|
1032
|
-
wrapped
|
|
1208
|
+
wrapped,
|
|
1209
|
+
this.wrapOnDrain(options?.onDrain)
|
|
1033
1210
|
);
|
|
1034
1211
|
stimulation.enqueueTasks(tasks);
|
|
1035
1212
|
return stimulation;
|
|
@@ -1282,11 +1459,16 @@ var neuron = (axon) => {
|
|
|
1282
1459
|
};
|
|
1283
1460
|
return api;
|
|
1284
1461
|
};
|
|
1285
|
-
var
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1462
|
+
var neuronFactory = () => {
|
|
1463
|
+
const factory = {
|
|
1464
|
+
withCtx: () => factory,
|
|
1465
|
+
withGlobal: () => factory,
|
|
1466
|
+
neuron: (axon) => neuron(axon)
|
|
1467
|
+
};
|
|
1468
|
+
return factory;
|
|
1469
|
+
};
|
|
1470
|
+
var withCtx = () => neuronFactory();
|
|
1471
|
+
var withGlobal = () => neuronFactory();
|
|
1290
1472
|
var afferentPath = (parentAfferentPath) => {
|
|
1291
1473
|
return {
|
|
1292
1474
|
...parentAfferentPath !== void 0 && {
|
|
@@ -1315,6 +1497,14 @@ var createPersistRegistry = (namedNeurons) => {
|
|
|
1315
1497
|
}
|
|
1316
1498
|
return registry;
|
|
1317
1499
|
};
|
|
1500
|
+
var createCNS = (namedNeurons, options) => {
|
|
1501
|
+
const neurons = Object.values(namedNeurons).map(
|
|
1502
|
+
(entry) => entry && typeof entry === "object" && "neuron" in entry ? entry.neuron : entry
|
|
1503
|
+
);
|
|
1504
|
+
const cns = new CNS(neurons, options, options?.global);
|
|
1505
|
+
const registry = createPersistRegistry(namedNeurons);
|
|
1506
|
+
return { cns, registry };
|
|
1507
|
+
};
|
|
1318
1508
|
|
|
1319
1509
|
exports.CNS = CNS;
|
|
1320
1510
|
exports.CNSCollateral = CNSCollateral;
|
|
@@ -1323,9 +1513,12 @@ exports.CNSStimulationContextStore = CNSStimulationContextStore;
|
|
|
1323
1513
|
exports.CNSStimulationGate = CNSStimulationGate;
|
|
1324
1514
|
exports.afferentPath = afferentPath;
|
|
1325
1515
|
exports.collateral = collateral;
|
|
1516
|
+
exports.createCNS = createCNS;
|
|
1326
1517
|
exports.createPersistRegistry = createPersistRegistry;
|
|
1327
1518
|
exports.modality = modality;
|
|
1328
1519
|
exports.neuron = neuron;
|
|
1520
|
+
exports.neuronFactory = neuronFactory;
|
|
1329
1521
|
exports.withCtx = withCtx;
|
|
1522
|
+
exports.withGlobal = withGlobal;
|
|
1330
1523
|
//# sourceMappingURL=index.cjs.map
|
|
1331
1524
|
//# sourceMappingURL=index.cjs.map
|