scrabble-solver 2.18.0 → 2.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/.nx/workspace-data/d/server-process.json +2 -2
  2. package/.nx/workspace-data/file-map.json +1481 -1485
  3. package/.nx/workspace-data/lockfile-dependencies.hash +1 -1
  4. package/.nx/workspace-data/lockfile-nodes.hash +1 -1
  5. package/.nx/workspace-data/nx_files.nxt +0 -0
  6. package/.nx/workspace-data/project-graph.json +71 -28
  7. package/.nx/workspace-data/source-maps.json +172 -0
  8. package/CLAUDE.md +1 -1
  9. package/bun.lock +29 -29
  10. package/e2e/app.spec.ts +1 -1
  11. package/e2e/features/solver-paths.spec.ts +2 -2
  12. package/lerna.json +1 -1
  13. package/package.json +18 -37
  14. package/packages/configs/package.json +13 -4
  15. package/packages/constants/package.json +6 -2
  16. package/packages/dictionaries/package.json +12 -5
  17. package/packages/logger/package.json +7 -2
  18. package/packages/scrabble-solver/.next/BUILD_ID +1 -1
  19. package/packages/scrabble-solver/.next/build-manifest.json +10 -10
  20. package/packages/scrabble-solver/.next/cache/.previewinfo +1 -1
  21. package/packages/scrabble-solver/.next/cache/.rscinfo +1 -1
  22. package/packages/scrabble-solver/.next/cache/.tsbuildinfo +1 -1
  23. package/packages/scrabble-solver/.next/cache/webpack/client-production/0.pack +0 -0
  24. package/packages/scrabble-solver/.next/cache/webpack/client-production/index.pack +0 -0
  25. package/packages/scrabble-solver/.next/cache/webpack/client-production/index.pack.old +0 -0
  26. package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/index.pack +0 -0
  27. package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/index.pack.old +0 -0
  28. package/packages/scrabble-solver/.next/cache/webpack/server-production/0.pack +0 -0
  29. package/packages/scrabble-solver/.next/cache/webpack/server-production/index.pack +0 -0
  30. package/packages/scrabble-solver/.next/cache/webpack/server-production/index.pack.old +0 -0
  31. package/packages/scrabble-solver/.next/prerender-manifest.json +4 -4
  32. package/packages/scrabble-solver/.next/routes-manifest.json +1 -1
  33. package/packages/scrabble-solver/.next/server/chunks/712.js +1 -1
  34. package/packages/scrabble-solver/.next/server/middleware-build-manifest.js +1 -1
  35. package/packages/scrabble-solver/.next/server/pages/404.html +3 -2
  36. package/packages/scrabble-solver/.next/server/pages/500.html +3 -2
  37. package/packages/scrabble-solver/.next/server/pages/_document.js +1 -1
  38. package/packages/scrabble-solver/.next/server/pages/_error.js +2 -2
  39. package/packages/scrabble-solver/.next/server/pages/index.html +3 -2
  40. package/packages/scrabble-solver/.next/server/pages/index.js +3 -3
  41. package/packages/scrabble-solver/.next/server/pages/index.json +1 -1
  42. package/packages/scrabble-solver/.next/server/pages/not-found.html +3 -2
  43. package/packages/scrabble-solver/.next/server/pages-manifest.json +1 -1
  44. package/packages/scrabble-solver/.next/static/{FL82obwzFHRzvV6z76I-U → 5KOWzYqfY1Z2rjrzptr8D}/_buildManifest.js +1 -1
  45. package/packages/scrabble-solver/.next/static/chunks/pages/_app-2e607dcd4135f340.js +1 -0
  46. package/packages/scrabble-solver/.next/static/chunks/pages/index-e0087247c995328d.js +1 -0
  47. package/packages/scrabble-solver/.next/static/chunks/pages/not-found-a59f9deeeff63d17.js +1 -0
  48. package/packages/scrabble-solver/.next/static/chunks/{webpack-e34c3ae12275e978.js → webpack-cfb34d175e081981.js} +1 -1
  49. package/packages/scrabble-solver/.next/static/css/{abc2425d3ba607bc.css → 4dbcacc1122ac6b9.css} +1 -0
  50. package/packages/scrabble-solver/.next/trace +21 -21
  51. package/packages/scrabble-solver/.next/trace-build +1 -1
  52. package/packages/scrabble-solver/package.json +17 -10
  53. package/packages/scrabble-solver/public/robots.txt +1 -0
  54. package/packages/scrabble-solver/public/service-worker.js +1 -1
  55. package/packages/scrabble-solver/public/site.webmanifest +14 -0
  56. package/packages/scrabble-solver/src/lib/waitForIdleOrFirstIntent.ts +19 -8
  57. package/packages/scrabble-solver/src/pages/_app.tsx +40 -76
  58. package/packages/scrabble-solver/src/pages/_document.tsx +21 -19
  59. package/packages/scrabble-solver/src/pages/index.tsx +30 -3
  60. package/packages/scrabble-solver/src/pages/not-found.tsx +13 -2
  61. package/packages/scrabble-solver/src/parameters/index.ts +7 -0
  62. package/packages/scrabble-solver/src/state/sagas.ts +4 -4
  63. package/packages/scrabble-solver/tsconfig.tsbuildinfo +1 -1
  64. package/packages/solver/package.json +14 -6
  65. package/packages/types/package.json +10 -3
  66. package/packages/word-definitions/package.json +9 -3
  67. package/packages/word-lists/package.json +11 -3
  68. package/playwright-report/index.html +1 -1
  69. package/packages/scrabble-solver/.next/static/chunks/pages/_app-ba5d628e81a15461.js +0 -1
  70. package/packages/scrabble-solver/.next/static/chunks/pages/index-5f9fa6ac3cd3d97b.js +0 -1
  71. package/packages/scrabble-solver/.next/static/chunks/pages/not-found-23d61fd3ed791cad.js +0 -1
  72. package/packages/scrabble-solver/src/components/SeoMessage/SeoMessage.tsx +0 -18
  73. package/packages/scrabble-solver/src/components/SeoMessage/index.ts +0 -1
  74. /package/packages/scrabble-solver/.next/static/{FL82obwzFHRzvV6z76I-U → 5KOWzYqfY1Z2rjrzptr8D}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- 7090437633827324634
