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