scrabble-solver 2.16.7 → 2.18.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 (589) hide show
  1. package/.github/workflows/bunx.yml +13 -10
  2. package/.github/workflows/e2e.yml +7 -9
  3. package/.github/workflows/npx.yml +13 -10
  4. package/.nx/workspace-data/d/server-process.json +2 -2
  5. package/.nx/workspace-data/file-map.json +796 -816
  6. package/.nx/workspace-data/lockfile-dependencies.hash +1 -1
  7. package/.nx/workspace-data/lockfile-nodes.hash +1 -1
  8. package/.nx/workspace-data/nx_files.nxt +0 -0
  9. package/.nx/workspace-data/parsed-lock-file.dependencies.json +218 -1298
  10. package/.nx/workspace-data/parsed-lock-file.nodes.json +770 -2669
  11. package/.nx/workspace-data/project-graph.json +1083 -4104
  12. package/.nx/workspace-data/source-maps.json +128 -0
  13. package/.oxlintrc.json +13 -10
  14. package/CLAUDE.md +36 -28
  15. package/README.md +17 -1
  16. package/bun.lock +233 -528
  17. package/e2e/app.spec.ts +124 -0
  18. package/e2e/bugs/112-character-bonus.spec.ts +25 -0
  19. package/e2e/bugs/129-esc-sidebar.spec.ts +17 -0
  20. package/e2e/bugs/2-q-tile-in-english.spec.ts +19 -0
  21. package/e2e/bugs/3-x-tile-in-polish.spec.ts +19 -0
  22. package/e2e/bugs/30-click-inside-radio-icon.spec.ts +25 -0
  23. package/e2e/bugs/333-disabled-radio-cursor.spec.ts +18 -0
  24. package/e2e/bugs/342-results-sorting.spec.ts +30 -0
  25. package/e2e/bugs/352-dictionary-race-condition.spec.ts +27 -0
  26. package/e2e/bugs/363-dictionary-input-unique-words.spec.ts +27 -0
  27. package/e2e/bugs/380-transliteration-when-pasting.spec.ts +55 -0
  28. package/e2e/bugs/398-digraphs-in-created-words.spec.ts +23 -0
  29. package/e2e/bugs/401-board-state-on-game-change.spec.ts +24 -0
  30. package/e2e/features/198-highlight-unreachable-cells.spec.ts +85 -0
  31. package/e2e/features/91-hover-remaining-tile-highlights.spec.ts +76 -0
  32. package/e2e/features/hidden-coordinates-migration.spec.ts +27 -0
  33. package/e2e/features/solver-paths.spec.ts +45 -0
  34. package/e2e/lib/actions.ts +119 -0
  35. package/e2e/lib/selectors.ts +71 -0
  36. package/e2e/tsconfig.json +10 -0
  37. package/lerna.json +1 -1
  38. package/package.json +16 -18
  39. package/packages/configs/package.json +3 -3
  40. package/packages/constants/package.json +1 -1
  41. package/packages/dictionaries/README.md +1 -1
  42. package/packages/dictionaries/build/Dictionaries.d.ts +2 -2
  43. package/packages/dictionaries/build/Dictionaries.js +6 -6
  44. package/packages/dictionaries/build/lib/DiskCache.d.ts +11 -4
  45. package/packages/dictionaries/build/lib/DiskCache.js +27 -10
  46. package/packages/dictionaries/build/lib/LayeredCache.d.ts +4 -4
  47. package/packages/dictionaries/build/lib/LayeredCache.js +3 -3
  48. package/packages/dictionaries/build/lib/MemoryCache.d.ts +4 -4
  49. package/packages/dictionaries/build/lib/MemoryCache.js +2 -2
  50. package/packages/dictionaries/build/lib/createCacheTimestampComparator.d.ts +2 -2
  51. package/packages/dictionaries/build/lib/downloadDictionary.d.ts +2 -2
  52. package/packages/dictionaries/build/lib/downloadDictionary.js +4 -3
  53. package/packages/dictionaries/build/lib/getDictionaryFilepath.d.ts +3 -1
  54. package/packages/dictionaries/build/lib/getDictionaryFilepath.js +8 -3
  55. package/packages/dictionaries/package.json +7 -6
  56. package/packages/dictionaries/src/Dictionaries.ts +12 -12
  57. package/packages/dictionaries/src/lib/DiskCache.test.ts +85 -0
  58. package/packages/dictionaries/src/lib/DiskCache.ts +34 -14
  59. package/packages/dictionaries/src/lib/LayeredCache.ts +7 -7
  60. package/packages/dictionaries/src/lib/MemoryCache.ts +6 -6
  61. package/packages/dictionaries/src/lib/createCacheTimestampComparator.ts +2 -2
  62. package/packages/dictionaries/src/lib/downloadDictionary.ts +5 -4
  63. package/packages/dictionaries/src/lib/getDictionaryFilepath.ts +7 -2
  64. package/packages/gaddag/build/Gaddag.d.ts +39 -0
  65. package/packages/gaddag/build/Gaddag.js +128 -0
  66. package/packages/gaddag/build/buildGaddag.d.ts +10 -0
  67. package/packages/gaddag/build/buildGaddag.js +360 -0
  68. package/packages/gaddag/build/constants.d.ts +12 -0
  69. package/packages/gaddag/build/constants.js +15 -0
  70. package/packages/gaddag/build/index.d.ts +3 -0
  71. package/packages/gaddag/build/index.js +13 -0
  72. package/packages/logger/package.json +1 -1
  73. package/packages/scrabble-solver/.next/BUILD_ID +1 -1
  74. package/packages/scrabble-solver/.next/build-manifest.json +22 -20
  75. package/packages/scrabble-solver/.next/cache/.previewinfo +1 -1
  76. package/packages/scrabble-solver/.next/cache/.rscinfo +1 -1
  77. package/packages/scrabble-solver/.next/cache/.tsbuildinfo +1 -1
  78. package/packages/scrabble-solver/.next/cache/webpack/client-production/0.pack +0 -0
  79. package/packages/scrabble-solver/.next/cache/webpack/client-production/index.pack +0 -0
  80. package/packages/scrabble-solver/.next/cache/webpack/client-production/index.pack.old +0 -0
  81. package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/index.pack +0 -0
  82. package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/index.pack.old +0 -0
  83. package/packages/scrabble-solver/.next/cache/webpack/server-production/0.pack +0 -0
  84. package/packages/scrabble-solver/.next/cache/webpack/server-production/index.pack +0 -0
  85. package/packages/scrabble-solver/.next/cache/webpack/server-production/index.pack.old +0 -0
  86. package/packages/scrabble-solver/.next/diagnostics/framework.json +1 -1
  87. package/packages/scrabble-solver/.next/dynamic-css-manifest.json +8 -1
  88. package/packages/scrabble-solver/.next/next-minimal-server.js.nft.json +1 -1
  89. package/packages/scrabble-solver/.next/next-server.js.nft.json +1 -1
  90. package/packages/scrabble-solver/.next/prerender-manifest.json +4 -4
  91. package/packages/scrabble-solver/.next/react-loadable-manifest.json +176 -1
  92. package/packages/scrabble-solver/.next/required-server-files.js +3 -2
  93. package/packages/scrabble-solver/.next/required-server-files.json +3 -2
  94. package/packages/scrabble-solver/.next/routes-manifest.json +1 -1
  95. package/packages/scrabble-solver/.next/server/chunks/30.js +1 -1
  96. package/packages/scrabble-solver/.next/server/chunks/309.js +1 -0
  97. package/packages/scrabble-solver/.next/server/chunks/316.js +1 -0
  98. package/packages/scrabble-solver/.next/server/chunks/344.js +1 -0
  99. package/packages/scrabble-solver/.next/server/chunks/371.js +1 -0
  100. package/packages/scrabble-solver/.next/server/chunks/392.js +1 -1
  101. package/packages/scrabble-solver/.next/server/chunks/465.js +1 -0
  102. package/packages/scrabble-solver/.next/server/chunks/546.js +1 -0
  103. package/packages/scrabble-solver/.next/server/chunks/623.js +1 -0
  104. package/packages/scrabble-solver/.next/server/chunks/624.js +1 -0
  105. package/packages/scrabble-solver/.next/server/chunks/641.js +1 -0
  106. package/packages/scrabble-solver/.next/server/chunks/671.js +1 -1
  107. package/packages/scrabble-solver/.next/server/chunks/692.js +1 -0
  108. package/packages/scrabble-solver/.next/server/chunks/705.js +1 -0
  109. package/packages/scrabble-solver/.next/server/chunks/712.js +1 -1
  110. package/packages/scrabble-solver/.next/server/chunks/846.js +1 -0
  111. package/packages/scrabble-solver/.next/server/chunks/853.js +15 -0
  112. package/packages/scrabble-solver/.next/server/chunks/886.js +1 -0
  113. package/packages/scrabble-solver/.next/server/chunks/916.js +1 -0
  114. package/packages/scrabble-solver/.next/server/chunks/953.js +1 -0
  115. package/packages/scrabble-solver/.next/server/chunks/961.js +1 -0
  116. package/packages/scrabble-solver/.next/server/chunks/968.js +1 -0
  117. package/packages/scrabble-solver/.next/server/dynamic-css-manifest.js +1 -1
  118. package/packages/scrabble-solver/.next/server/middleware-build-manifest.js +1 -1
  119. package/packages/scrabble-solver/.next/server/middleware-react-loadable-manifest.js +1 -1
  120. package/packages/scrabble-solver/.next/server/pages/404.html +28 -1
  121. package/packages/scrabble-solver/.next/server/pages/500.html +28 -1
  122. package/packages/scrabble-solver/.next/server/pages/_app.js +1 -1
  123. package/packages/scrabble-solver/.next/server/pages/_app.js.nft.json +1 -1
  124. package/packages/scrabble-solver/.next/server/pages/_document.js +28 -1
  125. package/packages/scrabble-solver/.next/server/pages/_document.js.nft.json +1 -1
  126. package/packages/scrabble-solver/.next/server/pages/_error.js +28 -1
  127. package/packages/scrabble-solver/.next/server/pages/_error.js.nft.json +1 -1
  128. package/packages/scrabble-solver/.next/server/pages/api/dictionary/[locale]/[word].js +1 -1
  129. package/packages/scrabble-solver/.next/server/pages/api/dictionary/[locale]/[word].js.nft.json +1 -1
  130. package/packages/scrabble-solver/.next/server/pages/api/dictionary/[locale].js +1 -1
  131. package/packages/scrabble-solver/.next/server/pages/api/dictionary/[locale].js.nft.json +1 -1
  132. package/packages/scrabble-solver/.next/server/pages/api/solve.js +1 -1
  133. package/packages/scrabble-solver/.next/server/pages/api/solve.js.nft.json +1 -1
  134. package/packages/scrabble-solver/.next/server/pages/api/verify.js +1 -1
  135. package/packages/scrabble-solver/.next/server/pages/api/verify.js.nft.json +1 -1
  136. package/packages/scrabble-solver/.next/server/pages/api/visit.js.nft.json +1 -1
  137. package/packages/scrabble-solver/.next/server/pages/index.html +28 -1
  138. package/packages/scrabble-solver/.next/server/pages/index.js +30 -1
  139. package/packages/scrabble-solver/.next/server/pages/index.js.nft.json +1 -1
  140. package/packages/scrabble-solver/.next/server/pages/index.json +1 -1
  141. package/packages/scrabble-solver/.next/server/pages/not-found.html +28 -1
  142. package/packages/scrabble-solver/.next/server/pages/not-found.js.nft.json +1 -1
  143. package/packages/scrabble-solver/.next/server/pages-manifest.json +1 -1
  144. package/packages/scrabble-solver/.next/server/webpack-api-runtime.js +1 -1
  145. package/packages/scrabble-solver/.next/server/webpack-runtime.js +1 -1
  146. package/packages/scrabble-solver/.next/static/FL82obwzFHRzvV6z76I-U/_buildManifest.js +1 -0
  147. package/packages/scrabble-solver/.next/static/chunks/101-829ab8a8d310e7a0.js +3 -0
  148. package/packages/scrabble-solver/.next/static/chunks/106.e414e88694add27f.js +1 -0
  149. package/packages/scrabble-solver/.next/static/chunks/127.125d896a19061d71.js +1 -0
  150. package/packages/scrabble-solver/.next/static/chunks/18.8b91e137d239e15c.js +1 -0
  151. package/packages/scrabble-solver/.next/static/chunks/277.6785dfaf22fdb0b7.js +1 -0
  152. package/packages/scrabble-solver/.next/static/chunks/307.67f52f13e3d60d4e.js +1 -0
  153. package/packages/scrabble-solver/.next/static/chunks/341.79535ba85bf1986f.js +1 -0
  154. package/packages/scrabble-solver/.next/static/chunks/363.01eed3233f92b6a4.js +1 -0
  155. package/packages/scrabble-solver/.next/static/chunks/422.1559ae6756912ca5.js +1 -0
  156. package/packages/scrabble-solver/.next/static/chunks/541.dcd9e8b804f88da5.js +1 -0
  157. package/packages/scrabble-solver/.next/static/chunks/583.7a46807be14c377e.js +1 -0
  158. package/packages/scrabble-solver/.next/static/chunks/631.98d42abad0a60af6.js +1 -0
  159. package/packages/scrabble-solver/.next/static/chunks/663.d2c9ca36b26695b8.js +1 -0
  160. package/packages/scrabble-solver/.next/static/chunks/711.ba7b8f900dfd40d0.js +1 -0
  161. package/packages/scrabble-solver/.next/static/chunks/744.b06c9a3de4a1d877.js +1 -0
  162. package/packages/scrabble-solver/.next/static/chunks/820.97b82f751ca49579.js +1 -0
  163. package/packages/scrabble-solver/.next/static/chunks/865.a9b563a45848a83c.js +1 -0
  164. package/packages/scrabble-solver/.next/static/chunks/912.ff8037ba9d4db5c8.js +1 -0
  165. package/packages/scrabble-solver/.next/static/chunks/939.19b33a3d3c351d73.js +1 -0
  166. package/packages/scrabble-solver/.next/static/chunks/990.61296e5870b91f11.js +1 -0
  167. package/packages/scrabble-solver/.next/static/chunks/framework-626cbd48ac5aca57.js +1 -0
  168. package/packages/scrabble-solver/.next/static/chunks/main-b92e08f3fc96dd8d.js +5 -0
  169. package/packages/scrabble-solver/.next/static/chunks/pages/_app-ba5d628e81a15461.js +1 -0
  170. package/packages/scrabble-solver/.next/static/chunks/pages/{_error-afeda7c5231b6c3c.js → _error-f0290a98eb3ed0ec.js} +1 -1
  171. package/packages/scrabble-solver/.next/static/chunks/pages/index-5f9fa6ac3cd3d97b.js +1 -0
  172. package/packages/scrabble-solver/.next/static/chunks/pages/not-found-23d61fd3ed791cad.js +1 -0
  173. package/packages/scrabble-solver/.next/static/chunks/webpack-e34c3ae12275e978.js +1 -0
  174. package/packages/scrabble-solver/.next/static/css/2d03f0da2c678dfc.css +1 -0
  175. package/packages/scrabble-solver/.next/static/css/7b6724d2df70f48f.css +1 -0
  176. package/packages/scrabble-solver/.next/static/css/abc2425d3ba607bc.css +1 -0
  177. package/packages/scrabble-solver/.next/static/css/b736be3bd02b5d99.css +1 -0
  178. package/packages/scrabble-solver/.next/static/css/b74cd7de82dabcdd.css +1 -0
  179. package/packages/scrabble-solver/.next/static/css/c403ce739a9c0d83.css +1 -0
  180. package/packages/scrabble-solver/.next/static/css/ca311e6c030663d4.css +1 -0
  181. package/packages/scrabble-solver/.next/static/css/dee878eb64099d92.css +1 -0
  182. package/packages/scrabble-solver/.next/static/css/fbfdce70731d0d2b.css +1 -0
  183. package/packages/scrabble-solver/.next/trace +21 -21
  184. package/packages/scrabble-solver/.next/trace-build +1 -1
  185. package/packages/scrabble-solver/empty-module.js +2 -0
  186. package/packages/scrabble-solver/next.config.js +13 -8
  187. package/packages/scrabble-solver/package.json +34 -15
  188. package/packages/scrabble-solver/public/llms.txt +11 -0
  189. package/packages/scrabble-solver/public/robots.txt +4 -0
  190. package/packages/scrabble-solver/public/service-worker.js +2 -2
  191. package/packages/scrabble-solver/scripts/generate-scss-types.ts +112 -0
  192. package/packages/scrabble-solver/src/@types/scss.d.ts +6 -9
  193. package/packages/scrabble-solver/src/@types/svg.d.ts +1 -1
  194. package/packages/scrabble-solver/src/components/Alert/Alert.module.scss.d.ts +13 -0
  195. package/packages/scrabble-solver/src/components/Alert/Alert.tsx +4 -1
  196. package/packages/scrabble-solver/src/components/Badge/Badge.module.scss.d.ts +6 -0
  197. package/packages/scrabble-solver/src/components/Board/Board.module.scss +10 -0
  198. package/packages/scrabble-solver/src/components/Board/Board.module.scss.d.ts +17 -0
  199. package/packages/scrabble-solver/src/components/Board/Board.tsx +14 -26
  200. package/packages/scrabble-solver/src/components/Board/BoardPure.tsx +54 -49
  201. package/packages/scrabble-solver/src/components/Board/components/Actions/Actions.module.scss +18 -18
  202. package/packages/scrabble-solver/src/components/Board/components/Actions/Actions.module.scss.d.ts +7 -0
  203. package/packages/scrabble-solver/src/components/Board/components/Actions/Actions.tsx +6 -3
  204. package/packages/scrabble-solver/src/components/Board/components/Actions/lib.ts +3 -1
  205. package/packages/scrabble-solver/src/components/Board/components/Cell/Cell.module.scss.d.ts +13 -0
  206. package/packages/scrabble-solver/src/components/Board/components/Cell/Cell.tsx +32 -34
  207. package/packages/scrabble-solver/src/components/Board/components/InputPrompt/InputPrompt.module.scss.d.ts +10 -0
  208. package/packages/scrabble-solver/src/components/Board/components/InputPrompt/InputPrompt.tsx +1 -1
  209. package/packages/scrabble-solver/src/components/Board/components/ToggleDirectionButton/ToggleDirectionButton.module.scss.d.ts +8 -0
  210. package/packages/scrabble-solver/src/components/Board/components/ToggleDirectionButton/ToggleDirectionButton.tsx +2 -2
  211. package/packages/scrabble-solver/src/components/Board/getBoardBackground.ts +175 -0
  212. package/packages/scrabble-solver/src/components/Board/hooks/index.ts +0 -1
  213. package/packages/scrabble-solver/src/components/Board/hooks/useBoardStyle.ts +10 -20
  214. package/packages/scrabble-solver/src/components/Board/hooks/useFloatingActions.ts +3 -6
  215. package/packages/scrabble-solver/src/components/Board/hooks/useGrid.ts +23 -9
  216. package/packages/scrabble-solver/src/components/Board/selectors.ts +1 -1
  217. package/packages/scrabble-solver/src/components/Button/Button.module.scss.d.ts +12 -0
  218. package/packages/scrabble-solver/src/components/Dictionary/Dictionary.module.scss +8 -22
  219. package/packages/scrabble-solver/src/components/Dictionary/Dictionary.module.scss.d.ts +14 -0
  220. package/packages/scrabble-solver/src/components/Dictionary/Dictionary.tsx +1 -10
  221. package/packages/scrabble-solver/src/components/DictionaryInput/DictionaryInput.module.scss.d.ts +7 -0
  222. package/packages/scrabble-solver/src/components/DictionaryInput/DictionaryInput.tsx +1 -1
  223. package/packages/scrabble-solver/src/components/EmptyState/EmptyState.module.scss.d.ts +7 -0
  224. package/packages/scrabble-solver/src/components/EmptyState/EmptyState.tsx +1 -1
  225. package/packages/scrabble-solver/src/components/IconButton/IconButton.module.scss.d.ts +8 -0
  226. package/packages/scrabble-solver/src/components/Key/Key.module.scss.d.ts +6 -0
  227. package/packages/scrabble-solver/src/components/Keys/Arrows/Arrows.module.scss.d.ts +11 -0
  228. package/packages/scrabble-solver/src/components/Keys/Arrows/Arrows.tsx +4 -1
  229. package/packages/scrabble-solver/src/components/Keys/index.tsx +1 -1
  230. package/packages/scrabble-solver/src/components/Loading/Loading.module.scss.d.ts +9 -0
  231. package/packages/scrabble-solver/src/components/Loading/Loading.tsx +1 -1
  232. package/packages/scrabble-solver/src/components/Logo/Logo.tsx +4 -9
  233. package/packages/scrabble-solver/src/components/Logo/LogoBlueprint.tsx +1 -0
  234. package/packages/scrabble-solver/src/components/Modal/Modal.module.scss.d.ts +15 -0
  235. package/packages/scrabble-solver/src/components/Modal/Modal.tsx +16 -3
  236. package/packages/scrabble-solver/src/components/Modal/components/Section/Section.module.scss.d.ts +7 -0
  237. package/packages/scrabble-solver/src/components/NavButtons/NavButtons.module.scss +20 -0
  238. package/packages/scrabble-solver/src/components/NavButtons/NavButtons.module.scss.d.ts +13 -0
  239. package/packages/scrabble-solver/src/components/NavButtons/NavButtons.tsx +29 -45
  240. package/packages/scrabble-solver/src/components/NotFound/NotFound.module.scss.d.ts +9 -0
  241. package/packages/scrabble-solver/src/components/NotFound/NotFound.tsx +1 -1
  242. package/packages/scrabble-solver/src/components/PlainTiles/PlainTiles.module.scss.d.ts +11 -0
  243. package/packages/scrabble-solver/src/components/PlainTiles/PlainTiles.tsx +0 -1
  244. package/packages/scrabble-solver/src/components/PlainTiles/Tile.tsx +3 -4
  245. package/packages/scrabble-solver/src/components/PlainTiles/lib.ts +4 -19
  246. package/packages/scrabble-solver/src/components/PlainTiles/types.ts +0 -1
  247. package/packages/scrabble-solver/src/components/Progress/Progress.module.scss +7 -0
  248. package/packages/scrabble-solver/src/components/Progress/Progress.module.scss.d.ts +6 -0
  249. package/packages/scrabble-solver/src/components/Progress/Progress.tsx +2 -11
  250. package/packages/scrabble-solver/src/components/Rack/Rack.module.scss +3 -0
  251. package/packages/scrabble-solver/src/components/Rack/Rack.module.scss.d.ts +10 -0
  252. package/packages/scrabble-solver/src/components/Rack/Rack.tsx +8 -11
  253. package/packages/scrabble-solver/src/components/Rack/components/InputPrompt/InputPrompt.module.scss +2 -0
  254. package/packages/scrabble-solver/src/components/Rack/components/InputPrompt/InputPrompt.module.scss.d.ts +7 -0
  255. package/packages/scrabble-solver/src/components/Rack/components/InputPrompt/InputPrompt.tsx +1 -13
  256. package/packages/scrabble-solver/src/components/Rack/components/InputPrompt/lib.ts +1 -1
  257. package/packages/scrabble-solver/src/components/Rack/components/RackTile/RackTile.module.scss.d.ts +6 -0
  258. package/packages/scrabble-solver/src/components/Rack/components/RackTile/RackTile.tsx +5 -4
  259. package/packages/scrabble-solver/src/components/Rack/selectors.ts +1 -1
  260. package/packages/scrabble-solver/src/components/Radio/Radio.module.scss.d.ts +12 -0
  261. package/packages/scrabble-solver/src/components/Results/Cell.tsx +3 -12
  262. package/packages/scrabble-solver/src/components/Results/Header.tsx +9 -18
  263. package/packages/scrabble-solver/src/components/Results/HeaderButton.tsx +4 -5
  264. package/packages/scrabble-solver/src/components/Results/Result.tsx +4 -15
  265. package/packages/scrabble-solver/src/components/Results/Results.module.scss +4 -7
  266. package/packages/scrabble-solver/src/components/Results/Results.module.scss.d.ts +27 -0
  267. package/packages/scrabble-solver/src/components/Results/Results.tsx +14 -5
  268. package/packages/scrabble-solver/src/components/Results/SolveButton.tsx +1 -1
  269. package/packages/scrabble-solver/src/components/Results/types.ts +3 -3
  270. package/packages/scrabble-solver/src/components/ResultsInput/ResultsInput.module.scss.d.ts +7 -0
  271. package/packages/scrabble-solver/src/components/ResultsInput/ResultsInput.tsx +1 -1
  272. package/packages/scrabble-solver/src/components/Solver/Solver.module.scss +6 -5
  273. package/packages/scrabble-solver/src/components/Solver/Solver.module.scss.d.ts +20 -0
  274. package/packages/scrabble-solver/src/components/Solver/Solver.tsx +23 -24
  275. package/packages/scrabble-solver/src/components/Solver/components/InsertButton/InsertButton.module.scss.d.ts +7 -0
  276. package/packages/scrabble-solver/src/components/Solver/components/InsertButton/InsertButton.tsx +1 -1
  277. package/packages/scrabble-solver/src/components/Solver/components/ResultCandidatePicker/ResultCandidatePicker.module.scss.d.ts +18 -0
  278. package/packages/scrabble-solver/src/components/Solver/components/ResultCandidatePicker/ResultCandidatePicker.tsx +3 -1
  279. package/packages/scrabble-solver/src/components/Spinner/Spinner.module.scss.d.ts +10 -0
  280. package/packages/scrabble-solver/src/components/Tile/Tile.module.scss +3 -0
  281. package/packages/scrabble-solver/src/components/Tile/Tile.module.scss.d.ts +19 -0
  282. package/packages/scrabble-solver/src/components/Tile/Tile.tsx +5 -14
  283. package/packages/scrabble-solver/src/components/Tile/TilePure.tsx +2 -12
  284. package/packages/scrabble-solver/src/components/Tooltip/Tooltip.module.scss.d.ts +7 -0
  285. package/packages/scrabble-solver/src/components/Tooltip/Tooltip.tsx +14 -3
  286. package/packages/scrabble-solver/src/components/Tooltip/useTooltip.ts +2 -1
  287. package/packages/scrabble-solver/src/hooks/useColumns.ts +4 -7
  288. package/packages/scrabble-solver/src/hooks/useDeferredRender.ts +20 -0
  289. package/packages/scrabble-solver/src/hooks/useDirection.ts +4 -3
  290. package/packages/scrabble-solver/src/hooks/useLanguage.ts +2 -2
  291. package/packages/scrabble-solver/src/hooks/useLocalStorage.ts +32 -8
  292. package/packages/scrabble-solver/src/hooks/useMedia.ts +26 -26
  293. package/packages/scrabble-solver/src/i18n/constants.ts +2 -15
  294. package/packages/scrabble-solver/src/i18n/i18n.ts +18 -17
  295. package/packages/scrabble-solver/src/i18n/languages/english.json +0 -1
  296. package/packages/scrabble-solver/src/i18n/languages/french.json +0 -1
  297. package/packages/scrabble-solver/src/i18n/languages/german.json +0 -1
  298. package/packages/scrabble-solver/src/i18n/languages/persian.json +0 -1
  299. package/packages/scrabble-solver/src/i18n/languages/polish.json +0 -1
  300. package/packages/scrabble-solver/src/i18n/languages/romanian.json +0 -1
  301. package/packages/scrabble-solver/src/i18n/languages/spanish.json +0 -1
  302. package/packages/scrabble-solver/src/i18n/languages/turkish.json +0 -1
  303. package/packages/scrabble-solver/src/i18n/localeIcons.ts +24 -0
  304. package/packages/scrabble-solver/src/lib/localeTransliterate.test.ts +5 -0
  305. package/packages/scrabble-solver/src/lib/localeTransliterate.ts +26 -6
  306. package/packages/scrabble-solver/src/lib/waitForIdleOrFirstIntent.ts +33 -0
  307. package/packages/scrabble-solver/src/modals/DictionaryModal/DictionaryModal.module.scss.d.ts +8 -0
  308. package/packages/scrabble-solver/src/modals/DictionaryModal/DictionaryModal.tsx +3 -1
  309. package/packages/scrabble-solver/src/modals/KeyMapModal/KeyMapModal.tsx +3 -1
  310. package/packages/scrabble-solver/src/modals/KeyMapModal/components/Mapping/Mapping.module.scss.d.ts +11 -0
  311. package/packages/scrabble-solver/src/modals/MenuModal/MenuModal.module.scss +5 -0
  312. package/packages/scrabble-solver/src/modals/MenuModal/MenuModal.module.scss.d.ts +10 -0
  313. package/packages/scrabble-solver/src/modals/MenuModal/MenuModal.tsx +16 -5
  314. package/packages/scrabble-solver/src/modals/RemainingTilesModal/RemainingTilesModal.module.scss +4 -1
  315. package/packages/scrabble-solver/src/modals/RemainingTilesModal/RemainingTilesModal.module.scss.d.ts +9 -0
  316. package/packages/scrabble-solver/src/modals/RemainingTilesModal/RemainingTilesModal.tsx +4 -6
  317. package/packages/scrabble-solver/src/modals/RemainingTilesModal/components/Character/Character.module.scss +1 -0
  318. package/packages/scrabble-solver/src/modals/RemainingTilesModal/components/Character/Character.module.scss.d.ts +12 -0
  319. package/packages/scrabble-solver/src/modals/RemainingTilesModal/components/Character/Character.tsx +5 -12
  320. package/packages/scrabble-solver/src/modals/ResultsModal/ResultsModal.module.scss.d.ts +8 -0
  321. package/packages/scrabble-solver/src/modals/ResultsModal/ResultsModal.tsx +8 -4
  322. package/packages/scrabble-solver/src/modals/SettingsModal/SettingsModal.tsx +2 -2
  323. package/packages/scrabble-solver/src/modals/SettingsModal/components/AutoGroupTilesSetting/AutoGroupTilesSetting.module.scss.d.ts +7 -0
  324. package/packages/scrabble-solver/src/modals/SettingsModal/components/AutoGroupTilesSetting/AutoGroupTilesSetting.tsx +1 -1
  325. package/packages/scrabble-solver/src/modals/SettingsModal/components/ConfigSetting/ConfigSetting.module.scss.d.ts +7 -0
  326. package/packages/scrabble-solver/src/modals/SettingsModal/components/ConfigSetting/ConfigSetting.tsx +1 -1
  327. package/packages/scrabble-solver/src/modals/SettingsModal/components/HighlightUnreachableCellsSetting/HighlightUnreachableCellsSetting.module.scss.d.ts +7 -0
  328. package/packages/scrabble-solver/src/modals/SettingsModal/components/HighlightUnreachableCellsSetting/HighlightUnreachableCellsSetting.tsx +1 -1
  329. package/packages/scrabble-solver/src/modals/SettingsModal/components/InputModeSetting/InputModeSetting.module.scss.d.ts +7 -0
  330. package/packages/scrabble-solver/src/modals/SettingsModal/components/InputModeSetting/InputModeSetting.tsx +1 -1
  331. package/packages/scrabble-solver/src/modals/SettingsModal/components/LocaleSetting/LocaleSetting.module.scss.d.ts +8 -0
  332. package/packages/scrabble-solver/src/modals/SettingsModal/components/LocaleSetting/LocaleSetting.tsx +24 -21
  333. package/packages/scrabble-solver/src/modals/SettingsModal/components/RemoveCellFiltersSetting/RemoveCellFiltersSetting.module.scss.d.ts +7 -0
  334. package/packages/scrabble-solver/src/modals/SettingsModal/components/RemoveCellFiltersSetting/RemoveCellFiltersSetting.tsx +1 -1
  335. package/packages/scrabble-solver/src/modals/SettingsModal/components/ShowCoordinatesSetting/ShowCoordinatesSetting.module.scss.d.ts +7 -0
  336. package/packages/scrabble-solver/src/modals/SettingsModal/components/ShowCoordinatesSetting/ShowCoordinatesSetting.tsx +1 -5
  337. package/packages/scrabble-solver/src/modals/WordsModal/WordsModal.module.scss.d.ts +11 -0
  338. package/packages/scrabble-solver/src/modals/WordsModal/WordsModal.tsx +4 -2
  339. package/packages/scrabble-solver/src/modals/preload.ts +24 -0
  340. package/packages/scrabble-solver/src/pages/_app.tsx +5 -8
  341. package/packages/scrabble-solver/src/pages/_document.tsx +91 -5
  342. package/packages/scrabble-solver/src/pages/api/dictionary/[locale]/[word].ts +2 -2
  343. package/packages/scrabble-solver/src/pages/api/dictionary/[locale]/index.ts +80 -3
  344. package/packages/scrabble-solver/src/pages/api/solve.ts +3 -3
  345. package/packages/scrabble-solver/src/pages/api/verify.ts +12 -3
  346. package/packages/scrabble-solver/src/pages/index.module.scss +1 -0
  347. package/packages/scrabble-solver/src/pages/index.module.scss.d.ts +11 -0
  348. package/packages/scrabble-solver/src/pages/index.tsx +98 -38
  349. package/packages/scrabble-solver/src/pages/not-found.tsx +1 -1
  350. package/packages/scrabble-solver/src/parameters/index.ts +24 -93
  351. package/packages/scrabble-solver/src/sdk/solve.ts +13 -7
  352. package/packages/scrabble-solver/src/sdk/verify.ts +12 -6
  353. package/packages/scrabble-solver/src/service-worker/appShell.test.ts +86 -0
  354. package/packages/scrabble-solver/src/service-worker/appShell.ts +39 -0
  355. package/packages/scrabble-solver/src/service-worker/index.ts +4 -5
  356. package/packages/scrabble-solver/src/serviceWorkerManager.ts +5 -19
  357. package/packages/scrabble-solver/src/solver-worker/client.test.ts +151 -0
  358. package/packages/scrabble-solver/src/solver-worker/client.ts +106 -0
  359. package/packages/scrabble-solver/src/solver-worker/dictionaries/constants.ts +9 -0
  360. package/packages/scrabble-solver/src/solver-worker/dictionaries/getDictionary.ts +21 -0
  361. package/packages/scrabble-solver/src/solver-worker/dictionaries/index.ts +2 -0
  362. package/packages/scrabble-solver/src/solver-worker/dictionaries/revalidateDictionary.test.ts +199 -0
  363. package/packages/scrabble-solver/src/solver-worker/dictionaries/revalidateDictionary.ts +86 -0
  364. package/packages/scrabble-solver/src/solver-worker/dictionaries/revalidatedAt.ts +43 -0
  365. package/packages/scrabble-solver/src/solver-worker/getGaddag.test.ts +109 -0
  366. package/packages/scrabble-solver/src/solver-worker/getGaddag.ts +62 -0
  367. package/packages/scrabble-solver/src/solver-worker/index.ts +1 -0
  368. package/packages/scrabble-solver/src/solver-worker/index.worker.ts +124 -0
  369. package/packages/scrabble-solver/src/solver-worker/messages.ts +20 -0
  370. package/packages/scrabble-solver/src/state/actions.ts +1 -1
  371. package/packages/scrabble-solver/src/state/app/index.ts +4 -0
  372. package/packages/scrabble-solver/src/state/app/initialState.ts +6 -0
  373. package/packages/scrabble-solver/src/state/app/selectors.ts +5 -0
  374. package/packages/scrabble-solver/src/state/app/slice.ts +20 -0
  375. package/packages/scrabble-solver/src/state/app/types.ts +4 -0
  376. package/packages/scrabble-solver/src/state/board/initialState.ts +1 -2
  377. package/packages/scrabble-solver/src/state/i18n/index.ts +4 -0
  378. package/packages/scrabble-solver/src/state/i18n/initialState.ts +5 -0
  379. package/packages/scrabble-solver/src/state/i18n/selectors.ts +3 -0
  380. package/packages/scrabble-solver/src/state/i18n/slice.ts +16 -0
  381. package/packages/scrabble-solver/src/state/i18n/types.ts +7 -0
  382. package/packages/scrabble-solver/src/state/index.ts +3 -0
  383. package/packages/scrabble-solver/src/state/lib.ts +1 -1
  384. package/packages/scrabble-solver/src/state/localStorage.ts +86 -29
  385. package/packages/scrabble-solver/src/state/rack/initialState.ts +1 -2
  386. package/packages/scrabble-solver/src/state/rack/slice.ts +4 -1
  387. package/packages/scrabble-solver/src/state/results/lib.ts +5 -5
  388. package/packages/scrabble-solver/src/state/results/selectors.ts +1 -1
  389. package/packages/scrabble-solver/src/state/sagas.ts +139 -13
  390. package/packages/scrabble-solver/src/state/selectors.ts +1 -1
  391. package/packages/scrabble-solver/src/state/settings/initialState.ts +7 -10
  392. package/packages/scrabble-solver/src/state/settings/selectors.ts +7 -2
  393. package/packages/scrabble-solver/src/state/settings/slice.ts +5 -2
  394. package/packages/scrabble-solver/src/state/store.ts +4 -0
  395. package/packages/scrabble-solver/src/state/types.ts +4 -0
  396. package/packages/scrabble-solver/src/state/useTypedStore.ts +6 -0
  397. package/packages/scrabble-solver/src/styles/_tokens.scss +1 -0
  398. package/packages/scrabble-solver/src/styles/global.scss +9 -0
  399. package/packages/scrabble-solver/src/styles/variables.module.scss +0 -21
  400. package/packages/scrabble-solver/src/styles/variables.module.scss.d.ts +27 -0
  401. package/packages/scrabble-solver/src/styles/variables.scss +46 -2
  402. package/packages/scrabble-solver/src/types/api.ts +1 -2
  403. package/packages/scrabble-solver/src/types/index.ts +1 -2
  404. package/packages/scrabble-solver/tsconfig.json +4 -0
  405. package/packages/scrabble-solver/tsconfig.tsbuildinfo +1 -1
  406. package/packages/solver/README.md +24 -0
  407. package/packages/solver/benchmarks/index.ts +15 -0
  408. package/packages/solver/benchmarks/lib.ts +31 -0
  409. package/packages/solver/benchmarks/renderChart.ts +165 -0
  410. package/packages/solver/benchmarks/results/chart.svg +65 -0
  411. package/packages/solver/benchmarks/runBenchmarks.ts +66 -0
  412. package/packages/solver/benchmarks/scenarios.ts +64 -0
  413. package/packages/solver/benchmarks/types.ts +16 -0
  414. package/packages/solver/benchmarks/updateReadme.ts +53 -0
  415. package/packages/solver/build/MoveGenerator.d.ts +116 -0
  416. package/packages/solver/build/MoveGenerator.js +686 -0
  417. package/packages/solver/build/index.d.ts +0 -13
  418. package/packages/solver/build/index.js +1 -27
  419. package/packages/solver/build/solve.d.ts +2 -2
  420. package/packages/solver/build/solve.js +3 -19
  421. package/packages/solver/package.json +7 -6
  422. package/packages/solver/src/MoveGenerator.test.ts +1009 -0
  423. package/packages/solver/src/MoveGenerator.ts +926 -0
  424. package/packages/solver/src/ReferenceSolver.ts +401 -0
  425. package/packages/solver/src/index.ts +0 -13
  426. package/packages/solver/src/solve.test.ts +21 -21
  427. package/packages/solver/src/solve.ts +4 -22
  428. package/packages/solver/tsconfig.json +1 -1
  429. package/packages/types/build/Cell.d.ts +1 -0
  430. package/packages/types/build/Cell.js +3 -0
  431. package/packages/types/build/Direction.d.ts +1 -0
  432. package/packages/types/build/Result.d.ts +3 -2
  433. package/packages/types/build/Result.js +11 -6
  434. package/packages/types/build/ResultJson.d.ts +5 -4
  435. package/packages/types/build/ShowCoordinates.d.ts +1 -2
  436. package/packages/types/build/TextDirection.d.ts +1 -0
  437. package/packages/types/build/index.d.ts +2 -6
  438. package/packages/types/build/index.js +1 -9
  439. package/packages/types/build/readResultCells.d.ts +5 -0
  440. package/packages/types/build/readResultCells.js +75 -0
  441. package/packages/types/package.json +4 -3
  442. package/packages/types/src/Cell.ts +4 -0
  443. package/packages/types/src/Direction.ts +1 -0
  444. package/packages/types/src/Result.ts +15 -6
  445. package/packages/types/src/ResultJson.ts +5 -5
  446. package/packages/types/src/ShowCoordinates.ts +1 -2
  447. package/packages/types/src/TextDirection.ts +1 -0
  448. package/packages/types/src/index.ts +2 -6
  449. package/packages/types/src/readResultCells.test.ts +140 -0
  450. package/packages/types/src/readResultCells.ts +90 -0
  451. package/packages/word-definitions/package.json +2 -2
  452. package/packages/word-lists/package.json +2 -2
  453. package/playwright-report/index.html +49 -0
  454. package/playwright.config.ts +30 -0
  455. package/screencast.gif +0 -0
  456. package/scripts/record-screencast.ts +347 -0
  457. package/test-results/.last-run.json +4 -0
  458. package/tsconfig.json +1 -1
  459. package/babel.config.js +0 -4
  460. package/cypress/e2e/app.spec.cy.ts +0 -123
  461. package/cypress/e2e/bugs/112-character-bonus.ts +0 -40
  462. package/cypress/e2e/bugs/129-esc-sidebar.ts +0 -23
  463. package/cypress/e2e/bugs/2-q-tile-in-english.ts +0 -33
  464. package/cypress/e2e/bugs/3-x-tile-in-polish.ts +0 -33
  465. package/cypress/e2e/bugs/30-click-inside-radio-icon.ts +0 -26
  466. package/cypress/e2e/bugs/333-disabled-radio-cursor.ts +0 -24
  467. package/cypress/e2e/bugs/342-results-sorting.ts +0 -48
  468. package/cypress/e2e/bugs/348-results-word-padding.ts +0 -74
  469. package/cypress/e2e/bugs/352-dictionary-race-condition.ts +0 -29
  470. package/cypress/e2e/bugs/363-dictionary-input-unique-words.ts +0 -41
  471. package/cypress/e2e/bugs/380-transliteration-when-pasting.ts +0 -75
  472. package/cypress/e2e/bugs/398-digraphs-in-created-words.ts +0 -38
  473. package/cypress/e2e/bugs/401-board-state-on-game-change.ts +0 -36
  474. package/cypress/e2e/bugs.spec.cy.ts +0 -13
  475. package/cypress/e2e/features/198-highlight-unreachable-cells.ts +0 -101
  476. package/cypress/e2e/features/91-hover-remaining-tile-highlights.ts +0 -90
  477. package/cypress/e2e/features.spec.cy.ts +0 -2
  478. package/cypress/support/commands.ts +0 -4
  479. package/cypress/support/e2e.ts +0 -1
  480. package/cypress/support/index.ts +0 -1
  481. package/cypress/support/lib/actions.ts +0 -85
  482. package/cypress/support/lib/selectors.ts +0 -70
  483. package/cypress/tsconfig.json +0 -10
  484. package/cypress.config.ts +0 -17
  485. package/packages/scrabble-solver/.next/server/chunks/318.js +0 -3
  486. package/packages/scrabble-solver/.next/server/chunks/791.js +0 -15
  487. package/packages/scrabble-solver/.next/static/chunks/framework-3cf15b8041c59dd3.js +0 -1
  488. package/packages/scrabble-solver/.next/static/chunks/main-852475ca502b4e49.js +0 -5
  489. package/packages/scrabble-solver/.next/static/chunks/pages/_app-a5bbe02710f13d05.js +0 -7
  490. package/packages/scrabble-solver/.next/static/chunks/pages/index-ec0f6aeeaf7be227.js +0 -1
  491. package/packages/scrabble-solver/.next/static/chunks/pages/not-found-9e076427bad69d90.js +0 -1
  492. package/packages/scrabble-solver/.next/static/chunks/webpack-1a7a166b34ed8d24.js +0 -1
  493. package/packages/scrabble-solver/.next/static/css/0af35adb4bab56f0.css +0 -2
  494. package/packages/scrabble-solver/.next/static/css/a78e04fe95452380.css +0 -1
  495. package/packages/scrabble-solver/.next/static/vYpMmuC_yEurZGcyGVnLf/_buildManifest.js +0 -1
  496. package/packages/scrabble-solver/src/app-layout/AppLayoutContext.tsx +0 -25
  497. package/packages/scrabble-solver/src/app-layout/index.ts +0 -1
  498. package/packages/scrabble-solver/src/app-layout/useAppLayoutValue.ts +0 -112
  499. package/packages/scrabble-solver/src/components/Board/hooks/useBackgroundImage.tsx +0 -279
  500. package/packages/scrabble-solver/src/components/index.ts +0 -26
  501. package/packages/scrabble-solver/src/hooks/index.ts +0 -12
  502. package/packages/scrabble-solver/src/hooks/useOnWindowResize.ts +0 -11
  503. package/packages/scrabble-solver/src/hooks/useViewportSize.ts +0 -17
  504. package/packages/scrabble-solver/src/i18n/index.ts +0 -2
  505. package/packages/scrabble-solver/src/icons/Flag.svg +0 -4
  506. package/packages/scrabble-solver/src/icons/Star.svg +0 -4
  507. package/packages/scrabble-solver/src/icons/index.ts +0 -49
  508. package/packages/scrabble-solver/src/lib/getTileSizes.ts +0 -13
  509. package/packages/scrabble-solver/src/lib/index.ts +0 -24
  510. package/packages/scrabble-solver/src/modals/index.ts +0 -7
  511. package/packages/scrabble-solver/src/sdk/getDictionary.ts +0 -9
  512. package/packages/scrabble-solver/src/service-worker/average.ts +0 -7
  513. package/packages/scrabble-solver/src/service-worker/dictionaries/constants.ts +0 -5
  514. package/packages/scrabble-solver/src/service-worker/dictionaries/getDictionary.ts +0 -20
  515. package/packages/scrabble-solver/src/service-worker/dictionaries/index.ts +0 -2
  516. package/packages/scrabble-solver/src/service-worker/dictionaries/revalidateDictionary.ts +0 -33
  517. package/packages/scrabble-solver/src/service-worker/getTrie.ts +0 -24
  518. package/packages/scrabble-solver/src/service-worker/routeSolveRequests.ts +0 -91
  519. package/packages/scrabble-solver/src/service-worker/routeVerifyRequests.ts +0 -37
  520. package/packages/solver/build/areDigraphsValid.d.ts +0 -2
  521. package/packages/solver/build/areDigraphsValid.js +0 -17
  522. package/packages/solver/build/fillPattern.d.ts +0 -6
  523. package/packages/solver/build/fillPattern.js +0 -52
  524. package/packages/solver/build/generateEndIndices.d.ts +0 -2
  525. package/packages/solver/build/generateEndIndices.js +0 -17
  526. package/packages/solver/build/generateHorizontalPatterns.d.ts +0 -2
  527. package/packages/solver/build/generateHorizontalPatterns.js +0 -16
  528. package/packages/solver/build/generatePattern.d.ts +0 -7
  529. package/packages/solver/build/generatePattern.js +0 -20
  530. package/packages/solver/build/generatePatterns.d.ts +0 -2
  531. package/packages/solver/build/generatePatterns.js +0 -11
  532. package/packages/solver/build/generateStartIndices.d.ts +0 -2
  533. package/packages/solver/build/generateStartIndices.js +0 -16
  534. package/packages/solver/build/generateVectors.d.ts +0 -7
  535. package/packages/solver/build/generateVectors.js +0 -7
  536. package/packages/solver/build/generateVerticalPatterns.d.ts +0 -2
  537. package/packages/solver/build/generateVerticalPatterns.js +0 -16
  538. package/packages/solver/build/getCellsScore.d.ts +0 -2
  539. package/packages/solver/build/getCellsScore.js +0 -18
  540. package/packages/solver/build/getPatternHash.d.ts +0 -2
  541. package/packages/solver/build/getPatternHash.js +0 -14
  542. package/packages/solver/build/getPatternScore.d.ts +0 -2
  543. package/packages/solver/build/getPatternScore.js +0 -22
  544. package/packages/solver/build/getUniquePatterns.d.ts +0 -2
  545. package/packages/solver/build/getUniquePatterns.js +0 -17
  546. package/packages/solver/src/areDigraphsValid.ts +0 -18
  547. package/packages/solver/src/fillPattern.test.ts +0 -107
  548. package/packages/solver/src/fillPattern.ts +0 -68
  549. package/packages/solver/src/generateEndIndices.test.ts +0 -23
  550. package/packages/solver/src/generateEndIndices.ts +0 -19
  551. package/packages/solver/src/generateHorizontalPatterns.test.ts +0 -31
  552. package/packages/solver/src/generateHorizontalPatterns.ts +0 -15
  553. package/packages/solver/src/generatePattern.ts +0 -33
  554. package/packages/solver/src/generatePatterns.test.ts +0 -13
  555. package/packages/solver/src/generatePatterns.ts +0 -11
  556. package/packages/solver/src/generateStartIndices.test.ts +0 -19
  557. package/packages/solver/src/generateStartIndices.ts +0 -17
  558. package/packages/solver/src/generateVectors.test.ts +0 -12
  559. package/packages/solver/src/generateVectors.ts +0 -10
  560. package/packages/solver/src/generateVerticalPatterns.test.ts +0 -32
  561. package/packages/solver/src/generateVerticalPatterns.ts +0 -15
  562. package/packages/solver/src/getCellsScore.ts +0 -21
  563. package/packages/solver/src/getPatternHash.test.ts +0 -17
  564. package/packages/solver/src/getPatternHash.ts +0 -12
  565. package/packages/solver/src/getPatternScore.test.ts +0 -204
  566. package/packages/solver/src/getPatternScore.ts +0 -23
  567. package/packages/solver/src/getUniquePatterns.ts +0 -19
  568. package/packages/types/build/CollisionJson.d.ts +0 -2
  569. package/packages/types/build/FinalPattern.d.ts +0 -6
  570. package/packages/types/build/FinalPattern.js +0 -14
  571. package/packages/types/build/HorizontalPattern.d.ts +0 -5
  572. package/packages/types/build/HorizontalPattern.js +0 -34
  573. package/packages/types/build/Pattern.d.ts +0 -20
  574. package/packages/types/build/Pattern.js +0 -50
  575. package/packages/types/build/PatternJson.d.ts +0 -6
  576. package/packages/types/build/VerticalPattern.d.ts +0 -5
  577. package/packages/types/build/VerticalPattern.js +0 -34
  578. package/packages/types/src/CollisionJson.ts +0 -3
  579. package/packages/types/src/FinalPattern.ts +0 -14
  580. package/packages/types/src/HorizontalPattern.ts +0 -37
  581. package/packages/types/src/Pattern.ts +0 -71
  582. package/packages/types/src/PatternJson.ts +0 -7
  583. package/packages/types/src/VerticalPattern.ts +0 -37
  584. /package/{cypress/support → e2e}/lib/index.ts +0 -0
  585. /package/packages/scrabble-solver/.next/static/{vYpMmuC_yEurZGcyGVnLf → FL82obwzFHRzvV6z76I-U}/_ssgManifest.js +0 -0
  586. /package/packages/scrabble-solver/src/{service-worker → solver-worker}/dictionaries/expirationManager.ts +0 -0
  587. /package/packages/scrabble-solver/src/{service-worker → solver-worker}/dictionaries/getDictionaryUrl.ts +0 -0
  588. /package/packages/types/build/{CollisionJson.js → Direction.js} +0 -0
  589. /package/packages/types/build/{PatternJson.js → TextDirection.js} +0 -0
