@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 CHANGED
@@ -44,7 +44,7 @@ const userService = neuron('user-service', {
44
44
  })
45
45
  .dendrite({
46
46
  collateral: userCreated,
47
- reaction: async (payload, axon) => {
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({ userCreated }, [userService]);
62
+ const cns = new CNS([userService]);
63
63
 
64
64
  // Stimulate the system
65
- await cns.stimulate('userCreated', {
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
- reaction: async (payload, axon) => {
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(afferentAxon, neurons)
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(axonKey, payload, options?)
122
+ await cns.stimulate(collateral, payload, options?)
123
123
  ```
124
124
 
125
125
  **Parameters:**
126
- - `axonKey`: Key from the afferent axon to trigger
127
- - `payload`: Signal payload with type and data
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
- reaction: async (payload, axon) => {
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
- reaction: async (payload, axon) => {
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
- reaction: async (payload, axon) => {
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({ userCreated }, [emailService, notificationService]);
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
- reaction: async (payload, axon) => {
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
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
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(afferentLayerAsAxon, neurons) {
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.edgeId);
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.edgeId}::${incoming.spikeId}`;
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.reaction(incoming.payload, neuron2.axon);
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
- edgeId: spike.type,
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(axonKey, payload, opts) {
77
- const afferent = this.afferentLayerAsAxon[axonKey];
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
- edgeId: afferent.id,
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
- edgeId: item.edgeId,
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(s);
117
+ dendrites.push(
118
+ s
119
+ );
129
120
  return api;
130
121
  }
131
122
  };
132
123
  return api;
133
124
  };
134
- // Annotate the CommonJS export names for ESM import in node:
135
- 0 && (module.exports = {
136
- CNS,
137
- CNSCollateral,
138
- collateral,
139
- neuron
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":";;;AAEO,IAAM,6BAAN,MAAwE;AAAA,EAC3E,WAAA,CAA6B,GAAA,mBAA4B,IAAI,GAAA,EAAI,EAAG;AAAvC,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAwC;AAAA,EAErE,IAAI,GAAA,EAAsB;AACtB,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA;AAAA,EAC3B;AAAA,EAEA,GAAA,CAAI,KAAa,KAAA,EAAsB;AACnC,IAAA,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,GAAA,EAAK,KAAK,CAAA;AAAA,EAC3B;AACJ,CAAA;;;ACNA,IAAM,OAAA,GAAU,CAAI,CAAA,KAAgB,KAAA,CAAM,QAAQ,CAAC,CAAA,GAAI,CAAA,GAAI,CAAC,CAAC,CAAA;AAiBtD,IAAM,MAAN,MAIL;AAAA,EAOE,YAA+B,OAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAL/B;AAAA,IAAA,IAAA,CAAQ,QAAA,uBAAe,GAAA,EAGrB;AAGE,IAAA,IAAA,CAAK,UAAA,EAAW;AAAA,EACpB;AAAA,EAEQ,UAAA,GAAa;AACjB,IAAA,IAAA,CAAK,SAAS,KAAA,EAAM;AACpB,IAAA,KAAA,MAAWA,OAAAA,IAAU,KAAK,OAAA,EAAS;AAC/B,MAAA,KAAA,MAAW,QAAA,IAAYA,QAAO,SAAA,EAAW;AACrC,QAAA,MAAM,GAAA,GAAM,SAAS,UAAA,CAAW,EAAA;AAChC,QAAA,MAAM,MAAM,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,GAAG,KAAK,EAAC;AACvC,QAAA,GAAA,CAAI,IAAA,CAAK,EAAE,MAAA,EAAAA,OAAAA,EAAQ,UAAiC,CAAA;AACpD,QAAA,IAAA,CAAK,QAAA,CAAS,GAAA;AAAA,UACV,GAAA;AAAA,UACA;AAAA,SACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,MAAc,MAAA,CACV,QAAA,EACA,SAAA,EACA,IAAA,EACA,OACA,GAAA,EACF;AACE,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,SAAS,YAAY,CAAA;AAC3D,IAAA,IAAI,CAAC,WAAA,IAAe,WAAA,CAAY,MAAA,KAAW,CAAA,EAAG;AAE9C,IAAA,KAAA,MAAW,EAAE,MAAA,EAAAA,OAAAA,EAAQ,QAAA,MAAc,WAAA,EAAa;AAC5C,MAAA,MAAM,CAAA,GAAI,GAAGA,OAAAA,CAAO,EAAE,KAAK,QAAA,CAAS,YAAY,CAAA,EAAA,EAAK,QAAA,CAAS,OAAO,CAAA,CAAA;AACrE,MAAA,IAAI,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,EAAG;AACjB,MAAA,IAAA,CAAK,IAAI,CAAC,CAAA;AAEV,MAAA,MAAM,MAAM,MAAM,QAAA,CAAS,SAAS,QAAA,CAAS,OAAA,EAASA,QAAO,IAAA,EAAM;AAAA,QAC/D,GAAA,EAAK,MAAM,GAAA,CAAI,GAAA,CAAIA,QAAO,EAAE,CAAA;AAAA,QAC5B,KAAK,CAAA,KAAA,KAAS,GAAA,CAAI,GAAA,CAAIA,OAAAA,CAAO,IAAI,KAAK;AAAA,OACzC,CAAA;AACD,MAAA,IAAI,QAAQ,MAAA,EAAW;AAEvB,MAAA,KAAA,MAAW,KAAA,IAAS,OAAA,CAAQ,GAAG,CAAA,EAAG;AAC9B,QAAA,IAAI,SAAA,IAAa,CAAC,SAAA,CAAU,KAAA,CAAM,IAAqB,CAAA;AACnD,UAAA;AAEJ,QAAA,KAAA,CAAM,IAAA,CAAK;AAAA,UACP,cAAc,KAAA,CAAM,IAAA;AAAA,UACpB,SAAS,KAAA,CAAM,OAAA;AAAA,UACf,IAAA,EAAM,SAAS,IAAA,GAAO,CAAA;AAAA,UACtB,SAAS,QAAA,CAAS;AAAA;AAAA,SACrB,CAAA;AAAA,MACL;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,MAAM,SAAA,CAIFC,WAAAA,EAIA,OAAA,EACA,IAAA,EAYa;AACb,IAAA,MAAM,GAAA,GAAM,IAAA,EAAM,GAAA,IAAO,IAAI,0BAAA,EAA2B;AACxD,IAAA,MAAM,OAAA,GAAU,IAAA,EAAM,OAAA,IAAW,IAAA,CAAK,MAAA,GAAS,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA;AACnE,IAAA,MAAM,OAAA,GAAU,MAAM,OAAA,IAAW,GAAA;AAEjC,IAAA,MAAM,KAAA,GAAqC;AAAA,MACvC;AAAA,QACI,cAAcA,WAAAA,CAAW,EAAA;AAAA,QACzB,OAAA;AAAA,QACA,IAAA,EAAM,CAAA;AAAA,QACN;AAAA;AACJ,KACJ;AACA,IAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAE7B,IAAA,OAAO,MAAM,MAAA,EAAQ;AACjB,MAAA,IAAI,IAAA,EAAM,aAAa,OAAA,EAAS;AAEhC,MAAA,MAAM,IAAA,GAAO,MAAM,KAAA,EAAM;AACzB,MAAA,IAAA,EAAM,OAAA,GAAU;AAAA,QACZ,cAAc,IAAA,CAAK,YAAA;AAAA,QACnB,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,SAAS,IAAA,CAAK;AAAA,OACjB,CAAA;AACD,MAAA,IAAI,IAAA,CAAK,QAAQ,OAAA,EAAS;AAE1B,MAAA,MAAM,IAAA,CAAK,MAAA;AAAA,QACP,IAAA;AAAA,QACA,IAAA,EAAM,SAAA;AAAA,QACN,IAAA;AAAA,QACA,KAAA;AAAA,QACA;AAAA,OACJ;AAAA,IACJ;AAAA,EACJ;AACJ;;;AC9IO,IAAM,gBAAN,MAAkD;AAAA,EACrD,YAA4B,EAAA,EAAS;AAAT,IAAA,IAAA,CAAA,EAAA,GAAA,EAAA;AAAA,EAAU;AAAA,EAEtC,gBACO,IAAA,EACsB;AACzB,IAAA,MAAM,OAAA,GAAW,KAAa,CAAC,CAAA;AAC/B,IAAA,OAAO,EAAE,IAAA,EAAM,IAAA,CAAK,EAAA,EAAI,OAAA,EAAQ;AAAA,EACpC;AACJ;;;ACNO,IAAM,UAAA,GAAa,CACtB,EAAA,KACC,IAAI,cAA6B,EAAE;AA4CjC,IAAM,MAAA,GAAS,CAUlB,EAAA,EACA,IAAA,KAOC;AACD,EAAA,MAAM,YAOA,EAAC;AAEP,EAAA,MAAM,GAAA,GAMF;AAAA,IACA,IAAA;AAAA,IACA,EAAA;AAAA,IACA,SAAA;AAAA,IACA,SAII,CAAA,EAQF;AACE,MAAA,SAAA,CAAU,IAAA;AAAA,QACN;AAAA,OAQJ;AACA,MAAA,OAAO,GAAA;AAAA,IACX;AAAA,GACJ;AAEA,EAAA,OAAO,GAAA;AACX;AAEO,IAAM,UAAU,OAAsB;AAAA,EACzC,MAAA,EAAQ,CASJ,EAAA,EACA,IAAA,KACC;AACD,IAAA,OAAO,MAAA,CAML,IAAI,IAAI,CAAA;AAAA,EACd;AACJ,CAAA;AAEA,IAAM,OAAA,GAAU,WAA8B,SAAS,CAAA;AACvD,IAAM,OAAA,GAAU,WAA+B,SAAS,CAAA;AACxD,IAAM,KAAA,GAAQ,WAA8B,OAAO,CAAA;AAEpC,OAAO,QAAA,EAAU,EAAE,SAAS,KAAA,EAAO,EAAE,QAAA,CAAS;AAAA,EACzD,UAAA,EAAY,OAAA;AAAA,EACZ,QAAA,EAAU,OAAO,OAAA,EAAS,IAAA,KAAS;AAC/B,IAAA,MAAM,QAAS,OAAA,CAA8B,KAAA;AAC7C,IAAA,IAAI,QAAQ,CAAA,EAAG;AACX,MAAA,OAAO,IAAA,CAAK,QAAQ,YAAA,CAAa;AAAA,QAC7B,MAAA,EAAQ,YAAY,KAAK,CAAA;AAAA,OAC5B,CAAA;AAAA,IACL,CAAA,MAAO;AACH,MAAA,OAAO,IAAA,CAAK,MAAM,YAAA,CAAa;AAAA,QAC3B,KAAA,EAAO,UAAU,KAAK,CAAA,gBAAA;AAAA,OACzB,CAAA;AAAA,IACL;AAAA,EACJ;AACJ,CAAC;AAED,IAAM,EAAA,GAAK;AAAA,EACP,IAAA,EAAM,WAA6B,MAAM;AAC7C,CAAA;AAEA,IAAM,EAAA,GAAK;AAAA,EACP,KAAA,EAAO,WAA8B,OAAO;AAChD,CAAA;AAEA,IAAM,EAAA,GAAK;AAAA,EACP,KAAA,EAAO,WAA8B,OAAO;AAChD,CAAA;AAEA,IAAM,KAAK,OAAA,EAA6B,CACnC,OAAO,IAAA,EAAM,EAAE,EACf,QAAA,CAAS;AAAA,EACN,YAAY,EAAA,CAAG,KAAA;AAAA,EACf,QAAA,EAAU,OAAO,OAAA,EAAS,IAAA,EAAM,GAAA,KAAQ;AACpC,IAAA,GAAA,CAAI,GAAA,CAAI;AAAA,MACJ,SAAS,OAAA,CAAQ;AAAA,KACpB,CAAA;AACD,IAAA,GAAA,CAAI,KAAI,EAAG,OAAA;AACX,IAAA,OAAO,IAAA,CAAK,KAAK,YAAA,CAAa;AAAA,MAC1B,MAAM,OAAA,CAAQ;AAAA,KACjB,CAAA;AAAA,EACL;AACJ,CAAC,CAAA;AAEL,IAAM,EAAA,GAAK,MAAA,CAAO,IAAA,EAAM,EAAE,EAAE,QAAA,CAAS;AAAA,EACjC,YAAY,EAAA,CAAG,KAAA;AAAA,EACf,QAAA,EAAU,OAAO,OAAA,EAAS,IAAA,KAAS;AAC/B,IAAA,OAAO,IAAA,CAAK,MAAM,YAAA,CAAa;AAAA,MAC3B,OAAO,OAAA,CAAQ;AAAA,KAClB,CAAA;AAAA,EACL;AACJ,CAAC,CAAA;AAEW,IAAI,GAAA,CAAI,CAAC,EAAA,EAAI,EAAE,CAAC","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(afferentLayerAsAxon, neurons) {
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.edgeId);
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.edgeId}::${incoming.spikeId}`;
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.reaction(incoming.payload, neuron2.axon);
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
- edgeId: spike.type,
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(axonKey, payload, opts) {
48
- const afferent = this.afferentLayerAsAxon[axonKey];
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
- edgeId: afferent.id,
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
- edgeId: item.edgeId,
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(s);
115
+ dendrites.push(
116
+ s
117
+ );
100
118
  return api;
101
119
  }
102
120
  };
103
121
  return api;
104
122
  };
105
- export {
106
- CNS,
107
- CNSCollateral,
108
- collateral,
109
- neuron
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.0.0",
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 src/index.ts --dts --format esm,cjs --tsconfig tsconfig.build.json",
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 };