scrabble-solver 2.16.6 → 2.17.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.
- package/.github/workflows/bunx.yml +26 -2
- package/.github/workflows/npx.yml +26 -2
- package/.nx/workspace-data/d/server-process.json +3 -3
- package/.nx/workspace-data/file-map.json +441 -465
- package/.nx/workspace-data/lockfile-dependencies.hash +1 -1
- package/.nx/workspace-data/lockfile-nodes.hash +1 -1
- package/.nx/workspace-data/nx_files.nxt +0 -0
- package/.nx/workspace-data/parsed-lock-file.dependencies.json +2671 -2121
- package/.nx/workspace-data/parsed-lock-file.nodes.json +3846 -5277
- package/.nx/workspace-data/project-graph.json +7089 -7924
- package/.nx/workspace-data/source-maps.json +351 -255
- package/.oxlintrc.json +6 -0
- package/CLAUDE.md +25 -20
- package/README.md +9 -0
- package/bun.lock +1054 -2897
- package/bunfig.toml +6 -0
- package/cypress/e2e/app.spec.cy.ts +4 -4
- package/cypress/e2e/features/solver-paths.ts +66 -0
- package/cypress/e2e/features.spec.cy.ts +1 -0
- package/cypress/support/lib/actions.ts +28 -9
- package/cypress.config.ts +7 -0
- package/lerna.json +1 -1
- package/nx.json +3 -1
- package/package.json +18 -18
- package/packages/configs/package.json +4 -4
- package/packages/constants/package.json +2 -2
- package/packages/dictionaries/README.md +1 -1
- package/packages/dictionaries/build/Dictionaries.d.ts +2 -2
- package/packages/dictionaries/build/Dictionaries.js +6 -6
- package/packages/dictionaries/build/lib/DiskCache.d.ts +11 -4
- package/packages/dictionaries/build/lib/DiskCache.js +27 -10
- package/packages/dictionaries/build/lib/LayeredCache.d.ts +4 -4
- package/packages/dictionaries/build/lib/LayeredCache.js +3 -3
- package/packages/dictionaries/build/lib/MemoryCache.d.ts +4 -4
- package/packages/dictionaries/build/lib/MemoryCache.js +2 -2
- package/packages/dictionaries/build/lib/createCacheTimestampComparator.d.ts +2 -2
- package/packages/dictionaries/build/lib/downloadDictionary.d.ts +2 -2
- package/packages/dictionaries/build/lib/downloadDictionary.js +4 -3
- package/packages/dictionaries/build/lib/getDictionaryFilepath.d.ts +3 -1
- package/packages/dictionaries/build/lib/getDictionaryFilepath.js +8 -3
- package/packages/dictionaries/package.json +8 -7
- package/packages/dictionaries/src/Dictionaries.ts +12 -12
- package/packages/dictionaries/src/lib/DiskCache.test.ts +85 -0
- package/packages/dictionaries/src/lib/DiskCache.ts +34 -14
- package/packages/dictionaries/src/lib/LayeredCache.ts +7 -7
- package/packages/dictionaries/src/lib/MemoryCache.ts +6 -6
- package/packages/dictionaries/src/lib/createCacheTimestampComparator.ts +2 -2
- package/packages/dictionaries/src/lib/downloadDictionary.ts +5 -4
- package/packages/dictionaries/src/lib/getDictionaryFilepath.ts +7 -2
- package/packages/gaddag/build/Gaddag.d.ts +39 -0
- package/packages/gaddag/build/Gaddag.js +128 -0
- package/packages/gaddag/build/buildGaddag.d.ts +10 -0
- package/packages/gaddag/build/buildGaddag.js +360 -0
- package/packages/gaddag/build/constants.d.ts +12 -0
- package/packages/gaddag/build/constants.js +15 -0
- package/packages/gaddag/build/index.d.ts +3 -0
- package/packages/gaddag/build/index.js +13 -0
- package/packages/logger/package.json +2 -2
- package/packages/scrabble-solver/.next/BUILD_ID +1 -1
- package/packages/scrabble-solver/.next/build-manifest.json +17 -17
- package/packages/scrabble-solver/.next/cache/.previewinfo +1 -1
- package/packages/scrabble-solver/.next/cache/.rscinfo +1 -1
- package/packages/scrabble-solver/.next/cache/.tsbuildinfo +1 -1
- package/packages/scrabble-solver/.next/cache/webpack/client-production/0.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/client-production/index.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/client-production/index.pack.old +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/index.pack.old +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/server-production/0.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/server-production/index.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/server-production/index.pack.old +0 -0
- package/packages/scrabble-solver/.next/diagnostics/framework.json +1 -1
- package/packages/scrabble-solver/.next/next-minimal-server.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/next-server.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/prerender-manifest.json +7 -4
- package/packages/scrabble-solver/.next/required-server-files.js +29 -10
- package/packages/scrabble-solver/.next/required-server-files.json +29 -10
- package/packages/scrabble-solver/.next/routes-manifest.json +1 -1
- package/packages/scrabble-solver/.next/server/chunks/129.js +1 -0
- package/packages/scrabble-solver/.next/server/chunks/30.js +2 -2
- package/packages/scrabble-solver/.next/server/chunks/318.js +3 -3
- package/packages/scrabble-solver/.next/server/chunks/392.js +1 -1
- package/packages/scrabble-solver/.next/server/chunks/671.js +1 -1
- package/packages/scrabble-solver/.next/server/chunks/712.js +1 -1
- package/packages/scrabble-solver/.next/server/chunks/785.js +1 -0
- package/packages/scrabble-solver/.next/server/chunks/791.js +3 -3
- package/packages/scrabble-solver/.next/server/middleware-build-manifest.js +1 -1
- package/packages/scrabble-solver/.next/server/pages/404.html +1 -1
- package/packages/scrabble-solver/.next/server/pages/500.html +1 -1
- package/packages/scrabble-solver/.next/server/pages/_app.js +1 -1
- package/packages/scrabble-solver/.next/server/pages/_app.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/_document.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/_error.js +1 -1
- package/packages/scrabble-solver/.next/server/pages/_error.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/api/dictionary/[locale]/[word].js +1 -1
- package/packages/scrabble-solver/.next/server/pages/api/dictionary/[locale]/[word].js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/api/dictionary/[locale].js +1 -1
- package/packages/scrabble-solver/.next/server/pages/api/dictionary/[locale].js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/api/solve.js +1 -1
- package/packages/scrabble-solver/.next/server/pages/api/solve.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/api/verify.js +1 -1
- package/packages/scrabble-solver/.next/server/pages/api/verify.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/api/visit.js +1 -1
- package/packages/scrabble-solver/.next/server/pages/api/visit.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/index.html +1 -1
- package/packages/scrabble-solver/.next/server/pages/index.js +1 -1
- package/packages/scrabble-solver/.next/server/pages/index.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/index.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/not-found.html +1 -1
- package/packages/scrabble-solver/.next/server/pages/not-found.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages-manifest.json +1 -1
- package/packages/scrabble-solver/.next/server/webpack-runtime.js +1 -1
- package/packages/scrabble-solver/.next/static/{js6-w0PwySs2PyOSeCYfi → OLE8_ZInlGH7ENU0NIOpf}/_buildManifest.js +1 -1
- package/packages/scrabble-solver/.next/static/chunks/583.7a46807be14c377e.js +1 -0
- package/packages/scrabble-solver/.next/static/chunks/830.661816bf0de8c2f1.js +1 -0
- package/packages/scrabble-solver/.next/static/chunks/framework-3cf15b8041c59dd3.js +1 -0
- package/packages/scrabble-solver/.next/static/chunks/main-5b999f3f24ebfa84.js +5 -0
- package/packages/scrabble-solver/.next/static/chunks/pages/_app-7024e7a27ffbb2fa.js +7 -0
- package/packages/scrabble-solver/.next/static/chunks/pages/{index-bdf5e1e44cea16f6.js → index-8b398b0a5d870773.js} +1 -1
- package/packages/scrabble-solver/.next/static/chunks/webpack-3943d624bbb47a64.js +1 -0
- package/packages/scrabble-solver/.next/static/css/aedeaada218d7280.css +2 -0
- package/packages/scrabble-solver/.next/trace +21 -21
- package/packages/scrabble-solver/.next/trace-build +1 -1
- package/packages/scrabble-solver/.next/types/cache-life.d.ts +1 -0
- package/packages/scrabble-solver/.next/types/root-params.d.ts +3 -0
- package/packages/scrabble-solver/next-env.d.ts +1 -0
- package/packages/scrabble-solver/next.config.js +0 -1
- package/packages/scrabble-solver/package.json +19 -19
- package/packages/scrabble-solver/public/service-worker.js +2 -2
- package/packages/scrabble-solver/public/service-worker.js.map +1 -1
- package/packages/scrabble-solver/src/components/Board/components/Cell/Cell.tsx +4 -1
- package/packages/scrabble-solver/src/components/Board/hooks/useGrid.ts +17 -6
- package/packages/scrabble-solver/src/components/Dictionary/Dictionary.module.scss +7 -22
- package/packages/scrabble-solver/src/components/Dictionary/Dictionary.tsx +1 -8
- package/packages/scrabble-solver/src/components/Results/Result.tsx +0 -3
- package/packages/scrabble-solver/src/components/Results/Results.module.scss +0 -1
- package/packages/scrabble-solver/src/components/Results/Results.tsx +10 -2
- package/packages/scrabble-solver/src/components/Results/types.ts +3 -3
- package/packages/scrabble-solver/src/components/Solver/Solver.tsx +4 -3
- package/packages/scrabble-solver/src/components/Tooltip/useTooltip.ts +1 -1
- package/packages/scrabble-solver/src/pages/api/dictionary/[locale]/[word].ts +2 -2
- package/packages/scrabble-solver/src/pages/api/dictionary/[locale]/index.ts +80 -3
- package/packages/scrabble-solver/src/pages/api/solve.ts +2 -2
- package/packages/scrabble-solver/src/pages/api/verify.ts +12 -3
- package/packages/scrabble-solver/src/sdk/solve.ts +13 -7
- package/packages/scrabble-solver/src/sdk/verify.ts +12 -6
- package/packages/scrabble-solver/src/service-worker/appShell.test.ts +86 -0
- package/packages/scrabble-solver/src/service-worker/appShell.ts +39 -0
- package/packages/scrabble-solver/src/service-worker/index.ts +4 -5
- package/packages/scrabble-solver/src/serviceWorkerManager.ts +1 -18
- package/packages/scrabble-solver/src/solver-worker/client.test.ts +151 -0
- package/packages/scrabble-solver/src/solver-worker/client.ts +106 -0
- package/packages/scrabble-solver/src/solver-worker/dictionaries/constants.ts +9 -0
- package/packages/scrabble-solver/src/solver-worker/dictionaries/getDictionary.ts +21 -0
- package/packages/scrabble-solver/src/solver-worker/dictionaries/index.ts +2 -0
- package/packages/scrabble-solver/src/solver-worker/dictionaries/revalidateDictionary.test.ts +199 -0
- package/packages/scrabble-solver/src/solver-worker/dictionaries/revalidateDictionary.ts +86 -0
- package/packages/scrabble-solver/src/solver-worker/dictionaries/revalidatedAt.ts +43 -0
- package/packages/scrabble-solver/src/solver-worker/getGaddag.test.ts +109 -0
- package/packages/scrabble-solver/src/solver-worker/getGaddag.ts +62 -0
- package/packages/scrabble-solver/src/solver-worker/index.ts +1 -0
- package/packages/scrabble-solver/src/solver-worker/index.worker.ts +124 -0
- package/packages/scrabble-solver/src/solver-worker/messages.ts +20 -0
- package/packages/scrabble-solver/src/state/index.ts +1 -0
- package/packages/scrabble-solver/src/state/sagas.ts +19 -9
- package/packages/scrabble-solver/src/state/useTypedStore.ts +6 -0
- package/packages/scrabble-solver/src/types/api.ts +1 -2
- package/packages/scrabble-solver/tsconfig.json +4 -0
- package/packages/scrabble-solver/tsconfig.tsbuildinfo +1 -1
- package/packages/solver/README.md +24 -0
- package/packages/solver/benchmarks/index.ts +15 -0
- package/packages/solver/benchmarks/lib.ts +31 -0
- package/packages/solver/benchmarks/renderChart.ts +165 -0
- package/packages/solver/benchmarks/results/chart.svg +65 -0
- package/packages/solver/benchmarks/runBenchmarks.ts +66 -0
- package/packages/solver/benchmarks/scenarios.ts +64 -0
- package/packages/solver/benchmarks/types.ts +16 -0
- package/packages/solver/benchmarks/updateReadme.ts +53 -0
- package/packages/solver/build/MoveGenerator.d.ts +116 -0
- package/packages/solver/build/MoveGenerator.js +686 -0
- package/packages/solver/build/index.d.ts +0 -13
- package/packages/solver/build/index.js +1 -27
- package/packages/solver/build/solve.d.ts +2 -2
- package/packages/solver/build/solve.js +3 -19
- package/packages/solver/package.json +8 -7
- package/packages/solver/src/MoveGenerator.test.ts +1009 -0
- package/packages/solver/src/MoveGenerator.ts +926 -0
- package/packages/solver/src/ReferenceSolver.ts +401 -0
- package/packages/solver/src/index.ts +0 -13
- package/packages/solver/src/solve.test.ts +21 -21
- package/packages/solver/src/solve.ts +4 -22
- package/packages/solver/tsconfig.json +1 -1
- package/packages/types/build/Cell.d.ts +1 -0
- package/packages/types/build/Cell.js +3 -0
- package/packages/types/build/Result.d.ts +3 -2
- package/packages/types/build/Result.js +11 -6
- package/packages/types/build/ResultJson.d.ts +5 -4
- package/packages/types/build/index.d.ts +0 -6
- package/packages/types/build/index.js +1 -9
- package/packages/types/build/readResultCells.d.ts +5 -0
- package/packages/types/build/readResultCells.js +75 -0
- package/packages/types/package.json +5 -4
- package/packages/types/src/Cell.ts +4 -0
- package/packages/types/src/Result.ts +15 -6
- package/packages/types/src/ResultJson.ts +5 -5
- package/packages/types/src/index.ts +0 -6
- package/packages/types/src/readResultCells.test.ts +140 -0
- package/packages/types/src/readResultCells.ts +90 -0
- package/packages/word-definitions/package.json +3 -3
- package/packages/word-lists/package.json +4 -4
- package/packages/scrabble-solver/.next/static/chunks/framework-a23f7f643b59a2ca.js +0 -1
- package/packages/scrabble-solver/.next/static/chunks/main-92448bb08bb6bf1f.js +0 -5
- package/packages/scrabble-solver/.next/static/chunks/pages/_app-4ae86f006f6b9fe7.js +0 -7
- package/packages/scrabble-solver/.next/static/chunks/webpack-1a7a166b34ed8d24.js +0 -1
- package/packages/scrabble-solver/.next/static/css/0af35adb4bab56f0.css +0 -2
- package/packages/scrabble-solver/src/sdk/getDictionary.ts +0 -9
- package/packages/scrabble-solver/src/service-worker/average.ts +0 -7
- package/packages/scrabble-solver/src/service-worker/dictionaries/constants.ts +0 -5
- package/packages/scrabble-solver/src/service-worker/dictionaries/getDictionary.ts +0 -20
- package/packages/scrabble-solver/src/service-worker/dictionaries/index.ts +0 -2
- package/packages/scrabble-solver/src/service-worker/dictionaries/revalidateDictionary.ts +0 -33
- package/packages/scrabble-solver/src/service-worker/getTrie.ts +0 -24
- package/packages/scrabble-solver/src/service-worker/routeSolveRequests.ts +0 -91
- package/packages/scrabble-solver/src/service-worker/routeVerifyRequests.ts +0 -37
- package/packages/solver/build/areDigraphsValid.d.ts +0 -2
- package/packages/solver/build/areDigraphsValid.js +0 -17
- package/packages/solver/build/fillPattern.d.ts +0 -6
- package/packages/solver/build/fillPattern.js +0 -52
- package/packages/solver/build/generateEndIndices.d.ts +0 -2
- package/packages/solver/build/generateEndIndices.js +0 -17
- package/packages/solver/build/generateHorizontalPatterns.d.ts +0 -2
- package/packages/solver/build/generateHorizontalPatterns.js +0 -16
- package/packages/solver/build/generatePattern.d.ts +0 -7
- package/packages/solver/build/generatePattern.js +0 -20
- package/packages/solver/build/generatePatterns.d.ts +0 -2
- package/packages/solver/build/generatePatterns.js +0 -11
- package/packages/solver/build/generateStartIndices.d.ts +0 -2
- package/packages/solver/build/generateStartIndices.js +0 -16
- package/packages/solver/build/generateVectors.d.ts +0 -7
- package/packages/solver/build/generateVectors.js +0 -7
- package/packages/solver/build/generateVerticalPatterns.d.ts +0 -2
- package/packages/solver/build/generateVerticalPatterns.js +0 -16
- package/packages/solver/build/getCellsScore.d.ts +0 -2
- package/packages/solver/build/getCellsScore.js +0 -18
- package/packages/solver/build/getPatternHash.d.ts +0 -2
- package/packages/solver/build/getPatternHash.js +0 -14
- package/packages/solver/build/getPatternScore.d.ts +0 -2
- package/packages/solver/build/getPatternScore.js +0 -22
- package/packages/solver/build/getUniquePatterns.d.ts +0 -2
- package/packages/solver/build/getUniquePatterns.js +0 -17
- package/packages/solver/src/areDigraphsValid.ts +0 -18
- package/packages/solver/src/fillPattern.test.ts +0 -107
- package/packages/solver/src/fillPattern.ts +0 -68
- package/packages/solver/src/generateEndIndices.test.ts +0 -23
- package/packages/solver/src/generateEndIndices.ts +0 -19
- package/packages/solver/src/generateHorizontalPatterns.test.ts +0 -31
- package/packages/solver/src/generateHorizontalPatterns.ts +0 -15
- package/packages/solver/src/generatePattern.ts +0 -33
- package/packages/solver/src/generatePatterns.test.ts +0 -13
- package/packages/solver/src/generatePatterns.ts +0 -11
- package/packages/solver/src/generateStartIndices.test.ts +0 -19
- package/packages/solver/src/generateStartIndices.ts +0 -17
- package/packages/solver/src/generateVectors.test.ts +0 -12
- package/packages/solver/src/generateVectors.ts +0 -10
- package/packages/solver/src/generateVerticalPatterns.test.ts +0 -32
- package/packages/solver/src/generateVerticalPatterns.ts +0 -15
- package/packages/solver/src/getCellsScore.ts +0 -21
- package/packages/solver/src/getPatternHash.test.ts +0 -17
- package/packages/solver/src/getPatternHash.ts +0 -12
- package/packages/solver/src/getPatternScore.test.ts +0 -204
- package/packages/solver/src/getPatternScore.ts +0 -23
- package/packages/solver/src/getUniquePatterns.ts +0 -19
- package/packages/types/build/CollisionJson.d.ts +0 -2
- package/packages/types/build/CollisionJson.js +0 -2
- package/packages/types/build/FinalPattern.d.ts +0 -6
- package/packages/types/build/FinalPattern.js +0 -14
- package/packages/types/build/HorizontalPattern.d.ts +0 -5
- package/packages/types/build/HorizontalPattern.js +0 -34
- package/packages/types/build/Pattern.d.ts +0 -20
- package/packages/types/build/Pattern.js +0 -50
- package/packages/types/build/PatternJson.d.ts +0 -6
- package/packages/types/build/PatternJson.js +0 -2
- package/packages/types/build/VerticalPattern.d.ts +0 -5
- package/packages/types/build/VerticalPattern.js +0 -34
- package/packages/types/src/CollisionJson.ts +0 -3
- package/packages/types/src/FinalPattern.ts +0 -14
- package/packages/types/src/HorizontalPattern.ts +0 -37
- package/packages/types/src/Pattern.ts +0 -71
- package/packages/types/src/PatternJson.ts +0 -7
- package/packages/types/src/VerticalPattern.ts +0 -37
- /package/packages/scrabble-solver/.next/static/{js6-w0PwySs2PyOSeCYfi → OLE8_ZInlGH7ENU0NIOpf}/_ssgManifest.js +0 -0
- /package/packages/scrabble-solver/src/{service-worker → solver-worker}/dictionaries/expirationManager.ts +0 -0
- /package/packages/scrabble-solver/src/{service-worker → solver-worker}/dictionaries/getDictionaryUrl.ts +0 -0
package/bunfig.toml
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
|
+
# Keep the classic flat node_modules layout. With Bun's newer "isolated" layout,
|
|
2
|
+
# `next build` fails: webpack starts bundling unzipper (used by word-lists) and
|
|
3
|
+
# errors on @aws-sdk/client-s3 - an optional package we don't install.
|
|
4
|
+
[install]
|
|
5
|
+
linker = "hoisted"
|
|
6
|
+
|
|
1
7
|
[test]
|
|
2
8
|
preload = ["./bun.test.preload.ts"]
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
getSettingOption,
|
|
12
12
|
getSettingsButton,
|
|
13
13
|
getTooltip,
|
|
14
|
+
hoverResult,
|
|
14
15
|
moveMouseAway,
|
|
15
16
|
solve,
|
|
16
17
|
typeRack,
|
|
@@ -46,8 +47,7 @@ describe('app', () => {
|
|
|
46
47
|
|
|
47
48
|
describe('full app test', () => {
|
|
48
49
|
beforeEach(() => {
|
|
49
|
-
cy.intercept('/api/
|
|
50
|
-
cy.intercept('/api/dictionary/**/*').as('dictionary');
|
|
50
|
+
cy.intercept('/api/dictionary/*/*').as('dictionary');
|
|
51
51
|
});
|
|
52
52
|
|
|
53
53
|
it('Scrabble - Polish', () => {
|
|
@@ -60,7 +60,7 @@ describe('app', () => {
|
|
|
60
60
|
solve();
|
|
61
61
|
|
|
62
62
|
assertResult(0, 'bał', 14);
|
|
63
|
-
|
|
63
|
+
hoverResult(0);
|
|
64
64
|
getLoading().should('be.visible');
|
|
65
65
|
cy.wait('@dictionary');
|
|
66
66
|
getRackTile(0).parent().should('have.attr', 'role', 'mark');
|
|
@@ -88,7 +88,7 @@ describe('app', () => {
|
|
|
88
88
|
cy.findByLabelText('Punkty').realClick();
|
|
89
89
|
getTooltip().should('be.visible').and('have.text', 'Punkty');
|
|
90
90
|
assertResult(0, 'ba', 8);
|
|
91
|
-
|
|
91
|
+
hoverResult(0);
|
|
92
92
|
getRackTile(0).parent().should('have.attr', 'role', 'mark');
|
|
93
93
|
getRackTile(1).parent().should('have.attr', 'role', 'mark');
|
|
94
94
|
getRackTile(2).parent().should('not.have.attr', 'role', 'mark');
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import {
|
|
2
|
+
assertResult,
|
|
3
|
+
deleteCachedDictionaries,
|
|
4
|
+
getResults,
|
|
5
|
+
solve,
|
|
6
|
+
typeBoard,
|
|
7
|
+
typeRack,
|
|
8
|
+
unregisterServiceWorkers,
|
|
9
|
+
visitIndex,
|
|
10
|
+
} from '../../support';
|
|
11
|
+
|
|
12
|
+
describe('Solver paths', () => {
|
|
13
|
+
beforeEach(async () => {
|
|
14
|
+
await unregisterServiceWorkers();
|
|
15
|
+
await deleteCachedDictionaries();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
afterEach(() => {
|
|
19
|
+
cy.clearLocalStorage();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('solves through the server when no dictionary is available locally', () => {
|
|
23
|
+
cy.intercept('GET', '/api/dictionary/*', { statusCode: 503 });
|
|
24
|
+
cy.intercept('POST', '/api/solve').as('solve');
|
|
25
|
+
visitIndex();
|
|
26
|
+
typeBoard('i', 'horizontal', 7, 7);
|
|
27
|
+
typeRack('q');
|
|
28
|
+
solve();
|
|
29
|
+
cy.wait('@solve');
|
|
30
|
+
|
|
31
|
+
getResults().should('have.length', 2);
|
|
32
|
+
assertResult(0, 'qi', 11);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('solves locally once the dictionary is cached', () => {
|
|
36
|
+
visitIndex();
|
|
37
|
+
waitForCachedDictionary();
|
|
38
|
+
|
|
39
|
+
let solveRequestCount = 0;
|
|
40
|
+
cy.intercept('POST', '/api/solve', () => {
|
|
41
|
+
solveRequestCount += 1;
|
|
42
|
+
});
|
|
43
|
+
typeBoard('i', 'horizontal', 7, 7);
|
|
44
|
+
typeRack('q');
|
|
45
|
+
solve();
|
|
46
|
+
|
|
47
|
+
getResults().should('have.length', 2);
|
|
48
|
+
assertResult(0, 'qi', 11);
|
|
49
|
+
cy.then(() => {
|
|
50
|
+
expect(solveRequestCount).to.equal(0);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const waitForCachedDictionary = () => {
|
|
56
|
+
cy.then({ timeout: 30000 }, async () => {
|
|
57
|
+
const hasDictionary = async () => {
|
|
58
|
+
const cache = await caches.open('dictionary-api-cache');
|
|
59
|
+
return (await cache.match('/api/dictionary/en-US')) !== undefined;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
while (!(await hasDictionary())) {
|
|
63
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
};
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import {
|
|
2
|
+
getBoardTile,
|
|
3
|
+
getLoading,
|
|
4
|
+
getModal,
|
|
5
|
+
getOpenModal,
|
|
6
|
+
getRackTile,
|
|
7
|
+
getResult,
|
|
8
|
+
getResultsContainer,
|
|
9
|
+
} from './selectors';
|
|
6
10
|
|
|
7
11
|
export const visitIndex = () => {
|
|
8
12
|
cy.visit('/');
|
|
@@ -60,14 +64,29 @@ export const pasteBoard = (word: string, direction: 'horizontal' | 'vertical', x
|
|
|
60
64
|
};
|
|
61
65
|
|
|
62
66
|
export const solve = () => {
|
|
63
|
-
const id = `solve-${getRandomId()}`;
|
|
64
|
-
|
|
65
|
-
cy.intercept('/api/solve').as(id);
|
|
66
67
|
getRackTile().focus().parents('form').submit();
|
|
67
|
-
|
|
68
|
+
getResultsContainer().should('have.attr', 'data-outdated', 'false');
|
|
68
69
|
getLoading().should('not.exist');
|
|
69
70
|
};
|
|
70
71
|
|
|
72
|
+
/**
|
|
73
|
+
* react-window remounts rows during its initial measure pass, and a row
|
|
74
|
+
* replaced under an already-hovered cursor never receives a new mouseenter -
|
|
75
|
+
* let the list settle before hovering.
|
|
76
|
+
*/
|
|
77
|
+
export const hoverResult = (index = 0) => {
|
|
78
|
+
cy.wait(100);
|
|
79
|
+
getResult(index).realHover();
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Dropping the dictionary without its revalidation timestamp leaves the app
|
|
84
|
+
* throttled against re-downloading a dictionary it no longer has.
|
|
85
|
+
*/
|
|
86
|
+
export const deleteCachedDictionaries = async () => {
|
|
87
|
+
await Promise.all([caches.delete('dictionary-api-cache'), caches.delete('dictionary-revalidated-at')]);
|
|
88
|
+
};
|
|
89
|
+
|
|
71
90
|
export const assertResult = (index: number, word: string, points: number) => {
|
|
72
91
|
getResult(index).should('have.attr', 'aria-label', word).and('include.text', word);
|
|
73
92
|
getResult(index).findByTestId('points').should('have.text', String(points));
|
package/cypress.config.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
import webpackPreprocessor from '@cypress/webpack-batteries-included-preprocessor';
|
|
1
2
|
import { defineConfig } from 'cypress';
|
|
2
3
|
|
|
3
4
|
// eslint-disable-next-line no-restricted-exports
|
|
4
5
|
export default defineConfig({
|
|
5
6
|
e2e: {
|
|
6
7
|
baseUrl: 'http://localhost:3000',
|
|
8
|
+
setupNodeEvents(on) {
|
|
9
|
+
// The preprocessor bundled with Cypress 15.19.0 cannot transpile specs under
|
|
10
|
+
// TypeScript 7 - its @babel/preset-typescript copy ships without a package.json.
|
|
11
|
+
// The npm-published preprocessor is intact, so register it explicitly.
|
|
12
|
+
on('file:preprocessor', webpackPreprocessor({ typescript: require.resolve('typescript') }));
|
|
13
|
+
},
|
|
7
14
|
viewportHeight: 900,
|
|
8
15
|
viewportWidth: 1440,
|
|
9
16
|
},
|
package/lerna.json
CHANGED
package/nx.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scrabble-solver",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.17.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,6 +47,7 @@
|
|
|
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",
|
|
@@ -59,7 +60,7 @@
|
|
|
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",
|
|
61
62
|
"start": "concurrently -n w: bun:start:*",
|
|
62
|
-
"start:app": "bun run --
|
|
63
|
+
"start:app": "bun run --cwd packages/scrabble-solver start",
|
|
63
64
|
"start:browser": "wait-on http://localhost:3333 && open-cli http://localhost:3333",
|
|
64
65
|
"test": "bun run build && bun run test-unit && start-server-and-test start:app http://localhost:3333 test-cypress:run",
|
|
65
66
|
"test-cypress": "cypress open",
|
|
@@ -95,32 +96,31 @@
|
|
|
95
96
|
"packages/scrabble-solver"
|
|
96
97
|
],
|
|
97
98
|
"dependencies": {
|
|
98
|
-
"@scrabble-solver/scrabble-solver": "^2.
|
|
99
|
-
"concurrently": "^10.0.
|
|
99
|
+
"@scrabble-solver/scrabble-solver": "^2.17.0",
|
|
100
|
+
"concurrently": "^10.0.4",
|
|
100
101
|
"open-cli": "^9.0.0",
|
|
101
|
-
"wait-on": "^9.0
|
|
102
|
+
"wait-on": "^9.1.0"
|
|
102
103
|
},
|
|
103
104
|
"devDependencies": {
|
|
104
|
-
"@babel/core": "^7.29.7",
|
|
105
105
|
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
106
|
-
"@
|
|
106
|
+
"@cypress/webpack-batteries-included-preprocessor": "^4.2.0",
|
|
107
|
+
"@cypress/webpack-preprocessor": "^7.1.1",
|
|
107
108
|
"@testing-library/cypress": "^10.1.3",
|
|
108
109
|
"@types/bun": "^1.3.14",
|
|
109
|
-
"@types/node": "^
|
|
110
|
-
"
|
|
111
|
-
"cypress": "^15.17.0",
|
|
110
|
+
"@types/node": "^26.1.2",
|
|
111
|
+
"cypress": "^15.20.0",
|
|
112
112
|
"cypress-real-events": "^1.15.0",
|
|
113
113
|
"eslint-import-resolver-typescript": "^4.4.5",
|
|
114
114
|
"eslint-plugin-import": "^2.32.0",
|
|
115
|
-
"eslint-plugin-mocha": "^
|
|
115
|
+
"eslint-plugin-mocha": "^12.0.2",
|
|
116
116
|
"eslint-plugin-react": "^7.37.5",
|
|
117
|
-
"lerna": "^
|
|
118
|
-
"np": "^
|
|
119
|
-
"oxfmt": "^0.
|
|
120
|
-
"oxlint": "^1.
|
|
121
|
-
"oxlint-tsgolint": "^0.
|
|
117
|
+
"lerna": "^10.0.0",
|
|
118
|
+
"np": "^12.0.1",
|
|
119
|
+
"oxfmt": "^0.62.0",
|
|
120
|
+
"oxlint": "^1.77.0",
|
|
121
|
+
"oxlint-tsgolint": "^7.0.2001",
|
|
122
122
|
"rimraf": "^6.1.3",
|
|
123
|
-
"start-server-and-test": "^3.0.
|
|
124
|
-
"typescript": "^
|
|
123
|
+
"start-server-and-test": "^3.0.12",
|
|
124
|
+
"typescript": "^7.0.2"
|
|
125
125
|
}
|
|
126
126
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrabble-solver/configs",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.17.0",
|
|
4
4
|
"description": "Scrabble Solver 2 - Configs",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
},
|
|
20
20
|
"homepage": "https://scrabble-solver.org",
|
|
21
21
|
"scripts": {
|
|
22
|
-
"build": "
|
|
22
|
+
"build": "tsc --project .",
|
|
23
23
|
"clean": "rimraf build/"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@scrabble-solver/constants": "^2.
|
|
27
|
-
"@scrabble-solver/types": "^2.
|
|
26
|
+
"@scrabble-solver/constants": "^2.17.0",
|
|
27
|
+
"@scrabble-solver/types": "^2.17.0"
|
|
28
28
|
},
|
|
29
29
|
"gitHead": "1e2d1ad49a288d4a44196d8e3336740da132c637"
|
|
30
30
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrabble-solver/constants",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.17.0",
|
|
4
4
|
"description": "Scrabble Solver 2 - Constants",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"homepage": "https://scrabble-solver.org",
|
|
21
21
|
"scripts": {
|
|
22
|
-
"build": "
|
|
22
|
+
"build": "tsc --project .",
|
|
23
23
|
"clean": "rimraf build/"
|
|
24
24
|
},
|
|
25
25
|
"gitHead": "1e2d1ad49a288d4a44196d8e3336740da132c637"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { type
|
|
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<
|
|
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
|
|
20
|
-
if (
|
|
21
|
-
return
|
|
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
|
|
44
|
-
await this.cache.set(locale,
|
|
45
|
-
return
|
|
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 {
|
|
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,
|
|
5
|
-
|
|
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,
|
|
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
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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,
|
|
45
|
-
const filepath = (0, getDictionaryFilepath_1.getDictionaryFilepath)(locale);
|
|
46
|
-
await fs_1.default.promises.writeFile(filepath,
|
|
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
|
|
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,
|
|
4
|
+
export declare class LayeredCache implements Cache<Locale, Gaddag> {
|
|
5
5
|
private readonly layers;
|
|
6
|
-
get(locale: Locale): Promise<
|
|
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,
|
|
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,
|
|
42
|
+
async set(locale, gaddag) {
|
|
43
43
|
const [memoryCache, diskCache] = this.layers;
|
|
44
|
-
await diskCache.set(locale,
|
|
45
|
-
await memoryCache.set(locale,
|
|
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
|
|
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,
|
|
4
|
+
export declare class MemoryCache implements Cache<Locale, Gaddag> {
|
|
5
5
|
private readonly cache;
|
|
6
6
|
private readonly cacheTimestamps;
|
|
7
|
-
get(locale: Locale): Promise<
|
|
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,
|
|
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,
|
|
27
|
+
set(locale, gaddag) {
|
|
28
28
|
this.cacheTimestamps[locale] = Date.now();
|
|
29
|
-
this.cache[locale] =
|
|
29
|
+
this.cache[locale] = gaddag;
|
|
30
30
|
return Promise.resolve();
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
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,
|
|
4
|
+
export declare const createCacheTimestampComparator: (locale: Locale) => (a: Cache<Locale, Gaddag>, b: Cache<Locale, Gaddag>) => number;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Gaddag } from '@kamilmielnik/gaddag';
|
|
2
2
|
import { type Locale } from '@scrabble-solver/types';
|
|
3
|
-
export declare const downloadDictionary: (locale: Locale) => Promise<
|
|
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
|
|
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
|
|
12
|
-
|
|
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(
|
|
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;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrabble-solver/dictionaries",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.17.0",
|
|
4
4
|
"description": "Scrabble Solver 2 - Dictionaries",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -23,16 +23,17 @@
|
|
|
23
23
|
},
|
|
24
24
|
"homepage": "https://scrabble-solver.org",
|
|
25
25
|
"scripts": {
|
|
26
|
-
"build": "
|
|
26
|
+
"build": "tsc --project .",
|
|
27
27
|
"clean": "rimraf build/",
|
|
28
28
|
"clean:dictionaries": "node ./bin/remove-dictionaries.js",
|
|
29
|
-
"postbuild": "node ./bin/update-dictionaries.js"
|
|
29
|
+
"postbuild": "node ./bin/update-dictionaries.js",
|
|
30
|
+
"test": "bun test src"
|
|
30
31
|
},
|
|
31
32
|
"dependencies": {
|
|
32
|
-
"@kamilmielnik/
|
|
33
|
-
"@scrabble-solver/logger": "^2.
|
|
34
|
-
"@scrabble-solver/types": "^2.
|
|
35
|
-
"@scrabble-solver/word-lists": "^2.
|
|
33
|
+
"@kamilmielnik/gaddag": "^2.0.0",
|
|
34
|
+
"@scrabble-solver/logger": "^2.17.0",
|
|
35
|
+
"@scrabble-solver/types": "^2.17.0",
|
|
36
|
+
"@scrabble-solver/word-lists": "^2.17.0"
|
|
36
37
|
},
|
|
37
38
|
"gitHead": "1e2d1ad49a288d4a44196d8e3336740da132c637"
|
|
38
39
|
}
|