@@ -0,0 +1,45 @@
1
+ import { expect, type Page, test } from '@playwright/test';
2
+
3
+ import * as Lib from '../lib';
4
+
5
+ test.describe('Solver paths', () => {
6
+ test('solves through the server when no dictionary is available locally', async ({ page }) => {
7
+ await page.route('**/api/dictionary/*', (route) => route.fulfill({ status: 503 }));
8
+ const solveResponse = page.waitForResponse('**/api/solve');
9
+ await Lib.visitIndex(page);
10
+ await Lib.typeBoard(page, 'i', 'horizontal', { x: 7, y: 7 });
11
+ await Lib.typeRack(page, 'q');
12
+ await Lib.solve(page);
13
+ await solveResponse;
14
+
15
+ await expect(Lib.getResults(page)).toHaveCount(2);
16
+ await Lib.assertResult(page, 0, 'qi', 11);
17
+ });
18
+
19
+ test('solves locally once the dictionary is cached', async ({ page }) => {
20
+ await Lib.visitIndex(page);
21
+ await waitForCachedDictionary(page);
22
+
23
+ let solveRequestCount = 0;
24
+ await page.route('**/api/solve', (route) => {
25
+ solveRequestCount += 1;
26
+ return route.continue();
27
+ });
28
+ await Lib.typeBoard(page, 'i', 'horizontal', { x: 7, y: 7 });
29
+ await Lib.typeRack(page, 'q');
30
+ await Lib.solve(page);
31
+
32
+ await expect(Lib.getResults(page)).toHaveCount(2);
33
+ await Lib.assertResult(page, 0, 'qi', 11);
34
+ expect(solveRequestCount).toBe(0);
35
+ });
36
+ });
37
+
38
+ function waitForCachedDictionary(page: Page): Promise<void> {
39
+ return expect.poll(() => page.evaluate(isDictionaryCached), { timeout: 30000 }).toBe(true);
40
+ }
41
+
42
+ async function isDictionaryCached(): Promise<boolean> {
43
+ const cache = await caches.open('dictionary-api-cache');
44
+ return typeof (await cache.match('/api/dictionary/en-US')) !== 'undefined';
45
+ }
@@ -0,0 +1,119 @@
1
+ import { expect, type Locator, type Page } from '@playwright/test';
2
+ import { type Direction } from '@scrabble-solver/types';
3
+
4
+ import {
5
+ getBoardTile,
6
+ getLoading,
7
+ getModal,
8
+ getOpenModal,
9
+ getRackTile,
10
+ getResult,
11
+ getResultsContainer,
12
+ } from './selectors';
13
+
14
+ interface BoardPosition {
15
+ x?: number;
16
+ y?: number;
17
+ }
18
+
19
+ export async function visitIndex(page: Page): Promise<void> {
20
+ await page.goto('/');
21
+ }
22
+
23
+ export async function closeModal(page: Page): Promise<void> {
24
+ await expect(getOpenModal(page)).toBeVisible();
25
+ await page.keyboard.press('Escape');
26
+ await expect(getModal(page)).toHaveCount(0);
27
+ }
28
+
29
+ export async function typeRack(page: Page, tiles: string, index = 0): Promise<void> {
30
+ await getRackTile(page, index).focus();
31
+ await page.keyboard.type(tiles);
32
+ }
33
+
34
+ export async function typeBoard(
35
+ page: Page,
36
+ tiles: string,
37
+ direction: Direction,
38
+ { x = 0, y = 0 }: BoardPosition = {},
39
+ ): Promise<void> {
40
+ await getBoardTile(page, x, y).focus();
41
+ await ensureDirection(page, direction);
42
+
43
+ for (let index = 0; index < tiles.length; ++index) {
44
+ const xOffset = direction === 'horizontal' ? index : 0;
45
+ const yOffset = direction === 'vertical' ? index : 0;
46
+
47
+ await getBoardTile(page, x + xOffset, y + yOffset).focus();
48
+ await page.keyboard.type(tiles[index]);
49
+ }
50
+ }
51
+
52
+ export async function paste(target: Locator, text: string): Promise<void> {
53
+ await target.focus();
54
+ await target.evaluate((element, value) => {
55
+ const pasteEvent = new ClipboardEvent('paste', {
56
+ bubbles: true,
57
+ clipboardData: new DataTransfer(),
58
+ });
59
+
60
+ pasteEvent.clipboardData?.setData('text/plain', value);
61
+ element.dispatchEvent(pasteEvent);
62
+ }, text);
63
+ }
64
+
65
+ export async function pasteBoard(
66
+ page: Page,
67
+ word: string,
68
+ direction: Direction,
69
+ { x = 0, y = 0 }: BoardPosition = {},
70
+ ): Promise<void> {
71
+ await getBoardTile(page, x, y).focus();
72
+ await ensureDirection(page, direction);
73
+ await paste(getBoardTile(page, x, y), word);
74
+ }
75
+
76
+ export async function solve(page: Page): Promise<void> {
77
+ await getRackTile(page).evaluate((input: HTMLInputElement) => input.form?.requestSubmit());
78
+ await expect(getResultsContainer(page)).toHaveAttribute('data-outdated', 'false', { timeout: 90_000 });
79
+ await expect(getLoading(page)).toHaveCount(0);
80
+ }
81
+
82
+ /**
83
+ * react-window remounts rows during its initial measure pass, and a row
84
+ * replaced under an already-hovered cursor never receives a new mouseenter -
85
+ * let the list settle before hovering.
86
+ */
87
+ export async function hoverResult(page: Page, index = 0): Promise<void> {
88
+ await page.waitForTimeout(100);
89
+ await getResult(page, index).hover();
90
+ }
91
+
92
+ export async function assertResult(page: Page, index: number, word: string, points: number): Promise<void> {
93
+ const result = getResult(page, index);
94
+
95
+ await expect(result).toHaveAttribute('aria-label', word);
96
+ await expect(result).toContainText(word);
97
+ await expect(result.getByTestId('points')).toHaveText(String(points));
98
+ }
99
+
100
+ export async function expectTileHighlighted(tile: Locator): Promise<void> {
101
+ await expect(tile.locator('..')).toHaveAttribute('role', 'mark');
102
+ }
103
+
104
+ export async function expectTileNotHighlighted(tile: Locator): Promise<void> {
105
+ await expect(tile.locator('..')).not.toHaveAttribute('role', 'mark');
106
+ }
107
+
108
+ export async function moveMouseAway(page: Page): Promise<void> {
109
+ const viewport = page.viewportSize();
110
+ await page.mouse.move((viewport?.width ?? 0) / 2, 0);
111
+ }
112
+
113
+ async function ensureDirection(page: Page, direction: Direction): Promise<void> {
114
+ const toggleDirectionButton = page.getByTestId('toggle-direction-button');
115
+
116
+ if ((await toggleDirectionButton.getAttribute('data-direction')) !== direction) {
117
+ await toggleDirectionButton.click();
118
+ }
119
+ }
@@ -0,0 +1,71 @@
1
+ import { type Locator, type Page } from '@playwright/test';
2
+
3
+ export function getModal(page: Page): Locator {
4
+ return page.getByRole('dialog');
5
+ }
6
+
7
+ export function getOpenModal(page: Page): Locator {
8
+ return page.locator('.ReactModal__Overlay--after-open').getByRole('dialog');
9
+ }
10
+
11
+ export function getBoardContainer(page: Page): Locator {
12
+ return page.getByTestId('board');
13
+ }
14
+
15
+ export function getBoardTile(page: Page, x = 0, y = 0, boardWidth = 15): Locator {
16
+ const index = y * boardWidth + x;
17
+ return getBoardContainer(page).getByRole('textbox', { includeHidden: true }).nth(index);
18
+ }
19
+
20
+ export function getDictionary(page: Page): Locator {
21
+ return page.getByTestId('dictionary');
22
+ }
23
+
24
+ export function getDictionaryInput(page: Page): Locator {
25
+ return getDictionary(page).getByRole('textbox');
26
+ }
27
+
28
+ export function getDictionaryTitles(page: Page): Locator {
29
+ return getDictionary(page).locator('h2');
30
+ }
31
+
32
+ export function getLoading(page: Page): Locator {
33
+ return page.getByTestId('loading');
34
+ }
35
+
36
+ export function getRackContainer(page: Page): Locator {
37
+ return page.getByTestId('rack');
38
+ }
39
+
40
+ export function getRackTile(page: Page, index = 0): Locator {
41
+ // includeHidden: true so that rack can be interacted with while modal is opened
42
+ return getRackContainer(page).getByRole('textbox', { includeHidden: true }).nth(index);
43
+ }
44
+
45
+ export function getResultsContainer(page: Page): Locator {
46
+ return page.getByTestId('results');
47
+ }
48
+
49
+ export function getResults(page: Page): Locator {
50
+ return getResultsContainer(page).getByTestId('result');
51
+ }
52
+
53
+ export function getResultsFilterInput(page: Page): Locator {
54
+ return getResultsContainer(page).getByRole('textbox');
55
+ }
56
+
57
+ export function getResult(page: Page, index = 0): Locator {
58
+ return getResults(page).nth(index);
59
+ }
60
+
61
+ export function getSettingsButton(page: Page): Locator {
62
+ return page.getByTestId('settings-button');
63
+ }
64
+
65
+ export function getSettingOption(page: Page, section: string, option: string): Locator {
66
+ return getOpenModal(page).getByLabel(section, { exact: true }).getByLabel(option, { exact: true });
67
+ }
68
+
69
+ export function getTooltip(page: Page): Locator {
70
+ return page.getByRole('tooltip');
71
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../tsconfig.json",
3
+
4
+ "compilerOptions": {
5
+ "noEmit": true,
6
+ "types": ["node"]
7
+ },
8
+ "include": ["../playwright.config.ts", "./**/*.ts"],
9
+ "exclude": []
10
+ }
package/lerna.json CHANGED
@@ -6,6 +6,6 @@
6
6
  "access": "public"
