@cnstra/core 1.0.0 → 1.1.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 +34 -14
- package/dist/index.cjs +90 -45
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +87 -18
- package/dist/index.js.map +1 -0
- package/package.json +3 -2
- package/dist/index.d.cts +0 -56
- package/dist/index.d.ts +0 -56
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ const userService = neuron('user-service', {
|
|
|
44
44
|
})
|
|
45
45
|
.dendrite({
|
|
46
46
|
collateral: userCreated,
|
|
47
|
-
|
|
47
|
+
response: async (payload, axon) => {
|
|
48
48
|
const userData = payload as { id: string; name: string };
|
|
49
49
|
|
|
50
50
|
// Process the user creation
|
|
@@ -59,10 +59,10 @@ const userService = neuron('user-service', {
|
|
|
59
59
|
});
|
|
60
60
|
|
|
61
61
|
// Create the CNS system
|
|
62
|
-
const cns = new CNS(
|
|
62
|
+
const cns = new CNS([userService]);
|
|
63
63
|
|
|
64
64
|
// Stimulate the system
|
|
65
|
-
await cns.stimulate(
|
|
65
|
+
await cns.stimulate(userCreated, {
|
|
66
66
|
id: '123',
|
|
67
67
|
name: 'John Doe'
|
|
68
68
|
});
|
|
@@ -97,8 +97,9 @@ Adds a dendrite (input receptor) to a neuron. Returns the neuron for chaining.
|
|
|
97
97
|
myNeuron
|
|
98
98
|
.dendrite({
|
|
99
99
|
collateral: inputCollateral,
|
|
100
|
-
|
|
100
|
+
response: async (payload, axon, ctx) => {
|
|
101
101
|
// Process input and return output signal
|
|
102
|
+
// ctx parameter provides local context storage for this neuron
|
|
102
103
|
return axon.output.createSignal(result);
|
|
103
104
|
}
|
|
104
105
|
});
|
|
@@ -110,21 +111,20 @@ The main orchestrator that manages signal flow between neurons.
|
|
|
110
111
|
|
|
111
112
|
#### Constructor
|
|
112
113
|
```typescript
|
|
113
|
-
new CNS(
|
|
114
|
+
new CNS(neurons)
|
|
114
115
|
```
|
|
115
116
|
|
|
116
117
|
**Parameters:**
|
|
117
|
-
- `afferentAxon`: Object containing collaterals that can be used as input triggers
|
|
118
118
|
- `neurons`: Array of neurons that process signals
|
|
119
119
|
|
|
120
120
|
#### `stimulate()` Method
|
|
121
121
|
```typescript
|
|
122
|
-
await cns.stimulate(
|
|
122
|
+
await cns.stimulate(collateral, payload, options?)
|
|
123
123
|
```
|
|
124
124
|
|
|
125
125
|
**Parameters:**
|
|
126
|
-
- `
|
|
127
|
-
- `payload`: Signal payload
|
|
126
|
+
- `collateral`: The collateral instance to trigger
|
|
127
|
+
- `payload`: Signal payload data
|
|
128
128
|
- `options`: Optional configuration object
|
|
129
129
|
|
|
130
130
|
**Options:**
|
|
@@ -143,7 +143,7 @@ const processor = neuron('processor', {
|
|
|
143
143
|
})
|
|
144
144
|
.dendrite({
|
|
145
145
|
collateral: inputCollateral,
|
|
146
|
-
|
|
146
|
+
response: async (payload, axon) => {
|
|
147
147
|
// This signal is created but NOT processed
|
|
148
148
|
axon.output.createSignal({ message: 'Hello' });
|
|
149
149
|
|
|
@@ -160,7 +160,7 @@ Multiple neurons can listen to the same collateral:
|
|
|
160
160
|
const emailService = neuron('email-service', { emailSent })
|
|
161
161
|
.dendrite({
|
|
162
162
|
collateral: userCreated,
|
|
163
|
-
|
|
163
|
+
response: async (payload, axon) => {
|
|
164
164
|
return axon.emailSent.createSignal({ to: 'user@example.com' });
|
|
165
165
|
}
|
|
166
166
|
});
|
|
@@ -168,13 +168,13 @@ const emailService = neuron('email-service', { emailSent })
|
|
|
168
168
|
const notificationService = neuron('notification-service', { notificationSent })
|
|
169
169
|
.dendrite({
|
|
170
170
|
collateral: userCreated,
|
|
171
|
-
|
|
171
|
+
response: async (payload, axon) => {
|
|
172
172
|
return axon.notificationSent.createSignal({ message: 'User created' });
|
|
173
173
|
}
|
|
174
174
|
});
|
|
175
175
|
|
|
176
176
|
// Both neurons will process the userCreated signal
|
|
177
|
-
const cns = new CNS(
|
|
177
|
+
const cns = new CNS([emailService, notificationService]);
|
|
178
178
|
```
|
|
179
179
|
|
|
180
180
|
### Conditional Logic
|
|
@@ -185,7 +185,7 @@ const router = neuron('router', {
|
|
|
185
185
|
})
|
|
186
186
|
.dendrite({
|
|
187
187
|
collateral: requestCollateral,
|
|
188
|
-
|
|
188
|
+
response: async (payload, axon) => {
|
|
189
189
|
try {
|
|
190
190
|
const result = await processRequest(payload);
|
|
191
191
|
return axon.success.createSignal(result);
|
|
@@ -196,6 +196,26 @@ const router = neuron('router', {
|
|
|
196
196
|
});
|
|
197
197
|
```
|
|
198
198
|
|
|
199
|
+
### Context Management
|
|
200
|
+
|
|
201
|
+
Neurons can maintain local state using the context parameter:
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
const statefulNeuron = neuron('stateful', { output: outputCollateral })
|
|
205
|
+
.dendrite({
|
|
206
|
+
collateral: inputCollateral,
|
|
207
|
+
response: async (payload, axon, ctx) => {
|
|
208
|
+
// Get current state
|
|
209
|
+
const currentState = ctx.get();
|
|
210
|
+
|
|
211
|
+
// Update state
|
|
212
|
+
ctx.set({ count: (currentState?.count || 0) + 1 });
|
|
213
|
+
|
|
214
|
+
return axon.output.createSignal({ count: ctx.get()?.count });
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
```
|
|
218
|
+
|
|
199
219
|
## 🧪 Testing
|
|
200
220
|
|
|
201
221
|
```bash
|
package/dist/index.cjs
CHANGED
|
@@ -1,37 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/CNSStimulationContextStore.ts
|
|
4
|
+
var CNSStimulationContextStore = class {
|
|
5
|
+
constructor(ctx = /* @__PURE__ */ new Map()) {
|
|
6
|
+
this.ctx = ctx;
|
|
7
|
+
}
|
|
8
|
+
get(key) {
|
|
9
|
+
return this.ctx.get(key);
|
|
10
|
+
}
|
|
11
|
+
set(key, value) {
|
|
12
|
+
this.ctx.set(key, value);
|
|
15
13
|
}
|
|
16
|
-
return to;
|
|
17
14
|
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/index.ts
|
|
21
|
-
var index_exports = {};
|
|
22
|
-
__export(index_exports, {
|
|
23
|
-
CNS: () => CNS,
|
|
24
|
-
CNSCollateral: () => CNSCollateral,
|
|
25
|
-
collateral: () => collateral,
|
|
26
|
-
neuron: () => neuron
|
|
27
|
-
});
|
|
28
|
-
module.exports = __toCommonJS(index_exports);
|
|
29
15
|
|
|
30
16
|
// src/CNS.ts
|
|
31
17
|
var asArray = (x) => Array.isArray(x) ? x : [x];
|
|
32
18
|
var CNS = class {
|
|
33
|
-
constructor(
|
|
34
|
-
this.afferentLayerAsAxon = afferentLayerAsAxon;
|
|
19
|
+
constructor(neurons) {
|
|
35
20
|
this.neurons = neurons;
|
|
36
21
|
// index by collateral *type* => list of subscribers
|
|
37
22
|
this.subIndex = /* @__PURE__ */ new Map();
|
|
@@ -51,20 +36,23 @@ var CNS = class {
|
|
|
51
36
|
}
|
|
52
37
|
}
|
|
53
38
|
}
|
|
54
|
-
async fanOut(incoming, allowType, seen, queue) {
|
|
55
|
-
const subscribers = this.subIndex.get(incoming.
|
|
39
|
+
async fanOut(incoming, allowType, seen, queue, ctx) {
|
|
40
|
+
const subscribers = this.subIndex.get(incoming.collateralId);
|
|
56
41
|
if (!subscribers || subscribers.length === 0) return;
|
|
57
42
|
for (const { neuron: neuron2, dendrite } of subscribers) {
|
|
58
|
-
const k = `${neuron2.id}::${incoming.
|
|
43
|
+
const k = `${neuron2.id}::${incoming.collateralId}::${incoming.spikeId}`;
|
|
59
44
|
if (seen.has(k)) continue;
|
|
60
45
|
seen.add(k);
|
|
61
|
-
const out = await dendrite.
|
|
46
|
+
const out = await dendrite.response(incoming.payload, neuron2.axon, {
|
|
47
|
+
get: () => ctx.get(neuron2.id),
|
|
48
|
+
set: (value) => ctx.set(neuron2.id, value)
|
|
49
|
+
});
|
|
62
50
|
if (out === void 0) continue;
|
|
63
51
|
for (const spike of asArray(out)) {
|
|
64
52
|
if (allowType && !allowType(spike.type))
|
|
65
53
|
continue;
|
|
66
54
|
queue.push({
|
|
67
|
-
|
|
55
|
+
collateralId: spike.type,
|
|
68
56
|
payload: spike.payload,
|
|
69
57
|
hops: incoming.hops + 1,
|
|
70
58
|
spikeId: incoming.spikeId
|
|
@@ -73,13 +61,13 @@ var CNS = class {
|
|
|
73
61
|
}
|
|
74
62
|
}
|
|
75
63
|
}
|
|
76
|
-
async stimulate(
|
|
77
|
-
const
|
|
64
|
+
async stimulate(collateral2, payload, opts) {
|
|
65
|
+
const ctx = opts?.ctx ?? new CNSStimulationContextStore();
|
|
78
66
|
const spikeId = opts?.spikeId || Math.random().toString(36).slice(2);
|
|
79
67
|
const maxHops = opts?.maxHops ?? 1e3;
|
|
80
68
|
const queue = [
|
|
81
69
|
{
|
|
82
|
-
|
|
70
|
+
collateralId: collateral2.id,
|
|
83
71
|
payload,
|
|
84
72
|
hops: 0,
|
|
85
73
|
spikeId
|
|
@@ -90,7 +78,7 @@ var CNS = class {
|
|
|
90
78
|
if (opts?.abortSignal?.aborted) break;
|
|
91
79
|
const item = queue.shift();
|
|
92
80
|
opts?.onTrace?.({
|
|
93
|
-
|
|
81
|
+
collateralId: item.collateralId,
|
|
94
82
|
hops: item.hops,
|
|
95
83
|
payload: item.payload
|
|
96
84
|
});
|
|
@@ -99,7 +87,8 @@ var CNS = class {
|
|
|
99
87
|
item,
|
|
100
88
|
opts?.allowType,
|
|
101
89
|
seen,
|
|
102
|
-
queue
|
|
90
|
+
queue,
|
|
91
|
+
ctx
|
|
103
92
|
);
|
|
104
93
|
}
|
|
105
94
|
}
|
|
@@ -125,16 +114,72 @@ var neuron = (id, axon) => {
|
|
|
125
114
|
id,
|
|
126
115
|
dendrites,
|
|
127
116
|
dendrite(s) {
|
|
128
|
-
dendrites.push(
|
|
117
|
+
dendrites.push(
|
|
118
|
+
s
|
|
119
|
+
);
|
|
129
120
|
return api;
|
|
130
121
|
}
|
|
131
122
|
};
|
|
132
123
|
return api;
|
|
133
124
|
};
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
125
|
+
var withCtx = () => ({
|
|
126
|
+
neuron: (id, axon) => {
|
|
127
|
+
return neuron(id, axon);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
var request = collateral("request");
|
|
131
|
+
var success = collateral("success");
|
|
132
|
+
var error = collateral("error");
|
|
133
|
+
neuron("router", { success, error }).dendrite({
|
|
134
|
+
collateral: request,
|
|
135
|
+
response: async (payload, axon) => {
|
|
136
|
+
const value = payload.value;
|
|
137
|
+
if (value > 0) {
|
|
138
|
+
return axon.success.createSignal({
|
|
139
|
+
result: `Success: ${value}`
|
|
140
|
+
});
|
|
141
|
+
} else {
|
|
142
|
+
return axon.error.createSignal({
|
|
143
|
+
error: `Error: ${value} is not positive`
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
var a1 = {
|
|
149
|
+
test: collateral("test")
|
|
150
|
+
};
|
|
151
|
+
var a2 = {
|
|
152
|
+
test2: collateral("test2")
|
|
153
|
+
};
|
|
154
|
+
var a3 = {
|
|
155
|
+
test3: collateral("test3")
|
|
156
|
+
};
|
|
157
|
+
var n1 = withCtx().neuron("n1", a1).dendrite({
|
|
158
|
+
collateral: a2.test2,
|
|
159
|
+
response: async (payload, axon, ctx) => {
|
|
160
|
+
ctx.set({
|
|
161
|
+
testCtx: payload.test2
|
|
162
|
+
});
|
|
163
|
+
ctx.get()?.testCtx;
|
|
164
|
+
return axon.test.createSignal({
|
|
165
|
+
test: payload.test2
|
|
166
|
+
});
|
|
167
|
+
}
|
|
140
168
|
});
|
|
169
|
+
var n2 = neuron("n2", a2).dendrite({
|
|
170
|
+
collateral: a3.test3,
|
|
171
|
+
response: async (payload, axon) => {
|
|
172
|
+
return axon.test2.createSignal({
|
|
173
|
+
test2: payload.test3
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
new CNS([n1, n2]);
|
|
178
|
+
|
|
179
|
+
exports.CNS = CNS;
|
|
180
|
+
exports.CNSCollateral = CNSCollateral;
|
|
181
|
+
exports.collateral = collateral;
|
|
182
|
+
exports.neuron = neuron;
|
|
183
|
+
exports.withCtx = withCtx;
|
|
184
|
+
//# sourceMappingURL=index.cjs.map
|
|
185
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/CNSStimulationContextStore.ts","../src/CNS.ts","../src/CNSCollateral.ts","../src/factory/index.ts"],"names":["neuron","collateral"],"mappings":"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","file":"index.cjs","sourcesContent":["import { ICNSStimulationContextStore } from './interfaces/ICNSStimulationContextStore';\n\nexport class CNSStimulationContextStore implements ICNSStimulationContextStore {\n constructor(private readonly ctx: Map<string, unknown> = new Map()) {}\n\n get(key: string): unknown {\n return this.ctx.get(key);\n }\n\n set(key: string, value: unknown): void {\n this.ctx.set(key, value);\n }\n}\n","import { TCNSNeuron } from './types/TCNSNeuron';\nimport { TCNSDendrite } from './types/TCNSDendrite';\nimport { CNSCollateral } from './CNSCollateral';\nimport { ICNSStimulationContextStore } from './interfaces/ICNSStimulationContextStore';\nimport { CNSStimulationContextStore } from './CNSStimulationContextStore';\n\nconst asArray = <T>(x: T | T[]) => (Array.isArray(x) ? x : [x]);\n\ntype TSubscriber<\n TNeuron extends TCNSNeuron<any, any, any, any, any, any, any>,\n TDendrite extends TCNSDendrite<any, any, any, any, any, any>\n> = {\n neuron: TNeuron;\n dendrite: TDendrite;\n};\n\ntype TQueueItem<TCollateralId extends string> = {\n collateralId: TCollateralId;\n payload: unknown;\n hops: number;\n spikeId: string;\n};\n\nexport class CNS<\n TCollateralId extends string,\n TNeuron extends TCNSNeuron<any, any, any, any, any, any, any>,\n TDendrite extends TCNSDendrite<any, any, any, any, any, any>\n> {\n // index by collateral *type* => list of subscribers\n private subIndex = new Map<\n TCollateralId,\n TSubscriber<TNeuron, TDendrite>[]\n >();\n\n constructor(protected readonly neurons: TNeuron[]) {\n this.buildIndex();\n }\n\n private buildIndex() {\n this.subIndex.clear();\n for (const neuron of this.neurons) {\n for (const dendrite of neuron.dendrites) {\n const key = dendrite.collateral.id;\n const arr = this.subIndex.get(key) ?? [];\n arr.push({ neuron, dendrite: dendrite as TDendrite });\n this.subIndex.set(\n key,\n arr as TSubscriber<TNeuron, TDendrite>[]\n );\n }\n }\n }\n\n private async fanOut(\n incoming: TQueueItem<TCollateralId>,\n allowType: ((t: TCollateralId) => boolean) | undefined,\n seen: Set<string>,\n queue: TQueueItem<TCollateralId>[],\n ctx: ICNSStimulationContextStore\n ) {\n const subscribers = this.subIndex.get(incoming.collateralId);\n if (!subscribers || subscribers.length === 0) return;\n\n for (const { neuron, dendrite } of subscribers) {\n const k = `${neuron.id}::${incoming.collateralId}::${incoming.spikeId}`;\n if (seen.has(k)) continue;\n seen.add(k);\n\n const out = await dendrite.response(incoming.payload, neuron.axon, {\n get: () => ctx.get(neuron.id),\n set: value => ctx.set(neuron.id, value),\n });\n if (out === undefined) continue;\n\n for (const spike of asArray(out)) {\n if (allowType && !allowType(spike.type as TCollateralId))\n continue; // TODO: add allowType\n\n queue.push({\n collateralId: spike.type as TCollateralId,\n payload: spike.payload,\n hops: incoming.hops + 1,\n spikeId: incoming.spikeId, // keep the same spike id across the cascade\n });\n }\n }\n }\n\n async stimulate<\n TAfferentCollateralId extends TCollateralId,\n TAfferentCollateralPayload\n >(\n collateral: CNSCollateral<\n TAfferentCollateralId,\n TAfferentCollateralPayload\n >,\n payload: TAfferentCollateralPayload,\n opts?: {\n maxHops?: number;\n allowType?: (t: TCollateralId) => boolean;\n onTrace?: (e: {\n collateralId: TCollateralId;\n hops: number;\n payload: unknown;\n }) => void;\n abortSignal?: AbortSignal;\n spikeId?: string;\n ctx?: ICNSStimulationContextStore;\n }\n ): Promise<void> {\n const ctx = opts?.ctx ?? new CNSStimulationContextStore();\n const spikeId = opts?.spikeId || Math.random().toString(36).slice(2);\n const maxHops = opts?.maxHops ?? 1000;\n\n const queue: TQueueItem<TCollateralId>[] = [\n {\n collateralId: collateral.id,\n payload,\n hops: 0,\n spikeId,\n },\n ];\n const seen = new Set<string>();\n\n while (queue.length) {\n if (opts?.abortSignal?.aborted) break;\n\n const item = queue.shift()!;\n opts?.onTrace?.({\n collateralId: item.collateralId,\n hops: item.hops,\n payload: item.payload,\n });\n if (item.hops >= maxHops) continue;\n\n await this.fanOut(\n item as TQueueItem<TCollateralId>,\n opts?.allowType,\n seen,\n queue as TQueueItem<TCollateralId>[],\n ctx\n );\n }\n }\n}\n","import { TCNSSignal } from './types/TCNSSignal';\n\nexport class CNSCollateral<TId extends string, TPayload> {\n constructor(public readonly id: TId) {}\n\n createSignal(\n ...args: [TPayload] extends [undefined] ? [] : [payload: TPayload]\n ): TCNSSignal<TId, TPayload> {\n const payload = (args as any)[0] as TPayload;\n return { type: this.id, payload };\n }\n}\n","import { CNS } from '../CNS';\nimport { CNSCollateral } from '../CNSCollateral';\nimport { TCNSAxon } from '../types/TCNSAxon';\nimport { TCNSDendrite } from '../types/TCNSDendrite';\n\nexport const collateral = <TPayload = undefined, TId extends string = string>(\n id: TId\n) => new CNSCollateral<TId, TPayload>(id);\n\ntype InterNeuronAPI<\n TContextValue,\n TIdType extends string,\n TReceiverCollateralIdType extends string,\n TReceiverAxonCollateralPayload,\n TAxonType extends TCNSAxon<\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload\n >\n> = {\n id: TIdType;\n axon: TAxonType;\n dendrites: TCNSDendrite<\n TContextValue,\n string,\n unknown,\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload,\n TAxonType\n >[];\n dendrite: <\n TSenderExactCollateralIdType extends string,\n TSenderExactAxonCollateralPayload\n >(\n s: TCNSDendrite<\n TContextValue,\n TSenderExactCollateralIdType,\n TSenderExactAxonCollateralPayload,\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload,\n TAxonType\n >\n ) => InterNeuronAPI<\n TContextValue,\n TIdType,\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload,\n TAxonType\n >;\n};\n\n// Concrete builder\nexport const neuron = <\n TContextValue,\n TIdType extends string,\n TReceiverCollateralIdType extends string,\n TReceiverAxonCollateralPayload,\n TAxonType extends TCNSAxon<\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload\n >\n>(\n id: TIdType,\n axon: TAxonType\n): InterNeuronAPI<\n TContextValue,\n TIdType,\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload,\n TAxonType\n> => {\n const dendrites: TCNSDendrite<\n TContextValue,\n string,\n unknown,\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload,\n TAxonType\n >[] = [];\n\n const api: InterNeuronAPI<\n TContextValue,\n TIdType,\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload,\n TAxonType\n > = {\n axon,\n id,\n dendrites,\n dendrite<\n TSenderExactCollateralIdType extends string,\n TSenderExactAxonCollateralPayload\n >(\n s: TCNSDendrite<\n TContextValue,\n TSenderExactCollateralIdType,\n TSenderExactAxonCollateralPayload,\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload,\n TAxonType\n >\n ) {\n dendrites.push(\n s as TCNSDendrite<\n TContextValue,\n string,\n unknown,\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload,\n TAxonType\n >\n );\n return api; // keep full API for chaining\n },\n };\n\n return api;\n};\n\nexport const withCtx = <TContextValue>() => ({\n neuron: <\n TIdType extends string,\n TReceiverCollateralIdType extends string,\n TReceiverAxonCollateralPayload,\n TAxonType extends TCNSAxon<\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload\n >\n >(\n id: TIdType,\n axon: TAxonType\n ) => {\n return neuron<\n TContextValue,\n TIdType,\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload,\n TAxonType\n >(id, axon);\n },\n});\n\nconst request = collateral<{ value: number }>('request');\nconst success = collateral<{ result: string }>('success');\nconst error = collateral<{ error: string }>('error');\n\nconst router = neuron('router', { success, error }).dendrite({\n collateral: request,\n response: async (payload, axon) => {\n const value = (payload as { value: number }).value;\n if (value > 0) {\n return axon.success.createSignal({\n result: `Success: ${value}`,\n });\n } else {\n return axon.error.createSignal({\n error: `Error: ${value} is not positive`,\n });\n }\n },\n});\n\nconst a1 = {\n test: collateral<{ test: string }>('test'),\n};\n\nconst a2 = {\n test2: collateral<{ test2: string }>('test2'),\n};\n\nconst a3 = {\n test3: collateral<{ test3: string }>('test3'),\n};\n\nconst n1 = withCtx<{ testCtx: string }>()\n .neuron('n1', a1)\n .dendrite({\n collateral: a2.test2,\n response: async (payload, axon, ctx) => {\n ctx.set({\n testCtx: payload.test2,\n });\n ctx.get()?.testCtx;\n return axon.test.createSignal({\n test: payload.test2,\n });\n },\n });\n\nconst n2 = neuron('n2', a2).dendrite({\n collateral: a3.test3,\n response: async (payload, axon) => {\n return axon.test2.createSignal({\n test2: payload.test3,\n });\n },\n});\n\nconst cns = new CNS([n1, n2]);\n"]}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
|
+
// src/CNSStimulationContextStore.ts
|
|
2
|
+
var CNSStimulationContextStore = class {
|
|
3
|
+
constructor(ctx = /* @__PURE__ */ new Map()) {
|
|
4
|
+
this.ctx = ctx;
|
|
5
|
+
}
|
|
6
|
+
get(key) {
|
|
7
|
+
return this.ctx.get(key);
|
|
8
|
+
}
|
|
9
|
+
set(key, value) {
|
|
10
|
+
this.ctx.set(key, value);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
1
14
|
// src/CNS.ts
|
|
2
15
|
var asArray = (x) => Array.isArray(x) ? x : [x];
|
|
3
16
|
var CNS = class {
|
|
4
|
-
constructor(
|
|
5
|
-
this.afferentLayerAsAxon = afferentLayerAsAxon;
|
|
17
|
+
constructor(neurons) {
|
|
6
18
|
this.neurons = neurons;
|
|
7
19
|
// index by collateral *type* => list of subscribers
|
|
8
20
|
this.subIndex = /* @__PURE__ */ new Map();
|
|
@@ -22,20 +34,23 @@ var CNS = class {
|
|
|
22
34
|
}
|
|
23
35
|
}
|
|
24
36
|
}
|
|
25
|
-
async fanOut(incoming, allowType, seen, queue) {
|
|
26
|
-
const subscribers = this.subIndex.get(incoming.
|
|
37
|
+
async fanOut(incoming, allowType, seen, queue, ctx) {
|
|
38
|
+
const subscribers = this.subIndex.get(incoming.collateralId);
|
|
27
39
|
if (!subscribers || subscribers.length === 0) return;
|
|
28
40
|
for (const { neuron: neuron2, dendrite } of subscribers) {
|
|
29
|
-
const k = `${neuron2.id}::${incoming.
|
|
41
|
+
const k = `${neuron2.id}::${incoming.collateralId}::${incoming.spikeId}`;
|
|
30
42
|
if (seen.has(k)) continue;
|
|
31
43
|
seen.add(k);
|
|
32
|
-
const out = await dendrite.
|
|
44
|
+
const out = await dendrite.response(incoming.payload, neuron2.axon, {
|
|
45
|
+
get: () => ctx.get(neuron2.id),
|
|
46
|
+
set: (value) => ctx.set(neuron2.id, value)
|
|
47
|
+
});
|
|
33
48
|
if (out === void 0) continue;
|
|
34
49
|
for (const spike of asArray(out)) {
|
|
35
50
|
if (allowType && !allowType(spike.type))
|
|
36
51
|
continue;
|
|
37
52
|
queue.push({
|
|
38
|
-
|
|
53
|
+
collateralId: spike.type,
|
|
39
54
|
payload: spike.payload,
|
|
40
55
|
hops: incoming.hops + 1,
|
|
41
56
|
spikeId: incoming.spikeId
|
|
@@ -44,13 +59,13 @@ var CNS = class {
|
|
|
44
59
|
}
|
|
45
60
|
}
|
|
46
61
|
}
|
|
47
|
-
async stimulate(
|
|
48
|
-
const
|
|
62
|
+
async stimulate(collateral2, payload, opts) {
|
|
63
|
+
const ctx = opts?.ctx ?? new CNSStimulationContextStore();
|
|
49
64
|
const spikeId = opts?.spikeId || Math.random().toString(36).slice(2);
|
|
50
65
|
const maxHops = opts?.maxHops ?? 1e3;
|
|
51
66
|
const queue = [
|
|
52
67
|
{
|
|
53
|
-
|
|
68
|
+
collateralId: collateral2.id,
|
|
54
69
|
payload,
|
|
55
70
|
hops: 0,
|
|
56
71
|
spikeId
|
|
@@ -61,7 +76,7 @@ var CNS = class {
|
|
|
61
76
|
if (opts?.abortSignal?.aborted) break;
|
|
62
77
|
const item = queue.shift();
|
|
63
78
|
opts?.onTrace?.({
|
|
64
|
-
|
|
79
|
+
collateralId: item.collateralId,
|
|
65
80
|
hops: item.hops,
|
|
66
81
|
payload: item.payload
|
|
67
82
|
});
|
|
@@ -70,7 +85,8 @@ var CNS = class {
|
|
|
70
85
|
item,
|
|
71
86
|
opts?.allowType,
|
|
72
87
|
seen,
|
|
73
|
-
queue
|
|
88
|
+
queue,
|
|
89
|
+
ctx
|
|
74
90
|
);
|
|
75
91
|
}
|
|
76
92
|
}
|
|
@@ -96,15 +112,68 @@ var neuron = (id, axon) => {
|
|
|
96
112
|
id,
|
|
97
113
|
dendrites,
|
|
98
114
|
dendrite(s) {
|
|
99
|
-
dendrites.push(
|
|
115
|
+
dendrites.push(
|
|
116
|
+
s
|
|
117
|
+
);
|
|
100
118
|
return api;
|
|
101
119
|
}
|
|
102
120
|
};
|
|
103
121
|
return api;
|
|
104
122
|
};
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
123
|
+
var withCtx = () => ({
|
|
124
|
+
neuron: (id, axon) => {
|
|
125
|
+
return neuron(id, axon);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
var request = collateral("request");
|
|
129
|
+
var success = collateral("success");
|
|
130
|
+
var error = collateral("error");
|
|
131
|
+
neuron("router", { success, error }).dendrite({
|
|
132
|
+
collateral: request,
|
|
133
|
+
response: async (payload, axon) => {
|
|
134
|
+
const value = payload.value;
|
|
135
|
+
if (value > 0) {
|
|
136
|
+
return axon.success.createSignal({
|
|
137
|
+
result: `Success: ${value}`
|
|
138
|
+
});
|
|
139
|
+
} else {
|
|
140
|
+
return axon.error.createSignal({
|
|
141
|
+
error: `Error: ${value} is not positive`
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
var a1 = {
|
|
147
|
+
test: collateral("test")
|
|
148
|
+
};
|
|
149
|
+
var a2 = {
|
|
150
|
+
test2: collateral("test2")
|
|
110
151
|
};
|
|
152
|
+
var a3 = {
|
|
153
|
+
test3: collateral("test3")
|
|
154
|
+
};
|
|
155
|
+
var n1 = withCtx().neuron("n1", a1).dendrite({
|
|
156
|
+
collateral: a2.test2,
|
|
157
|
+
response: async (payload, axon, ctx) => {
|
|
158
|
+
ctx.set({
|
|
159
|
+
testCtx: payload.test2
|
|
160
|
+
});
|
|
161
|
+
ctx.get()?.testCtx;
|
|
162
|
+
return axon.test.createSignal({
|
|
163
|
+
test: payload.test2
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
var n2 = neuron("n2", a2).dendrite({
|
|
168
|
+
collateral: a3.test3,
|
|
169
|
+
response: async (payload, axon) => {
|
|
170
|
+
return axon.test2.createSignal({
|
|
171
|
+
test2: payload.test3
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
new CNS([n1, n2]);
|
|
176
|
+
|
|
177
|
+
export { CNS, CNSCollateral, collateral, neuron, withCtx };
|
|
178
|
+
//# sourceMappingURL=index.js.map
|
|
179
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/CNSStimulationContextStore.ts","../src/CNS.ts","../src/CNSCollateral.ts","../src/factory/index.ts"],"names":["neuron","collateral"],"mappings":"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","file":"index.js","sourcesContent":["import { ICNSStimulationContextStore } from './interfaces/ICNSStimulationContextStore';\n\nexport class CNSStimulationContextStore implements ICNSStimulationContextStore {\n constructor(private readonly ctx: Map<string, unknown> = new Map()) {}\n\n get(key: string): unknown {\n return this.ctx.get(key);\n }\n\n set(key: string, value: unknown): void {\n this.ctx.set(key, value);\n }\n}\n","import { TCNSNeuron } from './types/TCNSNeuron';\nimport { TCNSDendrite } from './types/TCNSDendrite';\nimport { CNSCollateral } from './CNSCollateral';\nimport { ICNSStimulationContextStore } from './interfaces/ICNSStimulationContextStore';\nimport { CNSStimulationContextStore } from './CNSStimulationContextStore';\n\nconst asArray = <T>(x: T | T[]) => (Array.isArray(x) ? x : [x]);\n\ntype TSubscriber<\n TNeuron extends TCNSNeuron<any, any, any, any, any, any, any>,\n TDendrite extends TCNSDendrite<any, any, any, any, any, any>\n> = {\n neuron: TNeuron;\n dendrite: TDendrite;\n};\n\ntype TQueueItem<TCollateralId extends string> = {\n collateralId: TCollateralId;\n payload: unknown;\n hops: number;\n spikeId: string;\n};\n\nexport class CNS<\n TCollateralId extends string,\n TNeuron extends TCNSNeuron<any, any, any, any, any, any, any>,\n TDendrite extends TCNSDendrite<any, any, any, any, any, any>\n> {\n // index by collateral *type* => list of subscribers\n private subIndex = new Map<\n TCollateralId,\n TSubscriber<TNeuron, TDendrite>[]\n >();\n\n constructor(protected readonly neurons: TNeuron[]) {\n this.buildIndex();\n }\n\n private buildIndex() {\n this.subIndex.clear();\n for (const neuron of this.neurons) {\n for (const dendrite of neuron.dendrites) {\n const key = dendrite.collateral.id;\n const arr = this.subIndex.get(key) ?? [];\n arr.push({ neuron, dendrite: dendrite as TDendrite });\n this.subIndex.set(\n key,\n arr as TSubscriber<TNeuron, TDendrite>[]\n );\n }\n }\n }\n\n private async fanOut(\n incoming: TQueueItem<TCollateralId>,\n allowType: ((t: TCollateralId) => boolean) | undefined,\n seen: Set<string>,\n queue: TQueueItem<TCollateralId>[],\n ctx: ICNSStimulationContextStore\n ) {\n const subscribers = this.subIndex.get(incoming.collateralId);\n if (!subscribers || subscribers.length === 0) return;\n\n for (const { neuron, dendrite } of subscribers) {\n const k = `${neuron.id}::${incoming.collateralId}::${incoming.spikeId}`;\n if (seen.has(k)) continue;\n seen.add(k);\n\n const out = await dendrite.response(incoming.payload, neuron.axon, {\n get: () => ctx.get(neuron.id),\n set: value => ctx.set(neuron.id, value),\n });\n if (out === undefined) continue;\n\n for (const spike of asArray(out)) {\n if (allowType && !allowType(spike.type as TCollateralId))\n continue; // TODO: add allowType\n\n queue.push({\n collateralId: spike.type as TCollateralId,\n payload: spike.payload,\n hops: incoming.hops + 1,\n spikeId: incoming.spikeId, // keep the same spike id across the cascade\n });\n }\n }\n }\n\n async stimulate<\n TAfferentCollateralId extends TCollateralId,\n TAfferentCollateralPayload\n >(\n collateral: CNSCollateral<\n TAfferentCollateralId,\n TAfferentCollateralPayload\n >,\n payload: TAfferentCollateralPayload,\n opts?: {\n maxHops?: number;\n allowType?: (t: TCollateralId) => boolean;\n onTrace?: (e: {\n collateralId: TCollateralId;\n hops: number;\n payload: unknown;\n }) => void;\n abortSignal?: AbortSignal;\n spikeId?: string;\n ctx?: ICNSStimulationContextStore;\n }\n ): Promise<void> {\n const ctx = opts?.ctx ?? new CNSStimulationContextStore();\n const spikeId = opts?.spikeId || Math.random().toString(36).slice(2);\n const maxHops = opts?.maxHops ?? 1000;\n\n const queue: TQueueItem<TCollateralId>[] = [\n {\n collateralId: collateral.id,\n payload,\n hops: 0,\n spikeId,\n },\n ];\n const seen = new Set<string>();\n\n while (queue.length) {\n if (opts?.abortSignal?.aborted) break;\n\n const item = queue.shift()!;\n opts?.onTrace?.({\n collateralId: item.collateralId,\n hops: item.hops,\n payload: item.payload,\n });\n if (item.hops >= maxHops) continue;\n\n await this.fanOut(\n item as TQueueItem<TCollateralId>,\n opts?.allowType,\n seen,\n queue as TQueueItem<TCollateralId>[],\n ctx\n );\n }\n }\n}\n","import { TCNSSignal } from './types/TCNSSignal';\n\nexport class CNSCollateral<TId extends string, TPayload> {\n constructor(public readonly id: TId) {}\n\n createSignal(\n ...args: [TPayload] extends [undefined] ? [] : [payload: TPayload]\n ): TCNSSignal<TId, TPayload> {\n const payload = (args as any)[0] as TPayload;\n return { type: this.id, payload };\n }\n}\n","import { CNS } from '../CNS';\nimport { CNSCollateral } from '../CNSCollateral';\nimport { TCNSAxon } from '../types/TCNSAxon';\nimport { TCNSDendrite } from '../types/TCNSDendrite';\n\nexport const collateral = <TPayload = undefined, TId extends string = string>(\n id: TId\n) => new CNSCollateral<TId, TPayload>(id);\n\ntype InterNeuronAPI<\n TContextValue,\n TIdType extends string,\n TReceiverCollateralIdType extends string,\n TReceiverAxonCollateralPayload,\n TAxonType extends TCNSAxon<\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload\n >\n> = {\n id: TIdType;\n axon: TAxonType;\n dendrites: TCNSDendrite<\n TContextValue,\n string,\n unknown,\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload,\n TAxonType\n >[];\n dendrite: <\n TSenderExactCollateralIdType extends string,\n TSenderExactAxonCollateralPayload\n >(\n s: TCNSDendrite<\n TContextValue,\n TSenderExactCollateralIdType,\n TSenderExactAxonCollateralPayload,\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload,\n TAxonType\n >\n ) => InterNeuronAPI<\n TContextValue,\n TIdType,\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload,\n TAxonType\n >;\n};\n\n// Concrete builder\nexport const neuron = <\n TContextValue,\n TIdType extends string,\n TReceiverCollateralIdType extends string,\n TReceiverAxonCollateralPayload,\n TAxonType extends TCNSAxon<\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload\n >\n>(\n id: TIdType,\n axon: TAxonType\n): InterNeuronAPI<\n TContextValue,\n TIdType,\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload,\n TAxonType\n> => {\n const dendrites: TCNSDendrite<\n TContextValue,\n string,\n unknown,\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload,\n TAxonType\n >[] = [];\n\n const api: InterNeuronAPI<\n TContextValue,\n TIdType,\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload,\n TAxonType\n > = {\n axon,\n id,\n dendrites,\n dendrite<\n TSenderExactCollateralIdType extends string,\n TSenderExactAxonCollateralPayload\n >(\n s: TCNSDendrite<\n TContextValue,\n TSenderExactCollateralIdType,\n TSenderExactAxonCollateralPayload,\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload,\n TAxonType\n >\n ) {\n dendrites.push(\n s as TCNSDendrite<\n TContextValue,\n string,\n unknown,\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload,\n TAxonType\n >\n );\n return api; // keep full API for chaining\n },\n };\n\n return api;\n};\n\nexport const withCtx = <TContextValue>() => ({\n neuron: <\n TIdType extends string,\n TReceiverCollateralIdType extends string,\n TReceiverAxonCollateralPayload,\n TAxonType extends TCNSAxon<\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload\n >\n >(\n id: TIdType,\n axon: TAxonType\n ) => {\n return neuron<\n TContextValue,\n TIdType,\n TReceiverCollateralIdType,\n TReceiverAxonCollateralPayload,\n TAxonType\n >(id, axon);\n },\n});\n\nconst request = collateral<{ value: number }>('request');\nconst success = collateral<{ result: string }>('success');\nconst error = collateral<{ error: string }>('error');\n\nconst router = neuron('router', { success, error }).dendrite({\n collateral: request,\n response: async (payload, axon) => {\n const value = (payload as { value: number }).value;\n if (value > 0) {\n return axon.success.createSignal({\n result: `Success: ${value}`,\n });\n } else {\n return axon.error.createSignal({\n error: `Error: ${value} is not positive`,\n });\n }\n },\n});\n\nconst a1 = {\n test: collateral<{ test: string }>('test'),\n};\n\nconst a2 = {\n test2: collateral<{ test2: string }>('test2'),\n};\n\nconst a3 = {\n test3: collateral<{ test3: string }>('test3'),\n};\n\nconst n1 = withCtx<{ testCtx: string }>()\n .neuron('n1', a1)\n .dendrite({\n collateral: a2.test2,\n response: async (payload, axon, ctx) => {\n ctx.set({\n testCtx: payload.test2,\n });\n ctx.get()?.testCtx;\n return axon.test.createSignal({\n test: payload.test2,\n });\n },\n });\n\nconst n2 = neuron('n2', a2).dendrite({\n collateral: a3.test3,\n response: async (payload, axon) => {\n return axon.test2.createSignal({\n test2: payload.test3,\n });\n },\n});\n\nconst cns = new CNS([n1, n2]);\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cnstra/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Neural network-inspired event flow system for building reactive applications with dependency-injected neurons and synapses",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"neural-network",
|
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"scripts": {
|
|
39
|
-
"build": "tsup
|
|
39
|
+
"build": "tsup && tsc --emitDeclarationOnly",
|
|
40
|
+
"build:types": "tsc --emitDeclarationOnly",
|
|
40
41
|
"prepublishOnly": "npm run build",
|
|
41
42
|
"test": "jest",
|
|
42
43
|
"test:types": "tsd",
|
package/dist/index.d.cts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
type TCNSSignal<TType extends string, TPayload> = {
|
|
2
|
-
type: TType;
|
|
3
|
-
payload?: TPayload;
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
declare class CNSCollateral<TId extends string, TPayload> {
|
|
7
|
-
readonly id: TId;
|
|
8
|
-
constructor(id: TId);
|
|
9
|
-
createSignal(...args: [TPayload] extends [undefined] ? [] : [payload: TPayload]): TCNSSignal<TId, TPayload>;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
type TCNSAxon<TCId extends string, TInputPayload = unknown> = Record<TCId, CNSCollateral<TCId, TInputPayload>>;
|
|
13
|
-
|
|
14
|
-
type TCNDendrite<TSenderCollateralIdType extends string, TReceiverAxonCollateralPayload, TReceiverCollateralIdType extends string, TReceiverAxon extends TCNSAxon<TReceiverCollateralIdType, TReceiverAxonCollateralPayload>> = {
|
|
15
|
-
collateral: CNSCollateral<TSenderCollateralIdType, TReceiverAxonCollateralPayload>;
|
|
16
|
-
reaction: (payload: TReceiverAxonCollateralPayload, axon: TReceiverAxon) => Promise<ReturnType<CNSCollateral<TReceiverCollateralIdType, TReceiverAxonCollateralPayload>['createSignal']>> | ReturnType<CNSCollateral<TReceiverCollateralIdType, TReceiverAxonCollateralPayload>['createSignal']> | Promise<void> | void;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
type TCNSNeuron<TId extends string, TCollateralId extends string, TAxon extends TCNSAxon<TCollateralId, unknown>, TSenderCollateralId extends string, TDendrites extends TCNDendrite<TSenderCollateralId, unknown, TCollateralId, TAxon>[]> = {
|
|
20
|
-
id: TId;
|
|
21
|
-
axon: TAxon;
|
|
22
|
-
dendrites: TDendrites;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
declare class CNS<TAfferentCollateralId extends string, TAfferentAxon extends TCNSAxon<TAfferentCollateralId, unknown>, TNeuronId extends string, TCollateralId extends string, TAxon extends TCNSAxon<TCollateralId, any>> {
|
|
26
|
-
protected readonly afferentLayerAsAxon: TAfferentAxon;
|
|
27
|
-
protected readonly neurons: TCNSNeuron<TNeuronId, TCollateralId, TAxon, TCollateralId, TCNDendrite<TCollateralId, any, TCollateralId, TAxon>[]>[];
|
|
28
|
-
private subIndex;
|
|
29
|
-
constructor(afferentLayerAsAxon: TAfferentAxon, neurons: TCNSNeuron<TNeuronId, TCollateralId, TAxon, TCollateralId, TCNDendrite<TCollateralId, any, TCollateralId, TAxon>[]>[]);
|
|
30
|
-
private buildIndex;
|
|
31
|
-
private fanOut;
|
|
32
|
-
stimulate<K extends keyof TAfferentAxon, TACollateralId extends string>(axonKey: K, payload: ReturnType<TAfferentAxon[K]['createSignal']> & {
|
|
33
|
-
type: TACollateralId;
|
|
34
|
-
}, opts?: {
|
|
35
|
-
maxHops?: number;
|
|
36
|
-
allowType?: (t: TCollateralId | TAfferentCollateralId) => boolean;
|
|
37
|
-
onTrace?: (e: {
|
|
38
|
-
edgeId: TCollateralId | TAfferentCollateralId;
|
|
39
|
-
hops: number;
|
|
40
|
-
payload: unknown;
|
|
41
|
-
}) => void;
|
|
42
|
-
abortSignal?: AbortSignal;
|
|
43
|
-
spikeId?: string;
|
|
44
|
-
}): Promise<void>;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
declare const collateral: <TPayload = undefined, TId extends string = string>(id: TId) => CNSCollateral<TId, TPayload>;
|
|
48
|
-
type InterNeuronAPI<TIdType extends string, TSenderCollateralIdType extends string, TReceiverAxonCollateralPayload, TReceiverCollateralIdType extends string, TReceiverAxon extends TCNSAxon<TReceiverCollateralIdType, TReceiverAxonCollateralPayload>> = {
|
|
49
|
-
id: TIdType;
|
|
50
|
-
axon: TReceiverAxon;
|
|
51
|
-
dendrites: TCNDendrite<TSenderCollateralIdType, TReceiverAxonCollateralPayload, TReceiverCollateralIdType, TReceiverAxon>[];
|
|
52
|
-
dendrite: (s: TCNDendrite<TSenderCollateralIdType, TReceiverAxonCollateralPayload, TReceiverCollateralIdType, TReceiverAxon>) => InterNeuronAPI<TIdType, TSenderCollateralIdType, TReceiverAxonCollateralPayload, TReceiverCollateralIdType, TReceiverAxon>;
|
|
53
|
-
};
|
|
54
|
-
declare const neuron: <TIdType extends string, TSenderCollateralIdType extends string, TReceiverAxonCollateralPayload, TReceiverCollateralIdType extends string, TReceiverAxon extends TCNSAxon<TReceiverCollateralIdType, TReceiverAxonCollateralPayload>>(id: TIdType, axon: TReceiverAxon) => InterNeuronAPI<TIdType, TSenderCollateralIdType, TReceiverAxonCollateralPayload, TReceiverCollateralIdType, TReceiverAxon>;
|
|
55
|
-
|
|
56
|
-
export { CNS, CNSCollateral, type TCNDendrite, type TCNSAxon, type TCNSNeuron, type TCNSSignal, collateral, neuron };
|
package/dist/index.d.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
type TCNSSignal<TType extends string, TPayload> = {
|
|
2
|
-
type: TType;
|
|
3
|
-
payload?: TPayload;
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
declare class CNSCollateral<TId extends string, TPayload> {
|
|
7
|
-
readonly id: TId;
|
|
8
|
-
constructor(id: TId);
|
|
9
|
-
createSignal(...args: [TPayload] extends [undefined] ? [] : [payload: TPayload]): TCNSSignal<TId, TPayload>;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
type TCNSAxon<TCId extends string, TInputPayload = unknown> = Record<TCId, CNSCollateral<TCId, TInputPayload>>;
|
|
13
|
-
|
|
14
|
-
type TCNDendrite<TSenderCollateralIdType extends string, TReceiverAxonCollateralPayload, TReceiverCollateralIdType extends string, TReceiverAxon extends TCNSAxon<TReceiverCollateralIdType, TReceiverAxonCollateralPayload>> = {
|
|
15
|
-
collateral: CNSCollateral<TSenderCollateralIdType, TReceiverAxonCollateralPayload>;
|
|
16
|
-
reaction: (payload: TReceiverAxonCollateralPayload, axon: TReceiverAxon) => Promise<ReturnType<CNSCollateral<TReceiverCollateralIdType, TReceiverAxonCollateralPayload>['createSignal']>> | ReturnType<CNSCollateral<TReceiverCollateralIdType, TReceiverAxonCollateralPayload>['createSignal']> | Promise<void> | void;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
type TCNSNeuron<TId extends string, TCollateralId extends string, TAxon extends TCNSAxon<TCollateralId, unknown>, TSenderCollateralId extends string, TDendrites extends TCNDendrite<TSenderCollateralId, unknown, TCollateralId, TAxon>[]> = {
|
|
20
|
-
id: TId;
|
|
21
|
-
axon: TAxon;
|
|
22
|
-
dendrites: TDendrites;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
declare class CNS<TAfferentCollateralId extends string, TAfferentAxon extends TCNSAxon<TAfferentCollateralId, unknown>, TNeuronId extends string, TCollateralId extends string, TAxon extends TCNSAxon<TCollateralId, any>> {
|
|
26
|
-
protected readonly afferentLayerAsAxon: TAfferentAxon;
|
|
27
|
-
protected readonly neurons: TCNSNeuron<TNeuronId, TCollateralId, TAxon, TCollateralId, TCNDendrite<TCollateralId, any, TCollateralId, TAxon>[]>[];
|
|
28
|
-
private subIndex;
|
|
29
|
-
constructor(afferentLayerAsAxon: TAfferentAxon, neurons: TCNSNeuron<TNeuronId, TCollateralId, TAxon, TCollateralId, TCNDendrite<TCollateralId, any, TCollateralId, TAxon>[]>[]);
|
|
30
|
-
private buildIndex;
|
|
31
|
-
private fanOut;
|
|
32
|
-
stimulate<K extends keyof TAfferentAxon, TACollateralId extends string>(axonKey: K, payload: ReturnType<TAfferentAxon[K]['createSignal']> & {
|
|
33
|
-
type: TACollateralId;
|
|
34
|
-
}, opts?: {
|
|
35
|
-
maxHops?: number;
|
|
36
|
-
allowType?: (t: TCollateralId | TAfferentCollateralId) => boolean;
|
|
37
|
-
onTrace?: (e: {
|
|
38
|
-
edgeId: TCollateralId | TAfferentCollateralId;
|
|
39
|
-
hops: number;
|
|
40
|
-
payload: unknown;
|
|
41
|
-
}) => void;
|
|
42
|
-
abortSignal?: AbortSignal;
|
|
43
|
-
spikeId?: string;
|
|
44
|
-
}): Promise<void>;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
declare const collateral: <TPayload = undefined, TId extends string = string>(id: TId) => CNSCollateral<TId, TPayload>;
|
|
48
|
-
type InterNeuronAPI<TIdType extends string, TSenderCollateralIdType extends string, TReceiverAxonCollateralPayload, TReceiverCollateralIdType extends string, TReceiverAxon extends TCNSAxon<TReceiverCollateralIdType, TReceiverAxonCollateralPayload>> = {
|
|
49
|
-
id: TIdType;
|
|
50
|
-
axon: TReceiverAxon;
|
|
51
|
-
dendrites: TCNDendrite<TSenderCollateralIdType, TReceiverAxonCollateralPayload, TReceiverCollateralIdType, TReceiverAxon>[];
|
|
52
|
-
dendrite: (s: TCNDendrite<TSenderCollateralIdType, TReceiverAxonCollateralPayload, TReceiverCollateralIdType, TReceiverAxon>) => InterNeuronAPI<TIdType, TSenderCollateralIdType, TReceiverAxonCollateralPayload, TReceiverCollateralIdType, TReceiverAxon>;
|
|
53
|
-
};
|
|
54
|
-
declare const neuron: <TIdType extends string, TSenderCollateralIdType extends string, TReceiverAxonCollateralPayload, TReceiverCollateralIdType extends string, TReceiverAxon extends TCNSAxon<TReceiverCollateralIdType, TReceiverAxonCollateralPayload>>(id: TIdType, axon: TReceiverAxon) => InterNeuronAPI<TIdType, TSenderCollateralIdType, TReceiverAxonCollateralPayload, TReceiverCollateralIdType, TReceiverAxon>;
|
|
55
|
-
|
|
56
|
-
export { CNS, CNSCollateral, type TCNDendrite, type TCNSAxon, type TCNSNeuron, type TCNSSignal, collateral, neuron };
|