1
+ 12352277066156011697
@@ -1 +1 @@
1
- 7090437633827324634
1
+ 12352277066156011697
Binary file
@@ -49,7 +49,11 @@
49
49
  },
50
50
  "name": "@scrabble-solver/word-definitions",
51
51
  "tags": [
52
- "npm:public"
52
+ "npm:public",
53
+ "npm:word-definitions",
54
+ "npm:dictionary",
55
+ "npm:wiktionary",
56
+ "npm:scrabble"
53
57
  ],
54
58
  "metadata": {
55
59
  "targetGroups": {
@@ -59,10 +63,10 @@
59
63
  "test"
60
64
  ]
61
65
  },
62
- "description": "Scrabble Solver 2 - Word definitions",
66
+ "description": "Word definition crawlers and parsers for Scrabble Solver (Wiktionary, CNRTL, DWDS, SJP, dexonline, and more).",
63
67
  "js": {
64
68
  "packageName": "@scrabble-solver/word-definitions",
65
- "packageVersion": "2.18.0",
69
+ "packageVersion": "2.18.1",
66
70
  "packageMain": "build/index.js",
67
71
  "isInPackageManagerWorkspaces": true
68
72
  }
@@ -179,7 +183,12 @@
179
183
  },
180
184
  "name": "@scrabble-solver/scrabble-solver",
181
185
  "tags": [
182
- "npm:public"
186
+ "npm:public",
187
+ "npm:scrabble",
188
+ "npm:word-finder",
189
+ "npm:solver",
190
+ "npm:nextjs",
191
+ "npm:react"
183
192
  ],
184
193
  "metadata": {
185
194
  "targetGroups": {
@@ -194,10 +203,10 @@
194
203
  "type-check"
195
204
  ]
196
205
  },
197
- "description": "Scrabble Solver 2 - App",
206
+ "description": "Scrabble Solver web app: free word finder and board solver for Scrabble, Super Scrabble, Literaki, and more.",
198
207
  "js": {
199
208
  "packageName": "@scrabble-solver/scrabble-solver",
200
- "packageVersion": "2.18.0",
209
+ "packageVersion": "2.18.1",
201
210
  "isInPackageManagerWorkspaces": true
202
211
  }
203
212
  },
@@ -277,7 +286,12 @@
277
286
  },
278
287
  "name": "@scrabble-solver/dictionaries",
279
288
  "tags": [
280
- "npm:public"
289
+ "npm:public",
290
+ "npm:scrabble",
291
+ "npm:dictionary",
292
+ "npm:gaddag",
293
+ "npm:word-list",
294
+ "npm:cache"
281
295
  ],
