@scrabble-solver/scrabble-solver 2.15.9 → 2.15.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (309) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +9 -9
  3. package/.next/cache/.rscinfo +1 -1
  4. package/.next/cache/.tsbuildinfo +1 -1
  5. package/.next/cache/webpack/client-production/0.pack +0 -0
  6. package/.next/cache/webpack/client-production/index.pack +0 -0
  7. package/.next/cache/webpack/client-production/index.pack.old +0 -0
  8. package/.next/cache/webpack/edge-server-production/0.pack +0 -0
  9. package/.next/cache/webpack/edge-server-production/index.pack +0 -0
  10. package/.next/cache/webpack/edge-server-production/index.pack.old +0 -0
  11. package/.next/cache/webpack/server-production/0.pack +0 -0
  12. package/.next/cache/webpack/server-production/index.pack +0 -0
  13. package/.next/cache/webpack/server-production/index.pack.old +0 -0
  14. package/.next/diagnostics/framework.json +1 -1
  15. package/.next/next-minimal-server.js.nft.json +1 -1
  16. package/.next/next-server.js.nft.json +1 -1
  17. package/.next/prerender-manifest.json +4 -4
  18. package/.next/required-server-files.json +1 -2
  19. package/.next/routes-manifest.json +1 -1
  20. package/.next/server/chunks/60.js +1 -1
  21. package/.next/server/chunks/812.js +1 -1
  22. package/.next/server/chunks/974.js +1 -1
  23. package/.next/server/middleware-build-manifest.js +1 -1
  24. package/.next/server/pages/404.html +1 -1
  25. package/.next/server/pages/404.js.nft.json +1 -1
  26. package/.next/server/pages/500.html +1 -1
  27. package/.next/server/pages/_app.js.nft.json +1 -1
  28. package/.next/server/pages/api/dictionary/[locale]/[word].js +2 -2
  29. package/.next/server/pages/api/dictionary/[locale]/[word].js.nft.json +1 -1
  30. package/.next/server/pages/api/dictionary/[locale].js +1 -1
  31. package/.next/server/pages/api/dictionary/[locale].js.nft.json +1 -1
  32. package/.next/server/pages/api/solve.js +1 -1
  33. package/.next/server/pages/api/solve.js.nft.json +1 -1
  34. package/.next/server/pages/api/verify.js +1 -1
  35. package/.next/server/pages/api/verify.js.nft.json +1 -1
  36. package/.next/server/pages/api/visit.js +1 -1
  37. package/.next/server/pages/index.html +1 -1
  38. package/.next/server/pages/index.js +1 -1
  39. package/.next/server/pages/index.js.nft.json +1 -1
  40. package/.next/server/pages/index.json +1 -1
  41. package/.next/server/webpack-api-runtime.js +1 -1
  42. package/.next/static/chunks/{main-b934e2c3dd3b55b5.js → main-016492249b3393e2.js} +1 -1
  43. package/.next/static/chunks/pages/{404-7451dd58396eaa39.js → 404-590e2a3839c1d9e0.js} +1 -1
  44. package/.next/static/chunks/pages/_app-ac93a74c390f2ab8.js +1 -0
  45. package/.next/static/chunks/pages/index-e5f1caa581e6d3b8.js +1 -0
  46. package/.next/static/{3MlxnccTCLyz9bgD30zY2 → ylO_ttKeJTuoqDYywao5A}/_buildManifest.js +1 -1
  47. package/.next/trace +23 -23
  48. package/next.config.js +3 -0
  49. package/package.json +10 -10
  50. package/src/api/getServerLoggingData.ts +1 -3
  51. package/src/api/index.ts +5 -5
  52. package/src/api/isBoardValid.ts +3 -5
  53. package/src/api/isCellValid.ts +4 -6
  54. package/src/api/isCharacterValid.ts +2 -3
  55. package/src/api/isRowValid.ts +3 -5
  56. package/src/components/Alert/Alert.tsx +1 -3
  57. package/src/components/Alert/index.ts +1 -1
  58. package/src/components/Badge/Badge.tsx +1 -3
  59. package/src/components/Badge/index.ts +1 -1
  60. package/src/components/Board/Board.tsx +2 -4
  61. package/src/components/Board/BoardPure.tsx +2 -2
  62. package/src/components/Board/components/Actions/Actions.tsx +3 -5
  63. package/src/components/Board/components/Actions/index.ts +1 -1
  64. package/src/components/Board/components/Cell/Cell.tsx +3 -5
  65. package/src/components/Board/components/Cell/index.ts +1 -1
  66. package/src/components/Board/components/InputPrompt/InputPrompt.tsx +3 -5
  67. package/src/components/Board/components/InputPrompt/index.ts +1 -1
  68. package/src/components/Board/components/ToggleDirectionButton/ToggleDirectionButton.tsx +2 -4
  69. package/src/components/Board/components/ToggleDirectionButton/index.ts +1 -1
  70. package/src/components/Board/components/index.ts +4 -4
  71. package/src/components/Board/hooks/index.ts +6 -6
  72. package/src/components/Board/hooks/useBackgroundImage.tsx +7 -9
  73. package/src/components/Board/hooks/useBoardStyle.ts +7 -9
  74. package/src/components/Board/hooks/useFloatingActions.ts +1 -3
  75. package/src/components/Board/hooks/useFloatingFocus.ts +1 -3
  76. package/src/components/Board/hooks/useFloatingInputPrompt.ts +1 -3
  77. package/src/components/Board/hooks/useGrid.ts +2 -4
  78. package/src/components/Board/index.ts +1 -1
  79. package/src/components/Board/lib/getBonusColor.ts +1 -3
  80. package/src/components/Board/lib/getPositionInGrid.ts +1 -3
  81. package/src/components/Board/lib/index.ts +2 -2
  82. package/src/components/Button/Button.tsx +3 -3
  83. package/src/components/Button/Link.tsx +1 -3
  84. package/src/components/Button/index.ts +1 -1
  85. package/src/components/Dictionary/Dictionary.tsx +3 -5
  86. package/src/components/Dictionary/index.ts +1 -1
  87. package/src/components/DictionaryInput/DictionaryInput.tsx +1 -3
  88. package/src/components/DictionaryInput/index.ts +1 -1
  89. package/src/components/EmptyState/EmptyState.tsx +2 -4
  90. package/src/components/EmptyState/index.ts +1 -1
  91. package/src/components/IconButton/IconButton.tsx +3 -3
  92. package/src/components/IconButton/Link.tsx +1 -3
  93. package/src/components/IconButton/index.ts +1 -1
  94. package/src/components/Key/Key.tsx +1 -3
  95. package/src/components/Key/index.ts +1 -1
  96. package/src/components/Keys/Arrows/Arrows.tsx +2 -4
  97. package/src/components/Keys/Arrows/index.ts +1 -1
  98. package/src/components/{keys.tsx → Keys/index.tsx} +3 -1
  99. package/src/components/Loading/Loading.tsx +2 -4
  100. package/src/components/Loading/index.ts +1 -1
  101. package/src/components/Logo/Logo.tsx +1 -3
  102. package/src/components/Logo/LogoBlueprint.tsx +2 -4
  103. package/src/components/Logo/index.ts +1 -1
  104. package/src/components/Modal/Modal.tsx +3 -3
  105. package/src/components/Modal/components/Section/Section.tsx +1 -3
  106. package/src/components/Modal/components/Section/index.ts +1 -1
  107. package/src/components/Modal/components/index.ts +1 -1
  108. package/src/components/Modal/index.ts +1 -1
  109. package/src/components/NavButtons/NavButtons.tsx +3 -3
  110. package/src/components/NavButtons/index.ts +1 -1
  111. package/src/components/NotFound/NotFound.tsx +2 -4
  112. package/src/components/NotFound/index.ts +1 -1
  113. package/src/components/PlainTiles/PlainTiles.tsx +10 -4
  114. package/src/components/PlainTiles/Tile.tsx +1 -3
  115. package/src/components/PlainTiles/index.ts +1 -1
  116. package/src/components/PlainTiles/lib/createPlainTile.ts +10 -6
  117. package/src/components/PlainTiles/lib/createPlainTiles.ts +2 -4
  118. package/src/components/PlainTiles/lib/getViewbox.ts +1 -3
  119. package/src/components/PlainTiles/lib/getX.ts +1 -3
  120. package/src/components/PlainTiles/lib/getY.ts +1 -3
  121. package/src/components/PlainTiles/lib/index.ts +6 -6
  122. package/src/components/PlainTiles/lib/randomize.ts +1 -3
  123. package/src/components/Progress/Progress.tsx +1 -3
  124. package/src/components/Progress/index.ts +1 -1
  125. package/src/components/Rack/Rack.tsx +2 -4
  126. package/src/components/Rack/components/InputPrompt/InputPrompt.tsx +2 -2
  127. package/src/components/Rack/components/InputPrompt/index.ts +1 -1
  128. package/src/components/Rack/components/RackTile/RackTile.tsx +4 -7
  129. package/src/components/Rack/components/RackTile/index.ts +1 -1
  130. package/src/components/Rack/components/index.ts +2 -2
  131. package/src/components/Rack/index.ts +1 -1
  132. package/src/components/Radio/Radio.tsx +1 -3
  133. package/src/components/Radio/index.ts +1 -1
  134. package/src/components/Results/Cell.tsx +9 -3
  135. package/src/components/Results/Header.tsx +2 -4
  136. package/src/components/Results/HeaderButton.tsx +1 -3
  137. package/src/components/Results/Result.tsx +2 -4
  138. package/src/components/Results/Results.tsx +7 -9
  139. package/src/components/Results/SolveButton.tsx +2 -4
  140. package/src/components/Results/index.ts +1 -1
  141. package/src/components/ResultsInput/ResultsInput.tsx +1 -3
  142. package/src/components/ResultsInput/index.ts +1 -1
  143. package/src/components/SeoMessage/SeoMessage.tsx +4 -6
  144. package/src/components/SeoMessage/index.ts +1 -1
  145. package/src/components/Solver/Solver.tsx +8 -8
  146. package/src/components/Solver/components/InsertButton/InsertButton.tsx +2 -4
  147. package/src/components/Solver/components/InsertButton/index.ts +1 -1
  148. package/src/components/Solver/components/ResultCandidatePicker/ResultCandidatePicker.tsx +4 -6
  149. package/src/components/Solver/components/ResultCandidatePicker/index.ts +1 -1
  150. package/src/components/Solver/components/index.ts +2 -2
  151. package/src/components/Solver/index.ts +1 -1
  152. package/src/components/Spinner/Spinner.tsx +1 -3
  153. package/src/components/Spinner/index.ts +1 -1
  154. package/src/components/Tile/Tile.tsx +2 -4
  155. package/src/components/Tile/TilePure.tsx +2 -2
  156. package/src/components/Tile/index.ts +1 -1
  157. package/src/components/Tooltip/TooltipTrigger.tsx +5 -3
  158. package/src/components/index.ts +24 -25
  159. package/src/hooks/index.ts +13 -13
  160. package/src/hooks/useAppLayout.ts +19 -15
  161. package/src/hooks/useColumns.ts +2 -4
  162. package/src/hooks/useDirection.ts +1 -3
  163. package/src/hooks/useEffectOnce.ts +2 -4
  164. package/src/hooks/useIsTouchDevice.ts +2 -4
  165. package/src/hooks/useLanguage.ts +1 -3
  166. package/src/hooks/useLatest.ts +1 -3
  167. package/src/hooks/useLocalStorage.ts +1 -3
  168. package/src/hooks/useMedia.ts +1 -3
  169. package/src/hooks/useMediaQueries.ts +2 -4
  170. package/src/hooks/useMediaQuery.ts +2 -4
  171. package/src/hooks/useOnWindowResize.ts +1 -3
  172. package/src/hooks/useViewportSize.ts +2 -4
  173. package/src/i18n/i18n.ts +1 -3
  174. package/src/i18n/index.ts +1 -1
  175. package/src/lib/arrayEquals.ts +1 -3
  176. package/src/lib/createArray.ts +1 -3
  177. package/src/lib/createComparator.ts +3 -5
  178. package/src/lib/createGridOf.ts +2 -4
  179. package/src/lib/createKeyComparator.ts +6 -5
  180. package/src/lib/createKeyboardNavigation.ts +2 -4
  181. package/src/lib/createNullMovingComparator.test.ts +1 -1
  182. package/src/lib/createNullMovingComparator.ts +1 -3
  183. package/src/lib/createRegExp.ts +1 -3
  184. package/src/lib/createStringComparator.ts +5 -3
  185. package/src/lib/detectLocale.ts +1 -3
  186. package/src/lib/extractCharacters.test.ts +1 -1
  187. package/src/lib/extractCharacters.ts +1 -3
  188. package/src/lib/extractCharactersByCase.test.ts +1 -1
  189. package/src/lib/extractCharactersByCase.ts +2 -4
  190. package/src/lib/extractInputValue.ts +1 -3
  191. package/src/lib/findCell.ts +1 -3
  192. package/src/lib/getCellSize.ts +3 -5
  193. package/src/lib/getCoordinate.ts +1 -3
  194. package/src/lib/getCoordinates.ts +2 -4
  195. package/src/lib/getRemainingTiles.ts +8 -5
  196. package/src/lib/getRemainingTilesCount.ts +1 -3
  197. package/src/lib/getRemainingTilesGroups.ts +3 -5
  198. package/src/lib/getTileSizes.ts +1 -3
  199. package/src/lib/getTotalRemainingTilesCount.ts +1 -3
  200. package/src/lib/groupResults.ts +3 -5
  201. package/src/lib/guessLocale.ts +2 -4
  202. package/src/lib/index.ts +39 -39
  203. package/src/lib/inverseDirection.ts +1 -3
  204. package/src/lib/isCtrl.ts +1 -3
  205. package/src/lib/isMac.ts +3 -4
  206. package/src/lib/isRegExp.ts +1 -3
  207. package/src/lib/isStringArray.ts +1 -3
  208. package/src/lib/isUpperCase.ts +1 -3
  209. package/src/lib/memoize.ts +18 -20
  210. package/src/lib/noop.ts +1 -3
  211. package/src/lib/numberComparator.ts +1 -3
  212. package/src/lib/resultMatchesCellFilter.ts +1 -3
  213. package/src/lib/reverseComparator.ts +1 -3
  214. package/src/lib/sortGroupedResults.ts +2 -4
  215. package/src/lib/sortResults.ts +5 -7
  216. package/src/lib/unorderedArraysEqual.ts +2 -4
  217. package/src/lib/zipCharactersAndTiles.ts +1 -3
  218. package/src/modals/DictionaryModal/DictionaryModal.tsx +2 -2
  219. package/src/modals/DictionaryModal/index.ts +1 -1
  220. package/src/modals/KeyMapModal/KeyMapModal.tsx +2 -2
  221. package/src/modals/KeyMapModal/components/Mapping/Mapping.tsx +1 -3
  222. package/src/modals/KeyMapModal/components/Mapping/index.ts +1 -1
  223. package/src/modals/KeyMapModal/components/index.ts +1 -1
  224. package/src/modals/KeyMapModal/index.ts +1 -1
  225. package/src/modals/MenuModal/MenuModal.tsx +2 -2
  226. package/src/modals/MenuModal/index.ts +1 -1
  227. package/src/modals/RemainingTilesModal/RemainingTilesModal.tsx +2 -2
  228. package/src/modals/RemainingTilesModal/components/Character/Character.tsx +1 -3
  229. package/src/modals/RemainingTilesModal/components/Character/index.ts +1 -1
  230. package/src/modals/RemainingTilesModal/components/index.ts +1 -1
  231. package/src/modals/RemainingTilesModal/index.ts +1 -1
  232. package/src/modals/ResultsModal/ResultsModal.tsx +2 -2
  233. package/src/modals/ResultsModal/index.ts +1 -1
  234. package/src/modals/SettingsModal/SettingsModal.tsx +2 -2
  235. package/src/modals/SettingsModal/components/AutoGroupTilesSetting/AutoGroupTilesSetting.tsx +1 -3
  236. package/src/modals/SettingsModal/components/AutoGroupTilesSetting/index.ts +1 -1
  237. package/src/modals/SettingsModal/components/ConfigSetting/ConfigSetting.tsx +4 -10
  238. package/src/modals/SettingsModal/components/ConfigSetting/index.ts +1 -1
  239. package/src/modals/SettingsModal/components/ConfigSetting/lib.ts +19 -0
  240. package/src/modals/SettingsModal/components/InputModeSetting/InputModeSetting.tsx +1 -3
  241. package/src/modals/SettingsModal/components/InputModeSetting/index.ts +1 -1
  242. package/src/modals/SettingsModal/components/LocaleSetting/LocaleSetting.tsx +1 -3
  243. package/src/modals/SettingsModal/components/LocaleSetting/index.ts +1 -1
  244. package/src/modals/SettingsModal/components/ShowCoordinatesSetting/ShowCoordinatesSetting.tsx +1 -3
  245. package/src/modals/SettingsModal/components/ShowCoordinatesSetting/index.ts +1 -1
  246. package/src/modals/SettingsModal/components/index.ts +5 -5
  247. package/src/modals/SettingsModal/index.ts +1 -1
  248. package/src/modals/WordsModal/WordsModal.tsx +2 -2
  249. package/src/modals/WordsModal/index.ts +1 -1
  250. package/src/modals/index.ts +7 -7
  251. package/src/pages/_app.tsx +2 -1
  252. package/src/pages/api/dictionary/[locale]/[word].ts +1 -1
  253. package/src/pages/api/dictionary/[locale]/index.ts +1 -1
  254. package/src/pages/api/solve.ts +6 -4
  255. package/src/pages/api/verify.ts +6 -4
  256. package/src/pages/api/visit.ts +2 -2
  257. package/src/pages/index.tsx +7 -0
  258. package/src/sdk/fetch.ts +1 -3
  259. package/src/sdk/fetchJson.ts +2 -4
  260. package/src/sdk/findWordDefinitions.ts +2 -4
  261. package/src/sdk/getDictionary.ts +2 -4
  262. package/src/sdk/index.ts +4 -4
  263. package/src/sdk/solve.ts +2 -4
  264. package/src/sdk/verify.ts +2 -4
  265. package/src/sdk/visit.ts +1 -3
  266. package/src/service-worker/average.ts +1 -3
  267. package/src/service-worker/dictionaries/expirationManager.ts +1 -3
  268. package/src/service-worker/dictionaries/getDictionary.ts +3 -5
  269. package/src/service-worker/dictionaries/getDictionaryUrl.ts +1 -3
  270. package/src/service-worker/dictionaries/index.ts +2 -2
  271. package/src/service-worker/dictionaries/revalidateDictionary.ts +3 -5
  272. package/src/service-worker/getTrie.ts +1 -3
  273. package/src/service-worker/index.ts +4 -2
  274. package/src/service-worker/routeSolveRequests.ts +17 -11
  275. package/src/service-worker/routeVerifyRequests.ts +7 -5
  276. package/src/serviceWorkerManager.ts +4 -4
  277. package/src/state/index.ts +4 -4
  278. package/src/state/localStorage.ts +10 -12
  279. package/src/state/sagas.ts +4 -1
  280. package/src/state/selectors.ts +2 -5
  281. package/src/state/slices/boardInitialState.ts +6 -7
  282. package/src/state/slices/boardSlice.ts +5 -7
  283. package/src/state/slices/cellFilterInitialState.ts +1 -3
  284. package/src/state/slices/cellFilterSlice.ts +2 -4
  285. package/src/state/slices/dictionaryInitialState.ts +2 -4
  286. package/src/state/slices/dictionarySlice.ts +2 -4
  287. package/src/state/slices/index.ts +16 -16
  288. package/src/state/slices/rackInitialState.ts +2 -4
  289. package/src/state/slices/rackSlice.ts +2 -4
  290. package/src/state/slices/resultsInitialState.ts +1 -3
  291. package/src/state/slices/resultsSlice.ts +2 -4
  292. package/src/state/slices/settingsInitialState.ts +2 -4
  293. package/src/state/slices/settingsSlice.ts +2 -4
  294. package/src/state/slices/solveInitialState.ts +3 -5
  295. package/src/state/slices/solveSlice.ts +2 -4
  296. package/src/state/slices/verifyInitialState.ts +2 -4
  297. package/src/state/slices/verifySlice.ts +2 -4
  298. package/src/state/store.ts +1 -3
  299. package/src/state/useTranslate.ts +2 -4
  300. package/src/state/useTypedSelector.ts +1 -3
  301. package/src/types/api.ts +15 -0
  302. package/src/types/index.ts +2 -0
  303. package/tsconfig.json +1 -1
  304. package/.next/cache/eslint/.cache_8dgz12 +0 -1
  305. package/.next/static/chunks/pages/_app-735105409cfdb48f.js +0 -1
  306. package/.next/static/chunks/pages/index-d492616d9bc42176.js +0 -1
  307. package/src/components/Keys/index.ts +0 -1
  308. package/tsconfig.jest.json +0 -7
  309. /package/.next/static/{3MlxnccTCLyz9bgD30zY2 → ylO_ttKeJTuoqDYywao5A}/_ssgManifest.js +0 -0
