@olane/o-core 0.7.9 → 0.7.10
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"o-address.d.ts","sourceRoot":"","sources":["../../../src/router/o-address.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAI1D,qBAAa,QAAS,SAAQ,OAAO;aAIjB,KAAK,EAAE,MAAM;IAHxB,UAAU,EAAE,UAAU,EAAE,CAAC;gBAGd,KAAK,EAAE,MAAM,EAC7B,UAAU,GAAE,UAAU,EAAO;IAM/B,IAAI,gBAAgB,IAAI,UAAU,EAAE,CAEnC;IAED,IAAI,gBAAgB,IAAI,UAAU,EAAE,CAEnC;IAED,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO;IAIhC,eAAe,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO;IAMzC,aAAa,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,IAAI;IAI7C,QAAQ,IAAI,OAAO;IAOnB,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,eAAe,IAAI,QAAQ;IAQ3B,aAAa,IAAI,QAAQ;IAQzB,QAAQ,IAAI,MAAM;IAIlB,MAAM,IAAI;QACR,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,EAAE,CAAC;KACtB;IAOD,iBAAiB,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO;IAI3C,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC;IAI3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO;IAIhD,MAAM,CAAC,MAAM,IAAI,QAAQ;IAIzB,MAAM,CAAC,IAAI,IAAI,QAAQ;IAIvB,MAAM,CAAC,QAAQ,IAAI,QAAQ;IAI3B,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO;IAI3C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,GAAG,QAAQ;
|
|
1
|
+
{"version":3,"file":"o-address.d.ts","sourceRoot":"","sources":["../../../src/router/o-address.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAI1D,qBAAa,QAAS,SAAQ,OAAO;aAIjB,KAAK,EAAE,MAAM;IAHxB,UAAU,EAAE,UAAU,EAAE,CAAC;gBAGd,KAAK,EAAE,MAAM,EAC7B,UAAU,GAAE,UAAU,EAAO;IAM/B,IAAI,gBAAgB,IAAI,UAAU,EAAE,CAEnC;IAED,IAAI,gBAAgB,IAAI,UAAU,EAAE,CAEnC;IAED,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO;IAIhC,eAAe,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO;IAMzC,aAAa,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,IAAI;IAI7C,QAAQ,IAAI,OAAO;IAOnB,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,eAAe,IAAI,QAAQ;IAQ3B,aAAa,IAAI,QAAQ;IAQzB,QAAQ,IAAI,MAAM;IAIlB,MAAM,IAAI;QACR,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,EAAE,CAAC;KACtB;IAOD,iBAAiB,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO;IAI3C,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC;IAI3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO;IAIhD,MAAM,CAAC,MAAM,IAAI,QAAQ;IAIzB,MAAM,CAAC,IAAI,IAAI,QAAQ;IAIvB,MAAM,CAAC,QAAQ,IAAI,QAAQ;IAI3B,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO;IAI3C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,GAAG,QAAQ;CAkClE"}
|
|
@@ -88,10 +88,23 @@ export class oAddress extends oObject {
|
|
|
88
88
|
if (remainingPath === '') {
|
|
89
89
|
return address;
|
|
90
90
|
}
|
|
91
|
+
// if remainingPath equals targetAddress.protocol, the replace didn't match
|
|
92
|
+
// this means we're either at destination (addresses are equal) or on different branch
|
|
93
|
+
if (remainingPath === targetAddress.protocol) {
|
|
94
|
+
// check if we're actually at the destination
|
|
95
|
+
if (address.value === targetAddress.value) {
|
|
96
|
+
return address;
|
|
97
|
+
}
|
|
98
|
+
// we're on a different branch, need to go back to leader for resolution
|
|
99
|
+
if (!address.equals(oAddress.leader())) {
|
|
100
|
+
return oAddress.leader();
|
|
101
|
+
}
|
|
102
|
+
// we ARE the leader, and we can't make progress - stay at leader for resolution
|
|
103
|
+
return address;
|
|
104
|
+
}
|
|
91
105
|
// do we need to go back to the leader?
|
|
92
106
|
if (!address.equals(oAddress.leader()) && // if we are a leader, do not got back to self
|
|
93
|
-
(
|
|
94
|
-
oAddress.isStatic(targetAddress))) {
|
|
107
|
+
oAddress.isStatic(targetAddress)) {
|
|
95
108
|
return oAddress.leader();
|
|
96
109
|
}
|
|
97
110
|
// we need to go to the child address
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"o-address.spec.d.ts","sourceRoot":"","sources":["../../../test/router/o-address.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { oAddress } from '../../src/index.js';
|
|
2
|
+
import { expect } from 'chai';
|
|
3
|
+
describe('oAddress helper properties', () => {
|
|
4
|
+
describe('protocol getter', () => {
|
|
5
|
+
it('should convert o:// to /o/', () => {
|
|
6
|
+
const addr = new oAddress('o://leader');
|
|
7
|
+
expect(addr.protocol).to.equal('/o/leader');
|
|
8
|
+
});
|
|
9
|
+
it('should handle nested paths', () => {
|
|
10
|
+
const addr = new oAddress('o://leader/services/embeddings-text');
|
|
11
|
+
expect(addr.protocol).to.equal('/o/leader/services/embeddings-text');
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
describe('paths getter', () => {
|
|
15
|
+
it('should strip o:// prefix', () => {
|
|
16
|
+
const addr = new oAddress('o://leader');
|
|
17
|
+
expect(addr.paths).to.equal('leader');
|
|
18
|
+
});
|
|
19
|
+
it('should handle nested paths', () => {
|
|
20
|
+
const addr = new oAddress('o://leader/services/embeddings-text');
|
|
21
|
+
expect(addr.paths).to.equal('leader/services/embeddings-text');
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
describe('toRootAddress()', () => {
|
|
25
|
+
it('should return first path segment', () => {
|
|
26
|
+
const addr = new oAddress('o://leader/services/embeddings-text');
|
|
27
|
+
expect(addr.toRootAddress().toString()).to.equal('o://leader');
|
|
28
|
+
});
|
|
29
|
+
it('should return same address if already root', () => {
|
|
30
|
+
const addr = new oAddress('o://leader');
|
|
31
|
+
expect(addr.toRootAddress().toString()).to.equal('o://leader');
|
|
32
|
+
});
|
|
33
|
+
it('should handle static addresses', () => {
|
|
34
|
+
const addr = new oAddress('o://embeddings-text');
|
|
35
|
+
expect(addr.toRootAddress().toString()).to.equal('o://embeddings-text');
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
describe('oAddress.next() routing logic', () => {
|
|
40
|
+
describe('Basic next hop calculation', () => {
|
|
41
|
+
it('should return same address when at destination', () => {
|
|
42
|
+
const current = new oAddress('o://leader');
|
|
43
|
+
const target = new oAddress('o://leader');
|
|
44
|
+
const next = oAddress.next(current, target);
|
|
45
|
+
expect(next.toString()).to.equal('o://leader');
|
|
46
|
+
});
|
|
47
|
+
it('should go one level down when target is direct child', () => {
|
|
48
|
+
const current = new oAddress('o://leader');
|
|
49
|
+
const target = new oAddress('o://leader/services');
|
|
50
|
+
const next = oAddress.next(current, target);
|
|
51
|
+
expect(next.toString()).to.equal('o://leader/services');
|
|
52
|
+
});
|
|
53
|
+
it('should go one level down when target is two levels deep (BUG CASE)', () => {
|
|
54
|
+
const current = new oAddress('o://leader');
|
|
55
|
+
const target = new oAddress('o://leader/services/embeddings-text');
|
|
56
|
+
const next = oAddress.next(current, target);
|
|
57
|
+
// Expected: should return the next immediate child in the hierarchy
|
|
58
|
+
// which is o://leader/services
|
|
59
|
+
console.log('Current:', current.toString());
|
|
60
|
+
console.log('Target:', target.toString());
|
|
61
|
+
console.log('Next hop returned:', next.toString());
|
|
62
|
+
console.log('Expected:', 'o://leader/services');
|
|
63
|
+
expect(next.toString()).to.equal('o://leader/services');
|
|
64
|
+
});
|
|
65
|
+
it('should reach final destination when already at intermediate node', () => {
|
|
66
|
+
const current = new oAddress('o://leader/services');
|
|
67
|
+
const target = new oAddress('o://leader/services/embeddings-text');
|
|
68
|
+
const next = oAddress.next(current, target);
|
|
69
|
+
console.log('Current:', current.toString());
|
|
70
|
+
console.log('Target:', target.toString());
|
|
71
|
+
console.log('Next hop returned:', next.toString());
|
|
72
|
+
console.log('Expected:', 'o://leader/services/embeddings-text');
|
|
73
|
+
expect(next.toString()).to.equal('o://leader/services/embeddings-text');
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
describe('Multi-level routing', () => {
|
|
77
|
+
it('should route through three-level hierarchy', () => {
|
|
78
|
+
const current = new oAddress('o://leader');
|
|
79
|
+
const target = new oAddress('o://leader/services/embeddings-text/method');
|
|
80
|
+
const next = oAddress.next(current, target);
|
|
81
|
+
console.log('Current:', current.toString());
|
|
82
|
+
console.log('Target:', target.toString());
|
|
83
|
+
console.log('Next hop returned:', next.toString());
|
|
84
|
+
console.log('Expected:', 'o://leader/services');
|
|
85
|
+
// Should go to first child in path
|
|
86
|
+
expect(next.toString()).to.equal('o://leader/services');
|
|
87
|
+
});
|
|
88
|
+
it('should handle routing from second level to third level', () => {
|
|
89
|
+
const current = new oAddress('o://leader/services');
|
|
90
|
+
const target = new oAddress('o://leader/services/embeddings-text/method');
|
|
91
|
+
const next = oAddress.next(current, target);
|
|
92
|
+
console.log('Current:', current.toString());
|
|
93
|
+
console.log('Target:', target.toString());
|
|
94
|
+
console.log('Next hop returned:', next.toString());
|
|
95
|
+
console.log('Expected:', 'o://leader/services/embeddings-text');
|
|
96
|
+
expect(next.toString()).to.equal('o://leader/services/embeddings-text');
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
describe('Edge cases', () => {
|
|
100
|
+
it('should route to leader from non-leader node', () => {
|
|
101
|
+
const current = new oAddress('o://worker');
|
|
102
|
+
const target = new oAddress('o://leader/services');
|
|
103
|
+
const next = oAddress.next(current, target);
|
|
104
|
+
console.log('Current:', current.toString());
|
|
105
|
+
console.log('Target:', target.toString());
|
|
106
|
+
console.log('Next hop returned:', next.toString());
|
|
107
|
+
console.log('Expected:', 'o://leader');
|
|
108
|
+
// Should route back to leader for resolution
|
|
109
|
+
expect(next.toString()).to.equal('o://leader');
|
|
110
|
+
});
|
|
111
|
+
it('should route static address to leader for resolution', () => {
|
|
112
|
+
const current = new oAddress('o://leader');
|
|
113
|
+
const target = new oAddress('o://embeddings-text');
|
|
114
|
+
const next = oAddress.next(current, target);
|
|
115
|
+
console.log('Current:', current.toString());
|
|
116
|
+
console.log('Target:', target.toString());
|
|
117
|
+
console.log('Next hop returned:', next.toString());
|
|
118
|
+
// Static addresses should be resolved by leader
|
|
119
|
+
expect(next.toString()).to.equal('o://leader');
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
describe('Exact bug reproduction scenario', () => {
|
|
123
|
+
it('should correctly route o://leader -> o://leader/services/embeddings-text', () => {
|
|
124
|
+
// This is the exact scenario from the bug report
|
|
125
|
+
const current = new oAddress('o://leader');
|
|
126
|
+
const target = new oAddress('o://leader/services/embeddings-text');
|
|
127
|
+
const next = oAddress.next(current, target);
|
|
128
|
+
console.log('=== BUG REPRODUCTION TEST ===');
|
|
129
|
+
console.log('Current address:', current.toString());
|
|
130
|
+
console.log('Current paths:', current.paths);
|
|
131
|
+
console.log('Current protocol:', current.protocol);
|
|
132
|
+
console.log('');
|
|
133
|
+
console.log('Target address:', target.toString());
|
|
134
|
+
console.log('Target paths:', target.paths);
|
|
135
|
+
console.log('Target protocol:', target.protocol);
|
|
136
|
+
console.log('');
|
|
137
|
+
// Calculate what the function does internally
|
|
138
|
+
const remainingPath = target.protocol.replace(current.protocol + '/', '');
|
|
139
|
+
console.log('remainingPath calculation:');
|
|
140
|
+
console.log(' target.protocol:', target.protocol);
|
|
141
|
+
console.log(' current.protocol + "/":', current.protocol + '/');
|
|
142
|
+
console.log(' remainingPath:', remainingPath);
|
|
143
|
+
console.log('');
|
|
144
|
+
const parts = remainingPath.replace('/o/', '').split('/');
|
|
145
|
+
console.log('parts calculation:');
|
|
146
|
+
console.log(' remainingPath.replace("/o/", ""):', remainingPath.replace('/o/', ''));
|
|
147
|
+
console.log(' split("/"):', parts);
|
|
148
|
+
console.log(' reversed:', [...parts].reverse());
|
|
149
|
+
console.log(' pop():', [...parts].reverse().pop());
|
|
150
|
+
console.log('');
|
|
151
|
+
const nextHop = remainingPath.replace('/o/', '').split('/').reverse().pop();
|
|
152
|
+
console.log('nextHop:', nextHop);
|
|
153
|
+
console.log('constructed address:', current.value + '/' + nextHop);
|
|
154
|
+
console.log('');
|
|
155
|
+
console.log('Actual next hop returned:', next.toString());
|
|
156
|
+
console.log('Expected next hop:', 'o://leader/services');
|
|
157
|
+
console.log('=== END BUG REPRODUCTION TEST ===');
|
|
158
|
+
// The bug manifests here - it should return o://leader/services
|
|
159
|
+
// but may return something else causing the duplication
|
|
160
|
+
expect(next.toString()).to.equal('o://leader/services');
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@olane/o-core",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"typescript": "^5.8.3"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
|
-
"@olane/o-protocol": "^0.7.
|
|
64
|
+
"@olane/o-protocol": "^0.7.9"
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
67
|
"chalk": "^5.4.1",
|