282
296
  "metadata": {
283
297
  "targetGroups": {
@@ -289,10 +303,10 @@
289
303
  "test"
290
304
  ]
291
305
  },
292
- "description": "Scrabble Solver 2 - Dictionaries",
306
+ "description": "Dictionary manager for Scrabble Solver: downloads per-locale word lists and serves them as GADDAG automata with layered disk/memory caching.",
293
307
  "js": {
294
308
  "packageName": "@scrabble-solver/dictionaries",
295
- "packageVersion": "2.18.0",
309
+ "packageVersion": "2.18.1",
296
310
  "packageMain": "build/index.js",
297
311
  "isInPackageManagerWorkspaces": true
298
312
  }
@@ -337,7 +351,13 @@
337
351
  },
338
352
  "name": "@scrabble-solver/word-lists",
339
353
  "tags": [
340
- "npm:public"
354
+ "npm:public",
355
+ "npm:word-list",
356
+ "npm:scrabble",
357
+ "npm:dictionary",
358
+ "npm:sowpods",
359
+ "npm:twl06",
360
+ "npm:sjp"
341
361
  ],
342
362
  "metadata": {
343
363
  "targetGroups": {
@@ -346,10 +366,10 @@
346
366
  "clean"
347
367
  ]
348
368
  },
349
- "description": "Scrabble Solver 2 - Word lists",
369
+ "description": "Per-locale word list downloaders for Scrabble Solver (SOWPODS, TWL06, SJP, and more).",
350
370
  "js": {
351
371
  "packageName": "@scrabble-solver/word-lists",
352
- "packageVersion": "2.18.0",
372
+ "packageVersion": "2.18.1",
353
373
  "packageMain": "build/index.js",
354
374
  "isInPackageManagerWorkspaces": true
355
375
  }
@@ -394,7 +414,9 @@
394
414
  },
395
415
  "name": "@scrabble-solver/constants",
396
416
  "tags": [
397
- "npm:public"
417
+ "npm:public",
418
+ "npm:scrabble",
419
+ "npm:constants"
398
420
  ],
399
421
  "metadata": {
400
422
  "targetGroups": {
@@ -403,10 +425,10 @@
403
425
  "clean"
404
426
  ]
405
427
  },
406
- "description": "Scrabble Solver 2 - Constants",
428
+ "description": "Shared constants for Scrabble Solver (blank tile, bonus markers).",
407
429
  "js": {
408
430
  "packageName": "@scrabble-solver/constants",
409
- "packageVersion": "2.18.0",
431
+ "packageVersion": "2.18.1",
410
432
  "packageMain": "build/index.js",
411
433
  "isInPackageManagerWorkspaces": true
412
434
  }
@@ -451,7 +473,14 @@
451
473
  },
452
474
  "name": "@scrabble-solver/configs",
453
475
  "tags": [
454
- "npm:public"
476
+ "npm:public",
477
+ "npm:scrabble",
478
+ "npm:board-game",
479
+ "npm:tile-distribution",
480
+ "npm:game-config",
481
+ "npm:literaki",
482
+ "npm:kelimelik",
483
+ "npm:super-scrabble"
455
484
  ],
456
485
  "metadata": {
457
486
  "targetGroups": {
@@ -460,10 +489,10 @@
460
489
  "clean"
461
490
  ]
462
491
  },
463
- "description": "Scrabble Solver 2 - Configs",
492
+ "description": "Game and language configs for Scrabble Solver: board layouts, bonus squares, tile distributions, and points for 7 games and 9 locales.",
464
493
  "js": {
465
494
  "packageName": "@scrabble-solver/configs",
466
- "packageVersion": "2.18.0",
495
+ "packageVersion": "2.18.1",
467
496
  "packageMain": "build/index.js",
468
497
  "isInPackageManagerWorkspaces": true
469
498
  }
@@ -520,7 +549,10 @@
520
549
  },
521
550
  "name": "@scrabble-solver/logger",
522
551
  "tags": [
523
- "npm:public"
552
+ "npm:public",
553
+ "npm:logger",
554
+ "npm:winston",
555
+ "npm:scrabble"
524
556
  ],
525
557
  "metadata": {
526
558
  "targetGroups": {
@@ -530,10 +562,10 @@
530
562
  "stats"
531
563
  ]
532
564
  },
533
- "description": "Scrabble Solver 2 - Logger",
565
+ "description": "Winston-based JSON file logger for Scrabble Solver.",
534
566
  "js": {
535
567
  "packageName": "@scrabble-solver/logger",
536
- "packageVersion": "2.18.0",
568
+ "packageVersion": "2.18.1",
537
569
  "packageMain": "build/index.js",
538
570
  "isInPackageManagerWorkspaces": true
539
571
  }