@@ -1,9 +1,9 @@
1
1
  import { getConfig, hasConfig } from '@scrabble-solver/configs';
2
2
  import { BLANK } from '@scrabble-solver/constants';
3
3
  import { dictionaries } from '@scrabble-solver/dictionaries';
4
- import logger from '@scrabble-solver/logger';
4
+ import { logger } from '@scrabble-solver/logger';
5
5
  import { solve as solveScrabble } from '@scrabble-solver/solver';
6
- import { Board, Config, Locale, Tile, isBoardJson, isGame, isLocale } from '@scrabble-solver/types';
6
+ import { Board, Config, Game, Locale, Tile, isBoardJson, isGame, isLocale } from '@scrabble-solver/types';
7
7
  import { NextApiRequest, NextApiResponse } from 'next';
8
8
 
9
9
  import { getServerLoggingData, isBoardValid, isCharacterValid } from 'api';
@@ -13,6 +13,7 @@ interface RequestData {
13
13
  board: Board;
14
14
  characters: string[];
15
15
  config: Config;
16
+ game: Game;
16
17
  locale: Locale;
17
18
  }
18
19
 
@@ -20,7 +21,7 @@ const solve = async (request: NextApiRequest, response: NextApiResponse): Promis
20
21
  const meta = getServerLoggingData(request);
