@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.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
export { CNS } from './CNS';
|
|
2
2
|
export { CNSCollateral } from './CNSCollateral';
|
|
3
|
-
export { CNSStimulationContextStore } from './CNSStimulationContextStore';
|
|
4
3
|
export { CNSStimulationGate } from './utils/CNSStimulationGate';
|
|
5
|
-
export type { TCNSStimulationGateOptions
|
|
6
|
-
export { collateral, neuron, neuronFactory,
|
|
4
|
+
export type { TCNSStimulationGateOptions } from './utils/CNSStimulationGate';
|
|
5
|
+
export { collateral, neuron, neuronFactory, withGlobal, afferentPath, modality, } from './factory/index';
|
|
7
6
|
export type { TNeuronFactory } from './factory/index';
|
|
8
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAG5B,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAG5B,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAKhE,YAAY,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAG7E,OAAO,EACH,UAAU,EACV,MAAM,EACN,aAAa,EACb,UAAU,EACV,YAAY,EACZ,QAAQ,GACX,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,39 +1,14 @@
|
|
|
1
|
-
// src/CNSStimulationContextStore.ts
|
|
2
|
-
var CNSStimulationContextStore = class {
|
|
3
|
-
constructor(ctx) {
|
|
4
|
-
this.ctx = ctx;
|
|
5
|
-
}
|
|
6
|
-
get(key) {
|
|
7
|
-
return this.ctx?.get(key);
|
|
8
|
-
}
|
|
9
|
-
set(key, value) {
|
|
10
|
-
(this.ctx ?? (this.ctx = /* @__PURE__ */ new Map())).set(key, value);
|
|
11
|
-
}
|
|
12
|
-
getAll() {
|
|
13
|
-
return this.ctx ? new Map(this.ctx) : /* @__PURE__ */ new Map();
|
|
14
|
-
}
|
|
15
|
-
setAll(values) {
|
|
16
|
-
const ctx = this.ctx ?? (this.ctx = /* @__PURE__ */ new Map());
|
|
17
|
-
ctx.clear();
|
|
18
|
-
for (const [key, value] of values) ctx.set(key, value);
|
|
19
|
-
}
|
|
20
|
-
delete(key) {
|
|
21
|
-
this.ctx?.delete(key);
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
|
|
25
1
|
// src/CNSStimulation.ts
|
|
26
2
|
var TASK_DENDRITE = /* @__PURE__ */ Symbol("cnstra.taskDendrite");
|
|
27
3
|
var CNSDendriteContext = class {
|
|
28
|
-
constructor(stimulation,
|
|
4
|
+
constructor(stimulation, abortSignal, cns) {
|
|
29
5
|
this.stimulation = stimulation;
|
|
30
|
-
this.neuron = neuron2;
|
|
31
6
|
this.abortSignal = abortSignal;
|
|
32
7
|
this.cns = cns;
|
|
33
8
|
}
|
|
34
|
-
// Prototype getter, not a constructor field:
|
|
35
|
-
//
|
|
36
|
-
//
|
|
9
|
+
// Prototype getter, not a constructor field: you only pay a single `cns.global`
|
|
10
|
+
// read on the dendrites that actually reach for it. Value getter, so
|
|
11
|
+
// `{ global }` destructuring is safe.
|
|
37
12
|
get global() {
|
|
38
13
|
return this.cns.global;
|
|
39
14
|
}
|
|
@@ -44,20 +19,10 @@ var CNSDendriteContext = class {
|
|
|
44
19
|
get stimulationContext() {
|
|
45
20
|
return this.stimulation.options?.stimulationContext;
|
|
46
21
|
}
|
|
47
|
-
get() {
|
|
48
|
-
return this.stimulation.getContext().get(this.neuron);
|
|
49
|
-
}
|
|
50
|
-
set(value) {
|
|
51
|
-
this.stimulation.getContext().set(this.neuron, value);
|
|
52
|
-
}
|
|
53
|
-
delete() {
|
|
54
|
-
this.stimulation.getContext().delete(this.neuron);
|
|
55
|
-
}
|
|
56
22
|
};
|
|
57
23
|
var CNSStimulationResponseImpl = class {
|
|
58
|
-
constructor(stimulation,
|
|
24
|
+
constructor(stimulation, inputSignal, outputSignal, queueLength, pendingActivations, activeActivations, hops, error, neuron2) {
|
|
59
25
|
this.stimulation = stimulation;
|
|
60
|
-
this.store = store;
|
|
61
26
|
this.inputSignal = inputSignal;
|
|
62
27
|
this.outputSignal = outputSignal;
|
|
63
28
|
this.queueLength = queueLength;
|
|
@@ -67,9 +32,6 @@ var CNSStimulationResponseImpl = class {
|
|
|
67
32
|
this.error = error;
|
|
68
33
|
this.neuron = neuron2;
|
|
69
34
|
}
|
|
70
|
-
get contextValue() {
|
|
71
|
-
return this.store ? this.store.getAll() : /* @__PURE__ */ new Map();
|
|
72
|
-
}
|
|
73
35
|
};
|
|
74
36
|
var CNSStimulation = class {
|
|
75
37
|
constructor(cns, instanceNeuronQueue, options, onResponse, onDrain) {
|
|
@@ -97,15 +59,11 @@ var CNSStimulation = class {
|
|
|
97
59
|
this.isCompleted = false;
|
|
98
60
|
this.completionRejected = false;
|
|
99
61
|
this.onDrain = onDrain;
|
|
100
|
-
this.ctxStore = options?.ctx;
|
|
101
62
|
this.instanceNeuronQueue = instanceNeuronQueue;
|
|
102
63
|
this.onResponse = onResponse;
|
|
103
64
|
if (this.options?.maxNeuronHops) {
|
|
104
65
|
this.neuronVisitMap = /* @__PURE__ */ new Map();
|
|
105
66
|
}
|
|
106
|
-
if (this.autoCleanupContextsEnabled) {
|
|
107
|
-
this.activeSccCounts = /* @__PURE__ */ new Map();
|
|
108
|
-
}
|
|
109
67
|
}
|
|
110
68
|
pushFailedTask(failure) {
|
|
111
69
|
(this.failedTasks ?? (this.failedTasks = [])).push(failure);
|
|
@@ -119,10 +77,6 @@ var CNSStimulation = class {
|
|
|
119
77
|
this.completionError = error;
|
|
120
78
|
this.rejectCompleted?.(error);
|
|
121
79
|
}
|
|
122
|
-
/** Lazily-created neuron context store (see {@link ctxStore}). */
|
|
123
|
-
get ctx() {
|
|
124
|
-
return this.ctxStore ?? (this.ctxStore = new CNSStimulationContextStore());
|
|
125
|
-
}
|
|
126
80
|
// ----- Inlined activation queue / pump -----
|
|
127
81
|
get canStartOperation() {
|
|
128
82
|
const limit = this.options?.concurrency ?? Infinity;
|
|
@@ -352,12 +306,6 @@ var CNSStimulation = class {
|
|
|
352
306
|
...this.getFailedTasks().map((f) => f.task)
|
|
353
307
|
];
|
|
354
308
|
}
|
|
355
|
-
/**
|
|
356
|
-
* Get the context store for this stimulation
|
|
357
|
-
*/
|
|
358
|
-
getContext() {
|
|
359
|
-
return this.ctx;
|
|
360
|
-
}
|
|
361
309
|
/**
|
|
362
310
|
* Enqueue activation tasks directly into the stimulation queue
|
|
363
311
|
*/
|
|
@@ -375,67 +323,6 @@ var CNSStimulation = class {
|
|
|
375
323
|
get concurrencyEnabled() {
|
|
376
324
|
return this.options?.concurrency !== void 0 && this.options?.concurrency > 0;
|
|
377
325
|
}
|
|
378
|
-
get autoCleanupContextsEnabled() {
|
|
379
|
-
return this.cns?.options?.autoCleanupContexts ?? false;
|
|
380
|
-
}
|
|
381
|
-
/**
|
|
382
|
-
* Mark a neuron as active (being processed)
|
|
383
|
-
*/
|
|
384
|
-
markNeuronActive(neuron2) {
|
|
385
|
-
if (!this.autoCleanupContextsEnabled) return;
|
|
386
|
-
this.incrementSccCount(neuron2);
|
|
387
|
-
}
|
|
388
|
-
/**
|
|
389
|
-
* Mark a neuron as inactive (finished processing)
|
|
390
|
-
*/
|
|
391
|
-
markNeuronInactive(neuron2) {
|
|
392
|
-
if (!this.autoCleanupContextsEnabled) return;
|
|
393
|
-
this.decrementSccCount(neuron2);
|
|
394
|
-
}
|
|
395
|
-
/**
|
|
396
|
-
* Increment the active count for the SCC containing this neuron
|
|
397
|
-
*/
|
|
398
|
-
incrementSccCount(neuron2) {
|
|
399
|
-
const counts = this.activeSccCounts;
|
|
400
|
-
if (!counts) return;
|
|
401
|
-
const sccIndex = this.cns.network.getSccIndexByNeuron(neuron2);
|
|
402
|
-
if (sccIndex === void 0) return;
|
|
403
|
-
const currentCount = counts.get(sccIndex) || 0;
|
|
404
|
-
counts.set(sccIndex, currentCount + 1);
|
|
405
|
-
}
|
|
406
|
-
/**
|
|
407
|
-
* Decrement the active count for the SCC containing this neuron
|
|
408
|
-
*/
|
|
409
|
-
decrementSccCount(neuron2) {
|
|
410
|
-
const counts = this.activeSccCounts;
|
|
411
|
-
if (!counts) return;
|
|
412
|
-
const sccIndex = this.cns.network.getSccIndexByNeuron(neuron2);
|
|
413
|
-
if (sccIndex === void 0) return;
|
|
414
|
-
const currentCount = counts.get(sccIndex) || 0;
|
|
415
|
-
const nextCount = Math.max(0, currentCount - 1);
|
|
416
|
-
counts.set(sccIndex, nextCount);
|
|
417
|
-
if (currentCount === 0) {
|
|
418
|
-
console.warn(
|
|
419
|
-
`[CNSStimulation] Attempting to decrement SCC count below 0 for neuron`
|
|
420
|
-
);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
/**
|
|
424
|
-
* Check if a neuron can be guaranteed not to be visited again
|
|
425
|
-
*/
|
|
426
|
-
canNeuronBeGuaranteedDone(neuron2) {
|
|
427
|
-
if (!this.autoCleanupContextsEnabled || !this.activeSccCounts)
|
|
428
|
-
return false;
|
|
429
|
-
return this.cns.network.canNeuronBeGuaranteedDone(
|
|
430
|
-
neuron2,
|
|
431
|
-
this.activeSccCounts
|
|
432
|
-
);
|
|
433
|
-
}
|
|
434
|
-
cleanupCtxIfNeeded(neuron2) {
|
|
435
|
-
if (this.autoCleanupContextsEnabled && this.canNeuronBeGuaranteedDone(neuron2)) {
|
|
436
|
-
this.ctxStore?.delete(neuron2);
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
326
|
createSubscriberQueueItem(subscriber, inputSignal) {
|
|
440
327
|
if (this.options?.maxNeuronHops) {
|
|
441
328
|
if ((this.neuronVisitMap?.get(subscriber.neuron) ?? 0) >= this.options?.maxNeuronHops) {
|
|
@@ -509,7 +396,6 @@ var CNSStimulation = class {
|
|
|
509
396
|
);
|
|
510
397
|
}
|
|
511
398
|
runStarter(neuron2, dendrite, inputSignal, neuronActivationTask) {
|
|
512
|
-
this.markNeuronActive(neuron2);
|
|
513
399
|
let response;
|
|
514
400
|
try {
|
|
515
401
|
response = dendrite.response(
|
|
@@ -517,13 +403,11 @@ var CNSStimulation = class {
|
|
|
517
403
|
neuron2.axon,
|
|
518
404
|
new CNSDendriteContext(
|
|
519
405
|
this,
|
|
520
|
-
neuron2,
|
|
521
406
|
this.options?.abortSignal,
|
|
522
407
|
this.cns
|
|
523
408
|
)
|
|
524
409
|
);
|
|
525
410
|
} catch (error) {
|
|
526
|
-
this.markNeuronInactive(neuron2);
|
|
527
411
|
const isAborted = this.options?.abortSignal?.aborted ?? false;
|
|
528
412
|
this.pushFailedTask({
|
|
529
413
|
task: neuronActivationTask,
|
|
@@ -563,7 +447,6 @@ var CNSStimulation = class {
|
|
|
563
447
|
return timedPromise.then(
|
|
564
448
|
(signal) => {
|
|
565
449
|
return () => {
|
|
566
|
-
this.markNeuronInactive(neuron2);
|
|
567
450
|
return this.processResponseOrResponses(
|
|
568
451
|
neuron2,
|
|
569
452
|
inputSignal,
|
|
@@ -573,7 +456,6 @@ var CNSStimulation = class {
|
|
|
573
456
|
},
|
|
574
457
|
(error) => {
|
|
575
458
|
return () => {
|
|
576
|
-
this.markNeuronInactive(neuron2);
|
|
577
459
|
const isAborted = this.options?.abortSignal?.aborted ?? false;
|
|
578
460
|
this.pushFailedTask({
|
|
579
461
|
task: neuronActivationTask,
|
|
@@ -591,7 +473,6 @@ var CNSStimulation = class {
|
|
|
591
473
|
);
|
|
592
474
|
} else {
|
|
593
475
|
return () => {
|
|
594
|
-
this.markNeuronInactive(neuron2);
|
|
595
476
|
return this.processResponseOrResponses(
|
|
596
477
|
neuron2,
|
|
597
478
|
inputSignal,
|
|
@@ -637,7 +518,6 @@ var CNSStimulation = class {
|
|
|
637
518
|
const onResponse = this.onResponse;
|
|
638
519
|
if (!onResponse) {
|
|
639
520
|
if (collateral2 && !error) {
|
|
640
|
-
if (emitter) this.cleanupCtxIfNeeded(emitter);
|
|
641
521
|
const n = subscribers.length;
|
|
642
522
|
if (n > 0) {
|
|
643
523
|
const tasks = new Array(n);
|
|
@@ -659,7 +539,6 @@ var CNSStimulation = class {
|
|
|
659
539
|
}
|
|
660
540
|
const subscriberActivationTasks = [];
|
|
661
541
|
if (collateral2 && !error) {
|
|
662
|
-
if (emitter) this.cleanupCtxIfNeeded(emitter);
|
|
663
542
|
const pending = this.pendingTasks ?? (this.pendingTasks = /* @__PURE__ */ new Set());
|
|
664
543
|
for (let i = 0; i < subscribers.length; i++) {
|
|
665
544
|
const task = this.createSubscriberQueueItem(
|
|
@@ -676,7 +555,6 @@ var CNSStimulation = class {
|
|
|
676
555
|
maybePromise = onResponse(
|
|
677
556
|
new CNSStimulationResponseImpl(
|
|
678
557
|
this,
|
|
679
|
-
this.ctxStore,
|
|
680
558
|
inputSignal,
|
|
681
559
|
outputSignal,
|
|
682
560
|
this.pendingActivations + this.activeOperations,
|
|
@@ -822,8 +700,9 @@ var CNSNetwork = class {
|
|
|
822
700
|
* Strongly Connected Components of the neuron graph.
|
|
823
701
|
* Each component is a set of neuron objects that can reach each other.
|
|
824
702
|
*
|
|
825
|
-
* Computed lazily on first access: the SCC machinery
|
|
826
|
-
*
|
|
703
|
+
* Computed lazily on first access: the SCC machinery only drives graph
|
|
704
|
+
* introspection (`getSCCSetByNeuron`, `canNeuronBeGuaranteedDone`), so a
|
|
705
|
+
* network that never inspects reachability never pays for it.
|
|
827
706
|
*/
|
|
828
707
|
this._stronglyConnectedComponents = [];
|
|
829
708
|
this.sccBuilt = false;
|
|
@@ -1109,16 +988,20 @@ var CNS = class {
|
|
|
1109
988
|
this.network = new CNSNetwork(this.neurons);
|
|
1110
989
|
this.global = global;
|
|
1111
990
|
}
|
|
1112
|
-
|
|
1113
|
-
|
|
991
|
+
/** Push a listener onto a list; return an idempotent unsubscribe. */
|
|
992
|
+
addListener(list, listener) {
|
|
993
|
+
list.push(listener);
|
|
1114
994
|
let active = true;
|
|
1115
995
|
return () => {
|
|
1116
996
|
if (!active) return;
|
|
1117
997
|
active = false;
|
|
1118
|
-
const idx =
|
|
1119
|
-
if (idx >= 0)
|
|
998
|
+
const idx = list.indexOf(listener);
|
|
999
|
+
if (idx >= 0) list.splice(idx, 1);
|
|
1120
1000
|
};
|
|
1121
1001
|
}
|
|
1002
|
+
addResponseListener(listener) {
|
|
1003
|
+
return this.addListener(this.globalResponseListeners, listener);
|
|
1004
|
+
}
|
|
1122
1005
|
/**
|
|
1123
1006
|
* Register a listener called once at the end of every synchronous turn of
|
|
1124
1007
|
* every stimulation - see {@link TCNSStimulationDrain}. This is how an
|
|
@@ -1128,14 +1011,7 @@ var CNS = class {
|
|
|
1128
1011
|
* Returns an unsubscribe function.
|
|
1129
1012
|
*/
|
|
1130
1013
|
addDrainListener(listener) {
|
|
1131
|
-
this.globalDrainListeners
|
|
1132
|
-
let active = true;
|
|
1133
|
-
return () => {
|
|
1134
|
-
if (!active) return;
|
|
1135
|
-
active = false;
|
|
1136
|
-
const idx = this.globalDrainListeners.indexOf(listener);
|
|
1137
|
-
if (idx >= 0) this.globalDrainListeners.splice(idx, 1);
|
|
1138
|
-
};
|
|
1014
|
+
return this.addListener(this.globalDrainListeners, listener);
|
|
1139
1015
|
}
|
|
1140
1016
|
/**
|
|
1141
1017
|
* Fan a drain out to the local and global listeners, or return undefined when
|
|
@@ -1204,15 +1080,18 @@ var CNS = class {
|
|
|
1204
1080
|
}
|
|
1205
1081
|
};
|
|
1206
1082
|
}
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1083
|
+
/** Build a stimulation (wired listeners, unseeded). Shared by stimulate/activate. */
|
|
1084
|
+
createStimulation(options) {
|
|
1085
|
+
return new CNSStimulation(
|
|
1210
1086
|
this,
|
|
1211
1087
|
this.instanceNeuronQueue,
|
|
1212
1088
|
options,
|
|
1213
|
-
|
|
1089
|
+
this.wrapOnResponse(options?.onResponse),
|
|
1214
1090
|
this.wrapOnDrain(options?.onDrain)
|
|
1215
1091
|
);
|
|
1092
|
+
}
|
|
1093
|
+
stimulate(signalOrSignals, options) {
|
|
1094
|
+
const stimulation = this.createStimulation(options);
|
|
1216
1095
|
stimulation.responseToSignal(signalOrSignals);
|
|
1217
1096
|
return stimulation;
|
|
1218
1097
|
}
|
|
@@ -1220,14 +1099,7 @@ var CNS = class {
|
|
|
1220
1099
|
* Start a stimulation with activation tasks directly
|
|
1221
1100
|
*/
|
|
1222
1101
|
activate(tasks, options) {
|
|
1223
|
-
const
|
|
1224
|
-
const stimulation = new CNSStimulation(
|
|
1225
|
-
this,
|
|
1226
|
-
this.instanceNeuronQueue,
|
|
1227
|
-
options,
|
|
1228
|
-
wrapped,
|
|
1229
|
-
this.wrapOnDrain(options?.onDrain)
|
|
1230
|
-
);
|
|
1102
|
+
const stimulation = this.createStimulation(options);
|
|
1231
1103
|
stimulation.enqueueTasks(tasks);
|
|
1232
1104
|
return stimulation;
|
|
1233
1105
|
}
|
|
@@ -1415,13 +1287,11 @@ var neuron = (axon) => {
|
|
|
1415
1287
|
};
|
|
1416
1288
|
var neuronFactory = () => {
|
|
1417
1289
|
const factory = {
|
|
1418
|
-
withCtx: () => factory,
|
|
1419
1290
|
withGlobal: () => factory,
|
|
1420
1291
|
neuron: (axon) => neuron(axon)
|
|
1421
1292
|
};
|
|
1422
1293
|
return factory;
|
|
1423
1294
|
};
|
|
1424
|
-
var withCtx = () => neuronFactory();
|
|
1425
1295
|
var withGlobal = () => neuronFactory();
|
|
1426
1296
|
var afferentPath = (parentAfferentPath) => {
|
|
1427
1297
|
return {
|
|
@@ -1436,6 +1306,6 @@ var modality = (afferentPaths) => {
|
|
|
1436
1306
|
};
|
|
1437
1307
|
};
|
|
1438
1308
|
|
|
1439
|
-
export { CNS, CNSCollateral,
|
|
1309
|
+
export { CNS, CNSCollateral, CNSStimulationGate, afferentPath, collateral, modality, neuron, neuronFactory, withGlobal };
|
|
1440
1310
|
//# sourceMappingURL=index.js.map
|
|
1441
1311
|
//# sourceMappingURL=index.js.map
|