@olane/o-node 0.7.12 → 0.7.13-alpha.1

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 (57) hide show
  1. package/dist/src/connection/interfaces/o-node-connection-manager.config.d.ts +1 -0
  2. package/dist/src/connection/interfaces/o-node-connection-manager.config.d.ts.map +1 -1
  3. package/dist/src/connection/o-node-connection.d.ts +0 -1
  4. package/dist/src/connection/o-node-connection.d.ts.map +1 -1
  5. package/dist/src/connection/o-node-connection.js +0 -8
  6. package/dist/src/connection/o-node-connection.manager.d.ts +33 -4
  7. package/dist/src/connection/o-node-connection.manager.d.ts.map +1 -1
  8. package/dist/src/connection/o-node-connection.manager.js +153 -44
  9. package/dist/src/connection/stream-handler.d.ts.map +1 -1
  10. package/dist/src/connection/stream-handler.js +0 -2
  11. package/dist/src/managers/o-connection-heartbeat.manager.d.ts.map +1 -1
  12. package/dist/src/managers/o-connection-heartbeat.manager.js +15 -1
  13. package/dist/src/managers/o-reconnection.manager.d.ts.map +1 -1
  14. package/dist/src/managers/o-reconnection.manager.js +12 -7
  15. package/dist/src/o-node.d.ts +5 -0
  16. package/dist/src/o-node.d.ts.map +1 -1
  17. package/dist/src/o-node.js +46 -8
  18. package/dist/src/o-node.tool.d.ts.map +1 -1
  19. package/dist/src/o-node.tool.js +5 -0
  20. package/dist/src/router/o-node.router.d.ts.map +1 -1
  21. package/dist/src/router/o-node.router.js +16 -6
  22. package/dist/src/router/o-node.routing-policy.d.ts.map +1 -1
  23. package/dist/src/router/o-node.routing-policy.js +4 -0
  24. package/dist/test/connection-management.spec.d.ts +2 -0
  25. package/dist/test/connection-management.spec.d.ts.map +1 -0
  26. package/dist/test/connection-management.spec.js +370 -0
  27. package/dist/test/helpers/connection-spy.d.ts +124 -0
  28. package/dist/test/helpers/connection-spy.d.ts.map +1 -0
  29. package/dist/test/helpers/connection-spy.js +229 -0
  30. package/dist/test/helpers/index.d.ts +6 -0
  31. package/dist/test/helpers/index.d.ts.map +1 -0
  32. package/dist/test/helpers/index.js +12 -0
  33. package/dist/test/helpers/network-builder.d.ts +109 -0
  34. package/dist/test/helpers/network-builder.d.ts.map +1 -0
  35. package/dist/test/helpers/network-builder.js +309 -0
  36. package/dist/test/helpers/simple-node-builder.d.ts +50 -0
  37. package/dist/test/helpers/simple-node-builder.d.ts.map +1 -0
  38. package/dist/test/helpers/simple-node-builder.js +66 -0
  39. package/dist/test/helpers/test-environment.d.ts +140 -0
  40. package/dist/test/helpers/test-environment.d.ts.map +1 -0
  41. package/dist/test/helpers/test-environment.js +184 -0
  42. package/dist/test/helpers/test-node.tool.d.ts +31 -0
  43. package/dist/test/helpers/test-node.tool.d.ts.map +1 -1
  44. package/dist/test/helpers/test-node.tool.js +49 -0
  45. package/dist/test/network-communication.spec.d.ts +2 -0
  46. package/dist/test/network-communication.spec.d.ts.map +1 -0
  47. package/dist/test/network-communication.spec.js +256 -0
  48. package/dist/test/o-node.spec.d.ts +2 -0
  49. package/dist/test/o-node.spec.d.ts.map +1 -0
  50. package/dist/test/o-node.spec.js +247 -0
  51. package/dist/test/parent-child-registration.spec.d.ts +2 -0
  52. package/dist/test/parent-child-registration.spec.d.ts.map +1 -0
  53. package/dist/test/parent-child-registration.spec.js +177 -0
  54. package/dist/test/search-resolver.spec.d.ts +2 -0
  55. package/dist/test/search-resolver.spec.d.ts.map +1 -0
  56. package/dist/test/search-resolver.spec.js +648 -0
  57. package/package.json +12 -7