21
22
 
22
23
  try {
23
- const { board, characters, config, locale } = parseRequest(request);
24
+ const { board, characters, config, game, locale } = parseRequest(request);
24
25
 
25
26
  logger.info('solve - request', {
26
27
  meta,
@@ -30,7 +31,7 @@ const solve = async (request: NextApiRequest, response: NextApiResponse): Promis
30
31
  boardBlanksCount: board.getBlanksCount(),
31
32
  boardTilesCount: board.getTilesCount(),
32
33
  characters: characters.join(''),
33
- game: request.body.game,
34
+ game,
34
35
  locale,
35
36
  },
36
37
  });
@@ -89,6 +90,7 @@ const parseRequest = (request: NextApiRequest): RequestData => {
89
90
  board,
90
91
  characters,
91
92
  config,
93
+ game,
92
94
  locale,
93
95
  };
94
96
  };
@@ -1,7 +1,7 @@
1
1
  import { getConfig, hasConfig } from '@scrabble-solver/configs';
2
2
  import { dictionaries } from '@scrabble-solver/dictionaries';
3
- import logger from '@scrabble-solver/logger';
4
- import { Board, Config, Locale, isBoardJson, isGame, isLocale } from '@scrabble-solver/types';
3
+ import { logger } from '@scrabble-solver/logger';
4
+ import { Board, Config, Game, Locale, isBoardJson, isGame, isLocale } from '@scrabble-solver/types';
5
5
  import { NextApiRequest, NextApiResponse } from 'next';
