glancey 2.0.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 (336) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +435 -0
  3. package/dist/__tests__/ast-chunker.test.d.ts +2 -0
  4. package/dist/__tests__/ast-chunker.test.d.ts.map +1 -0
  5. package/dist/__tests__/ast-chunker.test.js +307 -0
  6. package/dist/__tests__/ast-chunker.test.js.map +1 -0
  7. package/dist/__tests__/config.test.d.ts +2 -0
  8. package/dist/__tests__/config.test.d.ts.map +1 -0
  9. package/dist/__tests__/config.test.js +242 -0
  10. package/dist/__tests__/config.test.js.map +1 -0
  11. package/dist/__tests__/dashboard/beads.test.d.ts +2 -0
  12. package/dist/__tests__/dashboard/beads.test.d.ts.map +1 -0
  13. package/dist/__tests__/dashboard/beads.test.js +151 -0
  14. package/dist/__tests__/dashboard/beads.test.js.map +1 -0
  15. package/dist/__tests__/dashboard/index.test.d.ts +2 -0
  16. package/dist/__tests__/dashboard/index.test.d.ts.map +1 -0
  17. package/dist/__tests__/dashboard/index.test.js +116 -0
  18. package/dist/__tests__/dashboard/index.test.js.map +1 -0
  19. package/dist/__tests__/dashboard/routes.test.d.ts +2 -0
  20. package/dist/__tests__/dashboard/routes.test.d.ts.map +1 -0
  21. package/dist/__tests__/dashboard/routes.test.js +125 -0
  22. package/dist/__tests__/dashboard/routes.test.js.map +1 -0
  23. package/dist/__tests__/dashboard/server.test.d.ts +2 -0
  24. package/dist/__tests__/dashboard/server.test.d.ts.map +1 -0
  25. package/dist/__tests__/dashboard/server.test.js +75 -0
  26. package/dist/__tests__/dashboard/server.test.js.map +1 -0
  27. package/dist/__tests__/dashboard/state.test.d.ts +2 -0
  28. package/dist/__tests__/dashboard/state.test.d.ts.map +1 -0
  29. package/dist/__tests__/dashboard/state.test.js +124 -0
  30. package/dist/__tests__/dashboard/state.test.js.map +1 -0
  31. package/dist/__tests__/dashboard/token-tracking.test.d.ts +2 -0
  32. package/dist/__tests__/dashboard/token-tracking.test.d.ts.map +1 -0
  33. package/dist/__tests__/dashboard/token-tracking.test.js +315 -0
  34. package/dist/__tests__/dashboard/token-tracking.test.js.map +1 -0
  35. package/dist/__tests__/embeddings/factory.test.d.ts +2 -0
  36. package/dist/__tests__/embeddings/factory.test.d.ts.map +1 -0
  37. package/dist/__tests__/embeddings/factory.test.js +157 -0
  38. package/dist/__tests__/embeddings/factory.test.js.map +1 -0
  39. package/dist/__tests__/embeddings/gemini.test.d.ts +2 -0
  40. package/dist/__tests__/embeddings/gemini.test.d.ts.map +1 -0
  41. package/dist/__tests__/embeddings/gemini.test.js +178 -0
  42. package/dist/__tests__/embeddings/gemini.test.js.map +1 -0
  43. package/dist/__tests__/embeddings/ollama.test.d.ts +2 -0
  44. package/dist/__tests__/embeddings/ollama.test.d.ts.map +1 -0
  45. package/dist/__tests__/embeddings/ollama.test.js +273 -0
  46. package/dist/__tests__/embeddings/ollama.test.js.map +1 -0
  47. package/dist/__tests__/embeddings/rate-limiter.test.d.ts +2 -0
  48. package/dist/__tests__/embeddings/rate-limiter.test.d.ts.map +1 -0
  49. package/dist/__tests__/embeddings/rate-limiter.test.js +163 -0
  50. package/dist/__tests__/embeddings/rate-limiter.test.js.map +1 -0
  51. package/dist/__tests__/embeddings/retry.test.d.ts +2 -0
  52. package/dist/__tests__/embeddings/retry.test.d.ts.map +1 -0
  53. package/dist/__tests__/embeddings/retry.test.js +334 -0
  54. package/dist/__tests__/embeddings/retry.test.js.map +1 -0
  55. package/dist/__tests__/embeddings/types.test.d.ts +2 -0
  56. package/dist/__tests__/embeddings/types.test.d.ts.map +1 -0
  57. package/dist/__tests__/embeddings/types.test.js +31 -0
  58. package/dist/__tests__/embeddings/types.test.js.map +1 -0
  59. package/dist/__tests__/mocks/embedding-backend.mock.d.ts +10 -0
  60. package/dist/__tests__/mocks/embedding-backend.mock.d.ts.map +1 -0
  61. package/dist/__tests__/mocks/embedding-backend.mock.js +39 -0
  62. package/dist/__tests__/mocks/embedding-backend.mock.js.map +1 -0
  63. package/dist/__tests__/mocks/fetch.mock.d.ts +49 -0
  64. package/dist/__tests__/mocks/fetch.mock.d.ts.map +1 -0
  65. package/dist/__tests__/mocks/fetch.mock.js +102 -0
  66. package/dist/__tests__/mocks/fetch.mock.js.map +1 -0
  67. package/dist/__tests__/mocks/lancedb.mock.d.ts +38 -0
  68. package/dist/__tests__/mocks/lancedb.mock.d.ts.map +1 -0
  69. package/dist/__tests__/mocks/lancedb.mock.js +63 -0
  70. package/dist/__tests__/mocks/lancedb.mock.js.map +1 -0
  71. package/dist/__tests__/search/clustering.test.d.ts +2 -0
  72. package/dist/__tests__/search/clustering.test.d.ts.map +1 -0
  73. package/dist/__tests__/search/clustering.test.js +230 -0
  74. package/dist/__tests__/search/clustering.test.js.map +1 -0
  75. package/dist/__tests__/search/hybrid-search.test.d.ts +2 -0
  76. package/dist/__tests__/search/hybrid-search.test.d.ts.map +1 -0
  77. package/dist/__tests__/search/hybrid-search.test.js +279 -0
  78. package/dist/__tests__/search/hybrid-search.test.js.map +1 -0
  79. package/dist/__tests__/search/indexer.test.d.ts +2 -0
  80. package/dist/__tests__/search/indexer.test.d.ts.map +1 -0
  81. package/dist/__tests__/search/indexer.test.js +1305 -0
  82. package/dist/__tests__/search/indexer.test.js.map +1 -0
  83. package/dist/__tests__/search/tree-sitter-chunker.test.d.ts +2 -0
  84. package/dist/__tests__/search/tree-sitter-chunker.test.d.ts.map +1 -0
  85. package/dist/__tests__/search/tree-sitter-chunker.test.js +228 -0
  86. package/dist/__tests__/search/tree-sitter-chunker.test.js.map +1 -0
  87. package/dist/__tests__/setup.d.ts +2 -0
  88. package/dist/__tests__/setup.d.ts.map +1 -0
  89. package/dist/__tests__/setup.js +11 -0
  90. package/dist/__tests__/setup.js.map +1 -0
  91. package/dist/__tests__/tools/clustering-handlers.test.d.ts +2 -0
  92. package/dist/__tests__/tools/clustering-handlers.test.d.ts.map +1 -0
  93. package/dist/__tests__/tools/clustering-handlers.test.js +286 -0
  94. package/dist/__tests__/tools/clustering-handlers.test.js.map +1 -0
  95. package/dist/__tests__/tools/commit-handlers.test.d.ts +2 -0
  96. package/dist/__tests__/tools/commit-handlers.test.d.ts.map +1 -0
  97. package/dist/__tests__/tools/commit-handlers.test.js +153 -0
  98. package/dist/__tests__/tools/commit-handlers.test.js.map +1 -0
  99. package/dist/__tests__/tools/index-handlers.test.d.ts +2 -0
  100. package/dist/__tests__/tools/index-handlers.test.d.ts.map +1 -0
  101. package/dist/__tests__/tools/index-handlers.test.js +184 -0
  102. package/dist/__tests__/tools/index-handlers.test.js.map +1 -0
  103. package/dist/__tests__/tools/instructions-handlers.test.d.ts +2 -0
  104. package/dist/__tests__/tools/instructions-handlers.test.d.ts.map +1 -0
  105. package/dist/__tests__/tools/instructions-handlers.test.js +53 -0
  106. package/dist/__tests__/tools/instructions-handlers.test.js.map +1 -0
  107. package/dist/__tests__/tools/memory-handlers.test.d.ts +2 -0
  108. package/dist/__tests__/tools/memory-handlers.test.d.ts.map +1 -0
  109. package/dist/__tests__/tools/memory-handlers.test.js +175 -0
  110. package/dist/__tests__/tools/memory-handlers.test.js.map +1 -0
  111. package/dist/__tests__/tools/search-handlers.test.d.ts +2 -0
  112. package/dist/__tests__/tools/search-handlers.test.d.ts.map +1 -0
  113. package/dist/__tests__/tools/search-handlers.test.js +229 -0
  114. package/dist/__tests__/tools/search-handlers.test.js.map +1 -0
  115. package/dist/__tests__/tools/symbol-handlers.test.d.ts +2 -0
  116. package/dist/__tests__/tools/symbol-handlers.test.d.ts.map +1 -0
  117. package/dist/__tests__/tools/symbol-handlers.test.js +348 -0
  118. package/dist/__tests__/tools/symbol-handlers.test.js.map +1 -0
  119. package/dist/__tests__/tools/worktree-handlers.test.d.ts +2 -0
  120. package/dist/__tests__/tools/worktree-handlers.test.d.ts.map +1 -0
  121. package/dist/__tests__/tools/worktree-handlers.test.js +297 -0
  122. package/dist/__tests__/tools/worktree-handlers.test.js.map +1 -0
  123. package/dist/__tests__/utils/cache.test.d.ts +2 -0
  124. package/dist/__tests__/utils/cache.test.d.ts.map +1 -0
  125. package/dist/__tests__/utils/cache.test.js +147 -0
  126. package/dist/__tests__/utils/cache.test.js.map +1 -0
  127. package/dist/__tests__/utils/concurrency.test.d.ts +2 -0
  128. package/dist/__tests__/utils/concurrency.test.d.ts.map +1 -0
  129. package/dist/__tests__/utils/concurrency.test.js +83 -0
  130. package/dist/__tests__/utils/concurrency.test.js.map +1 -0
  131. package/dist/__tests__/utils/errors.test.d.ts +2 -0
  132. package/dist/__tests__/utils/errors.test.d.ts.map +1 -0
  133. package/dist/__tests__/utils/errors.test.js +136 -0
  134. package/dist/__tests__/utils/errors.test.js.map +1 -0
  135. package/dist/__tests__/utils/logger.test.d.ts +2 -0
  136. package/dist/__tests__/utils/logger.test.d.ts.map +1 -0
  137. package/dist/__tests__/utils/logger.test.js +131 -0
  138. package/dist/__tests__/utils/logger.test.js.map +1 -0
  139. package/dist/__tests__/utils/type-guards.test.d.ts +2 -0
  140. package/dist/__tests__/utils/type-guards.test.d.ts.map +1 -0
  141. package/dist/__tests__/utils/type-guards.test.js +80 -0
  142. package/dist/__tests__/utils/type-guards.test.js.map +1 -0
  143. package/dist/__tests__/worktree/worktree-manager.test.d.ts +2 -0
  144. package/dist/__tests__/worktree/worktree-manager.test.d.ts.map +1 -0
  145. package/dist/__tests__/worktree/worktree-manager.test.js +403 -0
  146. package/dist/__tests__/worktree/worktree-manager.test.js.map +1 -0
  147. package/dist/config.d.ts +191 -0
  148. package/dist/config.d.ts.map +1 -0
  149. package/dist/config.js +788 -0
  150. package/dist/config.js.map +1 -0
  151. package/dist/dashboard/beads.d.ts +35 -0
  152. package/dist/dashboard/beads.d.ts.map +1 -0
  153. package/dist/dashboard/beads.js +102 -0
  154. package/dist/dashboard/beads.js.map +1 -0
  155. package/dist/dashboard/events.d.ts +64 -0
  156. package/dist/dashboard/events.d.ts.map +1 -0
  157. package/dist/dashboard/events.js +211 -0
  158. package/dist/dashboard/events.js.map +1 -0
  159. package/dist/dashboard/index.d.ts +69 -0
  160. package/dist/dashboard/index.d.ts.map +1 -0
  161. package/dist/dashboard/index.js +93 -0
  162. package/dist/dashboard/index.js.map +1 -0
  163. package/dist/dashboard/routes.d.ts +6 -0
  164. package/dist/dashboard/routes.d.ts.map +1 -0
  165. package/dist/dashboard/routes.js +505 -0
  166. package/dist/dashboard/routes.js.map +1 -0
  167. package/dist/dashboard/server.d.ts +27 -0
  168. package/dist/dashboard/server.d.ts.map +1 -0
  169. package/dist/dashboard/server.js +72 -0
  170. package/dist/dashboard/server.js.map +1 -0
  171. package/dist/dashboard/state.d.ts +172 -0
  172. package/dist/dashboard/state.d.ts.map +1 -0
  173. package/dist/dashboard/state.js +362 -0
  174. package/dist/dashboard/state.js.map +1 -0
  175. package/dist/dashboard/token-tracking.d.ts +143 -0
  176. package/dist/dashboard/token-tracking.d.ts.map +1 -0
  177. package/dist/dashboard/token-tracking.js +363 -0
  178. package/dist/dashboard/token-tracking.js.map +1 -0
  179. package/dist/dashboard/ui.d.ts +6 -0
  180. package/dist/dashboard/ui.d.ts.map +1 -0
  181. package/dist/dashboard/ui.js +2710 -0
  182. package/dist/dashboard/ui.js.map +1 -0
  183. package/dist/embeddings/gemini.d.ts +28 -0
  184. package/dist/embeddings/gemini.d.ts.map +1 -0
  185. package/dist/embeddings/gemini.js +165 -0
  186. package/dist/embeddings/gemini.js.map +1 -0
  187. package/dist/embeddings/index.d.ts +34 -0
  188. package/dist/embeddings/index.d.ts.map +1 -0
  189. package/dist/embeddings/index.js +120 -0
  190. package/dist/embeddings/index.js.map +1 -0
  191. package/dist/embeddings/ollama.d.ts +22 -0
  192. package/dist/embeddings/ollama.d.ts.map +1 -0
  193. package/dist/embeddings/ollama.js +179 -0
  194. package/dist/embeddings/ollama.js.map +1 -0
  195. package/dist/embeddings/rate-limiter.d.ts +75 -0
  196. package/dist/embeddings/rate-limiter.d.ts.map +1 -0
  197. package/dist/embeddings/rate-limiter.js +145 -0
  198. package/dist/embeddings/rate-limiter.js.map +1 -0
  199. package/dist/embeddings/retry.d.ts +20 -0
  200. package/dist/embeddings/retry.d.ts.map +1 -0
  201. package/dist/embeddings/retry.js +227 -0
  202. package/dist/embeddings/retry.js.map +1 -0
  203. package/dist/embeddings/types.d.ts +103 -0
  204. package/dist/embeddings/types.d.ts.map +1 -0
  205. package/dist/embeddings/types.js +23 -0
  206. package/dist/embeddings/types.js.map +1 -0
  207. package/dist/index.d.ts +12 -0
  208. package/dist/index.d.ts.map +1 -0
  209. package/dist/index.js +2028 -0
  210. package/dist/index.js.map +1 -0
  211. package/dist/memory/index.d.ts +63 -0
  212. package/dist/memory/index.d.ts.map +1 -0
  213. package/dist/memory/index.js +168 -0
  214. package/dist/memory/index.js.map +1 -0
  215. package/dist/search/ast-chunker.d.ts +29 -0
  216. package/dist/search/ast-chunker.d.ts.map +1 -0
  217. package/dist/search/ast-chunker.js +236 -0
  218. package/dist/search/ast-chunker.js.map +1 -0
  219. package/dist/search/chunk-utils.d.ts +24 -0
  220. package/dist/search/chunk-utils.d.ts.map +1 -0
  221. package/dist/search/chunk-utils.js +41 -0
  222. package/dist/search/chunk-utils.js.map +1 -0
  223. package/dist/search/clustering.d.ts +77 -0
  224. package/dist/search/clustering.d.ts.map +1 -0
  225. package/dist/search/clustering.js +455 -0
  226. package/dist/search/clustering.js.map +1 -0
  227. package/dist/search/indexer.d.ts +377 -0
  228. package/dist/search/indexer.d.ts.map +1 -0
  229. package/dist/search/indexer.js +1557 -0
  230. package/dist/search/indexer.js.map +1 -0
  231. package/dist/search/tree-sitter-chunker.d.ts +64 -0
  232. package/dist/search/tree-sitter-chunker.d.ts.map +1 -0
  233. package/dist/search/tree-sitter-chunker.js +412 -0
  234. package/dist/search/tree-sitter-chunker.js.map +1 -0
  235. package/dist/symbols/index.d.ts +14 -0
  236. package/dist/symbols/index.d.ts.map +1 -0
  237. package/dist/symbols/index.js +19 -0
  238. package/dist/symbols/index.js.map +1 -0
  239. package/dist/symbols/name-path.d.ts +113 -0
  240. package/dist/symbols/name-path.d.ts.map +1 -0
  241. package/dist/symbols/name-path.js +194 -0
  242. package/dist/symbols/name-path.js.map +1 -0
  243. package/dist/symbols/pattern-search.d.ts +14 -0
  244. package/dist/symbols/pattern-search.d.ts.map +1 -0
  245. package/dist/symbols/pattern-search.js +224 -0
  246. package/dist/symbols/pattern-search.js.map +1 -0
  247. package/dist/symbols/reference-finder.d.ts +38 -0
  248. package/dist/symbols/reference-finder.d.ts.map +1 -0
  249. package/dist/symbols/reference-finder.js +376 -0
  250. package/dist/symbols/reference-finder.js.map +1 -0
  251. package/dist/symbols/symbol-editor.d.ts +81 -0
  252. package/dist/symbols/symbol-editor.d.ts.map +1 -0
  253. package/dist/symbols/symbol-editor.js +257 -0
  254. package/dist/symbols/symbol-editor.js.map +1 -0
  255. package/dist/symbols/symbol-extractor.d.ts +49 -0
  256. package/dist/symbols/symbol-extractor.d.ts.map +1 -0
  257. package/dist/symbols/symbol-extractor.js +593 -0
  258. package/dist/symbols/symbol-extractor.js.map +1 -0
  259. package/dist/symbols/symbol-renamer.d.ts +81 -0
  260. package/dist/symbols/symbol-renamer.d.ts.map +1 -0
  261. package/dist/symbols/symbol-renamer.js +204 -0
  262. package/dist/symbols/symbol-renamer.js.map +1 -0
  263. package/dist/symbols/types.d.ts +234 -0
  264. package/dist/symbols/types.d.ts.map +1 -0
  265. package/dist/symbols/types.js +106 -0
  266. package/dist/symbols/types.js.map +1 -0
  267. package/dist/tools/clustering-handlers.d.ts +70 -0
  268. package/dist/tools/clustering-handlers.d.ts.map +1 -0
  269. package/dist/tools/clustering-handlers.js +150 -0
  270. package/dist/tools/clustering-handlers.js.map +1 -0
  271. package/dist/tools/commit-handlers.d.ts +77 -0
  272. package/dist/tools/commit-handlers.d.ts.map +1 -0
  273. package/dist/tools/commit-handlers.js +251 -0
  274. package/dist/tools/commit-handlers.js.map +1 -0
  275. package/dist/tools/index-handlers.d.ts +31 -0
  276. package/dist/tools/index-handlers.d.ts.map +1 -0
  277. package/dist/tools/index-handlers.js +53 -0
  278. package/dist/tools/index-handlers.js.map +1 -0
  279. package/dist/tools/instructions-handlers.d.ts +25 -0
  280. package/dist/tools/instructions-handlers.d.ts.map +1 -0
  281. package/dist/tools/instructions-handlers.js +36 -0
  282. package/dist/tools/instructions-handlers.js.map +1 -0
  283. package/dist/tools/memory-handlers.d.ts +95 -0
  284. package/dist/tools/memory-handlers.d.ts.map +1 -0
  285. package/dist/tools/memory-handlers.js +126 -0
  286. package/dist/tools/memory-handlers.js.map +1 -0
  287. package/dist/tools/search-handlers.d.ts +51 -0
  288. package/dist/tools/search-handlers.d.ts.map +1 -0
  289. package/dist/tools/search-handlers.js +128 -0
  290. package/dist/tools/search-handlers.js.map +1 -0
  291. package/dist/tools/symbol-handlers.d.ts +171 -0
  292. package/dist/tools/symbol-handlers.d.ts.map +1 -0
  293. package/dist/tools/symbol-handlers.js +456 -0
  294. package/dist/tools/symbol-handlers.js.map +1 -0
  295. package/dist/tools/types.d.ts +32 -0
  296. package/dist/tools/types.d.ts.map +1 -0
  297. package/dist/tools/types.js +17 -0
  298. package/dist/tools/types.js.map +1 -0
  299. package/dist/tools/worktree-handlers.d.ts +96 -0
  300. package/dist/tools/worktree-handlers.d.ts.map +1 -0
  301. package/dist/tools/worktree-handlers.js +186 -0
  302. package/dist/tools/worktree-handlers.js.map +1 -0
  303. package/dist/utils/cache.d.ts +77 -0
  304. package/dist/utils/cache.d.ts.map +1 -0
  305. package/dist/utils/cache.js +134 -0
  306. package/dist/utils/cache.js.map +1 -0
  307. package/dist/utils/concurrency.d.ts +32 -0
  308. package/dist/utils/concurrency.d.ts.map +1 -0
  309. package/dist/utils/concurrency.js +57 -0
  310. package/dist/utils/concurrency.js.map +1 -0
  311. package/dist/utils/errors.d.ts +36 -0
  312. package/dist/utils/errors.d.ts.map +1 -0
  313. package/dist/utils/errors.js +91 -0
  314. package/dist/utils/errors.js.map +1 -0
  315. package/dist/utils/logger.d.ts +37 -0
  316. package/dist/utils/logger.d.ts.map +1 -0
  317. package/dist/utils/logger.js +114 -0
  318. package/dist/utils/logger.js.map +1 -0
  319. package/dist/utils/type-guards.d.ts +17 -0
  320. package/dist/utils/type-guards.d.ts.map +1 -0
  321. package/dist/utils/type-guards.js +25 -0
  322. package/dist/utils/type-guards.js.map +1 -0
  323. package/dist/worktree/index.d.ts +6 -0
  324. package/dist/worktree/index.d.ts.map +1 -0
  325. package/dist/worktree/index.js +6 -0
  326. package/dist/worktree/index.js.map +1 -0
  327. package/dist/worktree/types.d.ts +101 -0
  328. package/dist/worktree/types.d.ts.map +1 -0
  329. package/dist/worktree/types.js +6 -0
  330. package/dist/worktree/types.js.map +1 -0
  331. package/dist/worktree/worktree-manager.d.ts +80 -0
  332. package/dist/worktree/worktree-manager.d.ts.map +1 -0
  333. package/dist/worktree/worktree-manager.js +407 -0
  334. package/dist/worktree/worktree-manager.js.map +1 -0
  335. package/package.json +87 -0
  336. package/scripts/postinstall.js +48 -0
