@prosopo/load-balancer 2.8.8 → 2.8.12

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,224 +0,0 @@
1
- import { beforeEach, describe, expect, it, vi } from "vitest";
2
- import { loadBalancer } from "../index.js";
3
- import { getRandomActiveProvider, selectWeightedProvider, } from "../providers.js";
4
- import { _resetCache } from "../providers.js";
5
- vi.mock("../index.js", () => ({
6
- loadBalancer: vi.fn(),
7
- }));
8
- describe("selectWeightedProvider", () => {
9
- it("selects provider based on weight distribution", () => {
10
- const providers = [
11
- {
12
- address: "address1",
13
- url: "url1",
14
- datasetId: "dataset1",
15
- weight: 1,
16
- },
17
- {
18
- address: "address2",
19
- url: "url2",
20
- datasetId: "dataset2",
21
- weight: 3,
22
- },
23
- {
24
- address: "address3",
25
- url: "url3",
26
- datasetId: "dataset3",
27
- weight: 1,
28
- },
29
- ];
30
- expect(selectWeightedProvider(providers, 0).address).toBe("address1");
31
- expect(selectWeightedProvider(providers, 1).address).toBe("address2");
32
- expect(selectWeightedProvider(providers, 2).address).toBe("address2");
33
- expect(selectWeightedProvider(providers, 3).address).toBe("address2");
34
- expect(selectWeightedProvider(providers, 4).address).toBe("address3");
35
- expect(selectWeightedProvider(providers, 5).address).toBe("address1");
36
- expect(selectWeightedProvider(providers, 6).address).toBe("address2");
37
- });
38
- it("handles equal weights correctly", () => {
39
- const providers = [
40
- {
41
- address: "address1",
42
- url: "url1",
43
- datasetId: "dataset1",
44
- weight: 1,
45
- },
46
- {
47
- address: "address2",
48
- url: "url2",
49
- datasetId: "dataset2",
50
- weight: 1,
51
- },
52
- ];
53
- expect(selectWeightedProvider(providers, 0).address).toBe("address1");
54
- expect(selectWeightedProvider(providers, 1).address).toBe("address2");
55
- expect(selectWeightedProvider(providers, 2).address).toBe("address1");
56
- expect(selectWeightedProvider(providers, 3).address).toBe("address2");
57
- });
58
- it("handles single provider", () => {
59
- const providers = [
60
- {
61
- address: "address1",
62
- url: "url1",
63
- datasetId: "dataset1",
64
- weight: 10,
65
- },
66
- ];
67
- expect(selectWeightedProvider(providers, 0).address).toBe("address1");
68
- expect(selectWeightedProvider(providers, 5).address).toBe("address1");
69
- expect(selectWeightedProvider(providers, 100).address).toBe("address1");
70
- });
71
- it("throws error for empty provider list", () => {
72
- expect(() => selectWeightedProvider([], 0)).toThrow("No providers available");
73
- });
74
- it("heavily weighted provider is selected more often", () => {
75
- const providers = [
76
- {
77
- address: "address1",
78
- url: "url1",
79
- datasetId: "dataset1",
80
- weight: 1,
81
- },
82
- {
83
- address: "address2",
84
- url: "url2",
85
- datasetId: "dataset2",
86
- weight: 99,
87
- },
88
- ];
89
- const selections = { address1: 0, address2: 0 };
90
- for (let i = 0; i < 100; i++) {
91
- const selected = selectWeightedProvider(providers, i);
92
- if (selected.address === "address1") {
93
- selections.address1++;
94
- }
95
- else {
96
- selections.address2++;
97
- }
98
- }
99
- expect(selections.address1).toBe(1);
100
- expect(selections.address2).toBe(99);
101
- });
102
- it("handles maximum weight value (100)", () => {
103
- const providers = [
104
- {
105
- address: "address1",
106
- url: "url1",
107
- datasetId: "dataset1",
108
- weight: 100,
109
- },
110
- {
111
- address: "address2",
112
- url: "url2",
113
- datasetId: "dataset2",
114
- weight: 100,
115
- },
116
- ];
117
- const selections = { address1: 0, address2: 0 };
118
- for (let i = 0; i < 200; i++) {
119
- const selected = selectWeightedProvider(providers, i);
120
- if (selected.address === "address1") {
121
- selections.address1++;
122
- }
123
- else {
124
- selections.address2++;
125
- }
126
- }
127
- expect(selections.address1).toBe(100);
128
- expect(selections.address2).toBe(100);
129
- });
130
- it("correctly handles providers without values for weight", () => {
131
- const providers = [
132
- {
133
- address: "address1",
134
- url: "url1",
135
- datasetId: "dataset1",
136
- },
137
- {
138
- address: "address2",
139
- url: "url2",
140
- datasetId: "dataset2",
141
- weight: 3,
142
- },
143
- ];
144
- const providersWithDefaults = [
145
- { ...providers[0], weight: 1 },
146
- providers[1],
147
- ];
148
- const selections = { address1: 0, address2: 0 };
149
- for (let i = 0; i < 100; i++) {
150
- const selected = selectWeightedProvider(providersWithDefaults, i);
151
- if (selected.address === "address1") {
152
- selections.address1++;
153
- }
154
- else {
155
- selections.address2++;
156
- }
157
- }
158
- expect(selections.address1).toBe(25);
159
- expect(selections.address2).toBe(75);
160
- });
161
- });
162
- describe("getRandomActiveProvider", () => {
163
- beforeEach(() => {
164
- _resetCache();
165
- vi.clearAllMocks();
166
- vi.resetAllMocks();
167
- vi.resetModules();
168
- });
169
- it("returns a random provider when providers list is populated", async () => {
170
- const mockProviders = [
171
- { address: "address1", url: "url1", datasetId: "dataset1", weight: 1 },
172
- { address: "address2", url: "url2", datasetId: "dataset2", weight: 1 },
173
- ];
174
- loadBalancer.mockResolvedValue(mockProviders);
175
- const result = await getRandomActiveProvider("development", 1);
176
- expect(result.providerAccount).toBe("address2");
177
- expect(result.provider.url).toBe("url2");
178
- expect(result.provider.datasetId).toBe("dataset2");
179
- });
180
- it("loads providers only once when called multiple times", async () => {
181
- const mockProviders = [
182
- { address: "address1", url: "url1", datasetId: "dataset1", weight: 1 },
183
- ];
184
- loadBalancer.mockResolvedValue(mockProviders);
185
- await getRandomActiveProvider("development", 123);
186
- await getRandomActiveProvider("development", 456);
187
- expect(loadBalancer).toHaveBeenCalledTimes(1);
188
- });
189
- it("handles empty providers list gracefully", async () => {
190
- loadBalancer.mockResolvedValue([]);
191
- await expect(getRandomActiveProvider("development", 123)).rejects.toThrow();
192
- });
193
- it("respects provider weights when selecting", async () => {
194
- const mockProviders = [
195
- { address: "address1", url: "url1", datasetId: "dataset1", weight: 1 },
196
- { address: "address2", url: "url2", datasetId: "dataset2", weight: 3 },
197
- ];
198
- loadBalancer.mockResolvedValue(mockProviders);
199
- const result0 = await getRandomActiveProvider("development", 0);
200
- expect(result0.providerAccount).toBe("address1");
201
- _resetCache();
202
- const result1 = await getRandomActiveProvider("development", 1);
203
- expect(result1.providerAccount).toBe("address2");
204
- _resetCache();
205
- const result2 = await getRandomActiveProvider("development", 2);
206
- expect(result2.providerAccount).toBe("address2");
207
- _resetCache();
208
- const result3 = await getRandomActiveProvider("development", 3);
209
- expect(result3.providerAccount).toBe("address2");
210
- });
211
- it("handles providers with missing weight field (defaults to 1)", async () => {
212
- const mockProviders = [
213
- { address: "address1", url: "url1", datasetId: "dataset1", weight: 1 },
214
- { address: "address2", url: "url2", datasetId: "dataset2", weight: 1 },
215
- ];
216
- loadBalancer.mockResolvedValue(mockProviders);
217
- const result0 = await getRandomActiveProvider("development", 0);
218
- expect(result0.providerAccount).toBe("address1");
219
- _resetCache();
220
- const result1 = await getRandomActiveProvider("development", 1);
221
- expect(result1.providerAccount).toBe("address2");
222
- });
223
- });
224
- //# sourceMappingURL=providers.unit.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"providers.unit.test.js","sourceRoot":"","sources":["../../src/tests/providers.unit.test.ts"],"names":[],"mappings":"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"}