@scrabble-solver/scrabble-solver 2.15.8 → 2.15.9
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/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +7 -7
- package/.next/cache/.rscinfo +1 -1
- package/.next/cache/.tsbuildinfo +1 -1
- package/.next/cache/eslint/.cache_8dgz12 +1 -1
- package/.next/cache/webpack/client-production/0.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack.old +0 -0
- package/.next/cache/webpack/edge-server-production/0.pack +0 -0
- package/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/.next/cache/webpack/edge-server-production/index.pack.old +0 -0
- package/.next/cache/webpack/server-production/0.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack.old +0 -0
- package/.next/next-minimal-server.js.nft.json +1 -1
- package/.next/next-server.js.nft.json +1 -1
- package/.next/prerender-manifest.json +4 -4
- package/.next/routes-manifest.json +1 -1
- package/.next/server/chunks/60.js +1 -1
- package/.next/server/chunks/974.js +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/pages/_app.js +1 -1
- package/.next/server/pages/_app.js.nft.json +1 -1
- package/.next/server/pages/_error.js +1 -1
- package/.next/server/pages/_error.js.nft.json +1 -1
- package/.next/server/pages/api/dictionary/[locale]/[word].js +2 -2
- package/.next/server/pages/api/dictionary/[locale]/[word].js.nft.json +1 -1
- package/.next/server/pages/api/dictionary/[locale].js +1 -1
- package/.next/server/pages/api/dictionary/[locale].js.nft.json +1 -1
- package/.next/server/pages/api/solve.js +1 -1
- package/.next/server/pages/api/solve.js.nft.json +1 -1
- package/.next/server/pages/api/verify.js +1 -1
- package/.next/server/pages/api/verify.js.nft.json +1 -1
- package/.next/server/pages/index.html +1 -1
- package/.next/server/pages/index.js +1 -1
- package/.next/server/pages/index.js.nft.json +1 -1
- package/.next/server/pages/index.json +1 -1
- package/.next/server/pages-manifest.json +1 -1
- package/.next/static/chunks/pages/_app-735105409cfdb48f.js +1 -0
- package/.next/static/chunks/webpack-6224d37324e372cb.js +1 -0
- package/.next/trace +23 -23
- package/LICENSE +1 -1
- package/package.json +10 -9
- package/src/components/Board/Board.tsx +1 -1
- package/src/components/Board/hooks/useBoardStyle.ts +1 -1
- package/src/components/Board/hooks/useGrid.ts +5 -5
- package/src/components/EmptyState/EmptyState.tsx +2 -2
- package/src/components/Rack/Rack.tsx +7 -7
- package/src/components/Rack/components/InputPrompt/InputPrompt.tsx +1 -3
- package/src/components/Rack/components/RackTile/RackTile.tsx +6 -4
- package/src/hooks/useEffectOnce.ts +9 -1
- package/src/lib/extractCharacters.test.ts +2 -1
- package/src/lib/extractCharacters.ts +16 -2
- package/src/state/sagas.ts +1 -1
- package/.next/static/chunks/pages/_app-34618eeeff128581.js +0 -1
- package/.next/static/chunks/webpack-4224e970a97a4a86.js +0 -1
- /package/.next/static/{IJuVKnkd8P2us9rVuan82 → 3MlxnccTCLyz9bgD30zY2}/_buildManifest.js +0 -0
- /package/.next/static/{IJuVKnkd8P2us9rVuan82 → 3MlxnccTCLyz9bgD30zY2}/_ssgManifest.js +0 -0
package/LICENSE
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrabble-solver/scrabble-solver",
|
|
3
|
-
"version": "2.15.
|
|
3
|
+
"version": "2.15.9",
|
|
4
4
|
"description": "Scrabble Solver 2 - App",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -27,13 +27,13 @@
|
|
|
27
27
|
"@floating-ui/react": "^0.27.5",
|
|
28
28
|
"@kamilmielnik/trie": "^4.0.0",
|
|
29
29
|
"@reduxjs/toolkit": "^2.6.1",
|
|
30
|
-
"@scrabble-solver/configs": "^2.15.
|
|
31
|
-
"@scrabble-solver/constants": "^2.15.
|
|
32
|
-
"@scrabble-solver/dictionaries": "^2.15.
|
|
33
|
-
"@scrabble-solver/logger": "^2.15.
|
|
34
|
-
"@scrabble-solver/solver": "^2.15.
|
|
35
|
-
"@scrabble-solver/types": "^2.15.
|
|
36
|
-
"@scrabble-solver/word-definitions": "^2.15.
|
|
30
|
+
"@scrabble-solver/configs": "^2.15.9",
|
|
31
|
+
"@scrabble-solver/constants": "^2.15.9",
|
|
32
|
+
"@scrabble-solver/dictionaries": "^2.15.9",
|
|
33
|
+
"@scrabble-solver/logger": "^2.15.9",
|
|
34
|
+
"@scrabble-solver/solver": "^2.15.9",
|
|
35
|
+
"@scrabble-solver/types": "^2.15.9",
|
|
36
|
+
"@scrabble-solver/word-definitions": "^2.15.9",
|
|
37
37
|
"classnames": "^2.5.1",
|
|
38
38
|
"env-cmd": "^10.1.0",
|
|
39
39
|
"include-media": "^2.0.0",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"react-window": "^1.8.11",
|
|
50
50
|
"redux-saga": "^1.3.0",
|
|
51
51
|
"store2": "^2.14.4",
|
|
52
|
+
"transliteration": "^2.3.5",
|
|
52
53
|
"use-debounce": "^10.0.4",
|
|
53
54
|
"workbox-expiration": "^7.3.0",
|
|
54
55
|
"workbox-precaching": "^7.3.0",
|
|
@@ -70,5 +71,5 @@
|
|
|
70
71
|
"@types/redux-saga": "^0.10.5",
|
|
71
72
|
"sass": "^1.86.0"
|
|
72
73
|
},
|
|
73
|
-
"gitHead": "
|
|
74
|
+
"gitHead": "d0654f37094c58a9982d7984e3fc8722f1fa24f0"
|
|
74
75
|
}
|
|
@@ -116,7 +116,7 @@ const Board: FunctionComponent<Props> = ({ className }) => {
|
|
|
116
116
|
dispatch(solveSlice.actions.submit());
|
|
117
117
|
setHasFocus(false);
|
|
118
118
|
},
|
|
119
|
-
[activeIndex, dispatch, locale],
|
|
119
|
+
[activeIndex, dispatch, insertValue, locale],
|
|
120
120
|
);
|
|
121
121
|
|
|
122
122
|
const handleToggleBlank = useCallback(() => {
|
|
@@ -27,7 +27,7 @@ const useBoardStyle = () => {
|
|
|
27
27
|
? `repeat(${config.boardSize}, 1fr)`
|
|
28
28
|
: `${coordinatesSize}px repeat(${config.boardSize}, 1fr)`,
|
|
29
29
|
}),
|
|
30
|
-
[backgroundImage, config.boardSize, tileFontSize],
|
|
30
|
+
[backgroundImage, config.boardSize, coordinatesSize, showCoordinates, tileFontSize],
|
|
31
31
|
);
|
|
32
32
|
|
|
33
33
|
return boardStyle;
|
|
@@ -69,7 +69,7 @@ const useGrid = (rows: Cell[][]): [State, Actions] => {
|
|
|
69
69
|
setActiveIndex({ x, y });
|
|
70
70
|
inputRefs[y][x].current?.focus();
|
|
71
71
|
},
|
|
72
|
-
[safeActiveIndex, inputRefs],
|
|
72
|
+
[safeActiveIndex, height, inputRefs, width],
|
|
73
73
|
);
|
|
74
74
|
|
|
75
75
|
const getInputRefPosition = useCallback(
|
|
@@ -188,7 +188,7 @@ const useGrid = (rows: Cell[][]): [State, Actions] => {
|
|
|
188
188
|
moveFocus(Math.abs(position.x - x) + Math.abs(position.y - y));
|
|
189
189
|
actions.forEach(dispatch);
|
|
190
190
|
},
|
|
191
|
-
[config, directionRef, dispatch, moveFocus, rows],
|
|
191
|
+
[config, directionRef, dispatch, height, moveFocus, rows, width],
|
|
192
192
|
);
|
|
193
193
|
|
|
194
194
|
const onChange = useCallback(
|
|
@@ -219,7 +219,7 @@ const useGrid = (rows: Cell[][]): [State, Actions] => {
|
|
|
219
219
|
|
|
220
220
|
insertValue(position, value);
|
|
221
221
|
},
|
|
222
|
-
[dispatch, insertValue, moveFocus, rows],
|
|
222
|
+
[dispatch, insertValue, moveFocus, rows, getInputRefPosition],
|
|
223
223
|
);
|
|
224
224
|
|
|
225
225
|
const onDirectionToggle = useCallback(() => setLastDirection(toggleDirection), []);
|
|
@@ -347,7 +347,7 @@ const useGrid = (rows: Cell[][]): [State, Actions] => {
|
|
|
347
347
|
dispatch(boardSlice.actions.toggleCellIsBlank(position));
|
|
348
348
|
},
|
|
349
349
|
});
|
|
350
|
-
}, [changeActiveIndex, config, direction, dispatch, locale, moveFocus, onDirectionToggle, rows]);
|
|
350
|
+
}, [changeActiveIndex, config, direction, dispatch, getInputRefPosition, locale, moveFocus, onDirectionToggle, rows]);
|
|
351
351
|
|
|
352
352
|
const onPaste = useCallback<ClipboardEventHandler>(
|
|
353
353
|
(event) => {
|
|
@@ -366,7 +366,7 @@ const useGrid = (rows: Cell[][]): [State, Actions] => {
|
|
|
366
366
|
const value = event.clipboardData.getData('text/plain').toLocaleLowerCase();
|
|
367
367
|
insertValue(position, value);
|
|
368
368
|
},
|
|
369
|
-
[insertValue],
|
|
369
|
+
[getInputRefPosition, insertValue],
|
|
370
370
|
);
|
|
371
371
|
|
|
372
372
|
return [
|
|
@@ -34,9 +34,9 @@ const EmptyState: FunctionComponent<Props> = ({ children, className, variant })
|
|
|
34
34
|
const translate = useTranslate();
|
|
35
35
|
const locale = useTypedSelector(selectLocale);
|
|
36
36
|
const { direction } = LOCALE_FEATURES[locale];
|
|
37
|
-
const title = useMemo(() => translate(TITLE_KEY_PER_TYPE[variant]), [translate]);
|
|
37
|
+
const title = useMemo(() => translate(TITLE_KEY_PER_TYPE[variant]), [translate, variant]);
|
|
38
38
|
const message = direction === 'ltr' ? title : title.split('').reverse().join('');
|
|
39
|
-
const content = useMemo(() => [message.toUpperCase().split(' ')], [
|
|
39
|
+
const content = useMemo(() => [message.toUpperCase().split(' ')], [message]);
|
|
40
40
|
|
|
41
41
|
return (
|
|
42
42
|
<div className={classNames(styles.emptyState, className)}>
|
|
@@ -67,6 +67,11 @@ const Rack: FunctionComponent<Props> = ({ className, tileSize }) => {
|
|
|
67
67
|
const showInputPrompt = inputMode === 'touchscreen' && hasFocus;
|
|
68
68
|
const ref = useRef<HTMLDivElement>(null);
|
|
69
69
|
|
|
70
|
+
const floatingInputPrompt = useFloating({
|
|
71
|
+
placement: 'bottom-start',
|
|
72
|
+
whileElementsMounted: autoUpdate,
|
|
73
|
+
});
|
|
74
|
+
|
|
70
75
|
useOnclickOutside(() => setHasFocus(false), {
|
|
71
76
|
ignoreClass: [InputPrompt.styles.form, InputPrompt.styles.input],
|
|
72
77
|
refs: ref.current ? [ref as RefObject<HTMLDivElement>] : [],
|
|
@@ -120,7 +125,7 @@ const Rack: FunctionComponent<Props> = ({ className, tileSize }) => {
|
|
|
120
125
|
return character.length > 1 ? character.toLocaleUpperCase(locale) : character;
|
|
121
126
|
});
|
|
122
127
|
setInput(uppercasedDigraphs.join(''));
|
|
123
|
-
}, [rack, ref]);
|
|
128
|
+
}, [floatingInputPrompt.refs, locale, rack, ref]);
|
|
124
129
|
|
|
125
130
|
const handleKeyDown = useMemo(() => {
|
|
126
131
|
return createKeyboardNavigation({
|
|
@@ -159,12 +164,7 @@ const Rack: FunctionComponent<Props> = ({ className, tileSize }) => {
|
|
|
159
164
|
}
|
|
160
165
|
},
|
|
161
166
|
});
|
|
162
|
-
}, [changeActiveIndex, config, direction]);
|
|
163
|
-
|
|
164
|
-
const floatingInputPrompt = useFloating({
|
|
165
|
-
placement: 'bottom-start',
|
|
166
|
-
whileElementsMounted: autoUpdate,
|
|
167
|
-
});
|
|
167
|
+
}, [changeActiveIndex, config, direction, dispatch]);
|
|
168
168
|
|
|
169
169
|
return (
|
|
170
170
|
<>
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* eslint-disable max-lines, max-statements */
|
|
2
|
-
|
|
3
1
|
import classNames from 'classnames';
|
|
4
2
|
import {
|
|
5
3
|
CSSProperties,
|
|
@@ -45,7 +43,7 @@ const InputPrompt = forwardRef<HTMLFormElement, Props>(
|
|
|
45
43
|
dispatch(rackSlice.actions.changeCharacters({ characters, index: 0 }));
|
|
46
44
|
onSubmit(event);
|
|
47
45
|
},
|
|
48
|
-
[config, value, onSubmit],
|
|
46
|
+
[config, dispatch, value, onSubmit],
|
|
49
47
|
);
|
|
50
48
|
|
|
51
49
|
useEffect(() => {
|
|
@@ -87,7 +87,7 @@ const RackTile: FunctionComponent<Props> = ({
|
|
|
87
87
|
dispatch(rackSlice.actions.changeCharacters({ characters, index }));
|
|
88
88
|
onChange(event);
|
|
89
89
|
},
|
|
90
|
-
[config, index, onChange],
|
|
90
|
+
[config, dispatch, index, onChange],
|
|
91
91
|
);
|
|
92
92
|
|
|
93
93
|
const handleKeyDown = useMemo(() => {
|
|
@@ -101,14 +101,16 @@ const RackTile: FunctionComponent<Props> = ({
|
|
|
101
101
|
event.preventDefault();
|
|
102
102
|
event.stopPropagation();
|
|
103
103
|
const twoTilesCharacter = config.getTwoCharacterTileByPrefix(event.key);
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
|
|
105
|
+
if (twoTilesCharacter) {
|
|
106
|
+
dispatch(rackSlice.actions.changeCharacter({ character: twoTilesCharacter!, index }));
|
|
107
|
+
}
|
|
106
108
|
}
|
|
107
109
|
|
|
108
110
|
onKeyDown(event);
|
|
109
111
|
},
|
|
110
112
|
});
|
|
111
|
-
}, [index, onKeyDown]);
|
|
113
|
+
}, [config, dispatch, index, onKeyDown]);
|
|
112
114
|
|
|
113
115
|
const handleMouseDown: MouseEventHandler<HTMLInputElement> = useCallback(
|
|
114
116
|
(event) => {
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { EffectCallback, useEffect } from 'react';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import useLatest from './useLatest';
|
|
4
|
+
|
|
5
|
+
const useEffectOnce = (effect: EffectCallback) => {
|
|
6
|
+
const effectRef = useLatest(effect);
|
|
7
|
+
|
|
8
|
+
return useEffect(() => {
|
|
9
|
+
effectRef.current();
|
|
10
|
+
}, [effectRef]);
|
|
11
|
+
};
|
|
4
12
|
|
|
5
13
|
export default useEffectOnce;
|
|
@@ -6,7 +6,8 @@ import extractCharacters from './extractCharacters';
|
|
|
6
6
|
|
|
7
7
|
const tests = [
|
|
8
8
|
{ input: 'ab ', expected: ['a', 'b', BLANK] },
|
|
9
|
-
{ input: 'śćźa', expected: ['a'] },
|
|
9
|
+
{ input: 'śćźa', expected: ['s', 'c', 'z', 'a'] },
|
|
10
|
+
{ input: 'bañó', expected: ['b', 'a', 'ñ', 'o'] },
|
|
10
11
|
{ input: 'bueno', expected: ['b', 'u', 'e', 'n', 'o'] },
|
|
11
12
|
{ input: 'bellas', expected: ['b', 'e', 'll', 'a', 's'] },
|
|
12
13
|
{ input: 'BELLAS', expected: ['b', 'e', 'll', 'a', 's'] },
|
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
import { BLANK } from '@scrabble-solver/constants';
|
|
2
|
-
import { Config } from '@scrabble-solver/types';
|
|
2
|
+
import { Config, Locale } from '@scrabble-solver/types';
|
|
3
|
+
import { transliterate } from 'transliteration';
|
|
4
|
+
|
|
5
|
+
const transliteratePerLocale: Record<Locale, (word: string) => string> = {
|
|
6
|
+
[Locale.DE_DE]: (word) => word,
|
|
7
|
+
[Locale.EN_GB]: (word) => word,
|
|
8
|
+
[Locale.EN_US]: (word) => word,
|
|
9
|
+
[Locale.ES_ES]: (word) => transliterate(word, { ignore: ['ñ'] }),
|
|
10
|
+
[Locale.FA_IR]: (word) => word,
|
|
11
|
+
[Locale.FR_FR]: (word) => transliterate(word),
|
|
12
|
+
[Locale.PL_PL]: (word) => word,
|
|
13
|
+
[Locale.RO_RO]: (word) => transliterate(word),
|
|
14
|
+
[Locale.TR_TR]: (word) => word,
|
|
15
|
+
};
|
|
3
16
|
|
|
4
17
|
const extractCharacters = (config: Config, value: string): string[] => {
|
|
5
18
|
let index = 0;
|
|
6
19
|
const characters: string[] = [];
|
|
7
|
-
const
|
|
20
|
+
const localeTransliterate = transliteratePerLocale[config.locale];
|
|
21
|
+
const valueLowercase = localeTransliterate(value.toLocaleLowerCase(config.locale));
|
|
8
22
|
|
|
9
23
|
while (index < valueLowercase.length) {
|
|
10
24
|
const character = valueLowercase[index];
|
package/src/state/sagas.ts
CHANGED