6
6
 
7
7
  import { getServerLoggingData, isBoardValid } from 'api';
@@ -9,6 +9,7 @@ import { getServerLoggingData, isBoardValid } from 'api';
9
9
  interface RequestData {
10
10
  board: Board;
11
11
  config: Config;
12
+ game: Game;
12
13
  locale: Locale;
13
14
  }
14
15
 
@@ -16,7 +17,7 @@ const verify = async (request: NextApiRequest, response: NextApiResponse): Promi
16
17
  const meta = getServerLoggingData(request);
17
18
 
18
19
  try {
19
- const { board, locale } = parseRequest(request);
20
+ const { board, game, locale } = parseRequest(request);
20
21
 
21
22
  logger.info('verify - request', {
22
23
  meta,
@@ -24,7 +25,7 @@ const verify = async (request: NextApiRequest, response: NextApiResponse): Promi
24
25
  board: board.toString(),
25
26
  boardBlanksCount: board.getBlanksCount(),
26
27
  boardTilesCount: board.getTilesCount(),
27
- game: request.body.game,
28
+ game,
28
29
  locale,
29
30
  },
30
31
  });
@@ -67,6 +68,7 @@ const parseRequest = (request: NextApiRequest): RequestData => {
67
68
  return {
68
69
  board,
69
70
  config,
71
+ game,
70
72
  locale,
71
73
  };
72
74
  };