7
7
  },
8
8
  "tagVersionPrefix": "",
9
- "version": "2.16.7",
9
+ "version": "2.18.0",
10
10
  "$schema": "node_modules/lerna/schemas/lerna-schema.json"
11
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scrabble-solver",
3
- "version": "2.16.7",
3
+ "version": "2.18.0",
4
4
  "description": "Scrabble Solver 2 - Free, open-source, cross-platform, multi-language analysis tool for Scrabble, Scrabble Duel, Super Scrabble, Letter League, Crossplay, Literaki, and Kelimelik. Quickly find the top-scoring words using the given board and tiles.",
5
5
  "keywords": [
6
6
  "Scrabble",
@@ -47,23 +47,26 @@
47
47
  "scrabble-solver": "./bin/scrabble-solver.js"
48
48
  },
49
49
  "scripts": {
50
+ "benchmark": "bun run --filter @scrabble-solver/solver benchmark",
50
51
  "build": "bun run --filter './packages/*' build",
51
52
  "clean": "bun run --filter './packages/*' clean && rimraf node_modules/",
52
53
  "dev": "bun run --filter @scrabble-solver/scrabble-solver dev",
53
54
  "format": "oxfmt --check './**/*.{js,ts,tsx,scss}'",
54
55
  "format:fix": "oxfmt './**/*.{js,ts,tsx,scss}'",
55
- "lint": "oxlint cypress packages",
56
+ "lint": "oxlint e2e packages",
56
57
  "lint:fix": "bun run lint --fix",
57
58
  "reinstall": "bun run clean && bun install && bun run build",
58
59
  "release": "bun run release:prepare && bun run release:publish",
59
60
  "release:prepare": "bun run reinstall",
60
61
  "release:publish": "bun run version:bump && np --no-cleanup --package-manager bun && lerna publish from-package --yes",
62
+ "screencast": "start-server-and-test start:app http://localhost:3333 screencast:record",
63
+ "screencast:record": "bun scripts/record-screencast.ts",
61
64
  "start": "concurrently -n w: bun:start:*",
62
- "start:app": "bun run --filter @scrabble-solver/scrabble-solver start",
65
+ "start:app": "bun run --cwd packages/scrabble-solver start",
63
66
  "start:browser": "wait-on http://localhost:3333 && open-cli http://localhost:3333",
64
- "test": "bun run build && bun run test-unit && start-server-and-test start:app http://localhost:3333 test-cypress:run",
65
- "test-cypress": "cypress open",
66
- "test-cypress:run": "CYPRESS_BASE_URL=http://localhost:3333 cypress run",
67
+ "test": "bun run build && bun run test-unit && start-server-and-test start:app http://localhost:3333 test-playwright:run",
68
+ "test-playwright": "playwright test --ui",
69
+ "test-playwright:run": "PLAYWRIGHT_BASE_URL=http://localhost:3333 playwright test",
67
70
  "test-unit": "bun run --filter '*' test",
68
71
  "version:bump": "bun run version:bump-lerna && bun run version:commit",
69
72
  "version:bump-lerna": "lerna version --force-publish --no-git-tag-version --no-push",
@@ -95,28 +98,23 @@
95
98
  "packages/scrabble-solver"
96
99
  ],
