@science-corporation/synapse 0.9.0 → 0.12.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.
Files changed (138) hide show
  1. package/README.md +40 -18
  2. package/dist/api/api.d.ts +3881 -1739
  3. package/dist/api/api.js +10023 -5111
  4. package/dist/api/api.js.map +1 -1
  5. package/dist/api/proto.json +370 -63
  6. package/dist/api-science-device/api.d.ts +3 -0
  7. package/dist/api-science-device/api.d.ts.map +1 -0
  8. package/dist/api-science-device/api.js +3822 -0
  9. package/dist/api-science-device/api.js.map +1 -0
  10. package/dist/api-science-device/proto.json +258 -0
  11. package/dist/browser.d.ts +4 -0
  12. package/dist/browser.d.ts.map +1 -0
  13. package/dist/browser.js +22 -0
  14. package/dist/browser.js.map +1 -0
  15. package/dist/config.d.ts +5 -4
  16. package/dist/config.d.ts.map +1 -1
  17. package/dist/config.js +25 -17
  18. package/dist/config.js.map +1 -1
  19. package/dist/demo.js +42 -38
  20. package/dist/demo.js.map +1 -1
  21. package/dist/device.d.ts +20 -5
  22. package/dist/device.d.ts.map +1 -1
  23. package/dist/device.js +75 -27
  24. package/dist/device.js.map +1 -1
  25. package/dist/index.d.ts +3 -1
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +5 -3
  28. package/dist/index.js.map +1 -1
  29. package/dist/nodejs.d.ts +8 -0
  30. package/dist/nodejs.d.ts.map +1 -0
  31. package/dist/nodejs.js +32 -0
  32. package/dist/nodejs.js.map +1 -0
  33. package/dist/nodes/broadband_source.d.ts +11 -0
  34. package/dist/nodes/broadband_source.d.ts.map +1 -0
  35. package/dist/nodes/{optical_broadband.js → broadband_source.js} +9 -9
  36. package/dist/nodes/broadband_source.js.map +1 -0
  37. package/dist/nodes/index.d.ts +3 -2
  38. package/dist/nodes/index.d.ts.map +1 -1
  39. package/dist/nodes/index.js +5 -5
  40. package/dist/nodes/index.js.map +1 -1
  41. package/dist/nodes/spike_source.d.ts +11 -0
  42. package/dist/nodes/spike_source.d.ts.map +1 -0
  43. package/dist/nodes/{electrical_broadband.js → spike_source.js} +9 -9
  44. package/dist/nodes/spike_source.js.map +1 -0
  45. package/dist/nodes/stream_in.d.ts +0 -4
  46. package/dist/nodes/stream_in.d.ts.map +1 -1
  47. package/dist/nodes/stream_in.js +1 -1
  48. package/dist/nodes/stream_in.js.map +1 -1
  49. package/dist/nodes/stream_out.d.ts +2 -2
  50. package/dist/nodes/stream_out.d.ts.map +1 -1
  51. package/dist/nodes/stream_out.js +2 -2
  52. package/dist/nodes/stream_out.js.map +1 -1
  53. package/dist/science-device-api/api.d.ts +3 -0
  54. package/dist/science-device-api/api.d.ts.map +1 -0
  55. package/dist/science-device-api/api.js +3822 -0
  56. package/dist/science-device-api/api.js.map +1 -0
  57. package/dist/types/index.d.ts +3 -0
  58. package/dist/types/index.d.ts.map +1 -0
  59. package/dist/types/index.js +19 -0
  60. package/dist/types/index.js.map +1 -0
  61. package/dist/types.d.ts +5 -0
  62. package/dist/types.d.ts.map +1 -0
  63. package/dist/types.js +19 -0
  64. package/dist/types.js.map +1 -0
  65. package/dist/utils/client.d.ts +8 -1
  66. package/dist/utils/client.d.ts.map +1 -1
  67. package/dist/utils/client.js +30 -16
  68. package/dist/utils/client.js.map +1 -1
  69. package/dist/utils/device-management.d.ts +37 -0
  70. package/dist/utils/device-management.d.ts.map +1 -0
  71. package/dist/utils/device-management.js +126 -0
  72. package/dist/utils/device-management.js.map +1 -0
  73. package/dist/utils/discover.d.ts +3 -8
  74. package/dist/utils/discover.d.ts.map +1 -1
  75. package/dist/utils/discover.js +17 -32
  76. package/dist/utils/discover.js.map +1 -1
  77. package/dist/utils/enum.d.ts +1 -1
  78. package/dist/utils/enum.d.ts.map +1 -1
  79. package/dist/utils/enum.js.map +1 -1
  80. package/dist/utils/index.d.ts +1 -1
  81. package/dist/utils/index.d.ts.map +1 -1
  82. package/dist/utils/index.js +3 -0
  83. package/dist/utils/index.js.map +1 -1
  84. package/dist/utils/status.d.ts +28 -0
  85. package/dist/utils/status.d.ts.map +1 -0
  86. package/dist/utils/status.js +54 -0
  87. package/dist/utils/status.js.map +1 -0
  88. package/package.json +35 -9
  89. package/scripts/postinstall.sh +95 -0
  90. package/src/api/api.d.ts +3881 -1739
  91. package/src/api/api.js +10524 -5282
  92. package/src/api/proto.json +370 -63
  93. package/src/browser.ts +4 -0
  94. package/src/config.ts +31 -20
  95. package/src/demo.ts +43 -33
  96. package/src/device.ts +84 -30
  97. package/src/index.ts +4 -1
  98. package/src/nodes/broadband_source.ts +30 -0
  99. package/src/nodes/index.ts +4 -2
  100. package/src/nodes/spike_source.ts +30 -0
  101. package/src/nodes/stream_in.ts +1 -6
  102. package/src/nodes/stream_out.ts +4 -4
  103. package/src/utils/client.ts +38 -13
  104. package/src/utils/discover.ts +25 -45
  105. package/src/utils/enum.ts +1 -1
  106. package/src/utils/index.ts +1 -1
  107. package/src/utils/status.ts +57 -0
  108. package/synapse-api/.github/workflows/proto-check.yaml +33 -0
  109. package/synapse-api/COPYRIGHT +1 -0
  110. package/synapse-api/README.md +1 -1
  111. package/synapse-api/api/logging.proto +44 -0
  112. package/synapse-api/api/node.proto +22 -8
  113. package/synapse-api/api/nodes/broadband_source.proto +20 -0
  114. package/synapse-api/api/nodes/disk_writer.proto +7 -0
  115. package/synapse-api/api/nodes/electrical_stimulation.proto +4 -0
  116. package/synapse-api/api/nodes/signal_config.proto +22 -0
  117. package/synapse-api/api/nodes/signal_status.proto +18 -0
  118. package/synapse-api/api/nodes/spike_source.proto +15 -0
  119. package/synapse-api/api/nodes/stream_in.proto +5 -0
  120. package/synapse-api/api/nodes/stream_out.proto +4 -0
  121. package/synapse-api/api/query.proto +19 -0
  122. package/synapse-api/api/status.proto +6 -0
  123. package/synapse-api/api/synapse.proto +6 -2
  124. package/synapse-api/build.sh +17 -0
  125. package/dist/channel_mask.d.ts +0 -7
  126. package/dist/channel_mask.d.ts.map +0 -1
  127. package/dist/channel_mask.js +0 -14
  128. package/dist/channel_mask.js.map +0 -1
  129. package/dist/nodes/electrical_broadband.d.ts +0 -11
  130. package/dist/nodes/electrical_broadband.d.ts.map +0 -1
  131. package/dist/nodes/electrical_broadband.js.map +0 -1
  132. package/dist/nodes/optical_broadband.d.ts +0 -11
  133. package/dist/nodes/optical_broadband.d.ts.map +0 -1
  134. package/dist/nodes/optical_broadband.js.map +0 -1
  135. package/src/nodes/electrical_broadband.ts +0 -30
  136. package/src/nodes/optical_broadband.ts +0 -30
  137. package/synapse-api/api/nodes/electrical_broadband.proto +0 -15
  138. package/synapse-api/api/nodes/optical_broadband.proto +0 -11