@@ -1,9 +1,9 @@
1
- import logger from '@scrabble-solver/logger';
1
+ import { logger } from '@scrabble-solver/logger';
2
2
  import { NextApiRequest, NextApiResponse } from 'next';
3
3
 
4
4
  import { getServerLoggingData } from 'api';
5
5
 
6
- const visit = async (request: NextApiRequest, response: NextApiResponse): Promise<void> => {
6
+ const visit = (request: NextApiRequest, response: NextApiResponse): void => {
7
7
  const meta = getServerLoggingData(request);
8
8
 
9
9
  try {
@@ -1,3 +1,4 @@
1
+ import { isObject } from '@scrabble-solver/types';
1
2
  import fs from 'fs';
2
3
  import path from 'path';
3
4
  import { FunctionComponent, useCallback, useState } from 'react';
@@ -62,6 +63,7 @@ const Index: FunctionComponent<Props> = ({ version }) => {
62
63
 
63
64
  useEffectOnce(() => {
64
65
  if (process.env.NODE_ENV === 'production') {
66
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
65
67
  registerServiceWorker();
66
68
  }
67
69
 
@@ -129,6 +131,11 @@ const readVersion = async (): Promise<string> => {
129
131
  const packageJsonFilepath = path.resolve(process.cwd(), 'package.json');
130
132
  const data = await fs.promises.readFile(packageJsonFilepath, 'utf-8');
131
133
  const packageJson = JSON.parse(data);
134
+
135
+ if (!isObject(packageJson) || !('version' in packageJson) || typeof packageJson.version !== 'string') {
136
+ throw new Error('Invalid package.json');
137
+ }
138
+
132
139
  return `v${packageJson.version}`;
133
140
  };
134
141
 
package/src/sdk/fetch.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { isError } from '@scrabble-solver/types';
2
2
 
3
- const fetch = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {
3
+ export const fetch = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {
4
4
  let response: Response;
5
5
 
6
6
  try {
@@ -26,5 +26,3 @@ const fetch = async (input: RequestInfo | URL, init?: RequestInit): Promise<Resp
26
26
 
27
27
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
28
28
  };
29
-
30
- export default fetch;
@@ -1,6 +1,6 @@
1
- import fetch from './fetch';
1
+ import { fetch } from './fetch';
2
2
 
3
- const fetchJson = async <T>(input: RequestInfo | URL, init?: RequestInit): Promise<T> => {
3
+ export const fetchJson = async <T>(input: RequestInfo | URL, init?: RequestInit): Promise<T> => {
4
4
  const response = await fetch(input, {
5
5
  ...init,
6
6
  headers: {
@@ -11,5 +11,3 @@ const fetchJson = async <T>(input: RequestInfo | URL, init?: RequestInit): Promi
11
11
 
12
12
  return response.json();
13
13
  };
14
-
15
- export default fetchJson;
@@ -1,10 +1,8 @@
1
1
  import { Locale, WordDefinition, WordDefinitionJson } from '@scrabble-solver/types';
2
2
 
3
- import fetchJson from './fetchJson';
3
+ import { fetchJson } from './fetchJson';
4
4
 
5
- const findWordDefinitions = async (locale: Locale, word: string): Promise<WordDefinition[]> => {
5
+ export const findWordDefinitions = async (locale: Locale, word: string): Promise<WordDefinition[]> => {
6
6
  const json = await fetchJson<WordDefinitionJson[]>(`/api/dictionary/${locale}/${encodeURIComponent(word)}`);
7
7
  return json.map(WordDefinition.fromJson);
8
8
  };
9
-
10
- export default findWordDefinitions;
@@ -1,11 +1,9 @@
1
1
  import { Trie } from '@kamilmielnik/trie';
2
2
  import { Locale } from '@scrabble-solver/types';
3
3
 
4
- import fetchJson from './fetchJson';
4
+ import { fetchJson } from './fetchJson';
5
5
 
6
- const getDictionary = async (locale: Locale): Promise<Trie> => {
6
+ export const getDictionary = async (locale: Locale): Promise<Trie> => {
7
7
  const serialized = await fetchJson<string>(`/api/dictionary/${locale}`);
8
8
  return Trie.deserialize(serialized);
9
9
  };
10
-
11
- export default getDictionary;
package/src/sdk/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { default as findWordDefinitions } from './findWordDefinitions';
2
- export { default as solve } from './solve';
3
- export { default as verify } from './verify';
4
- export { default as visit } from './visit';
1
+ export { findWordDefinitions } from './findWordDefinitions';
2
+ export { solve } from './solve';
3
+ export { verify } from './verify';
4
+ export { visit } from './visit';
package/src/sdk/solve.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { BoardJson, Locale, Result, ResultJson } from '@scrabble-solver/types';
2
2
 
3
- import fetchJson from './fetchJson';
3
+ import { fetchJson } from './fetchJson';
4
4
 
5
5
  interface Payload {
6
6
  board: BoardJson;
@@ -9,7 +9,7 @@ interface Payload {
9
9
  locale: Locale;
10
10
  }
11
11
 
12
- const solve = async ({ board, characters, game, locale }: Payload): Promise<Result[]> => {
12
+ export const solve = async ({ board, characters, game, locale }: Payload): Promise<Result[]> => {
13
13
  const json = await fetchJson<ResultJson[]>('/api/solve', {
14
14
  method: 'POST',
15
15
  body: JSON.stringify({ board, characters, game, locale }),
@@ -17,5 +17,3 @@ const solve = async ({ board, characters, game, locale }: Payload): Promise<Resu
17
17
 
18
18
  return json.map(Result.fromJson);
19
19
  };
20
-
21
- export default solve;
package/src/sdk/verify.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { BoardJson, Locale } from '@scrabble-solver/types';
2
2
 
3
- import fetchJson from './fetchJson';
3
+ import { fetchJson } from './fetchJson';
4
4
 
5
5
  interface Payload {
6
6
  board: BoardJson;
@@ -13,11 +13,9 @@ interface Response {
13
13
  validWords: string[];
14
14
  }
15
15
 
16
- const verify = async ({ board, game, locale }: Payload): Promise<Response> => {
16
+ export const verify = async ({ board, game, locale }: Payload): Promise<Response> => {
17
17
  return fetchJson<Response>('/api/verify', {
18
18
  method: 'POST',
19
19
  body: JSON.stringify({ board, game, locale }),
20
20
  });
21
21
  };
22
-
23
- export default verify;
package/src/sdk/visit.ts CHANGED
@@ -1,7 +1,5 @@
1
- const visit = (): Promise<Response> => {
1
+ export const visit = (): Promise<Response> => {
2
2
  return fetch('/api/visit', {
3
3
  method: 'PUT',
4
4
  });
5
5
  };
6
-
7
- export default visit;
@@ -1,9 +1,7 @@
1
- const average = (numbers: number[]): number => {
1
+ export const average = (numbers: number[]): number => {
2
2
  if (numbers.length === 0) {
3
3
  return 0;
4
4
  }
5
5
 
6
6
  return numbers.reduce((sum, value) => sum + value, 0) / numbers.length;
7
7
  };
8
-
9
- export default average;
@@ -2,8 +2,6 @@ import { CacheExpiration } from 'workbox-expiration';
2
2
 
3
3
  import { DICTIONARY_CACHE, DICTIONARY_CACHE_MAX_AGE } from './constants';
4
4
 
5
- const expirationManager = new CacheExpiration(DICTIONARY_CACHE, {
5
+ export const expirationManager = new CacheExpiration(DICTIONARY_CACHE, {
6
6
  maxAgeSeconds: DICTIONARY_CACHE_MAX_AGE / 1000,
7
7
  });
8
-
9
- export default expirationManager;
@@ -1,10 +1,10 @@
1
1
  import { Locale } from '@scrabble-solver/types';
2
2
 
3
3
  import { DICTIONARY_CACHE } from './constants';
4
- import expirationManager from './expirationManager';
5
- import getDictionaryUrl from './getDictionaryUrl';
4
+ import { expirationManager } from './expirationManager';
5
+ import { getDictionaryUrl } from './getDictionaryUrl';
6
6
 
7
- const getDictionary = async (locale: Locale): Promise<string | undefined> => {
7
+ export const getDictionary = async (locale: Locale): Promise<string | undefined> => {
8
8
  await expirationManager.expireEntries();
9
9
 
10
10
  const url = getDictionaryUrl(locale);
@@ -18,5 +18,3 @@ const getDictionary = async (locale: Locale): Promise<string | undefined> => {
18
18
  const serialized = await cached.clone().text();
19
19
  return serialized;
20
20
  };
21
-
22
- export default getDictionary;
@@ -1,7 +1,5 @@
1
1
  import { Locale } from '@scrabble-solver/types';
2
2
 
3
- const getDictionaryUrl = (locale: Locale): string => {
3
+ export const getDictionaryUrl = (locale: Locale): string => {
4
4
  return `/api/dictionary/${locale}`;
5
5
  };
6
-
7
- export default getDictionaryUrl;
@@ -1,2 +1,2 @@
1
- export { default as getDictionary } from './getDictionary';
2
- export { default as revalidateDictionary } from './revalidateDictionary';
1
+ export { getDictionary } from './getDictionary';
2
+ export { revalidateDictionary } from './revalidateDictionary';
@@ -1,12 +1,12 @@
1
1
  import { Locale } from '@scrabble-solver/types';
2
2
 
3
3
  import { DICTIONARY_CACHE } from './constants';
4
- import expirationManager from './expirationManager';
5
- import getDictionaryUrl from './getDictionaryUrl';
4
+ import { expirationManager } from './expirationManager';
5
+ import { getDictionaryUrl } from './getDictionaryUrl';
6
6
 
7
7
  const requests: Partial<Record<Locale, Promise<Response> | undefined>> = {};
8
8
 
9
- const revalidateDictionary = async (locale: Locale): Promise<void> => {
9
+ export const revalidateDictionary = async (locale: Locale): Promise<void> => {
10
10
  if (requests[locale] instanceof Promise) {
11
11
  return;
12
12
  }
@@ -31,5 +31,3 @@ const revalidateDictionary = async (locale: Locale): Promise<void> => {
31
31
  requests[locale] = undefined;
32
32
  }
33
33
  };
34
-
35
- export default revalidateDictionary;
@@ -5,7 +5,7 @@ import { getDictionary } from './dictionaries';
5
5
 
6
6
  const cache: Partial<Record<Locale, { trie: Trie; dictionary: string } | undefined>> = {};
7
7
 
8
- const getTrie = async (locale: Locale): Promise<Trie | undefined> => {
8
+ export const getTrie = async (locale: Locale): Promise<Trie | undefined> => {
9
9
  const dictionary = await getDictionary(locale);
10
10
 
11
11
  if (typeof dictionary === 'undefined') {
@@ -22,5 +22,3 @@ const getTrie = async (locale: Locale): Promise<Trie | undefined> => {
22
22
 
23
23
  return cached.trie;
24
24
  };
25
-
26
- export default getTrie;
@@ -2,16 +2,18 @@
2
2
 
3
3
  import { cleanupOutdatedCaches, precacheAndRoute } from 'workbox-precaching';
4
4
 
5
- import routeSolveRequests from './routeSolveRequests';
6
- import routeVerifyRequests from './routeVerifyRequests';
5
+ import { routeSolveRequests } from './routeSolveRequests';
6
+ import { routeVerifyRequests } from './routeVerifyRequests';
7
7
 
8
8
  declare const self: ServiceWorkerGlobalScope;
9
9
 
10
10
  self.addEventListener('install', () => {
11
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
11
12
  self.skipWaiting();
12
13
  });
13
14
 
14
15
  self.addEventListener('activate', () => {
16
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
15
17
  self.clients.claim();
16
18
  });
17
19
 
@@ -5,9 +5,11 @@ import { solve } from '@scrabble-solver/solver';
5
5
  import { Board, Tile } from '@scrabble-solver/types';
6
6
  import { registerRoute } from 'workbox-routing';
7
7
 
8
- import average from './average';
8
+ import { SolveRequestPayload } from 'types';
9
+
10
+ import { average } from './average';
9
11
  import { revalidateDictionary } from './dictionaries';
10
- import getTrie from './getTrie';
12
+ import { getTrie } from './getTrie';
11
13
 
12
14
  const headers = {
13
15
  'Content-Type': 'application/json; charset=utf-8',
@@ -29,18 +31,22 @@ const isSlowDevice = (): boolean | undefined => {
29
31
  return average(local) > average(server);
30
32
  };
31
33
 
32
- const routeSolveRequests = () => {
34
+ export const routeSolveRequests = () => {
33
35
  registerRoute(
34
36
  ({ url }) => url.origin === location.origin && url.pathname === '/api/solve',
35
37
  async ({ request }) => {
36
- const { board, characters, game, locale } = await request.clone().json();
38
+ const requestJson: SolveRequestPayload = await request.clone().json();
39
+ const { board, characters, game, locale } = requestJson;
37
40
 
38
- const solveLocal = async (trie: Trie) => {
41
+ const solveLocal = async (trie: Trie): Promise<Response> => {
39
42
  const config = getConfig(game, locale);
40
43
  const tiles = characters.map((character: string) => new Tile({ character, isBlank: character === BLANK }));
41
- const resultsJson = solve(trie, config, Board.fromJson(board), tiles);
42
- const json = JSON.stringify(resultsJson);
43
- return new Response(json, { headers });
44
+
45
+ return new Promise((resolve) => {
46
+ const resultsJson = solve(trie, config, Board.fromJson(board), tiles);
47
+ const responseJson = JSON.stringify(resultsJson);
48
+ resolve(new Response(responseJson, { headers }));
49
+ });
44
50
  };
45
51
 
46
52
  const solveServer = () => fetch(request);
@@ -51,7 +57,7 @@ const routeSolveRequests = () => {
51
57
  const response = await Promise.race([
52
58
  (async () => {
53
59
  const start = Date.now();
54
- const result = await solveLocal(trie);
60
+ const result = solveLocal(trie);
55
61
  localDurations.push(Date.now() - start);
56
62
  return result;
57
63
  })(),
@@ -63,17 +69,17 @@ const routeSolveRequests = () => {
63
69
  })(),
64
70
  ]);
65
71
 
72
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
66
73
  revalidateDictionary(locale);
67
74
  return response;
68
75
  }
69
76
 
70
77
  const handleSolve = trie && !isSlowDevice() ? () => solveLocal(trie) : () => solveServer();
71
78
  const response = await handleSolve();
79
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
72
80
  revalidateDictionary(locale);
73
81
  return response;
74
82
  },
75
83
  'POST',
76
84
  );
77
85
  };
78
-
79
- export default routeSolveRequests;
@@ -1,22 +1,26 @@
1
1
  import { Board } from '@scrabble-solver/types';
2
2
  import { registerRoute } from 'workbox-routing';
3
3
 
4
+ import { VerifyRequestPayload } from 'types';
5
+
4
6
  import { revalidateDictionary } from './dictionaries';
5
- import getTrie from './getTrie';
7
+ import { getTrie } from './getTrie';
6
8
 
7
9
  const headers = {
8
10
  'Content-Type': 'application/json; charset=utf-8',
9
11
  };
10
12
 
11
- const routeVerifyRequests = () => {
13
+ export const routeVerifyRequests = () => {
12
14
  registerRoute(
13
15
  ({ url }) => url.origin === location.origin && url.pathname === '/api/verify',
14
16
  async ({ request }) => {
15
- const { board: boardJson, locale } = await request.clone().json();
17
+ const requestJson: VerifyRequestPayload = await request.clone().json();
18
+ const { board: boardJson, locale } = requestJson;
16
19
  const trie = await getTrie(locale);
17
20
 
18
21
  if (!trie) {
19
22
  const response = await fetch(request);
23
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
20
24
  revalidateDictionary(locale);
21
25
  return response;
22
26
  }
@@ -31,5 +35,3 @@ const routeVerifyRequests = () => {
31
35
  'POST',
32
36
  );
33
37
  };
34
-
35
- export default routeVerifyRequests;
@@ -2,16 +2,16 @@ import { Workbox } from 'workbox-window';
2
2
 
3
3
  let serviceWorker: Workbox | null = null;
4
4
 
5
- export const registerServiceWorker = () => {
5
+ export const registerServiceWorker = async () => {
6
6
  if (!globalThis.navigator || !('serviceWorker' in globalThis.navigator)) {
7
7
  return;
8
8
  }
9
9
 
10
10
  serviceWorker = new Workbox('/service-worker.js');
11
- serviceWorker.register({ immediate: true });
11
+ await serviceWorker.register({ immediate: true });
12
12
  };
13
13
 
14
- export const getServiceWorker = (): Workbox | null => {
14
+ export const getServiceWorker = async (): Promise<Workbox | null> => {
15
15
  if (process.env.NODE_ENV !== 'production') {
16
16
  return null;
17
17
  }
@@ -20,7 +20,7 @@ export const getServiceWorker = (): Workbox | null => {
20
20
  return serviceWorker;
21
21
  }
22
22
 
23
- registerServiceWorker();
23
+ await registerServiceWorker();
24
24
 
25
25
  return serviceWorker;
26
26
  };
@@ -1,7 +1,7 @@
1
1
  export * from './actions';
2
- export { default as localStorage } from './localStorage';
2
+ export { localStorage } from './localStorage';
3
3
  export * from './selectors';
4
4
  export * from './slices';
5
- export { default as store } from './store';
6
- export { default as useTranslate } from './useTranslate';
7
- export { default as useTypedSelector } from './useTypedSelector';
5
+ export { store } from './store';
6
+ export { useTranslate } from './useTranslate';
7
+ export { useTypedSelector } from './useTypedSelector';
@@ -1,4 +1,4 @@
1
- import { Board, Game, Locale, ShowCoordinates } from '@scrabble-solver/types';
1
+ import { Board, BoardJson, Game, Locale, ShowCoordinates } from '@scrabble-solver/types';
2
2
  import store2 from 'store2';
3
3
 
4
4
  import { AutoGroupTiles, InputMode, Rack } from 'types';
@@ -13,9 +13,9 @@ const SHOW_COORDINATES = 'show-coordinates';
13
13
 
14
14
  const store = store2.namespace('scrabble-solver');
15
15
 
16
- const localStorage = {
16
+ export const localStorage = {
17
17
  getAutoGroupTiles(): AutoGroupTiles | undefined {
18
- return store.get(AUTO_GROUP_TILES);
18
+ return store.get(AUTO_GROUP_TILES) as AutoGroupTiles | undefined;
19
19
  },
20
20
 
21
21
  setAutoGroupTiles(autoGroupTiles: AutoGroupTiles | undefined): void {
@@ -23,8 +23,8 @@ const localStorage = {
23
23
  },
24
24
 
25
25
  getBoard(): Board | undefined {
26
- const serialized = store.get(BOARD);
27
- return serialized ? Board.fromJson(JSON.parse(serialized)) : serialized;
26
+ const serialized = store.get(BOARD) as string | undefined;
27
+ return serialized ? Board.fromJson(JSON.parse(serialized) as BoardJson) : undefined;
28
28
  },
29
29
 
30
30
  setBoard(board: Board | undefined): void {
@@ -33,7 +33,7 @@ const localStorage = {
33
33
  },
34
34
 
35
35
  getGame(): Game | undefined {
36
- return store.get(GAME_ID);
36
+ return store.get(GAME_ID) as Game | undefined;
37
37
  },
38
38
 
39
39
  setGame(game: Game | undefined): void {
@@ -41,7 +41,7 @@ const localStorage = {
41
41
  },
42
42
 
43
43
  getInputMode(): InputMode | undefined {
44
- return store.get(INPUT_MODE);
44
+ return store.get(INPUT_MODE) as InputMode | undefined;
45
45
  },
46
46
 
47
47
  setInputMode(inputMode: InputMode | undefined): void {
@@ -49,7 +49,7 @@ const localStorage = {
49
49
  },
50
50
 
51
51
  getLocale(): Locale | undefined {
52
- return store.get(LOCALE);
52
+ return store.get(LOCALE) as Locale | undefined;
53
53
  },
54
54
 
55
55
  setLocale(locale: Locale | undefined): void {
@@ -57,7 +57,7 @@ const localStorage = {
57
57
  },
58
58
 
59
59
  getRack(): Rack | undefined {
60
- return store.get(RACK);
60
+ return store.get(RACK) as Rack | undefined;
61
61
  },
62
62
 
63
63
  setRack(rack: Rack | undefined): void {
@@ -65,12 +65,10 @@ const localStorage = {
65
65
  },
66
66
 
67
67
  getShowCoordinates(): ShowCoordinates | undefined {
68
- return store.get(SHOW_COORDINATES);
68
+ return store.get(SHOW_COORDINATES) as ShowCoordinates | undefined;
69
69
  },
70
70
 
71
71
  setShowCoordinates(showCoordinates: ShowCoordinates | undefined): void {
72
72
  store.set(SHOW_COORDINATES, showCoordinates, true);
73
73
  },
74
74
  };
75
-
76
- export default localStorage;
@@ -1,4 +1,7 @@
1
1
  /* eslint-disable max-lines, no-implicit-globals */
2
+ /* eslint-disable @typescript-eslint/no-unsafe-argument */
3
+ /* eslint-disable @typescript-eslint/no-unsafe-call */
4
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
2
5
 
3
6
  import { PayloadAction } from '@reduxjs/toolkit';
4
7
  import { hasConfig, languages } from '@scrabble-solver/configs';
@@ -131,7 +134,7 @@ function* onInitialize(): AnyGenerator {
131
134
  function* onReset(): AnyGenerator {
132
135
  const config = yield select(selectConfig);
133
136
 
134
- yield put(boardSlice.actions.init(Board.create(config.boardSize)));
137
+ yield put(boardSlice.actions.init(Board.create(config.boardWidth, config.boardHeight)));
135
138
  yield put(cellFilterSlice.actions.reset());
136
139
  yield put(dictionarySlice.actions.reset());
137
140
  yield put(rackSlice.actions.reset());
@@ -5,7 +5,7 @@ import { getConfig } from '@scrabble-solver/configs';
5
5
  import { BLANK } from '@scrabble-solver/constants';
6
6
  import { Cell, Config, isError, Tile } from '@scrabble-solver/types';
7
7
 
8
- import i18n, { LOCALE_FEATURES } from 'i18n';
8
+ import { i18n, LOCALE_FEATURES } from 'i18n';
9
9
  import {
10
10
  createRegExp,
11
11
  findCell,
@@ -185,10 +185,7 @@ export const selectTranslation = createSelector(
185
185
 
186
186
  export const selectRack = selectRackRoot;
187
187
 
188
- export const selectCharacters = createSelector(
189
- selectRackRoot,
190
- (rack): string[] => rack.filter((tile) => tile !== null) as string[],
191
- );
188
+ export const selectCharacters = createSelector(selectRackRoot, (rack) => rack.filter((tile) => tile !== null));
192
189
 
193
190
  export const selectLastSolvedParameters = createSelector([selectSolveRoot], (solve) => solve.lastSolvedParameters);
194
191