@@ -602,7 +634,13 @@
602
634
  },
603
635
  "name": "@scrabble-solver/solver",
604
636
  "tags": [
605
- "npm:public"
637
+ "npm:public",
638
+ "npm:scrabble",
639
+ "npm:solver",
640
+ "npm:gaddag",
641
+ "npm:move-generation",
642
+ "npm:word-finder",
643
+ "npm:anagram"
606
644
  ],
607
645
  "metadata": {
608
646
  "targetGroups": {
@@ -613,10 +651,10 @@
613
651
  "test"
614
652
  ]
615
653
  },
616
- "description": "Scrabble Solver 2 - Solver",
654
+ "description": "Scrabble move-generation engine: anchor-based GADDAG search that finds and scores every legal move for a given board, rack, and game config.",
617
655
  "js": {
618
656
  "packageName": "@scrabble-solver/solver",
619
- "packageVersion": "2.18.0",
657
+ "packageVersion": "2.18.1",
620
658
  "packageMain": "build/index.js",
621
659
  "isInPackageManagerWorkspaces": true
622
660
  }
@@ -673,7 +711,12 @@
673
711
  },
674
712
  "name": "@scrabble-solver/types",
675
713
  "tags": [
676
- "npm:public"
714
+ "npm:public",
715
+ "npm:scrabble",
716
+ "npm:types",
717
+ "npm:domain-model",
718
+ "npm:board",
719
+ "npm:tiles"
677
720
  ],
678
721
  "metadata": {
679
722
  "targetGroups": {
@@ -683,10 +726,10 @@
683
726
  "test"
684
727
  ]
685
728
  },
686
- "description": "Scrabble Solver 2 - Types",
729
+ "description": "Domain model for Scrabble Solver: Board, Cell, Tile, Result, Config, Locale, and their JSON wire shapes.",
687
730
  "js": {
688
731
  "packageName": "@scrabble-solver/types",
689
- "packageVersion": "2.18.0",
732
+ "packageVersion": "2.18.1",
690
733
  "packageMain": "build/index.js",
691
734
  "isInPackageManagerWorkspaces": true
692
735
  }
@@ -38767,5 +38810,5 @@
38767
38810
  },
38768
38811
  "version": "6.0",
38769
38812
  "errors": [],
38770
- "computedAt": 1786870680012
38813
+ "computedAt": 1786879908976
38771
38814
  }
@@ -40,6 +40,34 @@
40
40
  "packages/configs/package.json",
41
41
  "nx/core/package-json"
42
42
  ],
43
+ "tags.npm:scrabble": [
44
+ "packages/configs/package.json",
45
+ "nx/core/package-json"
46
+ ],
47
+ "tags.npm:board-game": [
48
+ "packages/configs/package.json",
49
+ "nx/core/package-json"
50
+ ],
51
+ "tags.npm:tile-distribution": [
52
+ "packages/configs/package.json",
53
+ "nx/core/package-json"
54
+ ],
55
+ "tags.npm:game-config": [
56
+ "packages/configs/package.json",
57
+ "nx/core/package-json"
58
+ ],
59
+ "tags.npm:literaki": [
60
+ "packages/configs/package.json",
61
+ "nx/core/package-json"
62
+ ],
63
+ "tags.npm:kelimelik": [
64
+ "packages/configs/package.json",
65
+ "nx/core/package-json"
66
+ ],
67
+ "tags.npm:super-scrabble": [
68
+ "packages/configs/package.json",
69
+ "nx/core/package-json"
70
+ ],
43
71
  "metadata.targetGroups": [
44
72
  "packages/configs/package.json",
45
73
  "nx/core/package-json"
@@ -174,6 +202,14 @@
174
202
  "packages/constants/package.json",
175
203
  "nx/core/package-json"
176
204
  ],
205
+ "tags.npm:scrabble": [
206
+ "packages/constants/package.json",
207
+ "nx/core/package-json"
208
+ ],
209
+ "tags.npm:constants": [
210
+ "packages/constants/package.json",
211
+ "nx/core/package-json"
212
+ ],
177
213
  "metadata.targetGroups": [
178
214
  "packages/constants/package.json",
179
215
  "nx/core/package-json"
@@ -308,6 +344,26 @@
308
344
  "packages/dictionaries/package.json",
309
345
  "nx/core/package-json"
310
346
  ],