package/src/config.ts CHANGED
@@ -1,19 +1,20 @@
1
1
  import Node from "./node";
2
2
  import { synapse } from "./api/api";
3
- import ElectricalBroadband from "./nodes/electrical_broadband";
3
+ import BroadbandSource from "./nodes/broadband_source";
4
4
  import ElectricalStimulation from "./nodes/electrical_stimulation";
5
- import OpticalBroadband from "./nodes/optical_broadband";
6
5
  import OpticalStimulation from "./nodes/optical_stimulation";
7
6
  import SpectralFilter from "./nodes/spectral_filter";
8
7
  import SpikeDetect from "./nodes/spike_detect";
8
+ import SpikeSource from "./nodes/spike_source";
9
9
  import StreamIn from "./nodes/stream_in";
10
10
  import StreamOut from "./nodes/stream_out";
11
+ import { Status, StatusCode } from "./utils/status";
11
12
 
12
13
  type Connection = [number, number];
13
14
  const kNodeTypeObjectMap = {
14
- [synapse.NodeType.kElectricalBroadband]: ElectricalBroadband,
15
+ [synapse.NodeType.kBroadbandSource]: BroadbandSource,
15
16
  [synapse.NodeType.kElectricalStimulation]: ElectricalStimulation,
16
- [synapse.NodeType.kOpticalBroadband]: OpticalBroadband,
17
+ [synapse.NodeType.kSpikeSource]: SpikeSource,
17
18
  [synapse.NodeType.kOpticalStimulation]: OpticalStimulation,
18
19
  [synapse.NodeType.kSpectralFilter]: SpectralFilter,
19
20
  [synapse.NodeType.kSpikeDetect]: SpikeDetect,
@@ -29,37 +30,47 @@ class Config {
29
30
  return this.nodes.length + 1;
30
31
  }
31
32
 
32
- add(nodes: Node[]) {
33
+ add(nodes: Node[]): Status {
33
34
  for (const node of nodes) {
34
- if (!this.addNode(node)) {
35
- return false;
35
+ const status = this.addNode(node);
36
+ if (!status.ok()) {
37
+ return status;
36
38
  }
37
39
  }
38
- return true;
40
+ return new Status();
39
41
  }
40
42
 
41
- connect(fromNode: Node, toNode: Node): boolean {
42
- if (fromNode.id === null || toNode.id === null) {
43
- return false;
43
+ connect(fromNode: Node, toNode: Node): Status {
44
+ if (!fromNode.id || !toNode.id) {
45
+ return new Status(StatusCode.INVALID_ARGUMENT, "source and destination nodes must have ids");
44
46
  }
45
47
  this.connections.push([fromNode.id, toNode.id]);
46
- return true;
48
+ return new Status();
47
49
  }
48
50
 
49
- addNode(node: Node): boolean {
50
- if (!!node.id) {
51
- return false;
51
+ addNode(node: Node, id?: number): Status {
52
+ if (node.id) {
53
+ return new Status(StatusCode.INVALID_ARGUMENT, "node must not have an id");
52
54
  }
53
- node.id = this._genNodeId();
55
+
56
+ if (id === undefined) {
57
+ id = this._genNodeId();
58
+ }
59
+
60
+ if (this.nodes.find((n) => n.id === id)) {
61
+ return new Status(StatusCode.INVALID_ARGUMENT, "node id must be unique");
62
+ }
63
+
64
+ node.id = id;
54
65
  this.nodes.push(node);
55
- return true;
66
+ return new Status();
56
67
  }
57
68
 
58
- setDevice(device): boolean {
69
+ setDevice(device): Status {
59
70
  for (const node of this.nodes) {
60
71
  node.device = device;
61
72
  }
62
- return true;
73
+ return new Status();
63
74
  }
64
75
 
65
76
  static fromProto(proto: synapse.IDeviceConfiguration): Config {
@@ -74,7 +85,7 @@ class Config {
74
85
  }
75
86
 
76
87
  const node = NodeType.fromProto(nodeProto);
77
- if (!!nodeProto.id) {
88
+ if (nodeProto.id) {
78
89
  node.id = nodeProto.id;
79
90
  config.nodes.push(node);
80
91
  } else {
package/src/demo.ts CHANGED
@@ -5,7 +5,7 @@ import { hideBin } from "yargs/helpers";
5
5
  import { synapse } from "./api/api";
6
6
  import Config from "./config";
7
7
  import Device from "./device";
8
- import ElectricalBroadband from "./nodes/electrical_broadband";
8
+ import ElectricalBroadband from "./nodes/broadband_source";
9
9
  import OpticalStimulation from "./nodes/optical_stimulation";
10
10
  import StreamIn from "./nodes/stream_in";
11
11
  import StreamOut from "./nodes/stream_out";
@@ -48,8 +48,13 @@ const cli = yargs(hideBin(process.argv))
48
48
  const info = async (device: Device) => {
49
49
  console.log("Info()");
50
50
 
51
- const info = await device.info();
52
- const { serial, name, status, synapseVersion, firmwareVersion, peripherals, configuration } = info;
51
+ const { status: s, response } = await device.info();
52
+ if (!s.ok()) {
53
+ console.error(s.message);
54
+ return false;
55
+ }
56
+
57
+ const { serial, name, status, synapseVersion, firmwareVersion, peripherals, configuration } = response;
53
58
 
54
59
  console.log(` - serial: ${serial}`);
55
60
  console.log(` - name: ${name}`);
@@ -89,7 +94,7 @@ const read = async (device: Device, argv: any) => {
89
94
  console.log("Reading from device's StreamOut node...");
90
95
 
91
96
  const { multicastGroup, output } = argv;
92
- let ok = true;
97
+ let status = null;
93
98
  let stream = null;
94
99
  if (output) {
95
100
  console.log(`Writing to file: ${output}`);
@@ -107,9 +112,13 @@ const read = async (device: Device, argv: any) => {
107
112
  const config = new Config();
108
113
  const nodeEphys = new ElectricalBroadband({
109
114
  peripheralId: 3,
110
- channels: [{ id: 0, referenceId: 0, electrodeId: 1 }],
115
+ signal: {
116
+ electrode: {
117
+ channels: [{ id: 0, referenceId: 0, electrodeId: 1 }],
118
+ },
119
+ },
111
120
  bitWidth: 12,
112
- sampleRate: 16000,
121
+ sampleRateHz: 16000,
113
122
  });
114
123
  const nodeStreamOut = new StreamOut(
115
124
  {
@@ -118,26 +127,24 @@ const read = async (device: Device, argv: any) => {
118
127
  onMessage
119
128
  );
120
129
 
121
- ok = config.add([nodeEphys, nodeStreamOut]);
122
- ok = config.connect(nodeEphys, nodeStreamOut);
123
- if (!ok) {
124
- console.error("Failed to connect nodes");
130
+ status = config.add([nodeEphys, nodeStreamOut]);
131
+ status = config.connect(nodeEphys, nodeStreamOut);
132
+ if (!status.ok()) {
133
+ console.error("failed to connect nodes: ", status.message);
125
134
  return;
126
135
  }
127
136
 
128
137
  console.log("Configuring device...");
129
- try {
130
- ok = await device.configure(config);
131
- } catch (e) {
132
- console.error(e);
138
+ status = await device.configure(config);
139
+ if (!status.ok()) {
140
+ console.error("failed to configure device: ", status.message);
133
141
  return;
134
142
  }
135
143
 
136
144
  console.log("Starting device...");
137
- try {
138
- ok = await device.start();
139
- } catch (e) {
140
- console.error(e);
145
+ status = await device.start();
146
+ if (!status.ok()) {
147
+ console.error("failed to start device: ", status.message);
141
148
  return;
142
149
  }
143
150
 
@@ -164,7 +171,7 @@ const write = async (device: Device, argv: any) => {
164
171
  }
165
172
 
166
173
  console.log("Writing to device's StreamOut node...");
167
- let ok = true;
174
+ let status = null;
168
175
 
169
176
  const config = new Config();
170
177
  const nodeStreamIn = new StreamIn({
@@ -172,26 +179,29 @@ const write = async (device: Device, argv: any) => {
172
179
  });
173
180
  const nodeOptical = new OpticalStimulation();
174
181
 
175
- ok = config.add([nodeStreamIn, nodeOptical]);
176
- ok = config.connect(nodeStreamIn, nodeOptical);
177
- if (!ok) {
178
- console.error("Failed to connect nodes");
182
+ status = config.add([nodeStreamIn, nodeOptical]);
183
+ if (!status.ok()) {
184
+ console.error("Failed to add nodes: ", status.message);
185
+ return;
186
+ }
187
+
188
+ status = config.connect(nodeStreamIn, nodeOptical);
189
+ if (!status.ok()) {
190
+ console.error("Failed to connect nodes: ", status.message);
179
191
  return;
180
192
  }
181
193
 
182
194
  console.log("Configuring device...");
183
- try {
184
- ok = await device.configure(config);
185
- } catch (e) {
186
- console.error(e);
195
+ status = await device.configure(config);
196
+ if (!status.ok()) {
197
+ console.error("Failed to configure device: ", status.message);
187
198
  return;
188
199
  }
189
200
 
190
201
  console.log("Starting device...");
191
- try {
192
- ok = await device.start();
193
- } catch (e) {
194
- console.error(e);
202
+ status = await device.start();
203
+ if (!status.ok()) {
204
+ console.error("Failed to start device: ", status.message);
195
205
  return;
196
206
  }
197
207
 
@@ -286,8 +296,8 @@ const main = async () => {
286
296
 
287
297
  try {
288
298
  await info(device);
289
- } catch (e) {
290
- console.error(e);
299
+ } catch (err) {
300
+ console.error(`Failed to get device info (${err.code}): ${err.message}`);
291
301
  return;
292
302
  }
293
303
 
package/src/device.ts CHANGED
@@ -1,9 +1,12 @@
1
- import { Channel, credentials } from "@grpc/grpc-js";
1
+ import { Channel, credentials, ServiceError } from "@grpc/grpc-js";
2
2
 
3
+ import protos from "./api/proto.json";
3
4
  import { synapse } from "./api/api";
4
5
  import Config from "./config";
5
- import { create } from "./utils/client";
6
- import { getName } from "./utils/enum";
6
+ import { CallOptions, create } from "./utils/client";
7
+ import { fromDeviceStatus, Status } from "./utils/status";
8
+
9
+ const kSynapseService = "synapse.SynapseDevice";
7
10
 
8
11
  class Device {
9
12
  rpc: any | null = null;
@@ -11,82 +14,133 @@ class Device {
11
14
  sockets: synapse.INodeSocket[] = [];
12
15
 
13
16
  constructor(public uri: string) {
14
- this.rpc = create(uri, credentials.createInsecure());
15
- if (!this.rpc) {
16
- throw new Error(`Failed to create client for ${uri}`);
17
+ const { status, client } = create(protos, kSynapseService)(uri, credentials.createInsecure());
18
+ if (!status.ok() || !client) {
19
+ throw new Error(`Failed to create client for ${uri}: ${status.message}`);
17
20
  }
21
+ this.rpc = client;
18
22
  }
19
23
 
20
- async configure(config: Config): Promise<boolean> {
24
+ async configure(config: Config, options: CallOptions = {}): Promise<Status> {
21
25
  return new Promise((resolve, reject) => {
22
26
  config.setDevice(this);
23
-
24
27
  const proto = config.toProto();
25
- this.rpc.configure(proto, (err, res) => {
28
+ this.rpc.configure(proto, options, (err: ServiceError, res) => {
26
29
  if (err) {
27
30
  reject(err);
28
31
  } else {
29
- if (this._handleStatusResponse(res!)) {
30
- resolve(true);
32
+ const status = this._handleStatusResponse(res!);
33
+ if (status.ok()) {
34
+ resolve(status);
31
35
  } else {
32
- reject(`Error configuring device: (code: ${getName(synapse.StatusCode, res.code)}) ${res.message}`);
36
+ reject(new Status(status.code, `failed to configure device: ${status.message}`));
33
37
  }
34
38
  }
35
39
  });
36
40
  });
37
41
  }
38
42
 
39
- async info(): Promise<synapse.DeviceInfo> {
43
+ async info(options: CallOptions = {}): Promise<{ status: Status; response?: synapse.DeviceInfo }> {
40
44
  return new Promise((resolve, reject) => {
41
- this.rpc.info({}, (err, res) => {
45
+ this.rpc.info({}, options, (err: ServiceError, res: synapse.DeviceInfo) => {
42
46
  if (err) {
43
47
  reject(err);
48
+ } else if (!res) {
49
+ reject(new Status(err.code, "failed to get device info: " + err.message));
44
50
  } else {
45
- resolve(res!);
51
+ const { sockets } = res.status;
52
+ this.sockets = sockets || [];
53
+ resolve({ status: new Status(), response: res });
46
54
  }
47
55
  });
48
56
  });
49
57
  }
50
58
 
51
- async start(): Promise<boolean> {
59
+ async start(options: CallOptions = {}): Promise<Status> {
52
60
  return new Promise((resolve, reject) => {
53
- this.rpc.start({}, (err, res) => {
61
+ this.rpc.start({}, options, (err: ServiceError, res: synapse.IStatus) => {
54
62
  if (err) {
55
63
  reject(err);
56
64
  } else {
57
- if (this._handleStatusResponse(res!)) {
58
- resolve(true);
65
+ const status = this._handleStatusResponse(res!);
66
+ if (status.ok()) {
67
+ resolve(status);
59
68
  } else {
60
- reject(`Error starting device: (code: ${getName(synapse.StatusCode, res.code)}) ${res.message}`);
69
+ reject(new Status(status.code, `failed to start device: ${status.message}`));
61
70
  }
62
71
  }
63
72
  });
64
73
  });
65
74
  }
66
75
 
67
- async stop(): Promise<boolean> {
76
+ async stop(options: CallOptions = {}): Promise<Status> {
68
77
  return new Promise((resolve, reject) => {
69
- this.rpc.stop({}, (err, res) => {
78
+ this.rpc.stop({}, options, (err: ServiceError, res: synapse.IStatus) => {
70
79
  if (err) {
71
80
  reject(err);
72
81
  } else {
73
- if (this._handleStatusResponse(res!)) {
74
- resolve(true);
82
+ const status = this._handleStatusResponse(res!);
83
+ if (status.ok()) {
84
+ resolve(status);
75
85
  } else {
76
- reject(`Error stopping device: (code: ${getName(synapse.StatusCode, res.code)}) ${res.message}`);
86
+ reject(new Status(status.code, `failed to stop device: ${status.message}`));
77
87
  }
78
88
  }
79
89
  });
80
90
  });
81
91
  }
82
92
 
83
- _handleStatusResponse(status: synapse.Status): boolean {
84
- const { code, sockets } = status;
85
- if (code && (code as any) !== synapse.StatusCode.kOk) {
86
- return false;
93
+ // Logs
94
+
95
+ async getLogs(
96
+ query: synapse.ILogQueryRequest,
97
+ options: CallOptions = {}
98
+ ): Promise<{ status: Status; response?: synapse.LogQueryResponse }> {
99
+ return new Promise((resolve, reject) => {
100
+ this.rpc.getLogs(query, options, (err: ServiceError, res: synapse.LogQueryResponse) => {
101
+ if (err) {
102
+ reject(err);
103
+ } else {
104
+ resolve({ status: new Status(), response: res });
105
+ }
106
+ });
107
+ });
108
+ }
109
+
110
+ async tailLogs(
111
+ query: synapse.ITailLogsRequest,
112
+ options: CallOptions = {},
113
+ callbacks: {
114
+ onData: (data: synapse.LogEntry) => void;
115
+ onEnd?: () => void;
116
+ onError?: (err: Error) => void;
117
+ onStatus?: (status: Status) => void;
118
+ }
119
+ ) {
120
+ const { onData, onEnd, onError, onStatus } = callbacks;
121
+ const call = this.rpc.tailLogs(query, options);
122
+ call.on("data", onData);
123
+ if (onEnd) {
124
+ call.on("end", onEnd);
125
+ }
126
+ if (onError) {
127
+ call.on("error", onError);
128
+ }
129
+ if (onStatus) {
130
+ call.on("status", (grpcStatus) => {
131
+ onStatus?.(new Status(grpcStatus.code, grpcStatus.details));
132
+ });
133
+ }
134
+ return call;
135
+ }
136
+
137
+ _handleStatusResponse(status: synapse.IStatus): Status {
138
+ const { code, message, sockets } = status;
139
+ if (code !== synapse.StatusCode.kOk) {
140
+ return fromDeviceStatus({ code, message });
87
141
  } else {
88
142
  this.sockets = sockets || [];
89
- return true;
143
+ return new Status();
90
144
  }
91
145
  }
92
146
  }
package/src/index.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  export { default as Config } from "./config";
2
2
  export { default as Device } from "./device";
3
3
  export * from "./nodes";
4
- export { synapse } from "./api/api";
4
+ export { IStatus, Status, StatusCode } from "./utils/status";
5
+
6
+ export type { CallOptions } from "./utils/client";
7
+ export * from "./api/api";
@@ -0,0 +1,30 @@
1
+ import { synapse } from "../api/api";
2
+ import Node from "../node";
3
+
4
+ class BroadbandSource extends Node {
5
+ type = synapse.NodeType.kBroadbandSource;
6
+ config: synapse.IBroadbandSourceConfig;
7
+
8
+ constructor(config: synapse.IBroadbandSourceConfig = {}) {
9
+ super();
10
+
11
+ this.config = config;
12
+ }
13
+
14
+ toProto(): synapse.NodeConfig {
15
+ return super.toProto({
16
+ broadbandSource: this.config,
17
+ });
18
+ }
19
+
20
+ static fromProto(proto: synapse.NodeConfig): BroadbandSource {
21
+ const { broadbandSource } = proto;
22
+ if (!broadbandSource) {
23
+ throw new Error("Invalid config, missing broadbandSource");
24
+ }
25
+
26
+ return new BroadbandSource(proto.broadbandSource);
27
+ }
28
+ }
29
+
30
+ export default BroadbandSource;
@@ -1,8 +1,10 @@
1
- export { default as ElectricalBroadband } from "./electrical_broadband";
1
+ export { default as BroadbandSource } from "./broadband_source";
2
2
  export { default as ElectricalStimulation } from "./electrical_stimulation";
3
- export { default as OpticalBroadband } from "./optical_broadband";
4
3
  export { default as OpticalStimulation } from "./optical_stimulation";
5
4
  export { default as SpectralFilter } from "./spectral_filter";
6
5
  export { default as SpikeDetect } from "./spike_detect";
6
+ export { default as SpikeSource } from "./spike_source";
7
7
  export { default as StreamIn } from "./stream_in";
8
8
  export { default as StreamOut } from "./stream_out";
9
+
10
+ export type * from "../api/api";
@@ -0,0 +1,30 @@
1
+ import { synapse } from "../api/api";
2
+ import Node from "../node";
3
+
4
+ class SpikeSource extends Node {
5
+ type = synapse.NodeType.kSpikeSource;
6
+ config: synapse.ISpikeSourceConfig;
7
+
8
+ constructor(config: synapse.ISpikeSourceConfig = {}) {
9
+ super();
10
+
11
+ this.config = config;
12
+ }
13
+
14
+ toProto(): synapse.NodeConfig {
15
+ return super.toProto({
16
+ spikeSource: this.config,
17
+ });
18
+ }
19
+
20
+ static fromProto(proto: synapse.NodeConfig): SpikeSource {
21
+ const { spikeSource } = proto;
22
+ if (!spikeSource) {
23
+ throw new Error("Invalid config, missing spikeSource");
24
+ }
25
+
26
+ return new SpikeSource(proto.spikeSource);
27
+ }
28
+ }
29
+
30
+ export default SpikeSource;
@@ -3,11 +3,6 @@ import dgram from "dgram";
3
3
  import { synapse } from "../api/api";
4
4
  import Node from "../node";
5
5
 
6
- export interface StreamInArgs {
7
- dataType: synapse.DataType;
8
- shape?: number[];
9
- }
10
-
11
6
  class StreamIn extends Node {
12
7
  type = synapse.NodeType.kStreamIn;
13
8
  config: synapse.IStreamInConfig;
@@ -49,7 +44,7 @@ class StreamIn extends Node {
49
44
 
50
45
  try {
51
46
  this._socket.send(data, port, host);
52
- } catch (e) {
47
+ } catch {
53
48
  return false;
54
49
  }
55
50
 
@@ -18,7 +18,7 @@ class StreamOut extends Node {
18
18
  this._onMessage = onMessage;
19
19
  }
20
20
 
21
- async start(): Promise<any> {
21
+ async start(): Promise<boolean> {
22
22
  if (this.device === null) {
23
23
  return false;
24
24
  }
@@ -45,9 +45,9 @@ class StreamOut extends Node {
45
45
 
46
46
  this._socket = dgram.createSocket("udp4");
47
47
 
48
- this._socket.on("error", (err: any) => {});
48
+ this._socket.on("error", () => {});
49
49
 
50
- this._socket.on("message", (msg: Buffer, rinfo: any) => {
50
+ this._socket.on("message", (msg: Buffer) => {
51
51
  this._onMessage?.(msg);
52
52
  });
53
53
 
@@ -65,7 +65,7 @@ class StreamOut extends Node {
65
65
  return true;
66
66
  }
67
67
 
68
- async stop(): Promise<any> {
68
+ async stop(): Promise<boolean> {
69
69
  if (this._socket) {
70
70
  this._socket.close();
71
71
  }
@@ -1,20 +1,45 @@
1
1
  import { ChannelCredentials, ChannelOptions, loadPackageDefinition } from "@grpc/grpc-js";
2
2
  import { fromJSON } from "@grpc/proto-loader";
3
+ import { Status, StatusCode } from "./status";
3
4
 
4
- import protoJson from "../api/proto.json";
5
+ export interface CallOptions {
6
+ deadline?: Date;
7
+ }
5
8
 
6
- const loadClient = () => {
7
- const definition = fromJSON(protoJson as any, {
8
- keepCase: false,
9
- arrays: true,
10
- enums: Number,
11
- defaults: true,
12
- oneofs: true,
13
- });
14
- const descriptor = loadPackageDefinition(definition as any);
15
- return (descriptor.synapse as any).SynapseDevice;
9
+ const pick = (obj: any, path: string) => {
10
+ return path.split(".").reduce((acc, part) => (acc && acc[part]) || null, obj);
16
11
  };
17
12
 
18
- export const create = (address: string, credentials: ChannelCredentials, options?: ChannelOptions) => {
19
- return new (loadClient())(address, credentials, options);
13
+ const loadClient = (protoJson: object, serviceName: string): { status: Status; factory?: any } => {
14
+ try {
15
+ const definition = fromJSON(protoJson as any, {
16
+ keepCase: false,
17
+ arrays: true,
18
+ enums: Number,
19
+ defaults: true,
20
+ oneofs: true,
21
+ });
22
+
23
+ const descriptor = loadPackageDefinition(definition as any);
24
+
25
+ const service = pick(descriptor, serviceName);
26
+ if (!service) {
27
+ return { status: new Status(StatusCode.INTERNAL, `service ${serviceName} not found in proto definition`) };
28
+ }
29
+
30
+ return { status: new Status(StatusCode.OK), factory: service };
31
+ } catch (error) {
32
+ return { status: new Status(StatusCode.INTERNAL, "failed to load proto definition: " + error) };
33
+ }
20
34
  };
35
+
36
+ export const create =
37
+ (protoJson: object, serviceName: string) =>
38
+ (address: string, credentials: ChannelCredentials, options?: ChannelOptions): { status: Status; client?: any } => {
39
+ const { status, factory } = loadClient(protoJson, serviceName);
40
+ if (!status.ok()) {
41
+ return { status };
42
+ }
43
+ const client = new factory(address, credentials, options);
44
+ return { status, client };
45
+ };