lance-context 0.1.0 → 1.0.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 (237) hide show
  1. package/README.md +232 -23
  2. package/dist/__tests__/ast-chunker.test.d.ts +2 -0
  3. package/dist/__tests__/ast-chunker.test.d.ts.map +1 -0
  4. package/dist/__tests__/ast-chunker.test.js +307 -0
  5. package/dist/__tests__/ast-chunker.test.js.map +1 -0
  6. package/dist/__tests__/config.test.d.ts +2 -0
  7. package/dist/__tests__/config.test.d.ts.map +1 -0
  8. package/dist/__tests__/config.test.js +242 -0
  9. package/dist/__tests__/config.test.js.map +1 -0
  10. package/dist/__tests__/dashboard/beads.test.d.ts +2 -0
  11. package/dist/__tests__/dashboard/beads.test.d.ts.map +1 -0
  12. package/dist/__tests__/dashboard/beads.test.js +151 -0
  13. package/dist/__tests__/dashboard/beads.test.js.map +1 -0
  14. package/dist/__tests__/dashboard/index.test.d.ts +2 -0
  15. package/dist/__tests__/dashboard/index.test.d.ts.map +1 -0
  16. package/dist/__tests__/dashboard/index.test.js +116 -0
  17. package/dist/__tests__/dashboard/index.test.js.map +1 -0
  18. package/dist/__tests__/dashboard/routes.test.d.ts +2 -0
  19. package/dist/__tests__/dashboard/routes.test.d.ts.map +1 -0
  20. package/dist/__tests__/dashboard/routes.test.js +125 -0
  21. package/dist/__tests__/dashboard/routes.test.js.map +1 -0
  22. package/dist/__tests__/dashboard/server.test.d.ts +2 -0
  23. package/dist/__tests__/dashboard/server.test.d.ts.map +1 -0
  24. package/dist/__tests__/dashboard/server.test.js +75 -0
  25. package/dist/__tests__/dashboard/server.test.js.map +1 -0
  26. package/dist/__tests__/dashboard/state.test.d.ts +2 -0
  27. package/dist/__tests__/dashboard/state.test.d.ts.map +1 -0
  28. package/dist/__tests__/dashboard/state.test.js +124 -0
  29. package/dist/__tests__/dashboard/state.test.js.map +1 -0
  30. package/dist/__tests__/embeddings/factory.test.d.ts +2 -0
  31. package/dist/__tests__/embeddings/factory.test.d.ts.map +1 -0
  32. package/dist/__tests__/embeddings/factory.test.js +100 -0
  33. package/dist/__tests__/embeddings/factory.test.js.map +1 -0
  34. package/dist/__tests__/embeddings/jina.test.d.ts +2 -0
  35. package/dist/__tests__/embeddings/jina.test.d.ts.map +1 -0
  36. package/dist/__tests__/embeddings/jina.test.js +156 -0
  37. package/dist/__tests__/embeddings/jina.test.js.map +1 -0
  38. package/dist/__tests__/embeddings/ollama.test.d.ts +2 -0
  39. package/dist/__tests__/embeddings/ollama.test.d.ts.map +1 -0
  40. package/dist/__tests__/embeddings/ollama.test.js +172 -0
  41. package/dist/__tests__/embeddings/ollama.test.js.map +1 -0
  42. package/dist/__tests__/embeddings/rate-limiter.test.d.ts +2 -0
  43. package/dist/__tests__/embeddings/rate-limiter.test.d.ts.map +1 -0
  44. package/dist/__tests__/embeddings/rate-limiter.test.js +163 -0
  45. package/dist/__tests__/embeddings/rate-limiter.test.js.map +1 -0
  46. package/dist/__tests__/embeddings/retry.test.d.ts +2 -0
  47. package/dist/__tests__/embeddings/retry.test.d.ts.map +1 -0
  48. package/dist/__tests__/embeddings/retry.test.js +260 -0
  49. package/dist/__tests__/embeddings/retry.test.js.map +1 -0
  50. package/dist/__tests__/embeddings/types.test.d.ts +2 -0
  51. package/dist/__tests__/embeddings/types.test.d.ts.map +1 -0
  52. package/dist/__tests__/embeddings/types.test.js +31 -0
  53. package/dist/__tests__/embeddings/types.test.js.map +1 -0
  54. package/dist/__tests__/mocks/embedding-backend.mock.d.ts +10 -0
  55. package/dist/__tests__/mocks/embedding-backend.mock.d.ts.map +1 -0
  56. package/dist/__tests__/mocks/embedding-backend.mock.js +39 -0
  57. package/dist/__tests__/mocks/embedding-backend.mock.js.map +1 -0
  58. package/dist/__tests__/mocks/fetch.mock.d.ts +38 -0
  59. package/dist/__tests__/mocks/fetch.mock.d.ts.map +1 -0
  60. package/dist/__tests__/mocks/fetch.mock.js +74 -0
  61. package/dist/__tests__/mocks/fetch.mock.js.map +1 -0
  62. package/dist/__tests__/mocks/lancedb.mock.d.ts +38 -0
  63. package/dist/__tests__/mocks/lancedb.mock.d.ts.map +1 -0
  64. package/dist/__tests__/mocks/lancedb.mock.js +63 -0
  65. package/dist/__tests__/mocks/lancedb.mock.js.map +1 -0
  66. package/dist/__tests__/search/clustering.test.d.ts +2 -0
  67. package/dist/__tests__/search/clustering.test.d.ts.map +1 -0
  68. package/dist/__tests__/search/clustering.test.js +230 -0
  69. package/dist/__tests__/search/clustering.test.js.map +1 -0
  70. package/dist/__tests__/search/hybrid-search.test.d.ts +2 -0
  71. package/dist/__tests__/search/hybrid-search.test.d.ts.map +1 -0
  72. package/dist/__tests__/search/hybrid-search.test.js +186 -0
  73. package/dist/__tests__/search/hybrid-search.test.js.map +1 -0
  74. package/dist/__tests__/search/indexer.test.d.ts +2 -0
  75. package/dist/__tests__/search/indexer.test.d.ts.map +1 -0
  76. package/dist/__tests__/search/indexer.test.js +878 -0
  77. package/dist/__tests__/search/indexer.test.js.map +1 -0
  78. package/dist/__tests__/search/tree-sitter-chunker.test.d.ts +2 -0
  79. package/dist/__tests__/search/tree-sitter-chunker.test.d.ts.map +1 -0
  80. package/dist/__tests__/search/tree-sitter-chunker.test.js +228 -0
  81. package/dist/__tests__/search/tree-sitter-chunker.test.js.map +1 -0
  82. package/dist/__tests__/setup.d.ts +2 -0
  83. package/dist/__tests__/setup.d.ts.map +1 -0
  84. package/dist/__tests__/setup.js +11 -0
  85. package/dist/__tests__/setup.js.map +1 -0
  86. package/dist/__tests__/utils/concurrency.test.d.ts +2 -0
  87. package/dist/__tests__/utils/concurrency.test.d.ts.map +1 -0
  88. package/dist/__tests__/utils/concurrency.test.js +83 -0
  89. package/dist/__tests__/utils/concurrency.test.js.map +1 -0
  90. package/dist/__tests__/utils/errors.test.d.ts +2 -0
  91. package/dist/__tests__/utils/errors.test.d.ts.map +1 -0
  92. package/dist/__tests__/utils/errors.test.js +136 -0
  93. package/dist/__tests__/utils/errors.test.js.map +1 -0
  94. package/dist/__tests__/utils/type-guards.test.d.ts +2 -0
  95. package/dist/__tests__/utils/type-guards.test.d.ts.map +1 -0
  96. package/dist/__tests__/utils/type-guards.test.js +80 -0
  97. package/dist/__tests__/utils/type-guards.test.js.map +1 -0
  98. package/dist/__tests__/worktree/worktree-manager.test.d.ts +2 -0
  99. package/dist/__tests__/worktree/worktree-manager.test.d.ts.map +1 -0
  100. package/dist/__tests__/worktree/worktree-manager.test.js +403 -0
  101. package/dist/__tests__/worktree/worktree-manager.test.js.map +1 -0
  102. package/dist/config.d.ts +122 -0
  103. package/dist/config.d.ts.map +1 -0
  104. package/dist/config.js +508 -0
  105. package/dist/config.js.map +1 -0
  106. package/dist/dashboard/beads.d.ts +35 -0
  107. package/dist/dashboard/beads.d.ts.map +1 -0
  108. package/dist/dashboard/beads.js +102 -0
  109. package/dist/dashboard/beads.js.map +1 -0
  110. package/dist/dashboard/events.d.ts +46 -0
  111. package/dist/dashboard/events.d.ts.map +1 -0
  112. package/dist/dashboard/events.js +141 -0
  113. package/dist/dashboard/events.js.map +1 -0
  114. package/dist/dashboard/index.d.ts +67 -0
  115. package/dist/dashboard/index.d.ts.map +1 -0
  116. package/dist/dashboard/index.js +90 -0
  117. package/dist/dashboard/index.js.map +1 -0
  118. package/dist/dashboard/routes.d.ts +6 -0
  119. package/dist/dashboard/routes.d.ts.map +1 -0
  120. package/dist/dashboard/routes.js +244 -0
  121. package/dist/dashboard/routes.js.map +1 -0
  122. package/dist/dashboard/server.d.ts +27 -0
  123. package/dist/dashboard/server.d.ts.map +1 -0
  124. package/dist/dashboard/server.js +72 -0
  125. package/dist/dashboard/server.js.map +1 -0
  126. package/dist/dashboard/state.d.ts +116 -0
  127. package/dist/dashboard/state.d.ts.map +1 -0
  128. package/dist/dashboard/state.js +251 -0
  129. package/dist/dashboard/state.js.map +1 -0
  130. package/dist/dashboard/ui.d.ts +6 -0
  131. package/dist/dashboard/ui.d.ts.map +1 -0
  132. package/dist/dashboard/ui.js +1407 -0
  133. package/dist/dashboard/ui.js.map +1 -0
  134. package/dist/embeddings/index.d.ts +20 -2
  135. package/dist/embeddings/index.d.ts.map +1 -1
  136. package/dist/embeddings/index.js +49 -6
  137. package/dist/embeddings/index.js.map +1 -1
  138. package/dist/embeddings/jina.d.ts +9 -0
  139. package/dist/embeddings/jina.d.ts.map +1 -1
  140. package/dist/embeddings/jina.js +42 -2
  141. package/dist/embeddings/jina.js.map +1 -1
  142. package/dist/embeddings/ollama.d.ts +2 -0
  143. package/dist/embeddings/ollama.d.ts.map +1 -1
  144. package/dist/embeddings/ollama.js +21 -5
  145. package/dist/embeddings/ollama.js.map +1 -1
  146. package/dist/embeddings/rate-limiter.d.ts +75 -0
  147. package/dist/embeddings/rate-limiter.d.ts.map +1 -0
  148. package/dist/embeddings/rate-limiter.js +145 -0
  149. package/dist/embeddings/rate-limiter.js.map +1 -0
  150. package/dist/embeddings/retry.d.ts +14 -0
  151. package/dist/embeddings/retry.d.ts.map +1 -0
  152. package/dist/embeddings/retry.js +89 -0
  153. package/dist/embeddings/retry.js.map +1 -0
  154. package/dist/embeddings/types.d.ts +56 -2
  155. package/dist/embeddings/types.d.ts.map +1 -1
  156. package/dist/embeddings/types.js +16 -0
  157. package/dist/embeddings/types.js.map +1 -1
  158. package/dist/index.js +1870 -44
  159. package/dist/index.js.map +1 -1
  160. package/dist/memory/index.d.ts +63 -0
  161. package/dist/memory/index.d.ts.map +1 -0
  162. package/dist/memory/index.js +168 -0
  163. package/dist/memory/index.js.map +1 -0
  164. package/dist/search/ast-chunker.d.ts +34 -0
  165. package/dist/search/ast-chunker.d.ts.map +1 -0
  166. package/dist/search/ast-chunker.js +261 -0
  167. package/dist/search/ast-chunker.js.map +1 -0
  168. package/dist/search/clustering.d.ts +77 -0
  169. package/dist/search/clustering.d.ts.map +1 -0
  170. package/dist/search/clustering.js +455 -0
  171. package/dist/search/clustering.js.map +1 -0
  172. package/dist/search/indexer.d.ts +239 -3
  173. package/dist/search/indexer.d.ts.map +1 -1
  174. package/dist/search/indexer.js +941 -45
  175. package/dist/search/indexer.js.map +1 -1
  176. package/dist/search/tree-sitter-chunker.d.ts +69 -0
  177. package/dist/search/tree-sitter-chunker.d.ts.map +1 -0
  178. package/dist/search/tree-sitter-chunker.js +436 -0
  179. package/dist/search/tree-sitter-chunker.js.map +1 -0
  180. package/dist/symbols/index.d.ts +14 -0
  181. package/dist/symbols/index.d.ts.map +1 -0
  182. package/dist/symbols/index.js +19 -0
  183. package/dist/symbols/index.js.map +1 -0
  184. package/dist/symbols/name-path.d.ts +113 -0
  185. package/dist/symbols/name-path.d.ts.map +1 -0
  186. package/dist/symbols/name-path.js +194 -0
  187. package/dist/symbols/name-path.js.map +1 -0
  188. package/dist/symbols/pattern-search.d.ts +14 -0
  189. package/dist/symbols/pattern-search.d.ts.map +1 -0
  190. package/dist/symbols/pattern-search.js +224 -0
  191. package/dist/symbols/pattern-search.js.map +1 -0
  192. package/dist/symbols/reference-finder.d.ts +38 -0
  193. package/dist/symbols/reference-finder.d.ts.map +1 -0
  194. package/dist/symbols/reference-finder.js +376 -0
  195. package/dist/symbols/reference-finder.js.map +1 -0
  196. package/dist/symbols/symbol-editor.d.ts +81 -0
  197. package/dist/symbols/symbol-editor.d.ts.map +1 -0
  198. package/dist/symbols/symbol-editor.js +257 -0
  199. package/dist/symbols/symbol-editor.js.map +1 -0
  200. package/dist/symbols/symbol-extractor.d.ts +49 -0
  201. package/dist/symbols/symbol-extractor.d.ts.map +1 -0
  202. package/dist/symbols/symbol-extractor.js +593 -0
  203. package/dist/symbols/symbol-extractor.js.map +1 -0
  204. package/dist/symbols/symbol-renamer.d.ts +81 -0
  205. package/dist/symbols/symbol-renamer.d.ts.map +1 -0
  206. package/dist/symbols/symbol-renamer.js +204 -0
  207. package/dist/symbols/symbol-renamer.js.map +1 -0
  208. package/dist/symbols/types.d.ts +234 -0
  209. package/dist/symbols/types.d.ts.map +1 -0
  210. package/dist/symbols/types.js +106 -0
  211. package/dist/symbols/types.js.map +1 -0
  212. package/dist/utils/concurrency.d.ts +32 -0
  213. package/dist/utils/concurrency.d.ts.map +1 -0
  214. package/dist/utils/concurrency.js +57 -0
  215. package/dist/utils/concurrency.js.map +1 -0
  216. package/dist/utils/errors.d.ts +36 -0
  217. package/dist/utils/errors.d.ts.map +1 -0
  218. package/dist/utils/errors.js +91 -0
  219. package/dist/utils/errors.js.map +1 -0
  220. package/dist/utils/type-guards.d.ts +17 -0
  221. package/dist/utils/type-guards.d.ts.map +1 -0
  222. package/dist/utils/type-guards.js +25 -0
  223. package/dist/utils/type-guards.js.map +1 -0
  224. package/dist/worktree/index.d.ts +6 -0
  225. package/dist/worktree/index.d.ts.map +1 -0
  226. package/dist/worktree/index.js +6 -0
  227. package/dist/worktree/index.js.map +1 -0
  228. package/dist/worktree/types.d.ts +101 -0
  229. package/dist/worktree/types.d.ts.map +1 -0
  230. package/dist/worktree/types.js +6 -0
  231. package/dist/worktree/types.js.map +1 -0
  232. package/dist/worktree/worktree-manager.d.ts +80 -0
  233. package/dist/worktree/worktree-manager.d.ts.map +1 -0
  234. package/dist/worktree/worktree-manager.js +407 -0
  235. package/dist/worktree/worktree-manager.js.map +1 -0
  236. package/package.json +39 -5
  237. package/scripts/postinstall.js +48 -0