@@ -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":""}
@@ -0,0 +1,334 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { fetchWithRetry } from '../../embeddings/retry.js';
3
+ describe('fetchWithRetry', () => {
4
+ beforeEach(() => {
5
+ vi.useFakeTimers();
6
+ });
7
+ afterEach(() => {
8
+ vi.useRealTimers();
9
+ });
10
+ describe('immediate success', () => {
11
+ it('should return response on first successful call', async () => {
12
+ const mockResponse = {
13
+ ok: true,
14
+ status: 200,
15
+ json: async () => ({ data: 'test' }),
16
+ };
17
+ vi.stubGlobal('fetch', vi.fn().mockResolvedValue(mockResponse));
18
+ const response = await fetchWithRetry('https://api.test.com', {});
19
+ expect(response).toBe(mockResponse);
20
+ expect(fetch).toHaveBeenCalledTimes(1);
21
+ });
22
+ it('should pass options to fetch', async () => {
23
+ const mockResponse = { ok: true, status: 200 };
24
+ vi.stubGlobal('fetch', vi.fn().mockResolvedValue(mockResponse));
25
+ const options = {
26
+ method: 'POST',
27
+ headers: { 'Content-Type': 'application/json' },
28
+ body: JSON.stringify({ test: true }),
29
+ };
30
+ await fetchWithRetry('https://api.test.com', options);
31
+ expect(fetch).toHaveBeenCalledWith('https://api.test.com', expect.objectContaining(options));
32
+ });
33
+ });
34
+ describe('retryable status codes', () => {
35
+ it('should retry on 429 status code', async () => {
36
+ const mockFetch = vi
37
+ .fn()
38
+ .mockResolvedValueOnce({ ok: false, status: 429, statusText: 'Too Many Requests' })
39
+ .mockResolvedValueOnce({ ok: true, status: 200 });
40
+ vi.stubGlobal('fetch', mockFetch);
41
+ const responsePromise = fetchWithRetry('https://api.test.com', {}, { maxRetries: 3 });
42
+ // First call returns 429
43
+ await vi.advanceTimersByTimeAsync(0);
44
+ expect(mockFetch).toHaveBeenCalledTimes(1);
45
+ // Wait for retry delay (2000ms base for 429 rate limit errors)
46
+ await vi.advanceTimersByTimeAsync(2000);
47
+ const response = await responsePromise;
48
+ expect(response.ok).toBe(true);
49
+ expect(mockFetch).toHaveBeenCalledTimes(2);
50
+ });
51
+ it('should retry on 500 status code', async () => {
52
+ const mockFetch = vi
53
+ .fn()
54
+ .mockResolvedValueOnce({ ok: false, status: 500, statusText: 'Internal Server Error' })
55
+ .mockResolvedValueOnce({ ok: true, status: 200 });
56
+ vi.stubGlobal('fetch', mockFetch);
57
+ const responsePromise = fetchWithRetry('https://api.test.com', {});
58
+ await vi.advanceTimersByTimeAsync(1000);
59
+ const response = await responsePromise;
60
+ expect(response.ok).toBe(true);
61
+ expect(mockFetch).toHaveBeenCalledTimes(2);
62
+ });
63
+ it('should retry on 503 status code', async () => {
64
+ const mockFetch = vi
65
+ .fn()
66
+ .mockResolvedValueOnce({ ok: false, status: 503, statusText: 'Service Unavailable' })
67
+ .mockResolvedValueOnce({ ok: true, status: 200 });
68
+ vi.stubGlobal('fetch', mockFetch);
69
+ const responsePromise = fetchWithRetry('https://api.test.com', {});
70
+ await vi.advanceTimersByTimeAsync(1000);
71
+ const response = await responsePromise;
72
+ expect(response.ok).toBe(true);
73
+ expect(mockFetch).toHaveBeenCalledTimes(2);
74
+ });
75
+ it('should retry on 408 status code', async () => {
76
+ const mockFetch = vi
77
+ .fn()
78
+ .mockResolvedValueOnce({ ok: false, status: 408, statusText: 'Request Timeout' })
79
+ .mockResolvedValueOnce({ ok: true, status: 200 });
80
+ vi.stubGlobal('fetch', mockFetch);
81
+ const responsePromise = fetchWithRetry('https://api.test.com', {});
82
+ await vi.advanceTimersByTimeAsync(1000);
83
+ const response = await responsePromise;
84
+ expect(response.ok).toBe(true);
85
+ expect(mockFetch).toHaveBeenCalledTimes(2);
86
+ });
87
+ });
88
+ describe('exponential backoff', () => {
89
+ it('should use exponential backoff timing for server errors', async () => {
90
+ // Use 500 status to test standard exponential backoff (429 has special handling)
91
+ const mockFetch = vi
92
+ .fn()
93
+ .mockResolvedValueOnce({ ok: false, status: 500 })
94
+ .mockResolvedValueOnce({ ok: false, status: 500 })
95
+ .mockResolvedValueOnce({ ok: false, status: 500 })
96
+ .mockResolvedValueOnce({ ok: true, status: 200 });
97
+ vi.stubGlobal('fetch', mockFetch);
98
+ const responsePromise = fetchWithRetry('https://api.test.com', {}, {
99
+ maxRetries: 3,
100
+ baseDelayMs: 1000,
101
+ });
102
+ await vi.advanceTimersByTimeAsync(0);
103
+ expect(mockFetch).toHaveBeenCalledTimes(1);
104
+ // First retry: 1000ms (1000 * 2^0)
105
+ await vi.advanceTimersByTimeAsync(1000);
106
+ expect(mockFetch).toHaveBeenCalledTimes(2);
107
+ // Second retry: 2000ms (1000 * 2^1)
108
+ await vi.advanceTimersByTimeAsync(2000);
109
+ expect(mockFetch).toHaveBeenCalledTimes(3);
110
+ // Third retry: 4000ms (1000 * 2^2)
111
+ await vi.advanceTimersByTimeAsync(4000);
112
+ expect(mockFetch).toHaveBeenCalledTimes(4);
113
+ const response = await responsePromise;
114
+ expect(response.ok).toBe(true);
115
+ });
116
+ it('should use longer backoff for 429 rate limit errors', async () => {
117
+ // 429 errors use 2x base delay (min 2000ms) for more graceful rate limiting
118
+ const mockFetch = vi
119
+ .fn()
120
+ .mockResolvedValueOnce({ ok: false, status: 429 })
121
+ .mockResolvedValueOnce({ ok: false, status: 429 })
122
+ .mockResolvedValueOnce({ ok: true, status: 200 });
123
+ vi.stubGlobal('fetch', mockFetch);
124
+ const responsePromise = fetchWithRetry('https://api.test.com', {}, {
125
+ maxRetries: 3,
126
+ baseDelayMs: 1000,
127
+ });
128
+ await vi.advanceTimersByTimeAsync(0);
129
+ expect(mockFetch).toHaveBeenCalledTimes(1);
130
+ // First retry: 2000ms (2x base delay for rate limits)
131
+ await vi.advanceTimersByTimeAsync(2000);
132
+ expect(mockFetch).toHaveBeenCalledTimes(2);
133
+ // Second retry: 4000ms (2000 * 2^1)
134
+ await vi.advanceTimersByTimeAsync(4000);
135
+ expect(mockFetch).toHaveBeenCalledTimes(3);
136
+ const response = await responsePromise;
137
+ expect(response.ok).toBe(true);
138
+ });
139
+ it('should respect maxDelayMs for server errors', async () => {
140
+ // Use 500 status to test standard maxDelayMs behavior
141
+ const mockFetch = vi
142
+ .fn()
143
+ .mockResolvedValueOnce({ ok: false, status: 500 })
144
+ .mockResolvedValueOnce({ ok: false, status: 500 })
145
+ .mockResolvedValueOnce({ ok: false, status: 500 })
146
+ .mockResolvedValueOnce({ ok: true, status: 200 });
147
+ vi.stubGlobal('fetch', mockFetch);
148
+ const responsePromise = fetchWithRetry('https://api.test.com', {}, {
149
+ maxRetries: 3,
150
+ baseDelayMs: 5000,
151
+ maxDelayMs: 8000,
152
+ });
153
+ await vi.advanceTimersByTimeAsync(0);
154
+ expect(mockFetch).toHaveBeenCalledTimes(1);
155
+ // First retry: 5000ms (5000 * 2^0)
156
+ await vi.advanceTimersByTimeAsync(5000);
157
+ expect(mockFetch).toHaveBeenCalledTimes(2);
158
+ // Second retry: capped at 8000ms (would be 10000 = 5000 * 2^1)
159
+ await vi.advanceTimersByTimeAsync(8000);
160
+ expect(mockFetch).toHaveBeenCalledTimes(3);
161
+ // Third retry: capped at 8000ms (would be 20000 = 5000 * 2^2)
162
+ await vi.advanceTimersByTimeAsync(8000);
163
+ expect(mockFetch).toHaveBeenCalledTimes(4);
164
+ await responsePromise;
165
+ });
166
+ });
167
+ describe('max retries exhaustion', () => {
168
+ it('should return error response after max retries', async () => {
169
+ const errorResponse = { ok: false, status: 429, statusText: 'Too Many Requests' };
170
+ const mockFetch = vi.fn().mockResolvedValue(errorResponse);
171
+ vi.stubGlobal('fetch', mockFetch);
172
+ const responsePromise = fetchWithRetry('https://api.test.com', {}, { maxRetries: 2 });
173
+ // Process all retries (429 uses 2x base delay, min 2000ms)
174
+ await vi.advanceTimersByTimeAsync(2000); // First retry
175
+ await vi.advanceTimersByTimeAsync(4000); // Second retry
176
+ const response = await responsePromise;
177
+ expect(response.ok).toBe(false);
178
+ expect(response.status).toBe(429);
179
+ expect(mockFetch).toHaveBeenCalledTimes(3); // Initial + 2 retries
180
+ });
181
+ });
182
+ describe('non-retryable errors', () => {
183
+ it('should not retry on 400 status code', async () => {
184
+ const mockFetch = vi
185
+ .fn()
186
+ .mockResolvedValue({ ok: false, status: 400, statusText: 'Bad Request' });
187
+ vi.stubGlobal('fetch', mockFetch);
188
+ const response = await fetchWithRetry('https://api.test.com', {});
189
+ expect(response.ok).toBe(false);
190
+ expect(response.status).toBe(400);
191
+ expect(mockFetch).toHaveBeenCalledTimes(1);
192
+ });
193
+ it('should not retry on 401 status code', async () => {
194
+ const mockFetch = vi
195
+ .fn()
196
+ .mockResolvedValue({ ok: false, status: 401, statusText: 'Unauthorized' });
197
+ vi.stubGlobal('fetch', mockFetch);
198
+ const response = await fetchWithRetry('https://api.test.com', {});
199
+ expect(response.ok).toBe(false);
200
+ expect(response.status).toBe(401);
201
+ expect(mockFetch).toHaveBeenCalledTimes(1);
202
+ });
203
+ it('should not retry on 403 status code', async () => {
204
+ const mockFetch = vi
205
+ .fn()
206
+ .mockResolvedValue({ ok: false, status: 403, statusText: 'Forbidden' });
207
+ vi.stubGlobal('fetch', mockFetch);
208
+ const response = await fetchWithRetry('https://api.test.com', {});
209
+ expect(response.ok).toBe(false);
210
+ expect(response.status).toBe(403);
211
+ expect(mockFetch).toHaveBeenCalledTimes(1);
212
+ });
213
+ it('should not retry on 404 status code', async () => {
214
+ const mockFetch = vi
215
+ .fn()
216
+ .mockResolvedValue({ ok: false, status: 404, statusText: 'Not Found' });
217
+ vi.stubGlobal('fetch', mockFetch);
218
+ const response = await fetchWithRetry('https://api.test.com', {});
219
+ expect(response.ok).toBe(false);
220
+ expect(response.status).toBe(404);
221
+ expect(mockFetch).toHaveBeenCalledTimes(1);
222
+ });
223
+ });
224
+ describe('network errors', () => {
225
+ it('should retry on fetch network error', async () => {
226
+ const mockFetch = vi
227
+ .fn()
228
+ .mockRejectedValueOnce(new Error('fetch failed'))
229
+ .mockResolvedValueOnce({ ok: true, status: 200 });
230
+ vi.stubGlobal('fetch', mockFetch);
231
+ const responsePromise = fetchWithRetry('https://api.test.com', {});
232
+ await vi.advanceTimersByTimeAsync(1000);
233
+ const response = await responsePromise;
234
+ expect(response.ok).toBe(true);
235
+ expect(mockFetch).toHaveBeenCalledTimes(2);
236
+ });
237
+ it('should retry on ECONNREFUSED error', async () => {
238
+ const mockFetch = vi
239
+ .fn()
240
+ .mockRejectedValueOnce(new Error('ECONNREFUSED'))
241
+ .mockResolvedValueOnce({ ok: true, status: 200 });
242
+ vi.stubGlobal('fetch', mockFetch);
243
+ const responsePromise = fetchWithRetry('https://api.test.com', {});
244
+ await vi.advanceTimersByTimeAsync(1000);
245
+ const response = await responsePromise;
246
+ expect(response.ok).toBe(true);
247
+ expect(mockFetch).toHaveBeenCalledTimes(2);
248
+ });
249
+ it('should throw after max retries on network error', async () => {
250
+ const mockFetch = vi.fn().mockRejectedValue(new Error('fetch failed'));
251
+ vi.stubGlobal('fetch', mockFetch);
252
+ // Wrap in try-catch to properly handle the rejection
253
+ let error = null;
254
+ const responsePromise = fetchWithRetry('https://api.test.com', {}, { maxRetries: 2 }).catch((e) => {
255
+ error = e;
256
+ });
257
+ // Need to flush all timers to let the retries complete
258
+ await vi.runAllTimersAsync();
259
+ await responsePromise;
260
+ expect(error).toBeInstanceOf(Error);
261
+ expect(error.message).toBe('fetch failed');
262
+ expect(mockFetch).toHaveBeenCalledTimes(3);
263
+ });
264
+ it('should not retry on non-network errors', async () => {
265
+ const mockFetch = vi.fn().mockRejectedValue(new Error('some other error'));
266
+ vi.stubGlobal('fetch', mockFetch);
267
+ await expect(fetchWithRetry('https://api.test.com', {})).rejects.toThrow('some other error');
268
+ expect(mockFetch).toHaveBeenCalledTimes(1);
269
+ });
270
+ });
271
+ describe('default options', () => {
272
+ it('should use default maxRetries of 5', async () => {
273
+ const mockFetch = vi.fn().mockResolvedValue({ ok: false, status: 429 });
274
+ vi.stubGlobal('fetch', mockFetch);
275
+ const responsePromise = fetchWithRetry('https://api.test.com', {});
276
+ // Process all retries (429 uses 2x base delay, min 2000ms for rate limits)
277
+ // Delays: 2s, 4s, 8s, 16s, 32s (but capped at 60s maxDelay)
278
+ await vi.advanceTimersByTimeAsync(2000); // Retry 1
279
+ await vi.advanceTimersByTimeAsync(4000); // Retry 2
280
+ await vi.advanceTimersByTimeAsync(8000); // Retry 3
281
+ await vi.advanceTimersByTimeAsync(16000); // Retry 4
282
+ await vi.advanceTimersByTimeAsync(32000); // Retry 5
283
+ await responsePromise;
284
+ expect(mockFetch).toHaveBeenCalledTimes(6); // Initial + 5 retries
285
+ });
286
+ });
287
+ describe('Retry-After header', () => {
288
+ it('should respect Retry-After header in seconds', async () => {
289
+ const mockResponse = {
290
+ ok: false,
291
+ status: 429,
292
+ headers: {
293
+ get: (name) => (name.toLowerCase() === 'retry-after' ? '5' : null),
294
+ },
295
+ };
296
+ const mockFetch = vi
297
+ .fn()
298
+ .mockResolvedValueOnce(mockResponse)
299
+ .mockResolvedValueOnce({ ok: true, status: 200 });
300
+ vi.stubGlobal('fetch', mockFetch);
301
+ const responsePromise = fetchWithRetry('https://api.test.com', {}, { maxRetries: 3 });
302
+ await vi.advanceTimersByTimeAsync(0);
303
+ expect(mockFetch).toHaveBeenCalledTimes(1);
304
+ // Should wait ~5 seconds (5000ms) plus small jitter (up to 1000ms)
305
+ await vi.advanceTimersByTimeAsync(6000);
306
+ expect(mockFetch).toHaveBeenCalledTimes(2);
307
+ const response = await responsePromise;
308
+ expect(response.ok).toBe(true);
309
+ });
310
+ it('should cap Retry-After at maxDelayMs', async () => {
311
+ const mockResponse = {
312
+ ok: false,
313
+ status: 429,
314
+ headers: {
315
+ get: (name) => (name.toLowerCase() === 'retry-after' ? '120' : null),
316
+ },
317
+ };
318
+ const mockFetch = vi
319
+ .fn()
320
+ .mockResolvedValueOnce(mockResponse)
321
+ .mockResolvedValueOnce({ ok: true, status: 200 });
322
+ vi.stubGlobal('fetch', mockFetch);
323
+ const responsePromise = fetchWithRetry('https://api.test.com', {}, { maxRetries: 3, maxDelayMs: 10000 });
324
+ await vi.advanceTimersByTimeAsync(0);
325
+ expect(mockFetch).toHaveBeenCalledTimes(1);
326
+ // Should be capped at maxDelayMs (10000ms) even though Retry-After says 120s
327
+ await vi.advanceTimersByTimeAsync(10000);
328
+ expect(mockFetch).toHaveBeenCalledTimes(2);
329
+ const response = await responsePromise;
330
+ expect(response.ok).toBe(true);
331
+ });
332
+ });
333
+ });
334
+ //# sourceMappingURL=retry.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.test.js","sourceRoot":"","sources":["../../../src/__tests__/embeddings/retry.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/embeddings/types.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,31 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { chunkArray } from '../../embeddings/types.js';
3
+ describe('chunkArray', () => {
4
+ it('should return empty array for empty input', () => {
5
+ expect(chunkArray([], 10)).toEqual([]);
6
+ });
7
+ it('should return single chunk when array is smaller than chunk size', () => {
8
+ expect(chunkArray([1, 2, 3], 10)).toEqual([[1, 2, 3]]);
9
+ });
10
+ it('should split array into even chunks', () => {
11
+ expect(chunkArray([1, 2, 3, 4], 2)).toEqual([
12
+ [1, 2],
13
+ [3, 4],
14
+ ]);
15
+ });
16
+ it('should handle uneven splits with remainder in last chunk', () => {
17
+ expect(chunkArray([1, 2, 3, 4, 5], 2)).toEqual([[1, 2], [3, 4], [5]]);
18
+ });
19
+ it('should create individual chunks when chunk size is 1', () => {
20
+ expect(chunkArray([1, 2, 3], 1)).toEqual([[1], [2], [3]]);
21
+ });
22
+ it('should work with strings', () => {
23
+ expect(chunkArray(['a', 'b', 'c', 'd'], 3)).toEqual([['a', 'b', 'c'], ['d']]);
24
+ });
25
+ it('should work with objects', () => {
26
+ const arr = [{ id: 1 }, { id: 2 }, { id: 3 }];
27
+ const result = chunkArray(arr, 2);
28
+ expect(result).toEqual([[{ id: 1 }, { id: 2 }], [{ id: 3 }]]);
29
+ });
30
+ });
31
+ //# sourceMappingURL=types.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.test.js","sourceRoot":"","sources":["../../../src/__tests__/embeddings/types.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAEvD,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAC1C,CAAC,CAAC,EAAE,CAAC,CAAC;YACN,CAAC,CAAC,EAAE,CAAC,CAAC;SACP,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAChF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { EmbeddingBackend } from '../../embeddings/types.js';
2
+ /**
3
+ * Creates a mock EmbeddingBackend for testing
4
+ */
5
+ export declare function createMockEmbeddingBackend(overrides?: Partial<EmbeddingBackend>): EmbeddingBackend;
6
+ /**
7
+ * Creates a mock EmbeddingBackend that fails initialization
8
+ */
9
+ export declare function createFailingMockEmbeddingBackend(error: Error): EmbeddingBackend;
10
+ //# sourceMappingURL=embedding-backend.mock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding-backend.mock.d.ts","sourceRoot":"","sources":["../../../src/__tests__/mocks/embedding-backend.mock.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAElE;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,SAAS,GAAE,OAAO,CAAC,gBAAgB,CAAM,GACxC,gBAAgB,CAuBlB;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,KAAK,GAAG,gBAAgB,CAShF"}
@@ -0,0 +1,39 @@
1
+ import { vi } from 'vitest';
2
+ /**
3
+ * Creates a mock EmbeddingBackend for testing
4
+ */
5
+ export function createMockEmbeddingBackend(overrides = {}) {
6
+ const dimensions = overrides.getDimensions?.() ?? 1536;
7
+ const model = overrides.getModel?.() ?? 'mock-model';
8
+ return {
9
+ name: 'mock',
10
+ initialize: vi.fn().mockResolvedValue(undefined),
11
+ embed: vi.fn().mockImplementation(async () => {
12
+ return Array(dimensions)
13
+ .fill(0)
14
+ .map(() => Math.random());
15
+ }),
16
+ embedBatch: vi.fn().mockImplementation(async (texts) => {
17
+ return texts.map(() => Array(dimensions)
18
+ .fill(0)
19
+ .map(() => Math.random()));
20
+ }),
21
+ getDimensions: vi.fn().mockReturnValue(dimensions),
22
+ getModel: vi.fn().mockReturnValue(model),
23
+ ...overrides,
24
+ };
25
+ }
26
+ /**
27
+ * Creates a mock EmbeddingBackend that fails initialization
28
+ */
29
+ export function createFailingMockEmbeddingBackend(error) {
30
+ return {
31
+ name: 'failing-mock',
32
+ initialize: vi.fn().mockRejectedValue(error),
33
+ embed: vi.fn().mockRejectedValue(error),
34
+ embedBatch: vi.fn().mockRejectedValue(error),
35
+ getDimensions: vi.fn().mockReturnValue(1536),
36
+ getModel: vi.fn().mockReturnValue('failing-mock-model'),
37
+ };
38
+ }
39
+ //# sourceMappingURL=embedding-backend.mock.js.map