347
+ "tags.npm:scrabble": [
348
+ "packages/dictionaries/package.json",
349
+ "nx/core/package-json"
350
+ ],
351
+ "tags.npm:dictionary": [
352
+ "packages/dictionaries/package.json",
353
+ "nx/core/package-json"
354
+ ],
355
+ "tags.npm:gaddag": [
356
+ "packages/dictionaries/package.json",
357
+ "nx/core/package-json"
358
+ ],
359
+ "tags.npm:word-list": [
360
+ "packages/dictionaries/package.json",
361
+ "nx/core/package-json"
362
+ ],
363
+ "tags.npm:cache": [
364
+ "packages/dictionaries/package.json",
365
+ "nx/core/package-json"
366
+ ],
311
367
  "metadata.targetGroups": [
312
368
  "packages/dictionaries/package.json",
313
369
  "nx/core/package-json"
@@ -538,6 +594,18 @@
538
594
  "packages/logger/package.json",
539
595
  "nx/core/package-json"
540
596
  ],
597
+ "tags.npm:logger": [
598
+ "packages/logger/package.json",
599
+ "nx/core/package-json"
600
+ ],
601
+ "tags.npm:winston": [
602
+ "packages/logger/package.json",
603
+ "nx/core/package-json"
604
+ ],
605
+ "tags.npm:scrabble": [
606
+ "packages/logger/package.json",
607
+ "nx/core/package-json"
608
+ ],
541
609
  "metadata.targetGroups": [
542
610
  "packages/logger/package.json",
543
611
  "nx/core/package-json"
@@ -704,6 +772,26 @@
704
772
  "packages/scrabble-solver/package.json",
705
773
  "nx/core/package-json"
706
774
  ],
775
+ "tags.npm:scrabble": [
776
+ "packages/scrabble-solver/package.json",
777
+ "nx/core/package-json"
778
+ ],
779
+ "tags.npm:word-finder": [
780
+ "packages/scrabble-solver/package.json",
781
+ "nx/core/package-json"
782
+ ],
783
+ "tags.npm:solver": [
784
+ "packages/scrabble-solver/package.json",
785
+ "nx/core/package-json"
786
+ ],
787
+ "tags.npm:nextjs": [
788
+ "packages/scrabble-solver/package.json",
789
+ "nx/core/package-json"
790
+ ],
791
+ "tags.npm:react": [
792
+ "packages/scrabble-solver/package.json",
793
+ "nx/core/package-json"
794
+ ],
707
795
  "metadata.targetGroups": [
708
796
  "packages/scrabble-solver/package.json",
709
797
  "nx/core/package-json"
@@ -1030,6 +1118,30 @@
1030
1118
  "packages/solver/package.json",
1031
1119
  "nx/core/package-json"
1032
1120
  ],
1121
+ "tags.npm:scrabble": [
1122
+ "packages/solver/package.json",
1123
+ "nx/core/package-json"
1124
+ ],
1125
+ "tags.npm:solver": [
1126
+ "packages/solver/package.json",
1127
+ "nx/core/package-json"
1128
+ ],
1129
+ "tags.npm:gaddag": [
1130
+ "packages/solver/package.json",
1131
+ "nx/core/package-json"
1132
+ ],
1133
+ "tags.npm:move-generation": [
1134
+ "packages/solver/package.json",
1135
+ "nx/core/package-json"
1136
+ ],
1137
+ "tags.npm:word-finder": [
1138
+ "packages/solver/package.json",
1139
+ "nx/core/package-json"
1140
+ ],
1141
+ "tags.npm:anagram": [
1142
+ "packages/solver/package.json",
1143
+ "nx/core/package-json"
1144
+ ],
1033
1145
  "metadata.targetGroups": [
1034
1146
  "packages/solver/package.json",
1035
1147
  "nx/core/package-json"
@@ -1228,6 +1340,26 @@
1228
1340
  "packages/types/package.json",
1229
1341
  "nx/core/package-json"
1230
1342
  ],
1343
+ "tags.npm:scrabble": [
1344
+ "packages/types/package.json",
1345
+ "nx/core/package-json"
1346
+ ],
1347
+ "tags.npm:types": [
1348
+ "packages/types/package.json",
1349
+ "nx/core/package-json"
1350
+ ],
1351
+ "tags.npm:domain-model": [
1352
+ "packages/types/package.json",
1353
+ "nx/core/package-json"
1354
+ ],
1355
+ "tags.npm:board": [
1356
+ "packages/types/package.json",
1357
+ "nx/core/package-json"
1358
+ ],
1359
+ "tags.npm:tiles": [
1360
+ "packages/types/package.json",
1361
+ "nx/core/package-json"
1362
+ ],
1231
1363
  "metadata.targetGroups": [
1232
1364
  "packages/types/package.json",
1233
1365
  "nx/core/package-json"
@@ -1394,6 +1526,22 @@
1394
1526
  "packages/word-definitions/package.json",
1395
1527
  "nx/core/package-json"
1396
1528
  ],