97
100
  "dependencies": {
98
- "@scrabble-solver/scrabble-solver": "^2.16.7",
99
- "concurrently": "^10.0.4",
101
+ "@scrabble-solver/scrabble-solver": "^2.18.0",
102
+ "concurrently": "^10.0.5",
100
103
  "open-cli": "^9.0.0",
101
104
  "wait-on": "^9.1.0"
102
105
  },
103
106
  "devDependencies": {
104
- "@babel/plugin-proposal-class-properties": "^7.18.6",
105
- "@cypress/webpack-batteries-included-preprocessor": "^4.2.0",
106
- "@cypress/webpack-preprocessor": "^7.1.1",
107
- "@testing-library/cypress": "^10.1.3",
107
+ "@playwright/test": "^1.62.1",
108
108
  "@types/bun": "^1.3.14",
109
- "@types/node": "^26.1.2",
110
- "cypress": "^15.19.0",
111
- "cypress-real-events": "^1.15.0",
109
+ "@types/node": "^26.2.0",
112
110
  "eslint-import-resolver-typescript": "^4.4.5",
113
111
  "eslint-plugin-import": "^2.32.0",
114
- "eslint-plugin-mocha": "^12.0.1",
112
+ "eslint-plugin-playwright": "^2.11.0",
115
113
  "eslint-plugin-react": "^7.37.5",
116
114
  "lerna": "^10.0.0",
117
115
  "np": "^12.0.1",
118
- "oxfmt": "^0.61.0",
119
- "oxlint": "^1.76.0",
116
+ "oxfmt": "^0.63.0",
117
+ "oxlint": "^1.78.0",
120
118
  "oxlint-tsgolint": "^7.0.2001",
121
119
  "rimraf": "^6.1.3",
122
120
  "start-server-and-test": "^3.0.12",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scrabble-solver/configs",
3
- "version": "2.16.7",
3
+ "version": "2.18.0",
4
4
  "description": "Scrabble Solver 2 - Configs",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -23,8 +23,8 @@
23
23
  "clean": "rimraf build/"
24
24
  },
