@cnstra/core 1.5.2 → 1.7.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 +103 -29
- package/dist/CNS.d.ts +5 -3
- package/dist/CNS.d.ts.map +1 -1
- package/dist/CNSFunctionalQueue.d.ts +3 -3
- package/dist/CNSFunctionalQueue.d.ts.map +1 -1
- package/dist/CNSStimulation.d.ts +10 -6
- package/dist/CNSStimulation.d.ts.map +1 -1
- package/dist/factory/index.d.ts +2 -0
- package/dist/factory/index.d.ts.map +1 -1
- package/dist/index.cjs +177 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +177 -39
- package/dist/index.js.map +1 -1
- package/dist/interfaces/ICNS.d.ts +4 -2
- package/dist/interfaces/ICNS.d.ts.map +1 -1
- package/dist/types/TCNSDendrite.d.ts +1 -0
- package/dist/types/TCNSDendrite.d.ts.map +1 -1
- package/dist/types/TCNSNeuron.d.ts +2 -0
- package/dist/types/TCNSNeuron.d.ts.map +1 -1
- package/dist/types/TCNSNeuronResponseReturn.d.ts +1 -1
- package/dist/types/TCNSNeuronResponseReturn.d.ts.map +1 -1
- package/dist/types/TCNSSerializedSignal.d.ts +7 -0
- package/dist/types/TCNSSerializedSignal.d.ts.map +1 -0
- package/dist/types/TCNSSignal.d.ts +1 -2
- package/dist/types/TCNSSignal.d.ts.map +1 -1
- package/dist/types/TCNSStimulationOptions.d.ts +1 -1
- package/dist/types/TCNSStimulationOptions.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -104,7 +104,7 @@ var CNSFunctionalQueue = class {
|
|
|
104
104
|
throw err;
|
|
105
105
|
}
|
|
106
106
|
);
|
|
107
|
-
|
|
107
|
+
continue;
|
|
108
108
|
}
|
|
109
109
|
this.activeOperations--;
|
|
110
110
|
if (typeof ret === "function") ret();
|
|
@@ -134,6 +134,11 @@ var CNSStimulation = class {
|
|
|
134
134
|
this.cns = cns;
|
|
135
135
|
this.options = options;
|
|
136
136
|
this.scheduledCount = 0;
|
|
137
|
+
this.completed = new Promise((resolve, reject) => {
|
|
138
|
+
this.resolveCompleted = resolve;
|
|
139
|
+
this.rejectCompleted = reject;
|
|
140
|
+
});
|
|
141
|
+
this.isCompleted = false;
|
|
137
142
|
/**
|
|
138
143
|
* Track active SCCs: SCC index -> count of active neurons in that SCC
|
|
139
144
|
*/
|
|
@@ -149,6 +154,24 @@ var CNSStimulation = class {
|
|
|
149
154
|
if (this.options?.maxNeuronHops) {
|
|
150
155
|
this.nueronVisitMap = /* @__PURE__ */ new Map();
|
|
151
156
|
}
|
|
157
|
+
if (this.options?.abortSignal) {
|
|
158
|
+
this.options.abortSignal.addEventListener("abort", () => {
|
|
159
|
+
this.tryResolveCompleted();
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
tryResolveCompleted() {
|
|
164
|
+
if (this.isCompleted) return;
|
|
165
|
+
const noActive = this.queue.getActiveOperationsCount() === 0;
|
|
166
|
+
const noPending = this.queue.length + this.scheduledCount === 0;
|
|
167
|
+
const aborted = !!this.options?.abortSignal?.aborted;
|
|
168
|
+
if (noPending && noActive || aborted && noActive) {
|
|
169
|
+
this.isCompleted = true;
|
|
170
|
+
this.resolveCompleted();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
waitUntilComplete() {
|
|
174
|
+
return this.completed;
|
|
152
175
|
}
|
|
153
176
|
get concurrencyEnabled() {
|
|
154
177
|
return this.options?.concurrency !== void 0 && this.options?.concurrency > 0;
|
|
@@ -222,15 +245,31 @@ var CNSStimulation = class {
|
|
|
222
245
|
);
|
|
223
246
|
}
|
|
224
247
|
}
|
|
225
|
-
|
|
248
|
+
const serialized = {
|
|
226
249
|
neuronId: subscriber.neuron.name,
|
|
227
|
-
subscriber,
|
|
228
|
-
inputSignal
|
|
250
|
+
dendriteCollateralName: subscriber.dendrite.collateral.name,
|
|
251
|
+
input: inputSignal ? {
|
|
252
|
+
collateralName: inputSignal.collateralName,
|
|
253
|
+
payload: inputSignal.payload
|
|
254
|
+
} : void 0
|
|
229
255
|
};
|
|
256
|
+
return serialized;
|
|
230
257
|
}
|
|
231
258
|
processQueueItem(item) {
|
|
232
|
-
const
|
|
233
|
-
|
|
259
|
+
const subscribers = this.cns.getSubscribers(
|
|
260
|
+
item.dendriteCollateralName
|
|
261
|
+
);
|
|
262
|
+
const subscriber = subscribers.find(
|
|
263
|
+
(s) => s.neuron.name === item.neuronId
|
|
264
|
+
);
|
|
265
|
+
if (!subscriber) return () => {
|
|
266
|
+
};
|
|
267
|
+
const neuron2 = subscriber.neuron;
|
|
268
|
+
const dendrite = subscriber.dendrite;
|
|
269
|
+
const inputSignal = item.input ? {
|
|
270
|
+
collateralName: item.input.collateralName,
|
|
271
|
+
payload: item.input.payload
|
|
272
|
+
} : void 0;
|
|
234
273
|
const starter = () => {
|
|
235
274
|
this.markNeuronActive(neuron2.name);
|
|
236
275
|
const response = dendrite.response(
|
|
@@ -241,15 +280,38 @@ var CNSStimulation = class {
|
|
|
241
280
|
set: (value) => this.ctx.set(neuron2.name, value),
|
|
242
281
|
delete: () => this.ctx.delete(neuron2.name),
|
|
243
282
|
abortSignal: this.options?.abortSignal,
|
|
244
|
-
cns: this.cns
|
|
283
|
+
cns: this.cns,
|
|
284
|
+
stimulationId: this.id
|
|
245
285
|
}
|
|
246
286
|
);
|
|
247
|
-
|
|
248
|
-
|
|
287
|
+
const maxDuration = neuron2.maxDuration;
|
|
288
|
+
const asPromise = response instanceof Promise ? response : Promise.resolve(response);
|
|
289
|
+
const timedPromise = maxDuration && maxDuration > 0 ? new Promise((resolve, reject) => {
|
|
290
|
+
const t = setTimeout(() => {
|
|
291
|
+
const err = new Error(
|
|
292
|
+
`Neuron "${String(
|
|
293
|
+
neuron2.name
|
|
294
|
+
)}" exceeded maxDuration ${maxDuration}ms`
|
|
295
|
+
);
|
|
296
|
+
reject(err);
|
|
297
|
+
}, maxDuration);
|
|
298
|
+
asPromise.then(
|
|
299
|
+
(v) => {
|
|
300
|
+
clearTimeout(t);
|
|
301
|
+
resolve(v);
|
|
302
|
+
},
|
|
303
|
+
(e) => {
|
|
304
|
+
clearTimeout(t);
|
|
305
|
+
reject(e);
|
|
306
|
+
}
|
|
307
|
+
);
|
|
308
|
+
}) : asPromise;
|
|
309
|
+
if (response instanceof Promise || maxDuration) {
|
|
310
|
+
return timedPromise.then(
|
|
249
311
|
(signal) => {
|
|
250
312
|
return () => {
|
|
251
313
|
this.markNeuronInactive(neuron2.name);
|
|
252
|
-
return this.
|
|
314
|
+
return this.processResponseOrResponses(
|
|
253
315
|
inputSignal,
|
|
254
316
|
signal
|
|
255
317
|
);
|
|
@@ -258,7 +320,7 @@ var CNSStimulation = class {
|
|
|
258
320
|
(error) => {
|
|
259
321
|
return () => {
|
|
260
322
|
this.markNeuronInactive(neuron2.name);
|
|
261
|
-
return this.
|
|
323
|
+
return this.processResponseOrResponses(
|
|
262
324
|
inputSignal,
|
|
263
325
|
void 0,
|
|
264
326
|
error
|
|
@@ -269,7 +331,7 @@ var CNSStimulation = class {
|
|
|
269
331
|
} else {
|
|
270
332
|
return () => {
|
|
271
333
|
this.markNeuronInactive(neuron2.name);
|
|
272
|
-
return this.
|
|
334
|
+
return this.processResponseOrResponses(
|
|
273
335
|
inputSignal,
|
|
274
336
|
response
|
|
275
337
|
);
|
|
@@ -278,12 +340,25 @@ var CNSStimulation = class {
|
|
|
278
340
|
};
|
|
279
341
|
return this.instanceNeuronQueue.run(neuron2, starter);
|
|
280
342
|
}
|
|
343
|
+
processResponseOrResponses(inputSignal, outputSignalOrSignals, error) {
|
|
344
|
+
if (Array.isArray(outputSignalOrSignals)) {
|
|
345
|
+
if (outputSignalOrSignals.length === 0) {
|
|
346
|
+
this.processResponse(inputSignal, void 0, error);
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
for (const signal of outputSignalOrSignals) {
|
|
350
|
+
this.processResponse(inputSignal, signal, error);
|
|
351
|
+
}
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
this.processResponse(inputSignal, outputSignalOrSignals, error);
|
|
355
|
+
}
|
|
281
356
|
processResponse(inputSignal, outputSignal, error) {
|
|
282
|
-
const
|
|
283
|
-
const ownerNeuron =
|
|
284
|
-
const subscribers =
|
|
357
|
+
const collateralName = outputSignal?.collateralName;
|
|
358
|
+
const ownerNeuron = collateralName ? this.cns.getParentNeuronByCollateralName(collateralName) : void 0;
|
|
359
|
+
const subscribers = collateralName ? this.cns.getSubscribers(collateralName) : [];
|
|
285
360
|
const subscriberQueueItems = [];
|
|
286
|
-
if (
|
|
361
|
+
if (collateralName && !error) {
|
|
287
362
|
if (ownerNeuron) {
|
|
288
363
|
this.cleanupCtxIfNeeded(ownerNeuron);
|
|
289
364
|
}
|
|
@@ -294,28 +369,63 @@ var CNSStimulation = class {
|
|
|
294
369
|
}
|
|
295
370
|
}
|
|
296
371
|
this.scheduledCount += subscriberQueueItems.length;
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
372
|
+
let maybePromise;
|
|
373
|
+
try {
|
|
374
|
+
maybePromise = this.options?.onResponse?.({
|
|
375
|
+
inputSignal,
|
|
376
|
+
outputSignal,
|
|
377
|
+
ctx: this.ctx,
|
|
378
|
+
queueLength: this.queue.length + this.scheduledCount,
|
|
379
|
+
stimulationId: this.id,
|
|
380
|
+
hops: this.options?.maxNeuronHops && ownerNeuron ? this.nueronVisitMap?.get(ownerNeuron.name) ?? 0 : void 0,
|
|
381
|
+
error
|
|
382
|
+
});
|
|
383
|
+
} catch (e) {
|
|
384
|
+
this.rejectCompleted(e);
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
if (maybePromise && typeof maybePromise.then === "function") {
|
|
388
|
+
maybePromise.then(
|
|
389
|
+
() => {
|
|
390
|
+
for (let i = 0; i < subscriberQueueItems.length; i++) {
|
|
391
|
+
this.scheduledCount--;
|
|
392
|
+
this.queue.enqueue(subscriberQueueItems[i]);
|
|
393
|
+
}
|
|
394
|
+
this.tryResolveCompleted();
|
|
395
|
+
},
|
|
396
|
+
(error2) => {
|
|
397
|
+
this.rejectCompleted(error2);
|
|
398
|
+
}
|
|
399
|
+
);
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
306
402
|
for (let i = 0; i < subscriberQueueItems.length; i++) {
|
|
307
403
|
this.scheduledCount--;
|
|
308
404
|
this.queue.enqueue(subscriberQueueItems[i]);
|
|
309
405
|
}
|
|
406
|
+
this.tryResolveCompleted();
|
|
310
407
|
}
|
|
311
|
-
responseToSignal(
|
|
408
|
+
responseToSignal(signalOrSignals) {
|
|
409
|
+
if (Array.isArray(signalOrSignals)) {
|
|
410
|
+
for (const signal of signalOrSignals) {
|
|
411
|
+
const ownerNeuron2 = this.cns.getParentNeuronByCollateralName(
|
|
412
|
+
signal.collateralName
|
|
413
|
+
);
|
|
414
|
+
if (ownerNeuron2) {
|
|
415
|
+
this.markNeuronActive(ownerNeuron2.name);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
this.processResponseOrResponses(void 0, signalOrSignals);
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
312
421
|
const ownerNeuron = this.cns.getParentNeuronByCollateralName(
|
|
313
|
-
|
|
422
|
+
signalOrSignals.collateralName
|
|
314
423
|
);
|
|
315
424
|
if (ownerNeuron) {
|
|
316
425
|
this.markNeuronActive(ownerNeuron.name);
|
|
317
426
|
}
|
|
318
|
-
this.processResponse(void 0,
|
|
427
|
+
this.processResponse(void 0, signalOrSignals);
|
|
428
|
+
this.tryResolveCompleted();
|
|
319
429
|
}
|
|
320
430
|
};
|
|
321
431
|
|
|
@@ -551,16 +661,30 @@ var CNS = class {
|
|
|
551
661
|
};
|
|
552
662
|
}
|
|
553
663
|
return (r) => {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
664
|
+
let anyPromise = false;
|
|
665
|
+
const promises = [];
|
|
666
|
+
if (local) {
|
|
667
|
+
const res = local(r);
|
|
668
|
+
if (res && typeof res.then === "function") {
|
|
669
|
+
anyPromise = true;
|
|
670
|
+
promises.push(res);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
for (let i = 0; i < this.globalResponseListeners.length; i++) {
|
|
674
|
+
const res = this.globalResponseListeners[i](r);
|
|
675
|
+
if (res && typeof res.then === "function") {
|
|
676
|
+
anyPromise = true;
|
|
677
|
+
promises.push(res);
|
|
562
678
|
}
|
|
563
679
|
}
|
|
680
|
+
if (anyPromise) {
|
|
681
|
+
return Promise.allSettled(promises).then((results) => {
|
|
682
|
+
const rejected = results.find(
|
|
683
|
+
(r2) => r2.status === "rejected"
|
|
684
|
+
);
|
|
685
|
+
if (rejected) throw rejected.reason;
|
|
686
|
+
});
|
|
687
|
+
}
|
|
564
688
|
};
|
|
565
689
|
}
|
|
566
690
|
runWithNeuronConcurrency(neuron2, fn) {
|
|
@@ -840,16 +964,25 @@ var CNS = class {
|
|
|
840
964
|
getNeurons() {
|
|
841
965
|
return Array.from(this.neuronIndex.values());
|
|
842
966
|
}
|
|
967
|
+
getCollateralByName(collateralName) {
|
|
968
|
+
return this.collateralIndex.get(
|
|
969
|
+
collateralName
|
|
970
|
+
);
|
|
971
|
+
}
|
|
972
|
+
getNeuronByName(neuronName) {
|
|
973
|
+
return this.neuronIndex.get(neuronName);
|
|
974
|
+
}
|
|
843
975
|
getSubscribers(collateralName) {
|
|
844
976
|
return this.subIndex.get(collateralName) ?? [];
|
|
845
977
|
}
|
|
846
|
-
stimulate(
|
|
978
|
+
stimulate(signalOrSignals, options) {
|
|
847
979
|
const wrapped = this.wrapOnResponse(options?.onResponse);
|
|
848
980
|
const stimulation = new CNSStimulation(this, this.instanceNeuronQueue, {
|
|
849
981
|
...options,
|
|
850
982
|
onResponse: wrapped
|
|
851
983
|
});
|
|
852
|
-
stimulation.responseToSignal(
|
|
984
|
+
stimulation.responseToSignal(signalOrSignals);
|
|
985
|
+
return stimulation.waitUntilComplete();
|
|
853
986
|
}
|
|
854
987
|
};
|
|
855
988
|
|
|
@@ -859,7 +992,7 @@ var CNSCollateral = class {
|
|
|
859
992
|
this.name = name;
|
|
860
993
|
}
|
|
861
994
|
createSignal(payload) {
|
|
862
|
-
return {
|
|
995
|
+
return { collateralName: this.name, payload };
|
|
863
996
|
}
|
|
864
997
|
};
|
|
865
998
|
|
|
@@ -872,6 +1005,10 @@ var neuron = (name, axon) => {
|
|
|
872
1005
|
api.concurrency = n;
|
|
873
1006
|
return api;
|
|
874
1007
|
},
|
|
1008
|
+
setMaxDuration: (ms) => {
|
|
1009
|
+
api.maxDuration = ms;
|
|
1010
|
+
return api;
|
|
1011
|
+
},
|
|
875
1012
|
bind: ((axon2, newDendrites) => {
|
|
876
1013
|
for (const key in newDendrites) {
|
|
877
1014
|
const value = newDendrites[key];
|
|
@@ -888,6 +1025,7 @@ var neuron = (name, axon) => {
|
|
|
888
1025
|
axon,
|
|
889
1026
|
name,
|
|
890
1027
|
concurrency: void 0,
|
|
1028
|
+
maxDuration: void 0,
|
|
891
1029
|
dendrites,
|
|
892
1030
|
dendrite(s) {
|
|
893
1031
|
dendrites.push(
|