1529
+ "tags.npm:word-definitions": [
1530
+ "packages/word-definitions/package.json",
1531
+ "nx/core/package-json"
1532
+ ],
1533
+ "tags.npm:dictionary": [
1534
+ "packages/word-definitions/package.json",
1535
+ "nx/core/package-json"
1536
+ ],
1537
+ "tags.npm:wiktionary": [
1538
+ "packages/word-definitions/package.json",
1539
+ "nx/core/package-json"
1540
+ ],
1541
+ "tags.npm:scrabble": [
1542
+ "packages/word-definitions/package.json",
1543
+ "nx/core/package-json"
1544
+ ],
1397
1545
  "metadata.targetGroups": [
1398
1546
  "packages/word-definitions/package.json",
1399
1547
  "nx/core/package-json"
@@ -1560,6 +1708,30 @@
1560
1708
  "packages/word-lists/package.json",
1561
1709
  "nx/core/package-json"
1562
1710
  ],
1711
+ "tags.npm:word-list": [
1712
+ "packages/word-lists/package.json",
1713
+ "nx/core/package-json"
1714
+ ],
1715
+ "tags.npm:scrabble": [
1716
+ "packages/word-lists/package.json",
1717
+ "nx/core/package-json"
1718
+ ],
1719
+ "tags.npm:dictionary": [
1720
+ "packages/word-lists/package.json",
1721
+ "nx/core/package-json"
1722
+ ],
1723
+ "tags.npm:sowpods": [
1724
+ "packages/word-lists/package.json",
1725
+ "nx/core/package-json"
1726
+ ],
1727
+ "tags.npm:twl06": [
1728
+ "packages/word-lists/package.json",
1729
+ "nx/core/package-json"
1730
+ ],
1731
+ "tags.npm:sjp": [
1732
+ "packages/word-lists/package.json",
1733
+ "nx/core/package-json"
1734
+ ],
1563
1735
  "metadata.targetGroups": [
1564
1736
  "packages/word-lists/package.json",
1565
1737
  "nx/core/package-json"
package/CLAUDE.md CHANGED
@@ -40,7 +40,7 @@ The GADDAG itself lives outside this repo, in [`@kamilmielnik/gaddag`](https://g
40
40
  - **Styling**: SCSS modules with a shared design-token system. When one module's class overrides another component's styles (e.g. `Actions` restyling `Button`), it must win on **specificity**, not stylesheet order — webpack's CSS emission order shifts with the import graph (this flipped once and widened a square button). Class names are type-checked (#16): `scripts/generate-scss-types.ts` writes a git-ignored sibling `.d.ts` for every `*.module.scss` — the `build` and `type-check` scripts run it up front, `dev` runs it in watch mode, and its sass options mirror `sassOptions` in `next.config.js`. `src/@types/scss.d.ts` only covers side-effect imports of non-module stylesheets, deliberately exporting nothing so an import of an ungenerated module fails the type-check. SCSS tokens live in `src/styles/_tokens.scss`; the same values are re-exported to TS via `:export` in `variables.module.scss`. Concrete JS constants live in `src/parameters/index.ts` (e.g. `BREAKPOINTS`, `COLOR_BLUE`, `TRANSITION_DURATION`) — that file is the only place that should read from `variables.module.scss`. Update `_tokens.scss` first → expose via `variables.module.scss` `:export` block → consume via `parameters/`. This was added in PR #228 (Apr 2026); before it, JS-side colors and breakpoints were hard-coded duplicates. Responsive helpers come from `include-media`.
41
41
  - **SVGs**: imported as React components via `@svgr/webpack` (configured in `next.config.js`), typed by `src/@types/svg.d.ts`.
42
42
  - **Service worker registration**: production-only. Registered by `serviceWorkerManager.ts` from the index page, deferred until load + idle (`waitForIdle`) so the install's precache downloads never compete with page resources (an eager install once caused Lighthouse's robots.txt fetch to time out). Playwright blocks registration entirely via `serviceWorkers: 'block'` in `playwright.config.ts`, and each test gets a fresh browser context, so e2e tests need no service-worker or localStorage cleanup.
43
- - **Deferral pattern**: anything that shouldn't compete with boot goes through `lib/waitForIdleOrFirstIntent.ts` (load + `requestIdleCallback`, or first pointerdown/keydown) — dictionary prefetch, translations preload, modal chunk warming, `visit()`, and (idle-only via `waitForIdle`) service worker registration. Tooltips defer their floating-ui setup one task past hydration via `useDeferredRender`.
43
+ - **Deferral pattern**: anything that shouldn't compete with boot goes through `lib/waitForIdleOrFirstIntent.ts` (load + `requestIdleCallback`, or first pointerdown/keydown) — translations preload, modal chunk warming, and `visit()`; service worker registration is idle-only (`waitForIdle`), and the dictionary prefetch is intent-only (`waitForFirstIntent` — the multi-MB download is pointless for passive visitors and would land in Lighthouse's payload audit). Tooltips defer their floating-ui setup one task past hydration via `useDeferredRender`.
44
44
 