@@ -0,0 +1,256 @@
1
+ import { expect } from 'chai';
2
+ import { TestEnvironment } from './helpers/index.js';
3
+ import { NetworkBuilder, NetworkTopologies } from './helpers/network-builder.js';
4
+ import { createConnectionSpy } from './helpers/connection-spy.js';
5
+ import { oNodeAddress } from '../src/router/o-node.address.js';
6
+ import { oErrorCodes } from '@olane/o-core';
7
+ describe('Network Communication', () => {
8
+ const env = new TestEnvironment();
9
+ let builder;
10
+ afterEach(async () => {
11
+ if (builder) {
12
+ await builder.cleanup();
13
+ }
14
+ await env.cleanup();
15
+ });
16
+ describe('Two-Node Direct Communication', () => {
17
+ it('should establish connection between parent and child', async () => {
18
+ builder = await NetworkTopologies.twoNode();
19
+ const leader = builder.getNode('o://leader');
20
+ const child = builder.getNode('o://child');
21
+ // Verify child has leader transports
22
+ expect(child.address.libp2pTransports.length).to.be.greaterThan(0);
23
+ // Create connection spy
24
+ const spy = createConnectionSpy(leader);
25
+ spy.start();
26
+ // Make a call from leader to child
27
+ const response = await leader.use(new oNodeAddress(child.address.toString(), child.address.libp2pTransports), {
28
+ method: 'echo',
29
+ params: { message: 'hello from leader' },
30
+ });
31
+ expect(response.result.success).to.be.true;
32
+ expect(response.result.data.message).to.equal('hello from leader');
33
+ expect(response.result.data.nodeAddress).to.include('child');
34
+ // Verify connection was established
35
+ const summary = spy.getSummary();
36
+ expect(summary.currentConnections).to.be.greaterThan(0);
37
+ spy.stop();
38
+ });
39
+ it('should allow bidirectional communication', async () => {
40
+ builder = await NetworkTopologies.twoNode();
41
+ const leader = builder.getNode('o://leader');
42
+ const child = builder.getNode('o://child');
43
+ // Leader → Child
44
+ const response1 = await leader.use(new oNodeAddress(child.address.toString(), child.address.libp2pTransports), {
45
+ method: 'echo',
46
+ params: { message: 'from leader' },
47
+ });
48
+ expect(response1.result.success).to.be.true;
49
+ expect(response1.result.data.message).to.equal('from leader');
50
+ // Child → Leader
51
+ const response2 = await child.use(new oNodeAddress(leader.address.toString(), leader.address.libp2pTransports), {
52
+ method: 'get_info',
53
+ params: {},
54
+ });
55
+ expect(response2.result.success).to.be.true;
56
+ expect(response2.result.data.address).to.include('leader');
57
+ });
58
+ it('should reuse connections for multiple requests', async () => {
59
+ builder = await NetworkTopologies.twoNode();
60
+ const leader = builder.getNode('o://leader');
61
+ const child = builder.getNode('o://child');
62
+ const spy = createConnectionSpy(leader);
63
+ spy.start();
64
+ // Make multiple requests
65
+ for (let i = 0; i < 5; i++) {
66
+ const response = await leader.use(new oNodeAddress(child.address.toString(), child.address.libp2pTransports), {
67
+ method: 'echo',
68
+ params: { message: `request ${i}` },
69
+ });
70
+ expect(response.result.success).to.be.true;
71
+ }
72
+ // Should have only 1 connection (reused)
73
+ const summary = spy.getSummary();
74
+ expect(summary.currentConnections).to.equal(1);
75
+ spy.stop();
76
+ });
77
+ });
78
+ describe('Three-Node Hierarchical Communication', () => {
79
+ it('should route through hierarchy (leader → parent → child)', async () => {
80
+ builder = await NetworkTopologies.threeNode();
81
+ const leader = builder.getNode('o://leader');
82
+ const parent = builder.getNode('o://parent');
83
+ const child = builder.getNode('o://child');
84
+ // Leader → Child (should route through parent)
85
+ const response = await leader.use(child.address, {
86
+ method: 'echo',
87
+ params: { message: 'hello from leader' },
88
+ });
89
+ expect(response.result.success).to.be.true;
90
+ expect(response.result.data.message).to.equal('hello from leader');
91
+ expect(response.result.data.nodeAddress).to.include('child');
92
+ });
93
+ });
94
+ describe('Self-Routing Optimization', () => {
95
+ it('should execute locally when routing to self', async () => {
96
+ builder = await NetworkTopologies.twoNode();
97
+ const leader = builder.getNode('o://leader');
98
+ const spy = createConnectionSpy(leader);
99
+ spy.start();
100
+ const initialStreamCount = spy.getTotalStreamCount();
101
+ // Call self
102
+ const response = await leader.use(leader.address, {
103
+ method: 'get_info',
104
+ params: {},
105
+ });
106
+ expect(response.result.success).to.be.true;
107
+ expect(response.result.data.address).to.include('leader');
108
+ // Stream count should not increase (no network call)
109
+ const finalStreamCount = spy.getTotalStreamCount();
110
+ expect(finalStreamCount).to.equal(initialStreamCount);
111
+ spy.stop();
112
+ });
113
+ it('should handle self-routing with different address formats', async () => {
114
+ builder = new NetworkBuilder();
115
+ const leader = await builder.addNode('o://leader');
116
+ // Call with exact address
117
+ const response1 = await leader.use(leader.address, {
118
+ method: 'get_info',
119
+ params: {},
120
+ });
121
+ expect(response1.result.success).to.be.true;
122
+ // Call with address string (should also detect self)
123
+ const response2 = await leader.use(new oNodeAddress('o://leader'), {
124
+ method: 'get_info',
125
+ params: {},
126
+ });
127
+ expect(response2.result.success).to.be.true;
128
+ });
129
+ });
130
+ describe('Method Execution', () => {
131
+ it('should execute tool methods correctly', async () => {
132
+ builder = await NetworkTopologies.twoNode();
133
+ const leader = builder.getNode('o://leader');
134
+ const child = builder.getNode('o://child');
135
+ // Test echo method
136
+ const echoResponse = await leader.use(new oNodeAddress(child.address.toString(), child.address.libp2pTransports), {
137
+ method: 'echo',
138
+ params: { message: 'test message' },
139
+ });
140
+ expect(echoResponse.result.success).to.be.true;
141
+ expect(echoResponse.result.data.message).to.equal('test message');
142
+ expect(echoResponse.result.data.timestamp).to.be.a('number');
143
+ // Test get_info method
144
+ const infoResponse = await leader.use(new oNodeAddress(child.address.toString(), child.address.libp2pTransports), {
145
+ method: 'get_info',
146
+ params: {},
147
+ });
148
+ expect(infoResponse.result.success).to.be.true;
149
+ expect(infoResponse.result.data.address).to.be.a('string');
150
+ expect(infoResponse.result.data.callCount).to.equal(1); // One echo call
151
+ });
152
+ it('should handle method not found errors', async () => {
153
+ builder = await NetworkTopologies.twoNode();
154
+ const leader = builder.getNode('o://leader');
155
+ const child = builder.getNode('o://child');
156
+ await leader.use(new oNodeAddress(child.address.toString(), child.address.libp2pTransports), {
157
+ method: 'non_existent_method',
158
+ params: {},
159
+ }).catch((error) => {
160
+ expect(error).to.exist;
161
+ expect(error?.code).to.be.equal(oErrorCodes.INVALID_ACTION);
162
+ });
163
+ });
164
+ });
165
+ describe('Concurrent Requests', () => {
166
+ it('should handle concurrent requests to same node', async () => {
167
+ builder = await NetworkTopologies.twoNode();
168
+ const leader = builder.getNode('o://leader');
169
+ const child = builder.getNode('o://child');
170
+ const promises = [];
171
+ for (let i = 0; i < 10; i++) {
172
+ promises.push(leader.use(new oNodeAddress(child.address.toString(), child.address.libp2pTransports), {
173
+ method: 'echo',
174
+ params: { message: `concurrent ${i}` },
175
+ }));
176
+ }
177
+ const responses = await Promise.all(promises);
178
+ // All should succeed
179
+ expect(responses).to.have.lengthOf(10);
180
+ responses.forEach((response, i) => {
181
+ expect(response.result.success).to.be.true;
182
+ expect(response.result.data.message).to.equal(`concurrent ${i}`);
183
+ });
184
+ });
185
+ it('should handle concurrent requests to different nodes', async () => {
186
+ builder = await NetworkTopologies.fiveNode();
187
+ const leader = builder.getNode('o://leader');
188
+ const parent1 = builder.getNode('o://parent1');
189
+ const parent2 = builder.getNode('o://parent2');
190
+ const child1 = builder.getNode('o://child1');
191
+ const child2 = builder.getNode('o://child2');
192
+ const promises = [
193
+ leader.use(parent1.address, { method: 'get_info', params: {} }),
194
+ leader.use(parent2.address, { method: 'get_info', params: {} }),
195
+ leader.use(child1.address, { method: 'get_info', params: {} }),
196
+ leader.use(child2.address, { method: 'get_info', params: {} }),
197
+ ];
198
+ const responses = await Promise.all(promises);
199
+ // All should succeed
200
+ expect(responses).to.have.lengthOf(4);
201
+ responses.forEach((response) => {
202
+ expect(response.result.success).to.be.true;
203
+ });
204
+ // Verify correct nodes responded
205
+ expect(responses[0].result.data.address).to.include('parent1');
206
+ expect(responses[1].result.data.address).to.include('parent2');
207
+ expect(responses[2].result.data.address).to.include('child1');
208
+ expect(responses[3].result.data.address).to.include('child2');
209
+ });
210
+ });
211
+ describe('Connection Pooling', () => {
212
+ it('should pool connections efficiently', async () => {
213
+ builder = await NetworkTopologies.fiveNode();
214
+ const leader = builder.getNode('o://leader');
215
+ const spy = createConnectionSpy(leader);
216
+ spy.start();
217
+ const child1 = builder.getNode('o://child1');
218
+ const child2 = builder.getNode('o://child2');
219
+ // Make multiple calls to same nodes
220
+ for (let i = 0; i < 5; i++) {
221
+ await leader.use(child1.address, {
222
+ method: 'echo',
223
+ params: { message: `child1-${i}` },
224
+ });
225
+ await leader.use(child2.address, {
226
+ method: 'echo',
227
+ params: { message: `child2-${i}` },
228
+ });
229
+ }
230
+ const summary = spy.getSummary();
231
+ // Should have connections to parents (which route to children)
232
+ expect(summary.currentConnections).to.be.greaterThan(0);
233
+ expect(summary.currentConnections).to.be.lessThan(10); // Not 10 (one per call)
234
+ spy.stop();
235
+ });
236
+ it('should maintain connection status correctly', async () => {
237
+ builder = await NetworkTopologies.twoNode();
238
+ const leader = builder.getNode('o://leader');
239
+ const child = builder.getNode('o://child');
240
+ const spy = createConnectionSpy(leader);
241
+ spy.start();
242
+ // Make initial request to establish connection
243
+ await leader.use(new oNodeAddress(child.address.toString(), child.address.libp2pTransports), {
244
+ method: 'echo',
245
+ params: { message: 'test' },
246
+ });
247
+ // Get connection stats
248
+ const stats = spy.getConnectionStats();
249
+ expect(stats.length).to.be.greaterThan(0);
250
+ const connection = stats[0];
251
+ expect(connection.status).to.equal('open');
252
+ expect(connection.peerId).to.be.a('string');
253
+ spy.stop();
254
+ });
255
+ });
256
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=o-node.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"o-node.spec.d.ts","sourceRoot":"","sources":["../../test/o-node.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,247 @@
1
+ import { NodeState } from '@olane/o-core';
2
+ import { expect } from 'chai';
3
+ import { assertRunning, assertStopped } from '@olane/o-test';
4
+ import { TestEnvironment } from './helpers/index.js';
5
+ import { oNodeTool } from '../src/o-node.tool.js';
6
+ import { oNodeAddress } from '../src/index.js';
7
+ describe('oNode', () => {
8
+ const env = new TestEnvironment();
9
+ afterEach(async () => {
10
+ await env.cleanup();
11
+ });
12
+ describe('Lifecycle', () => {
13
+ it('should be able to start a single node with no leader', async () => {
14
+ const node = new oNodeTool({
15
+ address: new oNodeAddress('o://test'),
16
+ leader: null,
17
+ parent: null,
18
+ });
19
+ await node.start();
20
+ // Use o-test assertion helpers
21
+ assertRunning(node);
22
+ const transports = node.transports;
23
+ // expect(transports.length).to.equal(1);
24
+ // expect(transports[0].toString()).to.contain('/memory');
25
+ await node.stop();
26
+ assertStopped(node);
27
+ // Also verify with traditional chai for backward compatibility
28
+ expect(node.state).to.equal(NodeState.STOPPED);
29
+ });
30
+ it('should initialize with correct address', async () => {
31
+ const testAddress = new oNodeAddress('o://test-node');
32
+ const node = new oNodeTool({
33
+ address: testAddress,
34
+ leader: null,
35
+ parent: null,
36
+ });
37
+ await node.start();
38
+ expect(node.address.value).to.equal('o://test-node');
39
+ assertRunning(node);
40
+ await node.stop();
41
+ });
42
+ it('should handle start and stop lifecycle correctly', async () => {
43
+ const node = new oNodeTool({
44
+ address: new oNodeAddress('o://lifecycle-test'),
45
+ leader: null,
46
+ parent: null,
47
+ });
48
+ // Initially not started
49
+ expect(node.state).to.equal(NodeState.STOPPED);
50
+ // Start node
51
+ await node.start();
52
+ assertRunning(node);
53
+ // Stop node
54
+ await node.stop();
55
+ assertStopped(node);
56
+ // Verify state is properly reset
57
+ expect(node.state).to.equal(NodeState.STOPPED);
58
+ });
59
+ it('should allow restart after stop with state reset', async () => {
60
+ const node = new oNodeTool({
61
+ address: new oNodeAddress('o://restart-test'),
62
+ leader: null,
63
+ parent: null,
64
+ seed: 'restart-test-seed',
65
+ });
66
+ // First start
67
+ await node.start();
68
+ assertRunning(node);
69
+ // Verify node has transports after start
70
+ expect(node.address.libp2pTransports.length).to.be.greaterThan(0);
71
+ const firstPeerId = node.peerId.toString();
72
+ // Stop the node
73
+ await node.stop();
74
+ assertStopped(node);
75
+ // After stop, state should be reset
76
+ expect(node.p2pNode).to.be.undefined;
77
+ expect(node.peerId).to.be.undefined;
78
+ expect(node.connectionManager).to.be.undefined;
79
+ // Restart should now work
80
+ await node.start();
81
+ assertRunning(node);
82
+ // Verify node is functional after restart
83
+ expect(node.peerId.toString()).to.equal(firstPeerId); // Same seed = same peerId
84
+ expect(node.address.libp2pTransports.length).to.be.greaterThan(0);
85
+ await node.stop();
86
+ });
87
+ it('should reset address to staticAddress with no transports', async () => {
88
+ const staticAddress = new oNodeAddress('o://address-reset-test');
89
+ const node = new oNodeTool({
90
+ address: staticAddress,
91
+ leader: null,
92
+ parent: null,
93
+ });
94
+ // Verify initial state
95
+ expect(node.address.value).to.equal('o://address-reset-test');
96
+ expect(node.address.transports).to.have.length(0);
97
+ // Start node
98
+ await node.start();
99
+ assertRunning(node);
100
+ // After start, address should have transports
101
+ expect(node.address.transports.length).to.be.greaterThan(0);
102
+ const transportsDuringRun = node.address.transports.length;
103
+ // Stop node
104
+ await node.stop();
105
+ assertStopped(node);
106
+ // After stop, address should be reset to staticAddress with no transports
107
+ expect(node.address.value).to.equal('o://address-reset-test');
108
+ expect(node.address.transports).to.have.length(0);
109
+ // Restart to verify it works
110
+ await node.start();
111
+ assertRunning(node);
112
+ expect(node.address.transports.length).to.be.greaterThan(0);
113
+ await node.stop();
114
+ });
115
+ it('should reset errors array on stop', async () => {
116
+ const node = new oNodeTool({
117
+ address: new oNodeAddress('o://errors-reset-test'),
118
+ leader: null,
119
+ parent: null,
120
+ });
121
+ await node.start();
122
+ assertRunning(node);
123
+ // Simulate adding errors
124
+ node.errors.push(new Error('Test error'));
125
+ expect(node.errors).to.have.length(1);
126
+ await node.stop();
127
+ assertStopped(node);
128
+ // Errors should be cleared
129
+ expect(node.errors).to.have.length(0);
130
+ });
131
+ it('should reset metrics on stop', async () => {
132
+ const node = new oNodeTool({
133
+ address: new oNodeAddress('o://metrics-reset-test'),
134
+ leader: null,
135
+ parent: null,
136
+ });
137
+ await node.start();
138
+ assertRunning(node);
139
+ // Make some calls to accumulate metrics
140
+ await node.use(node.address, {
141
+ method: 'get_libp2p_metrics',
142
+ params: {},
143
+ });
144
+ // Verify metrics were recorded
145
+ const metricsBeforeStop = node.metrics.successCount;
146
+ expect(metricsBeforeStop).to.be.greaterThan(0);
147
+ await node.stop();
148
+ assertStopped(node);
149
+ // Metrics should be reset
150
+ expect(node.metrics.successCount).to.equal(0);
151
+ expect(node.metrics.errorCount).to.equal(0);
152
+ });
153
+ it('should support multiple restart cycles', async () => {
154
+ const node = new oNodeTool({
155
+ address: new oNodeAddress('o://multi-restart-test'),
156
+ leader: null,
157
+ parent: null,
158
+ seed: 'multi-restart-seed',
159
+ });
160
+ const peerId = node.peerId?.toString();
161
+ // First cycle
162
+ await node.start();
163
+ assertRunning(node);
164
+ expect(node.p2pNode).to.exist;
165
+ await node.stop();
166
+ assertStopped(node);
167
+ expect(node.p2pNode).to.be.undefined;
168
+ // Second cycle
169
+ await node.start();
170
+ assertRunning(node);
171
+ expect(node.p2pNode).to.exist;
172
+ await node.stop();
173
+ assertStopped(node);
174
+ expect(node.p2pNode).to.be.undefined;
175
+ // Third cycle
176
+ await node.start();
177
+ assertRunning(node);
178
+ expect(node.p2pNode).to.exist;
179
+ // Verify node is still functional
180
+ const response = await node.use(node.address, {
181
+ method: 'get_libp2p_metrics',
182
+ params: {},
183
+ });
184
+ expect(response.result.success).to.be.true;
185
+ await node.stop();
186
+ assertStopped(node);
187
+ });
188
+ it('should reset didRegister flag on stop', async () => {
189
+ const node = new oNodeTool({
190
+ address: new oNodeAddress('o://didregister-test'),
191
+ leader: null,
192
+ parent: null,
193
+ });
194
+ await node.start();
195
+ assertRunning(node);
196
+ // After start, didRegister might be true (depending on if registration happened)
197
+ // For standalone nodes without leader, it stays false, but let's verify the reset works
198
+ await node.stop();
199
+ assertStopped(node);
200
+ // Should be able to restart
201
+ await node.start();
202
+ assertRunning(node);
203
+ await node.stop();
204
+ });
205
+ it('should clear p2p node after stop', async () => {
206
+ const node = new oNodeTool({
207
+ address: new oNodeAddress('o://clear-test'),
208
+ leader: null,
209
+ parent: null,
210
+ seed: 'clear-test-seed',
211
+ });
212
+ await node.start();
213
+ assertRunning(node);
214
+ // Test basic functionality before stop
215
+ const response1 = await node.use(node.address, {
216
+ method: 'get_libp2p_metrics',
217
+ params: {},
218
+ });
219
+ expect(response1.result.success).to.be.true;
220
+ expect(response1.result.data).to.exist;
221
+ // Verify p2pNode exists
222
+ expect(node.p2pNode).to.exist;
223
+ await node.stop();
224
+ assertStopped(node);
225
+ // p2pNode should be cleared (allowing restart)
226
+ expect(node.p2pNode).to.be.undefined;
227
+ });
228
+ it('should clean up resources properly on stop', async () => {
229
+ const node = new oNodeTool({
230
+ address: new oNodeAddress('o://cleanup-test'),
231
+ leader: null,
232
+ parent: null,
233
+ });
234
+ await node.start();
235
+ assertRunning(node);
236
+ // Verify p2p node exists and is started
237
+ expect(node.p2pNode).to.exist;
238
+ expect(node.p2pNode.status).to.equal('started');
239
+ await node.stop();
240
+ assertStopped(node);
241
+ // Verify resources are cleaned up
242
+ expect(node.p2pNode).to.be.undefined;
243
+ expect(node.connectionManager).to.be.undefined;
244
+ expect(node.connectionHeartbeatManager).to.be.undefined;
245
+ });
246
+ });
247
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=parent-child-registration.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parent-child-registration.spec.d.ts","sourceRoot":"","sources":["../../test/parent-child-registration.spec.ts"],"names":[],"mappings":""}