@@ -0,0 +1,156 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { JinaBackend } from '../../embeddings/jina.js';
3
+ import { createJinaEmbeddingResponse, createErrorFetch } from '../mocks/fetch.mock.js';
4
+ describe('JinaBackend', () => {
5
+ beforeEach(() => {
6
+ vi.stubGlobal('fetch', vi.fn());
7
+ });
8
+ afterEach(() => {
9
+ vi.unstubAllGlobals();
10
+ });
11
+ describe('constructor', () => {
12
+ it('should throw if API key is not provided', () => {
13
+ expect(() => new JinaBackend({ backend: 'jina' })).toThrow('Jina API key is required. Set JINA_API_KEY environment variable.');
14
+ });
15
+ it('should accept API key in config', () => {
16
+ const backend = new JinaBackend({ backend: 'jina', apiKey: 'test-key' });
17
+ expect(backend.name).toBe('jina');
18
+ });
19
+ it('should use default model jina-embeddings-v3', () => {
20
+ const backend = new JinaBackend({ backend: 'jina', apiKey: 'test-key' });
21
+ expect(backend.getDimensions()).toBe(1024);
22
+ });
23
+ it('should accept custom model', () => {
24
+ const backend = new JinaBackend({
25
+ backend: 'jina',
26
+ apiKey: 'test-key',
27
+ model: 'custom-model',
28
+ });
29
+ expect(backend.name).toBe('jina');
30
+ });
31
+ });
32
+ describe('initialize', () => {
33
+ it('should test API key by calling embed', async () => {
34
+ const mockFetch = vi.fn().mockResolvedValue(createJinaEmbeddingResponse([[0.1, 0.2]]));
35
+ vi.stubGlobal('fetch', mockFetch);
36
+ const backend = new JinaBackend({ backend: 'jina', apiKey: 'test-key' });
37
+ await backend.initialize();
38
+ expect(mockFetch).toHaveBeenCalledWith('https://api.jina.ai/v1/embeddings', expect.objectContaining({
39
+ method: 'POST',
40
+ headers: expect.objectContaining({
41
+ Authorization: 'Bearer test-key',
42
+ }),
43
+ }));
44
+ });
45
+ it('should throw on initialization failure', async () => {
46
+ const mockFetch = createErrorFetch(401, 'Unauthorized');
47
+ vi.stubGlobal('fetch', mockFetch);
48
+ const backend = new JinaBackend({ backend: 'jina', apiKey: 'invalid-key' });
49
+ await expect(backend.initialize()).rejects.toThrow('Failed to initialize Jina backend');
50
+ });
51
+ });
52
+ describe('embed', () => {
53
+ it('should send correct request format', async () => {
54
+ const mockFetch = vi.fn().mockResolvedValue(createJinaEmbeddingResponse([[0.1, 0.2, 0.3]]));
55
+ vi.stubGlobal('fetch', mockFetch);
56
+ const backend = new JinaBackend({ backend: 'jina', apiKey: 'test-key' });
57
+ await backend.embed('test text');
58
+ expect(mockFetch).toHaveBeenCalledWith('https://api.jina.ai/v1/embeddings', expect.objectContaining({
59
+ method: 'POST',
60
+ headers: {
61
+ 'Content-Type': 'application/json',
62
+ Authorization: 'Bearer test-key',
63
+ },
64
+ body: JSON.stringify({
65
+ model: 'jina-embeddings-v3',
66
+ input: ['test text'],
67
+ }),
68
+ }));
69
+ });
70
+ it('should return embedding from response', async () => {
71
+ const embedding = [0.1, 0.2, 0.3];
72
+ const mockFetch = vi.fn().mockResolvedValue(createJinaEmbeddingResponse([embedding]));
73
+ vi.stubGlobal('fetch', mockFetch);
74
+ const backend = new JinaBackend({ backend: 'jina', apiKey: 'test-key' });
75
+ const result = await backend.embed('test text');
76
+ expect(result).toEqual(embedding);
77
+ });
78
+ it('should throw on API error', async () => {
79
+ const mockFetch = vi.fn().mockResolvedValue({
80
+ ok: false,
81
+ status: 400,
82
+ text: async () => 'Bad request',
83
+ });
84
+ vi.stubGlobal('fetch', mockFetch);
85
+ const backend = new JinaBackend({ backend: 'jina', apiKey: 'test-key' });
86
+ await expect(backend.embed('test')).rejects.toThrow('Jina API error: 400 - Bad request');
87
+ });
88
+ });
89
+ describe('embedBatch', () => {
90
+ it('should send all texts in single request', async () => {
91
+ const mockFetch = vi
92
+ .fn()
93
+ .mockResolvedValue(createJinaEmbeddingResponse([[0.1], [0.2], [0.3]]));
94
+ vi.stubGlobal('fetch', mockFetch);
95
+ const backend = new JinaBackend({ backend: 'jina', apiKey: 'test-key' });
96
+ await backend.embedBatch(['text1', 'text2', 'text3']);
97
+ expect(mockFetch).toHaveBeenCalledTimes(1);
98
+ expect(mockFetch).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
99
+ body: JSON.stringify({
100
+ model: 'jina-embeddings-v3',
101
+ input: ['text1', 'text2', 'text3'],
102
+ }),
103
+ }));
104
+ });
105
+ it('should return embeddings in order', async () => {
106
+ const embeddings = [[0.1], [0.2], [0.3]];
107
+ const mockFetch = vi.fn().mockResolvedValue(createJinaEmbeddingResponse(embeddings));
108
+ vi.stubGlobal('fetch', mockFetch);
109
+ const backend = new JinaBackend({ backend: 'jina', apiKey: 'test-key' });
110
+ const result = await backend.embedBatch(['text1', 'text2', 'text3']);
111
+ expect(result).toEqual(embeddings);
112
+ });
113
+ it('should throw on API error', async () => {
114
+ // Use 400 (non-retryable) instead of 500 (retryable)
115
+ const mockFetch = vi.fn().mockResolvedValue({
116
+ ok: false,
117
+ status: 400,
118
+ text: async () => 'Bad request',
119
+ });
120
+ vi.stubGlobal('fetch', mockFetch);
121
+ const backend = new JinaBackend({ backend: 'jina', apiKey: 'test-key' });
122
+ await expect(backend.embedBatch(['text'])).rejects.toThrow('Jina API error: 400 - Bad request');
123
+ });
124
+ it('should chunk large batches and make multiple requests', async () => {
125
+ const mockFetch = vi
126
+ .fn()
127
+ .mockImplementation(() => createJinaEmbeddingResponse([[0.1], [0.2]]));
128
+ vi.stubGlobal('fetch', mockFetch);
129
+ // Create backend with batch size of 2
130
+ const backend = new JinaBackend({ backend: 'jina', apiKey: 'test-key', batchSize: 2 });
131
+ const result = await backend.embedBatch(['text1', 'text2', 'text3', 'text4', 'text5']);
132
+ // Should make 3 requests: [text1, text2], [text3, text4], [text5]
133
+ expect(mockFetch).toHaveBeenCalledTimes(3);
134
+ // Should return all 5 embeddings (though mock returns 2 per call, so we get 6)
135
+ expect(result).toHaveLength(6);
136
+ });
137
+ it('should not chunk when batch is smaller than batch size', async () => {
138
+ const mockFetch = vi
139
+ .fn()
140
+ .mockResolvedValue(createJinaEmbeddingResponse([[0.1], [0.2], [0.3]]));
141
+ vi.stubGlobal('fetch', mockFetch);
142
+ // Create backend with batch size of 100 (larger than input)
143
+ const backend = new JinaBackend({ backend: 'jina', apiKey: 'test-key', batchSize: 100 });
144
+ await backend.embedBatch(['text1', 'text2', 'text3']);
145
+ // Should make only 1 request
146
+ expect(mockFetch).toHaveBeenCalledTimes(1);
147
+ });
148
+ });
149
+ describe('getDimensions', () => {
150
+ it('should return 1024 for default model', () => {
151
+ const backend = new JinaBackend({ backend: 'jina', apiKey: 'test-key' });
152
+ expect(backend.getDimensions()).toBe(1024);
153
+ });
154
+ });
155
+ });
156
+ //# sourceMappingURL=jina.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jina.test.js","sourceRoot":"","sources":["../../../src/__tests__/embeddings/jina.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ollama.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/embeddings/ollama.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,172 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { OllamaBackend } from '../../embeddings/ollama.js';
3
+ import { createOllamaEmbeddingResponse, createSuccessFetch, createErrorFetch, } from '../mocks/fetch.mock.js';
4
+ describe('OllamaBackend', () => {
5
+ beforeEach(() => {
6
+ vi.stubGlobal('fetch', vi.fn());
7
+ });
8
+ afterEach(() => {
9
+ vi.unstubAllGlobals();
10
+ });
11
+ describe('constructor', () => {
12
+ it('should use default baseUrl localhost:11434', () => {
13
+ const backend = new OllamaBackend({ backend: 'ollama' });
14
+ expect(backend.name).toBe('ollama');
15
+ });
16
+ it('should accept custom baseUrl', () => {
17
+ const backend = new OllamaBackend({
18
+ backend: 'ollama',
19
+ baseUrl: 'http://custom:1234',
20
+ });
21
+ expect(backend.name).toBe('ollama');
22
+ });
23
+ it('should use default model nomic-embed-text', () => {
24
+ const backend = new OllamaBackend({ backend: 'ollama' });
25
+ expect(backend.getDimensions()).toBe(768);
26
+ });
27
+ it('should accept custom model', () => {
28
+ const backend = new OllamaBackend({
29
+ backend: 'ollama',
30
+ model: 'custom-model',
31
+ });
32
+ expect(backend.name).toBe('ollama');
33
+ });
34
+ });
35
+ describe('initialize', () => {
36
+ it('should test connection by calling /api/tags', async () => {
37
+ const mockFetch = createSuccessFetch({ models: [] });
38
+ vi.stubGlobal('fetch', mockFetch);
39
+ const backend = new OllamaBackend({ backend: 'ollama' });
40
+ await backend.initialize();
41
+ expect(mockFetch).toHaveBeenCalledWith('http://localhost:11434/api/tags', expect.anything());
42
+ });
43
+ it('should use custom baseUrl for initialization', async () => {
44
+ const mockFetch = createSuccessFetch({ models: [] });
45
+ vi.stubGlobal('fetch', mockFetch);
46
+ const backend = new OllamaBackend({
47
+ backend: 'ollama',
48
+ baseUrl: 'http://custom:1234',
49
+ });
50
+ await backend.initialize();
51
+ expect(mockFetch).toHaveBeenCalledWith('http://custom:1234/api/tags', expect.anything());
52
+ });
53
+ it('should throw on connection failure', async () => {
54
+ vi.stubGlobal('fetch', vi.fn().mockRejectedValue(new Error('Connection refused')));
55
+ const backend = new OllamaBackend({ backend: 'ollama' });
56
+ await expect(backend.initialize()).rejects.toThrow('Failed to connect to Ollama at http://localhost:11434');
57
+ });
58
+ it('should throw on non-OK response', async () => {
59
+ // Use 404 (non-retryable) instead of 500 (retryable)
60
+ const mockFetch = createErrorFetch(404, 'Not found');
61
+ vi.stubGlobal('fetch', mockFetch);
62
+ const backend = new OllamaBackend({ backend: 'ollama' });
63
+ await expect(backend.initialize()).rejects.toThrow('Failed to connect to Ollama at http://localhost:11434');
64
+ });
65
+ });
66
+ describe('embed', () => {
67
+ it('should use prompt instead of input', async () => {
68
+ const mockFetch = vi.fn().mockResolvedValue(createOllamaEmbeddingResponse([0.1, 0.2, 0.3]));
69
+ vi.stubGlobal('fetch', mockFetch);
70
+ const backend = new OllamaBackend({ backend: 'ollama' });
71
+ await backend.embed('test text');
72
+ expect(mockFetch).toHaveBeenCalledWith('http://localhost:11434/api/embeddings', expect.objectContaining({
73
+ method: 'POST',
74
+ headers: { 'Content-Type': 'application/json' },
75
+ body: JSON.stringify({
76
+ model: 'nomic-embed-text',
77
+ prompt: 'test text',
78
+ }),
79
+ }));
80
+ });
81
+ it('should return embedding from response', async () => {
82
+ const embedding = [0.1, 0.2, 0.3];
83
+ const mockFetch = vi.fn().mockResolvedValue(createOllamaEmbeddingResponse(embedding));
84
+ vi.stubGlobal('fetch', mockFetch);
85
+ const backend = new OllamaBackend({ backend: 'ollama' });
86
+ const result = await backend.embed('test text');
87
+ expect(result).toEqual(embedding);
88
+ });
89
+ it('should use custom model in request', async () => {
90
+ const mockFetch = vi.fn().mockResolvedValue(createOllamaEmbeddingResponse([0.1]));
91
+ vi.stubGlobal('fetch', mockFetch);
92
+ const backend = new OllamaBackend({
93
+ backend: 'ollama',
94
+ model: 'mxbai-embed-large',
95
+ });
96
+ await backend.embed('test');
97
+ expect(mockFetch).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
98
+ body: expect.stringContaining('mxbai-embed-large'),
99
+ }));
100
+ });
101
+ it('should throw on API error', async () => {
102
+ // Use 400 (non-retryable) instead of 500 (retryable)
103
+ const mockFetch = vi.fn().mockResolvedValue({
104
+ ok: false,
105
+ status: 400,
106
+ });
107
+ vi.stubGlobal('fetch', mockFetch);
108
+ const backend = new OllamaBackend({ backend: 'ollama' });
109
+ await expect(backend.embed('test')).rejects.toThrow('Ollama embedding failed: 400');
110
+ });
111
+ });
112
+ describe('embedBatch', () => {
113
+ it('should parallelize calls since Ollama has no native batch', async () => {
114
+ const mockFetch = vi
115
+ .fn()
116
+ .mockResolvedValueOnce(createOllamaEmbeddingResponse([0.1]))
117
+ .mockResolvedValueOnce(createOllamaEmbeddingResponse([0.2]))
118
+ .mockResolvedValueOnce(createOllamaEmbeddingResponse([0.3]));
119
+ vi.stubGlobal('fetch', mockFetch);
120
+ const backend = new OllamaBackend({ backend: 'ollama' });
121
+ const result = await backend.embedBatch(['text1', 'text2', 'text3']);
122
+ expect(mockFetch).toHaveBeenCalledTimes(3);
123
+ expect(result).toEqual([[0.1], [0.2], [0.3]]);
124
+ });
125
+ it('should preserve order of embeddings', async () => {
126
+ // Simulate different response times by controlling mock order
127
+ const mockFetch = vi.fn().mockImplementation(async (_url, options) => {
128
+ const body = JSON.parse(options.body);
129
+ const index = ['text1', 'text2', 'text3'].indexOf(body.prompt);
130
+ return createOllamaEmbeddingResponse([index * 0.1]);
131
+ });
132
+ vi.stubGlobal('fetch', mockFetch);
133
+ const backend = new OllamaBackend({ backend: 'ollama' });
134
+ const result = await backend.embedBatch(['text1', 'text2', 'text3']);
135
+ expect(result).toEqual([[0], [0.1], [0.2]]);
136
+ });
137
+ it('should process in chunks with controlled parallelism', async () => {
138
+ const callOrder = [];
139
+ const mockFetch = vi.fn().mockImplementation(async (_url, options) => {
140
+ const body = JSON.parse(options.body);
141
+ callOrder.push(body.prompt);
142
+ return createOllamaEmbeddingResponse([0.1]);
143
+ });
144
+ vi.stubGlobal('fetch', mockFetch);
145
+ // Create backend with batch size of 2
146
+ const backend = new OllamaBackend({ backend: 'ollama', batchSize: 2 });
147
+ const result = await backend.embedBatch(['t1', 't2', 't3', 't4', 't5']);
148
+ // Should make 5 calls total
149
+ expect(mockFetch).toHaveBeenCalledTimes(5);
150
+ // Should return 5 embeddings
151
+ expect(result).toHaveLength(5);
152
+ });
153
+ it('should use default batch size of 10', async () => {
154
+ const mockFetch = vi.fn().mockResolvedValue(createOllamaEmbeddingResponse([0.1]));
155
+ vi.stubGlobal('fetch', mockFetch);
156
+ // Create backend without custom batchSize (should use default 10)
157
+ const backend = new OllamaBackend({ backend: 'ollama' });
158
+ // Create 15 texts - should process in 2 chunks: 10 parallel, then 5 parallel
159
+ const texts = Array.from({ length: 15 }, (_, i) => `text${i}`);
160
+ await backend.embedBatch(texts);
161
+ // All 15 calls should complete
162
+ expect(mockFetch).toHaveBeenCalledTimes(15);
163
+ });
164
+ });
165
+ describe('getDimensions', () => {
166
+ it('should return 768 for default nomic-embed-text model', () => {
167
+ const backend = new OllamaBackend({ backend: 'ollama' });
168
+ expect(backend.getDimensions()).toBe(768);
169
+ });
170
+ });
171
+ });
172
+ //# sourceMappingURL=ollama.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama.test.js","sourceRoot":"","sources":["../../../src/__tests__/embeddings/ollama.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=rate-limiter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/embeddings/rate-limiter.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,163 @@
1
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
2
+ import { RateLimiter, DEFAULT_RATE_LIMITER_CONFIG } from '../../embeddings/rate-limiter.js';
3
+ describe('RateLimiter', () => {
4
+ beforeEach(() => {
5
+ vi.useFakeTimers();
6
+ });
7
+ describe('constructor', () => {
8
+ it('should use default config when none provided', () => {
9
+ const limiter = new RateLimiter();
10
+ expect(limiter.getAvailableTokens()).toBe(DEFAULT_RATE_LIMITER_CONFIG.burstCapacity);
11
+ });
12
+ it('should use provided config', () => {
13
+ const limiter = new RateLimiter({
14
+ requestsPerSecond: 10,
15
+ burstCapacity: 20,
16
+ });
17
+ expect(limiter.getAvailableTokens()).toBe(20);
18
+ });
19
+ it('should use partial config with defaults', () => {
20
+ const limiter = new RateLimiter({
21
+ requestsPerSecond: 2,
22
+ });
23
+ expect(limiter.getAvailableTokens()).toBe(DEFAULT_RATE_LIMITER_CONFIG.burstCapacity);
24
+ });
25
+ });
26
+ describe('tryAcquire', () => {
27
+ it('should acquire token when available', () => {
28
+ const limiter = new RateLimiter({ requestsPerSecond: 5, burstCapacity: 10 });
29
+ expect(limiter.tryAcquire()).toBe(true);
30
+ expect(limiter.getAvailableTokens()).toBe(9);
31
+ });
32
+ it('should fail when no tokens available', () => {
33
+ const limiter = new RateLimiter({ requestsPerSecond: 5, burstCapacity: 2 });
34
+ expect(limiter.tryAcquire()).toBe(true);
35
+ expect(limiter.tryAcquire()).toBe(true);
36
+ expect(limiter.tryAcquire()).toBe(false);
37
+ });
38
+ it('should refill tokens over time', () => {
39
+ const limiter = new RateLimiter({ requestsPerSecond: 10, burstCapacity: 5 });
40
+ // Use all tokens
41
+ for (let i = 0; i < 5; i++) {
42
+ limiter.tryAcquire();
43
+ }
44
+ expect(limiter.getAvailableTokens()).toBe(0);
45
+ // Advance time by 500ms - should add 5 tokens
46
+ vi.advanceTimersByTime(500);
47
+ expect(limiter.getAvailableTokens()).toBe(5);
48
+ });
49
+ it('should not exceed burst capacity when refilling', () => {
50
+ const limiter = new RateLimiter({ requestsPerSecond: 10, burstCapacity: 5 });
51
+ // Advance time significantly
52
+ vi.advanceTimersByTime(5000);
53
+ // Should still be capped at burst capacity
54
+ expect(limiter.getAvailableTokens()).toBe(5);
55
+ });
56
+ });
57
+ describe('acquire', () => {
58
+ it('should resolve immediately when tokens available', async () => {
59
+ const limiter = new RateLimiter({ requestsPerSecond: 5, burstCapacity: 10 });
60
+ const promise = limiter.acquire();
61
+ await expect(promise).resolves.toBeUndefined();
62
+ expect(limiter.getAvailableTokens()).toBe(9);
63
+ });
64
+ it('should wait when no tokens available', async () => {
65
+ const limiter = new RateLimiter({ requestsPerSecond: 2, burstCapacity: 1 });
66
+ // Use the only token
67
+ await limiter.acquire();
68
+ expect(limiter.getAvailableTokens()).toBe(0);
69
+ // Start acquiring another token
70
+ let resolved = false;
71
+ const promise = limiter.acquire().then(() => {
72
+ resolved = true;
73
+ });
74
+ // Should not be resolved yet
75
+ expect(resolved).toBe(false);
76
+ // Advance time by 500ms (should add 1 token at 2 RPS)
77
+ // Use async version to properly handle promise resolution
78
+ await vi.advanceTimersByTimeAsync(500);
79
+ expect(resolved).toBe(true);
80
+ await promise;
81
+ });
82
+ it('should process multiple waiting requests in order', async () => {
83
+ const limiter = new RateLimiter({ requestsPerSecond: 1, burstCapacity: 1 });
84
+ // Use the only token
85
+ await limiter.acquire();
86
+ const order = [];
87
+ // Queue up multiple requests
88
+ const p1 = limiter.acquire().then(() => order.push(1));
89
+ const p2 = limiter.acquire().then(() => order.push(2));
90
+ expect(limiter.getQueueLength()).toBe(2);
91
+ // Advance time to process both requests
92
+ // Use async version to properly handle promise resolution
93
+ await vi.advanceTimersByTimeAsync(2000);
94
+ await Promise.all([p1, p2]);
95
+ expect(order).toEqual([1, 2]);
96
+ });
97
+ });
98
+ describe('getQueueLength', () => {
99
+ it('should return 0 when no pending requests', () => {
100
+ const limiter = new RateLimiter();
101
+ expect(limiter.getQueueLength()).toBe(0);
102
+ });
103
+ it('should return correct queue length when requests are pending', async () => {
104
+ const limiter = new RateLimiter({ requestsPerSecond: 1, burstCapacity: 1 });
105
+ // Use the only token
106
+ await limiter.acquire();
107
+ // Queue up requests without awaiting
108
+ limiter.acquire();
109
+ limiter.acquire();
110
+ expect(limiter.getQueueLength()).toBe(2);
111
+ });
112
+ });
113
+ describe('reset', () => {
114
+ it('should reset tokens to burst capacity', () => {
115
+ const limiter = new RateLimiter({ requestsPerSecond: 5, burstCapacity: 10 });
116
+ // Use some tokens
117
+ limiter.tryAcquire();
118
+ limiter.tryAcquire();
119
+ limiter.tryAcquire();
120
+ expect(limiter.getAvailableTokens()).toBe(7);
121
+ // Reset
122
+ limiter.reset();
123
+ expect(limiter.getAvailableTokens()).toBe(10);
124
+ });
125
+ it('should resolve pending requests', async () => {
126
+ const limiter = new RateLimiter({ requestsPerSecond: 1, burstCapacity: 1 });
127
+ // Use the only token
128
+ await limiter.acquire();
129
+ // Queue up a request
130
+ let resolved = false;
131
+ const promise = limiter.acquire().then(() => {
132
+ resolved = true;
133
+ });
134
+ expect(limiter.getQueueLength()).toBe(1);
135
+ // Reset should resolve pending requests
136
+ limiter.reset();
137
+ // Allow microtask queue to flush
138
+ await vi.advanceTimersByTimeAsync(0);
139
+ expect(resolved).toBe(true);
140
+ expect(limiter.getQueueLength()).toBe(0);
141
+ await promise;
142
+ });
143
+ });
144
+ describe('integration', () => {
145
+ it('should rate limit concurrent requests', async () => {
146
+ vi.useRealTimers(); // Use real timers for this test
147
+ const limiter = new RateLimiter({ requestsPerSecond: 100, burstCapacity: 5 });
148
+ const start = Date.now();
149
+ const requests = [];
150
+ // Make 10 requests (5 immediate, 5 rate limited)
151
+ for (let i = 0; i < 10; i++) {
152
+ requests.push(limiter.acquire());
153
+ }
154
+ await Promise.all(requests);
155
+ const elapsed = Date.now() - start;
156
+ // First 5 should be immediate, next 5 should take ~50ms at 100 RPS
157
+ // Allow some tolerance for timing
158
+ expect(elapsed).toBeGreaterThanOrEqual(40);
159
+ expect(elapsed).toBeLessThan(200);
160
+ });
161
+ });
162
+ });
163
+ //# sourceMappingURL=rate-limiter.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.test.js","sourceRoot":"","sources":["../../../src/__tests__/embeddings/rate-limiter.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=retry.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/embeddings/retry.test.ts"],"names":[],"mappings":""}