45
45
  ## Common commands
46
46
 
package/bun.lock CHANGED
@@ -5,7 +5,7 @@
5
5
  "": {
6
6
  "name": "scrabble-solver",
7
7
  "dependencies": {
8
- "@scrabble-solver/scrabble-solver": "^2.18.0",
8
+ "@scrabble-solver/scrabble-solver": "^2.18.1",
9
9
  "concurrently": "^10.0.5",
10
10
  "open-cli": "^9.0.0",
11
11
  "wait-on": "^9.1.0",
@@ -30,51 +30,51 @@
30
30
  },
31
31
  "packages/configs": {
32
32
  "name": "@scrabble-solver/configs",
33
- "version": "2.18.0",
33
+ "version": "2.18.1",
34
34
  "dependencies": {
35
- "@scrabble-solver/constants": "^2.18.0",
36
- "@scrabble-solver/types": "^2.18.0",
35
+ "@scrabble-solver/constants": "^2.18.1",
36
+ "@scrabble-solver/types": "^2.18.1",
37
37
  },
38
38
  },
39
39
  "packages/constants": {
40
40
  "name": "@scrabble-solver/constants",
41
- "version": "2.18.0",
41
+ "version": "2.18.1",
42
42
  },
43
43
  "packages/dictionaries": {
44
44
  "name": "@scrabble-solver/dictionaries",
45
- "version": "2.18.0",
45
+ "version": "2.18.1",
46
46
  "bin": {
47
47
  "remove-dictionaries": "./bin/remove-dictionaries.js",
48
48
  "update-dictionaries": "./bin/update-dictionaries.js",
49
49
  },
50
50
  "dependencies": {
51
51
  "@kamilmielnik/gaddag": "^2.0.0",
52
- "@scrabble-solver/logger": "^2.18.0",
53
- "@scrabble-solver/types": "^2.18.0",
54
- "@scrabble-solver/word-lists": "^2.18.0",
52
+ "@scrabble-solver/logger": "^2.18.1",
53
+ "@scrabble-solver/types": "^2.18.1",
54
+ "@scrabble-solver/word-lists": "^2.18.1",
55
55
  },
56
56
  },
57
57
  "packages/logger": {
58
58
  "name": "@scrabble-solver/logger",
59
- "version": "2.18.0",
59
+ "version": "2.18.1",
60
60
  "dependencies": {
61
61
  "winston": "^3.19.0",
62
62
  },
63
63
  },
64
64
  "packages/scrabble-solver": {
65
65
  "name": "@scrabble-solver/scrabble-solver",
66
- "version": "2.18.0",
66
+ "version": "2.18.1",
67
67
  "dependencies": {
68
68
  "@floating-ui/react": "^0.27.20",
69
69
  "@kamilmielnik/gaddag": "^2.0.0",
70
70
  "@reduxjs/toolkit": "^2.12.0",
71
- "@scrabble-solver/configs": "^2.18.0",
72
- "@scrabble-solver/constants": "^2.18.0",
73
- "@scrabble-solver/dictionaries": "^2.18.0",
74
- "@scrabble-solver/logger": "^2.18.0",
75
- "@scrabble-solver/solver": "^2.18.0",
76
- "@scrabble-solver/types": "^2.18.0",
77
- "@scrabble-solver/word-definitions": "^2.18.0",
71
+ "@scrabble-solver/configs": "^2.18.1",
72
+ "@scrabble-solver/constants": "^2.18.1",
73
+ "@scrabble-solver/dictionaries": "^2.18.1",
74
+ "@scrabble-solver/logger": "^2.18.1",
75
+ "@scrabble-solver/solver": "^2.18.1",
76
+ "@scrabble-solver/types": "^2.18.1",
77
+ "@scrabble-solver/word-definitions": "^2.18.1",
78
78
  "classnames": "^2.5.1",
79
79
  "env-cmd": "^11.0.0",
80
80
  "include-media": "^2.0.0",
@@ -110,29 +110,29 @@
110
110
  },
111
111
  "packages/solver": {
112
112
  "name": "@scrabble-solver/solver",
113
- "version": "2.18.0",
113
+ "version": "2.18.1",
114
114
  "dependencies": {
115
115
  "@kamilmielnik/gaddag": "^2.0.0",
116
- "@scrabble-solver/types": "^2.18.0",
116
+ "@scrabble-solver/types": "^2.18.1",
117
117
  },
118
118
  "devDependencies": {
119
- "@scrabble-solver/configs": "^2.18.0",
120
- "@scrabble-solver/constants": "^2.18.0",
121
- "@scrabble-solver/dictionaries": "^2.18.0",
119
+ "@scrabble-solver/configs": "^2.18.1",
120
+ "@scrabble-solver/constants": "^2.18.1",
121
+ "@scrabble-solver/dictionaries": "^2.18.1",
122
122
  },
123
123
  },
124
124
  "packages/types": {
125
125
  "name": "@scrabble-solver/types",
126
- "version": "2.18.0",
126
+ "version": "2.18.1",
127
127
  "dependencies": {
128
- "@scrabble-solver/constants": "^2.18.0",
128
+ "@scrabble-solver/constants": "^2.18.1",
129
129
  },
130
130
  },
131
131
  "packages/word-definitions": {
132
132
  "name": "@scrabble-solver/word-definitions",
133
- "version": "2.18.0",
133
+ "version": "2.18.1",
134
134
  "dependencies": {
135
- "@scrabble-solver/types": "^2.18.0",
135
+ "@scrabble-solver/types": "^2.18.1",
136
136
  "cheerio": "^1.2.0",
137
137
  "follow-redirects": "^1.16.0",
138
138
  "striptags": "^3.2.0",
@@ -144,9 +144,9 @@
144
144
  },
145
145
  "packages/word-lists": {
146
146
  "name": "@scrabble-solver/word-lists",
147
- "version": "2.18.0",
147
+ "version": "2.18.1",
148
148
  "dependencies": {
149
- "@scrabble-solver/types": "^2.18.0",
149
+ "@scrabble-solver/types": "^2.18.1",
150
150
  "cheerio": "^1.2.0",
151
151
  "follow-redirects": "^1.16.0",
152
152
  "transliteration": "^2.6.1",
package/e2e/app.spec.ts CHANGED
@@ -26,7 +26,7 @@ test.describe('app', () => {
26
26
  test('has title', async ({ page }) => {
27
27
  await visitIndex(page);
28
28
 
29
- await expect(page).toHaveTitle('Scrabble Solver 2');
29
+ await expect(page).toHaveTitle('Scrabble Solver 2 - Board Solver & Word Finder');
30
30
  });
31
31
 
32
32
  test('has default setting values', async ({ page }) => {
@@ -18,6 +18,8 @@ test.describe('Solver paths', () => {
18
18
 
19
19
  test('solves locally once the dictionary is cached', async ({ page }) => {
20
20
  await Lib.visitIndex(page);
21
+ await Lib.typeBoard(page, 'i', 'horizontal', { x: 7, y: 7 });
22
+ await Lib.typeRack(page, 'q');
21
23
  await waitForCachedDictionary(page);
22
24
 
23
25
  let solveRequestCount = 0;
@@ -25,8 +27,6 @@ test.describe('Solver paths', () => {
25
27
  solveRequestCount += 1;
26
28
  return route.continue();
27
29
  });
28
- await Lib.typeBoard(page, 'i', 'horizontal', { x: 7, y: 7 });
29
- await Lib.typeRack(page, 'q');
30
30
  await Lib.solve(page);
31
31
 
32
32
  await expect(Lib.getResults(page)).toHaveCount(2);
package/lerna.json CHANGED
@@ -6,6 +6,6 @@
6
6
  "access": "public"
7
7
  },
8
8
  "tagVersionPrefix": "",
9
- "version": "2.18.0",
9
+ "version": "2.18.1",
10
10
  "$schema": "node_modules/lerna/schemas/lerna-schema.json"
11
11
  }