@cnstra/core 2.6.0 → 3.0.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 +3 -4
- package/dist/CNS.d.ts +5 -1
- package/dist/CNS.d.ts.map +1 -1
- package/dist/CNSNetwork.d.ts +4 -3
- package/dist/CNSNetwork.d.ts.map +1 -1
- package/dist/CNSStimulation.d.ts +1 -36
- package/dist/CNSStimulation.d.ts.map +1 -1
- package/dist/factory/index.d.ts +30 -34
- package/dist/factory/index.d.ts.map +1 -1
- package/dist/index.cjs +25 -157
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -156
- package/dist/index.js.map +1 -1
- package/dist/utils/CNSStimulationGate.d.ts +2 -2
- package/dist/utils/CNSStimulationGate.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/CNSStimulationContextStore.d.ts +0 -11
- package/dist/CNSStimulationContextStore.d.ts.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,41 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
// src/CNSStimulationContextStore.ts
|
|
4
|
-
var CNSStimulationContextStore = class {
|
|
5
|
-
constructor(ctx) {
|
|
6
|
-
this.ctx = ctx;
|
|
7
|
-
}
|
|
8
|
-
get(key) {
|
|
9
|
-
return this.ctx?.get(key);
|
|
10
|
-
}
|
|
11
|
-
set(key, value) {
|
|
12
|
-
(this.ctx ?? (this.ctx = /* @__PURE__ */ new Map())).set(key, value);
|
|
13
|
-
}
|
|
14
|
-
getAll() {
|
|
15
|
-
return this.ctx ? new Map(this.ctx) : /* @__PURE__ */ new Map();
|
|
16
|
-
}
|
|
17
|
-
setAll(values) {
|
|
18
|
-
const ctx = this.ctx ?? (this.ctx = /* @__PURE__ */ new Map());
|
|
19
|
-
ctx.clear();
|
|
20
|
-
for (const [key, value] of values) ctx.set(key, value);
|
|
21
|
-
}
|
|
22
|
-
delete(key) {
|
|
23
|
-
this.ctx?.delete(key);
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
|
|
27
3
|
// src/CNSStimulation.ts
|
|
28
4
|
var TASK_DENDRITE = /* @__PURE__ */ Symbol("cnstra.taskDendrite");
|
|
29
5
|
var CNSDendriteContext = class {
|
|
30
|
-
constructor(stimulation,
|
|
6
|
+
constructor(stimulation, abortSignal, cns) {
|
|
31
7
|
this.stimulation = stimulation;
|
|
32
|
-
this.neuron = neuron2;
|
|
33
8
|
this.abortSignal = abortSignal;
|
|
34
9
|
this.cns = cns;
|
|
35
10
|
}
|
|
36
|
-
// Prototype getter, not a constructor field:
|
|
37
|
-
//
|
|
38
|
-
//
|
|
11
|
+
// Prototype getter, not a constructor field: you only pay a single `cns.global`
|
|
12
|
+
// read on the dendrites that actually reach for it. Value getter, so
|
|
13
|
+
// `{ global }` destructuring is safe.
|
|
39
14
|
get global() {
|
|
40
15
|
return this.cns.global;
|
|
41
16
|
}
|
|
@@ -46,20 +21,10 @@ var CNSDendriteContext = class {
|
|
|
46
21
|
get stimulationContext() {
|
|
47
22
|
return this.stimulation.options?.stimulationContext;
|
|
48
23
|
}
|
|
49
|
-
get() {
|
|
50
|
-
return this.stimulation.getContext().get(this.neuron);
|
|
51
|
-
}
|
|
52
|
-
set(value) {
|
|
53
|
-
this.stimulation.getContext().set(this.neuron, value);
|
|
54
|
-
}
|
|
55
|
-
delete() {
|
|
56
|
-
this.stimulation.getContext().delete(this.neuron);
|
|
57
|
-
}
|
|
58
24
|
};
|
|
59
25
|
var CNSStimulationResponseImpl = class {
|
|
60
|
-
constructor(stimulation,
|
|
26
|
+
constructor(stimulation, inputSignal, outputSignal, queueLength, pendingActivations, activeActivations, hops, error, neuron2) {
|
|
61
27
|
this.stimulation = stimulation;
|
|
62
|
-
this.store = store;
|
|
63
28
|
this.inputSignal = inputSignal;
|
|
64
29
|
this.outputSignal = outputSignal;
|
|
65
30
|
this.queueLength = queueLength;
|
|
@@ -69,9 +34,6 @@ var CNSStimulationResponseImpl = class {
|
|
|
69
34
|
this.error = error;
|
|
70
35
|
this.neuron = neuron2;
|
|
71
36
|
}
|
|
72
|
-
get contextValue() {
|
|
73
|
-
return this.store ? this.store.getAll() : /* @__PURE__ */ new Map();
|
|
74
|
-
}
|
|
75
37
|
};
|
|
76
38
|
var CNSStimulation = class {
|
|
77
39
|
constructor(cns, instanceNeuronQueue, options, onResponse, onDrain) {
|
|
@@ -99,15 +61,11 @@ var CNSStimulation = class {
|
|
|
99
61
|
this.isCompleted = false;
|
|
100
62
|
this.completionRejected = false;
|
|
101
63
|
this.onDrain = onDrain;
|
|
102
|
-
this.ctxStore = options?.ctx;
|
|
103
64
|
this.instanceNeuronQueue = instanceNeuronQueue;
|
|
104
65
|
this.onResponse = onResponse;
|
|
105
66
|
if (this.options?.maxNeuronHops) {
|
|
106
67
|
this.neuronVisitMap = /* @__PURE__ */ new Map();
|
|
107
68
|
}
|
|
108
|
-
if (this.autoCleanupContextsEnabled) {
|
|
109
|
-
this.activeSccCounts = /* @__PURE__ */ new Map();
|
|
110
|
-
}
|
|
111
69
|
}
|
|
112
70
|
pushFailedTask(failure) {
|
|
113
71
|
(this.failedTasks ?? (this.failedTasks = [])).push(failure);
|
|
@@ -121,10 +79,6 @@ var CNSStimulation = class {
|
|
|
121
79
|
this.completionError = error;
|
|
122
80
|
this.rejectCompleted?.(error);
|
|
123
81
|
}
|
|
124
|
-
/** Lazily-created neuron context store (see {@link ctxStore}). */
|
|
125
|
-
get ctx() {
|
|
126
|
-
return this.ctxStore ?? (this.ctxStore = new CNSStimulationContextStore());
|
|
127
|
-
}
|
|
128
82
|
// ----- Inlined activation queue / pump -----
|
|
129
83
|
get canStartOperation() {
|
|
130
84
|
const limit = this.options?.concurrency ?? Infinity;
|
|
@@ -354,12 +308,6 @@ var CNSStimulation = class {
|
|
|
354
308
|
...this.getFailedTasks().map((f) => f.task)
|
|
355
309
|
];
|
|
356
310
|
}
|
|
357
|
-
/**
|
|
358
|
-
* Get the context store for this stimulation
|
|
359
|
-
*/
|
|
360
|
-
getContext() {
|
|
361
|
-
return this.ctx;
|
|
362
|
-
}
|
|
363
311
|
/**
|
|
364
312
|
* Enqueue activation tasks directly into the stimulation queue
|
|
365
313
|
*/
|
|
@@ -377,67 +325,6 @@ var CNSStimulation = class {
|
|
|
377
325
|
get concurrencyEnabled() {
|
|
378
326
|
return this.options?.concurrency !== void 0 && this.options?.concurrency > 0;
|
|
379
327
|
}
|
|
380
|
-
get autoCleanupContextsEnabled() {
|
|
381
|
-
return this.cns?.options?.autoCleanupContexts ?? false;
|
|
382
|
-
}
|
|
383
|
-
/**
|
|
384
|
-
* Mark a neuron as active (being processed)
|
|
385
|
-
*/
|
|
386
|
-
markNeuronActive(neuron2) {
|
|
387
|
-
if (!this.autoCleanupContextsEnabled) return;
|
|
388
|
-
this.incrementSccCount(neuron2);
|
|
389
|
-
}
|
|
390
|
-
/**
|
|
391
|
-
* Mark a neuron as inactive (finished processing)
|
|
392
|
-
*/
|
|
393
|
-
markNeuronInactive(neuron2) {
|
|
394
|
-
if (!this.autoCleanupContextsEnabled) return;
|
|
395
|
-
this.decrementSccCount(neuron2);
|
|
396
|
-
}
|
|
397
|
-
/**
|
|
398
|
-
* Increment the active count for the SCC containing this neuron
|
|
399
|
-
*/
|
|
400
|
-
incrementSccCount(neuron2) {
|
|
401
|
-
const counts = this.activeSccCounts;
|
|
402
|
-
if (!counts) return;
|
|
403
|
-
const sccIndex = this.cns.network.getSccIndexByNeuron(neuron2);
|
|
404
|
-
if (sccIndex === void 0) return;
|
|
405
|
-
const currentCount = counts.get(sccIndex) || 0;
|
|
406
|
-
counts.set(sccIndex, currentCount + 1);
|
|
407
|
-
}
|
|
408
|
-
/**
|
|
409
|
-
* Decrement the active count for the SCC containing this neuron
|
|
410
|
-
*/
|
|
411
|
-
decrementSccCount(neuron2) {
|
|
412
|
-
const counts = this.activeSccCounts;
|
|
413
|
-
if (!counts) return;
|
|
414
|
-
const sccIndex = this.cns.network.getSccIndexByNeuron(neuron2);
|
|
415
|
-
if (sccIndex === void 0) return;
|
|
416
|
-
const currentCount = counts.get(sccIndex) || 0;
|
|
417
|
-
const nextCount = Math.max(0, currentCount - 1);
|
|
418
|
-
counts.set(sccIndex, nextCount);
|
|
419
|
-
if (currentCount === 0) {
|
|
420
|
-
console.warn(
|
|
421
|
-
`[CNSStimulation] Attempting to decrement SCC count below 0 for neuron`
|
|
422
|
-
);
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
/**
|
|
426
|
-
* Check if a neuron can be guaranteed not to be visited again
|
|
427
|
-
*/
|
|
428
|
-
canNeuronBeGuaranteedDone(neuron2) {
|
|
429
|
-
if (!this.autoCleanupContextsEnabled || !this.activeSccCounts)
|
|
430
|
-
return false;
|
|
431
|
-
return this.cns.network.canNeuronBeGuaranteedDone(
|
|
432
|
-
neuron2,
|
|
433
|
-
this.activeSccCounts
|
|
434
|
-
);
|
|
435
|
-
}
|
|
436
|
-
cleanupCtxIfNeeded(neuron2) {
|
|
437
|
-
if (this.autoCleanupContextsEnabled && this.canNeuronBeGuaranteedDone(neuron2)) {
|
|
438
|
-
this.ctxStore?.delete(neuron2);
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
328
|
createSubscriberQueueItem(subscriber, inputSignal) {
|
|
442
329
|
if (this.options?.maxNeuronHops) {
|
|
443
330
|
if ((this.neuronVisitMap?.get(subscriber.neuron) ?? 0) >= this.options?.maxNeuronHops) {
|
|
@@ -511,7 +398,6 @@ var CNSStimulation = class {
|
|
|
511
398
|
);
|
|
512
399
|
}
|
|
513
400
|
runStarter(neuron2, dendrite, inputSignal, neuronActivationTask) {
|
|
514
|
-
this.markNeuronActive(neuron2);
|
|
515
401
|
let response;
|
|
516
402
|
try {
|
|
517
403
|
response = dendrite.response(
|
|
@@ -519,13 +405,11 @@ var CNSStimulation = class {
|
|
|
519
405
|
neuron2.axon,
|
|
520
406
|
new CNSDendriteContext(
|
|
521
407
|
this,
|
|
522
|
-
neuron2,
|
|
523
408
|
this.options?.abortSignal,
|
|
524
409
|
this.cns
|
|
525
410
|
)
|
|
526
411
|
);
|
|
527
412
|
} catch (error) {
|
|
528
|
-
this.markNeuronInactive(neuron2);
|
|
529
413
|
const isAborted = this.options?.abortSignal?.aborted ?? false;
|
|
530
414
|
this.pushFailedTask({
|
|
531
415
|
task: neuronActivationTask,
|
|
@@ -565,7 +449,6 @@ var CNSStimulation = class {
|
|
|
565
449
|
return timedPromise.then(
|
|
566
450
|
(signal) => {
|
|
567
451
|
return () => {
|
|
568
|
-
this.markNeuronInactive(neuron2);
|
|
569
452
|
return this.processResponseOrResponses(
|
|
570
453
|
neuron2,
|
|
571
454
|
inputSignal,
|
|
@@ -575,7 +458,6 @@ var CNSStimulation = class {
|
|
|
575
458
|
},
|
|
576
459
|
(error) => {
|
|
577
460
|
return () => {
|
|
578
|
-
this.markNeuronInactive(neuron2);
|
|
579
461
|
const isAborted = this.options?.abortSignal?.aborted ?? false;
|
|
580
462
|
this.pushFailedTask({
|
|
581
463
|
task: neuronActivationTask,
|
|
@@ -593,7 +475,6 @@ var CNSStimulation = class {
|
|
|
593
475
|
);
|
|
594
476
|
} else {
|
|
595
477
|
return () => {
|
|
596
|
-
this.markNeuronInactive(neuron2);
|
|
597
478
|
return this.processResponseOrResponses(
|
|
598
479
|
neuron2,
|
|
599
480
|
inputSignal,
|
|
@@ -639,7 +520,6 @@ var CNSStimulation = class {
|
|
|
639
520
|
const onResponse = this.onResponse;
|
|
640
521
|
if (!onResponse) {
|
|
641
522
|
if (collateral2 && !error) {
|
|
642
|
-
if (emitter) this.cleanupCtxIfNeeded(emitter);
|
|
643
523
|
const n = subscribers.length;
|
|
644
524
|
if (n > 0) {
|
|
645
525
|
const tasks = new Array(n);
|
|
@@ -661,7 +541,6 @@ var CNSStimulation = class {
|
|
|
661
541
|
}
|
|
662
542
|
const subscriberActivationTasks = [];
|
|
663
543
|
if (collateral2 && !error) {
|
|
664
|
-
if (emitter) this.cleanupCtxIfNeeded(emitter);
|
|
665
544
|
const pending = this.pendingTasks ?? (this.pendingTasks = /* @__PURE__ */ new Set());
|
|
666
545
|
for (let i = 0; i < subscribers.length; i++) {
|
|
667
546
|
const task = this.createSubscriberQueueItem(
|
|
@@ -678,7 +557,6 @@ var CNSStimulation = class {
|
|
|
678
557
|
maybePromise = onResponse(
|
|
679
558
|
new CNSStimulationResponseImpl(
|
|
680
559
|
this,
|
|
681
|
-
this.ctxStore,
|
|
682
560
|
inputSignal,
|
|
683
561
|
outputSignal,
|
|
684
562
|
this.pendingActivations + this.activeOperations,
|
|
@@ -824,8 +702,9 @@ var CNSNetwork = class {
|
|
|
824
702
|
* Strongly Connected Components of the neuron graph.
|
|
825
703
|
* Each component is a set of neuron objects that can reach each other.
|
|
826
704
|
*
|
|
827
|
-
* Computed lazily on first access: the SCC machinery
|
|
828
|
-
*
|
|
705
|
+
* Computed lazily on first access: the SCC machinery only drives graph
|
|
706
|
+
* introspection (`getSCCSetByNeuron`, `canNeuronBeGuaranteedDone`), so a
|
|
707
|
+
* network that never inspects reachability never pays for it.
|
|
829
708
|
*/
|
|
830
709
|
this._stronglyConnectedComponents = [];
|
|
831
710
|
this.sccBuilt = false;
|
|
@@ -1111,16 +990,20 @@ var CNS = class {
|
|
|
1111
990
|
this.network = new CNSNetwork(this.neurons);
|
|
1112
991
|
this.global = global;
|
|
1113
992
|
}
|
|
1114
|
-
|
|
1115
|
-
|
|
993
|
+
/** Push a listener onto a list; return an idempotent unsubscribe. */
|
|
994
|
+
addListener(list, listener) {
|
|
995
|
+
list.push(listener);
|
|
1116
996
|
let active = true;
|
|
1117
997
|
return () => {
|
|
1118
998
|
if (!active) return;
|
|
1119
999
|
active = false;
|
|
1120
|
-
const idx =
|
|
1121
|
-
if (idx >= 0)
|
|
1000
|
+
const idx = list.indexOf(listener);
|
|
1001
|
+
if (idx >= 0) list.splice(idx, 1);
|
|
1122
1002
|
};
|
|
1123
1003
|
}
|
|
1004
|
+
addResponseListener(listener) {
|
|
1005
|
+
return this.addListener(this.globalResponseListeners, listener);
|
|
1006
|
+
}
|
|
1124
1007
|
/**
|
|
1125
1008
|
* Register a listener called once at the end of every synchronous turn of
|
|
1126
1009
|
* every stimulation - see {@link TCNSStimulationDrain}. This is how an
|
|
@@ -1130,14 +1013,7 @@ var CNS = class {
|
|
|
1130
1013
|
* Returns an unsubscribe function.
|
|
1131
1014
|
*/
|
|
1132
1015
|
addDrainListener(listener) {
|
|
1133
|
-
this.globalDrainListeners
|
|
1134
|
-
let active = true;
|
|
1135
|
-
return () => {
|
|
1136
|
-
if (!active) return;
|
|
1137
|
-
active = false;
|
|
1138
|
-
const idx = this.globalDrainListeners.indexOf(listener);
|
|
1139
|
-
if (idx >= 0) this.globalDrainListeners.splice(idx, 1);
|
|
1140
|
-
};
|
|
1016
|
+
return this.addListener(this.globalDrainListeners, listener);
|
|
1141
1017
|
}
|
|
1142
1018
|
/**
|
|
1143
1019
|
* Fan a drain out to the local and global listeners, or return undefined when
|
|
@@ -1206,15 +1082,18 @@ var CNS = class {
|
|
|
1206
1082
|
}
|
|
1207
1083
|
};
|
|
1208
1084
|
}
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1085
|
+
/** Build a stimulation (wired listeners, unseeded). Shared by stimulate/activate. */
|
|
1086
|
+
createStimulation(options) {
|
|
1087
|
+
return new CNSStimulation(
|
|
1212
1088
|
this,
|
|
1213
1089
|
this.instanceNeuronQueue,
|
|
1214
1090
|
options,
|
|
1215
|
-
|
|
1091
|
+
this.wrapOnResponse(options?.onResponse),
|
|
1216
1092
|
this.wrapOnDrain(options?.onDrain)
|
|
1217
1093
|
);
|
|
1094
|
+
}
|
|
1095
|
+
stimulate(signalOrSignals, options) {
|
|
1096
|
+
const stimulation = this.createStimulation(options);
|
|
1218
1097
|
stimulation.responseToSignal(signalOrSignals);
|
|
1219
1098
|
return stimulation;
|
|
1220
1099
|
}
|
|
@@ -1222,14 +1101,7 @@ var CNS = class {
|
|
|
1222
1101
|
* Start a stimulation with activation tasks directly
|
|
1223
1102
|
*/
|
|
1224
1103
|
activate(tasks, options) {
|
|
1225
|
-
const
|
|
1226
|
-
const stimulation = new CNSStimulation(
|
|
1227
|
-
this,
|
|
1228
|
-
this.instanceNeuronQueue,
|
|
1229
|
-
options,
|
|
1230
|
-
wrapped,
|
|
1231
|
-
this.wrapOnDrain(options?.onDrain)
|
|
1232
|
-
);
|
|
1104
|
+
const stimulation = this.createStimulation(options);
|
|
1233
1105
|
stimulation.enqueueTasks(tasks);
|
|
1234
1106
|
return stimulation;
|
|
1235
1107
|
}
|
|
@@ -1417,13 +1289,11 @@ var neuron = (axon) => {
|
|
|
1417
1289
|
};
|
|
1418
1290
|
var neuronFactory = () => {
|
|
1419
1291
|
const factory = {
|
|
1420
|
-
withCtx: () => factory,
|
|
1421
1292
|
withGlobal: () => factory,
|
|
1422
1293
|
neuron: (axon) => neuron(axon)
|
|
1423
1294
|
};
|
|
1424
1295
|
return factory;
|
|
1425
1296
|
};
|
|
1426
|
-
var withCtx = () => neuronFactory();
|
|
1427
1297
|
var withGlobal = () => neuronFactory();
|
|
1428
1298
|
var afferentPath = (parentAfferentPath) => {
|
|
1429
1299
|
return {
|
|
@@ -1440,14 +1310,12 @@ var modality = (afferentPaths) => {
|
|
|
1440
1310
|
|
|
1441
1311
|
exports.CNS = CNS;
|
|
1442
1312
|
exports.CNSCollateral = CNSCollateral;
|
|
1443
|
-
exports.CNSStimulationContextStore = CNSStimulationContextStore;
|
|
1444
1313
|
exports.CNSStimulationGate = CNSStimulationGate;
|
|
1445
1314
|
exports.afferentPath = afferentPath;
|
|
1446
1315
|
exports.collateral = collateral;
|
|
1447
1316
|
exports.modality = modality;
|
|
1448
1317
|
exports.neuron = neuron;
|
|
1449
1318
|
exports.neuronFactory = neuronFactory;
|
|
1450
|
-
exports.withCtx = withCtx;
|
|
1451
1319
|
exports.withGlobal = withGlobal;
|
|
1452
1320
|
//# sourceMappingURL=index.cjs.map
|
|
1453
1321
|
//# sourceMappingURL=index.cjs.map
|