25
25
  "dependencies": {
26
- "@scrabble-solver/constants": "^2.16.7",
27
- "@scrabble-solver/types": "^2.16.7"
26
+ "@scrabble-solver/constants": "^2.18.0",
27
+ "@scrabble-solver/types": "^2.18.0"
28
28
  },
29
29
  "gitHead": "1e2d1ad49a288d4a44196d8e3336740da132c637"
30
30
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scrabble-solver/constants",
3
- "version": "2.16.7",
3
+ "version": "2.18.0",
4
4
  "description": "Scrabble Solver 2 - Constants",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -1,3 +1,3 @@
1
1
  # @scrabble-solver/dictionaries
2
2
 
3
- Downloads, caches & serves dictionaries. Dictionaries are [Trie](https://github.com/kamilmielnik/trie) instances.
3
+ Downloads, caches & serves dictionaries. Dictionaries are [Gaddag](https://github.com/kamilmielnik/gaddag) instances.
@@ -1,10 +1,10 @@
1
- import { type Trie } from '@kamilmielnik/trie';
1
+ import { type Gaddag } from '@kamilmielnik/gaddag';
2
2
  import { Locale } from '@scrabble-solver/types';
3
3
  export declare class Dictionaries {
4
4
  private readonly cache;
5
5
  private readonly downloadDictionaryProxies;
6
6
  constructor();
7
- get(locale: Locale): Promise<Trie>;
7
+ get(locale: Locale): Promise<Gaddag>;
8
8
  remove(): void;
9
9
  update(force?: boolean): Promise<void>;
10
10
  private getLocalesToUpdate;
@@ -16,9 +16,9 @@ class Dictionaries {
16
16
  }
17
17
  async get(locale) {
18
18
  if (this.cache.has(locale)) {
19
- const trie = await this.cache.get(locale);
20
- if (trie) {
21
- return trie;
19
+ const gaddag = await this.cache.get(locale);
20
+ if (gaddag) {
21
+ return gaddag;
22
22
  }
23
23
  }
24
24
  logger_1.logger.info('Dictionaries - cache miss', { locale });
@@ -40,9 +40,9 @@ class Dictionaries {
40
40
  logger_1.logger.info('Dictionaries - updateDictionary', { locale });
41
41
  fs_1.default.mkdirSync(constants_1.OUTPUT_DIRECTORY, { recursive: true });
42
42
  const downloadDictionaryProxy = this.downloadDictionaryProxies[locale];
43
- const trie = await downloadDictionaryProxy();
44
- await this.cache.set(locale, trie);
45
- return trie;
43
+ const gaddag = await downloadDictionaryProxy();
44
+ await this.cache.set(locale, gaddag);
45
+ return gaddag;
46
46
  }
47
47
  }
48
48
  exports.Dictionaries = Dictionaries;
@@ -1,10 +1,17 @@
1
- import { Trie } from '@kamilmielnik/trie';
1
+ import { Gaddag } from '@kamilmielnik/gaddag';
2
2
  import { type Locale } from '@scrabble-solver/types';
3
3
  import type { Cache } from '../types';
4
- export declare class DiskCache implements Cache<Locale, Trie> {
5
- get(locale: Locale): Promise<Trie | undefined>;
4
+ export declare class DiskCache implements Cache<Locale, Gaddag> {
5
+ private readonly directory;
6
+ constructor(directory?: string);
7
+ /**
8
+ * Returns undefined when the cached file cannot be deserialized (it was
9
+ * written by an app version with an incompatible format, or it is corrupted)
10
+ * so that callers re-download and re-serialize the dictionary.
11
+ */
12
+ get(locale: Locale): Promise<Gaddag | undefined>;
6
13
  getLastModifiedTimestamp(locale: Locale): number | undefined;
7
14
  has(locale: Locale): boolean;
8
15
  isStale(locale: Locale): boolean | undefined;
9
- set(locale: Locale, trie: Trie): Promise<void>;
16
+ set(locale: Locale, gaddag: Gaddag): Promise<void>;
10
17
  }
@@ -4,22 +4,37 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.DiskCache = void 0;
7
- const trie_1 = require("@kamilmielnik/trie");
7
+ const gaddag_1 = require("@kamilmielnik/gaddag");
8
+ const logger_1 = require("@scrabble-solver/logger");
8
9
  const fs_1 = __importDefault(require("fs"));
9
10
  const constants_1 = require("../constants");
10
11
  const getDictionaryFilepath_1 = require("./getDictionaryFilepath");
11
12
  class DiskCache {
13
+ constructor(directory = constants_1.OUTPUT_DIRECTORY) {
14
+ this.directory = directory;
15
+ }
16
+ /**
17
+ * Returns undefined when the cached file cannot be deserialized (it was
18
+ * written by an app version with an incompatible format, or it is corrupted)
19
+ * so that callers re-download and re-serialize the dictionary.
20
+ */
12
21
  async get(locale) {
13
22
  if (!this.has(locale)) {
14
23
  return undefined;
15
24
  }
16
- const filepath = (0, getDictionaryFilepath_1.getDictionaryFilepath)(locale);
17
- const serialized = await fs_1.default.promises.readFile(filepath, 'utf-8');
18
- const trie = trie_1.Trie.deserialize(serialized);
19
- return trie;
25
+ const filepath = (0, getDictionaryFilepath_1.getDictionaryFilepath)(locale, this.directory);
26
+ try {
27
+ const serialized = await fs_1.default.promises.readFile(filepath);
28
+ return gaddag_1.Gaddag.deserialize(new Uint8Array(serialized.buffer, serialized.byteOffset, serialized.byteLength));
29
+ }
30
+ catch (error) {
31
+ logger_1.logger.warn('DiskCache - incompatible or corrupted dictionary file, it will be rebuilt', { error, locale });
32
+ await fs_1.default.promises.rm(filepath, { force: true });
33
+ return undefined;
34
+ }
20
35
  }
21
36
  getLastModifiedTimestamp(locale) {
22
- const filepath = (0, getDictionaryFilepath_1.getDictionaryFilepath)(locale);
37
+ const filepath = (0, getDictionaryFilepath_1.getDictionaryFilepath)(locale, this.directory);
23
38
  if (!fs_1.default.existsSync(filepath)) {
24
39
  return undefined;
25
40
  }
@@ -27,7 +42,7 @@ class DiskCache {
27
42
  return stats.mtimeMs;
28
43
  }
29
44
  has(locale) {
30
- const filepath = (0, getDictionaryFilepath_1.getDictionaryFilepath)(locale);
45
+ const filepath = (0, getDictionaryFilepath_1.getDictionaryFilepath)(locale, this.directory);
31
46
  return fs_1.default.existsSync(filepath);
32
47
  }
33
48
  isStale(locale) {
@@ -41,9 +56,11 @@ class DiskCache {
41
56
  const timeSinceModification = Math.abs(lastModifiedTimestamp - Date.now());
42
57
  return timeSinceModification > constants_1.CACHE_STALE_THRESHOLD;
43
58
  }
44
- async set(locale, trie) {
45
- const filepath = (0, getDictionaryFilepath_1.getDictionaryFilepath)(locale);
46
- await fs_1.default.promises.writeFile(filepath, trie.serialize());
59
+ async set(locale, gaddag) {
60
+ const filepath = (0, getDictionaryFilepath_1.getDictionaryFilepath)(locale, this.directory);
61
+ await fs_1.default.promises.writeFile(filepath, gaddag.serialize());
62
+ // Serialized-trie cache from before the GADDAG migration - remove this in #437
63
+ await fs_1.default.promises.rm((0, getDictionaryFilepath_1.getLegacyDictionaryFilepath)(locale, this.directory), { force: true });
47
64
  }
48
65
  }
49
66
  exports.DiskCache = DiskCache;
@@ -1,12 +1,12 @@
1
- import { type Trie } from '@kamilmielnik/trie';
1
+ import { type Gaddag } from '@kamilmielnik/gaddag';
2
2
  import { type Locale } from '@scrabble-solver/types';
3
3
  import type { Cache } from '../types';
4
- export declare class LayeredCache implements Cache<Locale, Trie> {
4
+ export declare class LayeredCache implements Cache<Locale, Gaddag> {
5
5
  private readonly layers;
6
- get(locale: Locale): Promise<Trie | undefined>;
6
+ get(locale: Locale): Promise<Gaddag | undefined>;
7
7
  getLastModifiedTimestamp(locale: Locale): number | undefined;
8
8
  has(locale: Locale): boolean;
9
9
  isStale(locale: Locale): boolean | undefined;
10
- set(locale: Locale, trie: Trie): Promise<void>;
10
+ set(locale: Locale, gaddag: Gaddag): Promise<void>;
11
11
  private getLastModifiedLayer;
12
12
  }
@@ -39,10 +39,10 @@ class LayeredCache {
39
39
  }
40
40
  return false;
41
41
  }
42
- async set(locale, trie) {
42
+ async set(locale, gaddag) {
43
43
  const [memoryCache, diskCache] = this.layers;
44
- await diskCache.set(locale, trie);
45
- await memoryCache.set(locale, trie);
44
+ await diskCache.set(locale, gaddag);
45
+ await memoryCache.set(locale, gaddag);
46
46
  }
47
47
  getLastModifiedLayer(locale) {
48
48
  const layers = this.layers.filter((cache) => cache.has(locale));
@@ -1,12 +1,12 @@
1
- import { type Trie } from '@kamilmielnik/trie';
1
+ import { type Gaddag } from '@kamilmielnik/gaddag';
2
2
  import { type Locale } from '@scrabble-solver/types';
3
3
  import type { Cache } from '../types';
4
- export declare class MemoryCache implements Cache<Locale, Trie> {
4
+ export declare class MemoryCache implements Cache<Locale, Gaddag> {
5
5
  private readonly cache;
6
6
  private readonly cacheTimestamps;
7
- get(locale: Locale): Promise<Trie | undefined>;
7
+ get(locale: Locale): Promise<Gaddag | undefined>;
8
8
  getLastModifiedTimestamp(locale: Locale): number | undefined;
9
9
  has(locale: Locale): boolean;
10
10
  isStale(locale: Locale): boolean | undefined;
11
- set(locale: Locale, trie: Trie): Promise<void>;
11
+ set(locale: Locale, gaddag: Gaddag): Promise<void>;
12
12
  }
@@ -24,9 +24,9 @@ class MemoryCache {
24
24
  const timeSinceModification = Math.abs(timestamp - Date.now());
25
25
  return timeSinceModification > constants_1.CACHE_STALE_THRESHOLD;
26
26
  }
27
- set(locale, trie) {
27
+ set(locale, gaddag) {
28
28
  this.cacheTimestamps[locale] = Date.now();
29
- this.cache[locale] = trie;
29
+ this.cache[locale] = gaddag;
30
30
  return Promise.resolve();
31
31
  }
32
32
  }
@@ -1,4 +1,4 @@
1
- import { type Trie } from '@kamilmielnik/trie';
1
+ import { type Gaddag } from '@kamilmielnik/gaddag';
2
2
  import { type Locale } from '@scrabble-solver/types';
3
3
  import type { Cache } from '../types';
4
- export declare const createCacheTimestampComparator: (locale: Locale) => (a: Cache<Locale, Trie>, b: Cache<Locale, Trie>) => number;
4
+ export declare const createCacheTimestampComparator: (locale: Locale) => (a: Cache<Locale, Gaddag>, b: Cache<Locale, Gaddag>) => number;
@@ -1,3 +1,3 @@
1
- import { Trie } from '@kamilmielnik/trie';
1
+ import { Gaddag } from '@kamilmielnik/gaddag';
2
2
  import { type Locale } from '@scrabble-solver/types';
3
- export declare const downloadDictionary: (locale: Locale) => Promise<Trie>;
3
+ export declare const downloadDictionary: (locale: Locale) => Promise<Gaddag>;
@@ -1,14 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.downloadDictionary = void 0;
4
- const trie_1 = require("@kamilmielnik/trie");
4
+ const gaddag_1 = require("@kamilmielnik/gaddag");
5
5
  const logger_1 = require("@scrabble-solver/logger");
6
6
  const word_lists_1 = require("@scrabble-solver/word-lists");
7
7
  const downloadDictionary = async (locale) => {
8
8
  logger_1.logger.info('downloadDictionary', { locale });
9
9
  const words = await (0, word_lists_1.getWordList)(locale);
10
10
  logger_1.logger.info('downloadDictionary - success', { locale });
11
- const trie = trie_1.Trie.fromArray(words);
12
- return trie;
11
+ const gaddag = gaddag_1.Gaddag.fromArray(words);
12
+ logger_1.logger.info('downloadDictionary - gaddag built', { locale });
13
+ return gaddag;
13
14
  };
14
15
  exports.downloadDictionary = downloadDictionary;
@@ -1,2 +1,4 @@
1
1
  import { type Locale } from '@scrabble-solver/types';
2
- export declare const getDictionaryFilepath: (locale: Locale) => string;
2
+ export declare const getDictionaryFilepath: (locale: Locale, directory?: string) => string;
3
+ /** Filepath of the serialized-trie cache used before the GADDAG migration. Remove in #437. */
4
+ export declare const getLegacyDictionaryFilepath: (locale: Locale, directory?: string) => string;
@@ -3,10 +3,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getDictionaryFilepath = void 0;
6
+ exports.getLegacyDictionaryFilepath = exports.getDictionaryFilepath = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const constants_1 = require("../constants");
9
- const getDictionaryFilepath = (locale) => {
10
- return path_1.default.resolve(constants_1.OUTPUT_DIRECTORY, `${locale}.txt`);
9
+ const getDictionaryFilepath = (locale, directory = constants_1.OUTPUT_DIRECTORY) => {
10
+ return path_1.default.resolve(directory, `${locale}.gaddag`);
11
11
  };
12
12
  exports.getDictionaryFilepath = getDictionaryFilepath;
13
+ /** Filepath of the serialized-trie cache used before the GADDAG migration. Remove in #437. */
14
+ const getLegacyDictionaryFilepath = (locale, directory = constants_1.OUTPUT_DIRECTORY) => {
15
+ return path_1.default.resolve(directory, `${locale}.txt`);
16
+ };
17
+ exports.getLegacyDictionaryFilepath = getLegacyDictionaryFilepath;