@johnmorrisdotca/kumimoji 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/CHANGELOG.md +37 -1
  2. package/CONTRIBUTING.md +81 -44
  3. package/README.md +478 -327
  4. package/dist/check.d.ts +26 -1
  5. package/dist/check.js +26 -1
  6. package/dist/computer.types.d.ts +24 -2
  7. package/dist/computerPlay.d.ts +45 -2
  8. package/dist/computerPlay.js +45 -2
  9. package/dist/computerTurn.d.ts +42 -3
  10. package/dist/computerTurn.js +42 -3
  11. package/dist/daily.d.ts +22 -2
  12. package/dist/daily.js +22 -2
  13. package/dist/element-define.d.ts +1 -1
  14. package/dist/element-define.js +3 -13
  15. package/dist/element.d.ts +85 -4
  16. package/dist/element.js +176 -45
  17. package/dist/embed-day.d.ts +4 -0
  18. package/dist/embed-day.js +23 -0
  19. package/dist/export.d.ts +123 -6
  20. package/dist/export.js +91 -4
  21. package/dist/generate.d.ts +14 -0
  22. package/dist/generate.js +14 -0
  23. package/dist/grid.d.ts +181 -10
  24. package/dist/grid.js +122 -7
  25. package/dist/help.d.ts +36 -3
  26. package/dist/help.js +36 -3
  27. package/dist/judge.d.ts +14 -0
  28. package/dist/judge.js +14 -0
  29. package/dist/kana.d.ts +23 -1
  30. package/dist/kana.js +23 -1
  31. package/dist/kumimoji.types.d.ts +70 -5
  32. package/dist/party.d.ts +268 -14
  33. package/dist/party.js +268 -14
  34. package/dist/party.types.d.ts +50 -2
  35. package/dist/partyKept.d.ts +74 -4
  36. package/dist/partyKept.js +74 -4
  37. package/dist/partySeats.d.ts +92 -6
  38. package/dist/partySeats.js +72 -4
  39. package/dist/partyTurns.d.ts +171 -5
  40. package/dist/partyTurns.js +171 -5
  41. package/dist/placement.d.ts +50 -2
  42. package/dist/placement.js +30 -0
  43. package/dist/play.d.ts +247 -15
  44. package/dist/play.js +237 -15
  45. package/dist/random.d.ts +34 -3
  46. package/dist/random.js +23 -2
  47. package/dist/react.d.ts +42 -4
  48. package/dist/react.js +22 -5
  49. package/dist/showcase.d.ts +83 -7
  50. package/dist/showcase.js +49 -4
  51. package/dist/strings.d.ts +54 -5
  52. package/dist/strings.js +34 -3
  53. package/dist/tableView.d.ts +151 -8
  54. package/dist/tableView.js +129 -6
  55. package/dist/tileFace.d.ts +59 -5
  56. package/dist/tileFace.js +48 -4
  57. package/dist/tileFamily.d.ts +9 -0
  58. package/dist/tileFamily.js +9 -0
  59. package/dist/tileWords.d.ts +93 -6
  60. package/dist/tileWords.js +83 -6
  61. package/dist/tileWordsModule.d.ts +11 -1
  62. package/dist/tileWordsModule.js +11 -1
  63. package/dist/tiles.constants.d.ts +99 -5
  64. package/dist/tiles.constants.js +99 -5
  65. package/dist/turn.d.ts +82 -4
  66. package/dist/turn.js +82 -4
  67. package/dist/ui/board.d.ts +60 -5
  68. package/dist/ui/board.js +28 -2
  69. package/dist/ui/mount.d.ts +41 -2
  70. package/dist/ui/mount.js +38 -1
  71. package/dist/ui/style.d.ts +6 -1
  72. package/dist/ui/style.js +6 -0
  73. package/dist/version.d.ts +9 -2
  74. package/dist/version.js +9 -2
  75. package/dist/wilds.d.ts +22 -1
  76. package/dist/wilds.js +22 -1
  77. package/package.json +66 -57
package/dist/random.d.ts CHANGED
@@ -4,9 +4,40 @@
4
4
  * is small, fast and good enough for shuffling tiles; nothing here is a
5
5
  * credential.
6
6
  */
7
- /** A number in [0, 1), like `Math.random`, from a stream a seed fixes. */
7
+ /** A number in [0, 1), like `Math.random`, from a stream a seed fixes.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import type { Random } from "@johnmorrisdotca/kumimoji";
12
+ * import { seededRandom } from "@johnmorrisdotca/kumimoji";
13
+ *
14
+ * const value: Random = seededRandom(42);
15
+ * console.log(value);
16
+ * ```
17
+ */
8
18
  export type Random = () => number;
9
- /** A stream of numbers in [0, 1) that the seed fixes: mulberry32. */
19
+ /** A stream of numbers in [0, 1) that the seed fixes: mulberry32.
20
+ *
21
+ * @param seed - The numeric seed for deterministic deals or random draws.
22
+ * @returns A stream of numbers in [0, 1) that the seed fixes: mulberry32.
23
+ * @example
24
+ * ```ts
25
+ * import { seededRandom } from "@johnmorrisdotca/kumimoji";
26
+ *
27
+ * console.log(seededRandom(42)());
28
+ * ```
29
+ */
10
30
  export declare function seededRandom(seed: number): Random;
11
- /** A copy of the list in a random order (Fisher–Yates). */
31
+ /** A copy of the list in a random order (Fisher–Yates).
32
+ *
33
+ * @param items - The items to copy and shuffle.
34
+ * @param random - A reproducible random function returning values in [0,1).
35
+ * @returns A copy of the list in a random order (Fisher–Yates).
36
+ * @example
37
+ * ```ts
38
+ * import { seededRandom, shuffled } from "@johnmorrisdotca/kumimoji";
39
+ *
40
+ * console.log(shuffled(["c","a","t"],seededRandom(42)));
41
+ * ```
42
+ */
12
43
  export declare function shuffled<T>(items: readonly T[], random: Random): T[];
package/dist/random.js CHANGED
@@ -4,7 +4,17 @@
4
4
  * is small, fast and good enough for shuffling tiles; nothing here is a
5
5
  * credential.
6
6
  */
7
- /** A stream of numbers in [0, 1) that the seed fixes: mulberry32. */
7
+ /** A stream of numbers in [0, 1) that the seed fixes: mulberry32.
8
+ *
9
+ * @param seed - The numeric seed for deterministic deals or random draws.
10
+ * @returns A stream of numbers in [0, 1) that the seed fixes: mulberry32.
11
+ * @example
12
+ * ```ts
13
+ * import { seededRandom } from "@johnmorrisdotca/kumimoji";
14
+ *
15
+ * console.log(seededRandom(42)());
16
+ * ```
17
+ */
8
18
  export function seededRandom(seed) {
9
19
  let state = seed >>> 0;
10
20
  return () => {
@@ -15,7 +25,18 @@ export function seededRandom(seed) {
15
25
  return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
16
26
  };
17
27
  }
18
- /** A copy of the list in a random order (Fisher–Yates). */
28
+ /** A copy of the list in a random order (Fisher–Yates).
29
+ *
30
+ * @param items - The items to copy and shuffle.
31
+ * @param random - A reproducible random function returning values in [0,1).
32
+ * @returns A copy of the list in a random order (Fisher–Yates).
33
+ * @example
34
+ * ```ts
35
+ * import { seededRandom, shuffled } from "@johnmorrisdotca/kumimoji";
36
+ *
37
+ * console.log(shuffled(["c","a","t"],seededRandom(42)));
38
+ * ```
39
+ */
19
40
  export function shuffled(items, random) {
20
41
  const out = [...items];
21
42
  for (let i = out.length - 1; i > 0; i -= 1) {
package/dist/react.d.ts CHANGED
@@ -1,7 +1,21 @@
1
1
  import { type HTMLAttributes } from "react";
2
2
  import type { GridVerdict, Tiles } from "./grid.ts";
3
3
  import { type KumimojiTableOptions } from "./ui/mount.ts";
4
- /** What `KumimojiBoard` takes: a grid to draw, and any attribute of its `<div>`. */
4
+ /** What `KumimojiBoard` takes: a grid to draw, and any attribute of its `<div>`.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * import { loadTileWordsFromModule } from "@johnmorrisdotca/kumimoji/words";
9
+ * import { judgeWithWords } from "@johnmorrisdotca/kumimoji";
10
+ * import type { KumimojiBoardProps } from "@johnmorrisdotca/kumimoji/react";
11
+ *
12
+ * const words = await loadTileWordsFromModule("english");
13
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
14
+ * const verdict = judgeWithWords(new Map([["0,0","c"],["0,1","a"],["0,2","t"]]),words);
15
+ * const value: KumimojiBoardProps = {tiles,verdict:null};
16
+ * console.log(value);
17
+ * ```
18
+ */
5
19
  export type KumimojiBoardProps = {
6
20
  /** The tiles on the table, by square: `play.tiles`. */
7
21
  tiles: Tiles;
@@ -22,14 +36,38 @@ export type KumimojiBoardProps = {
22
36
  * apart from the crossword faded, and a press on any square reported by its
23
37
  * key (`squareAt(row, col)`). It draws; what a press does is yours to decide
24
38
  * with `placeFromHand`, `moveOnTable` and the rest.
39
+ *
40
+ * @param options - Native game, component or presentation options.
41
+ * @returns The React grid element.
42
+ * @example
43
+ * ```ts no-run
44
+ * import {createElement} from "react";
45
+ * import { KumimojiBoard } from "@johnmorrisdotca/kumimoji/react";
46
+ * console.log(createElement(KumimojiBoard,{tiles:new Map([["0,0","c"]])}));
47
+ * ```
25
48
  */
26
49
  export declare function KumimojiBoard({ tiles, verdict, glyphOf, onSquare, held, square, style, ...element }: KumimojiBoardProps): import("react").JSX.Element;
27
- /** What `KumimojiTable` takes: the options of `mountKumimoji`, and any attribute of its `<div>`. */
50
+ /**
51
+ * Native table options, readiness/error choices and attributes of the host div.
52
+ * @example
53
+ * ```ts
54
+ * import type { KumimojiTableProps } from "@johnmorrisdotca/kumimoji/react";
55
+ * const props: KumimojiTableProps = { controls: true, keep: false, onError: error => console.log(error.message) };
56
+ * console.log(props.controls);
57
+ * ```
58
+ */
28
59
  export type KumimojiTableProps = KumimojiTableOptions & Omit<HTMLAttributes<HTMLDivElement>, keyof KumimojiTableOptions>;
29
60
  /**
30
61
  * A whole game alone, as a React component: the plain-DOM table
31
62
  * (`mountKumimoji`) mounted into this component's element once the browser
32
63
  * has it. Options are read when it mounts; give it a new `key` to start over
33
- * with different ones.
64
+ * with different ones. Native callbacks are forwarded independently of host DOM events.
65
+ * @param props - Native table choices and host-div attributes.
66
+ * @returns A div whose effect owns the native table and cleanup.
67
+ * @example
68
+ * ```ts
69
+ * import { KumimojiTable } from "@johnmorrisdotca/kumimoji/react";
70
+ * console.log(typeof KumimojiTable);
71
+ * ```
34
72
  */
35
- export declare function KumimojiTable({ language, hand, level, gameLength, diagonals, seed, onFinish, onChange, locale, strings, theme, keep, ...element }: KumimojiTableProps): import("react").JSX.Element;
73
+ export declare function KumimojiTable(props: KumimojiTableProps): import("react").JSX.Element;
package/dist/react.js CHANGED
@@ -17,6 +17,15 @@ const TILE = {
17
17
  * apart from the crossword faded, and a press on any square reported by its
18
18
  * key (`squareAt(row, col)`). It draws; what a press does is yours to decide
19
19
  * with `placeFromHand`, `moveOnTable` and the rest.
20
+ *
21
+ * @param options - Native game, component or presentation options.
22
+ * @returns The React grid element.
23
+ * @example
24
+ * ```ts no-run
25
+ * import {createElement} from "react";
26
+ * import { KumimojiBoard } from "@johnmorrisdotca/kumimoji/react";
27
+ * console.log(createElement(KumimojiBoard,{tiles:new Map([["0,0","c"]])}));
28
+ * ```
20
29
  */
21
30
  export function KumimojiBoard({ tiles, verdict = null, glyphOf, onSquare, held = null, square = 36, style, ...element }) {
22
31
  const model = boardModel(tiles, verdict, glyphOf);
@@ -32,19 +41,27 @@ export function KumimojiBoard({ tiles, verdict = null, glyphOf, onSquare, held =
32
41
  * A whole game alone, as a React component: the plain-DOM table
33
42
  * (`mountKumimoji`) mounted into this component's element once the browser
34
43
  * has it. Options are read when it mounts; give it a new `key` to start over
35
- * with different ones.
44
+ * with different ones. Native callbacks are forwarded independently of host DOM events.
45
+ * @param props - Native table choices and host-div attributes.
46
+ * @returns A div whose effect owns the native table and cleanup.
47
+ * @example
48
+ * ```ts
49
+ * import { KumimojiTable } from "@johnmorrisdotca/kumimoji/react";
50
+ * console.log(typeof KumimojiTable);
51
+ * ```
36
52
  */
37
- export function KumimojiTable({ language, hand, level, gameLength, diagonals, seed, onFinish, onChange, locale, strings, theme, keep, ...element }) {
53
+ export function KumimojiTable(props) {
54
+ const { language, hand, level, gameLength, diagonals, seed, onFinish, onChange, locale, strings, theme, keep, controls, saved, onError, ...element } = props;
38
55
  const host = useRef(null);
39
- const latest = useRef({ onFinish, onChange });
56
+ const latest = useRef({ onFinish, onChange, onError });
40
57
  useEffect(() => {
41
- latest.current = { onFinish, onChange };
58
+ latest.current = { onFinish, onChange, onError };
42
59
  });
43
60
  useEffect(() => {
44
61
  const target = host.current;
45
62
  if (target === null)
46
63
  return;
47
- const table = mountKumimoji(target, { language, hand, level, gameLength, diagonals, seed, locale, strings, theme, keep, onFinish: (result) => latest.current.onFinish?.(result), onChange: (saved) => latest.current.onChange?.(saved) });
64
+ const table = mountKumimoji(target, { language, hand, level, gameLength, diagonals, seed, locale, strings, theme, keep, controls, saved, onError: error => latest.current.onError?.(error), onFinish: (result) => latest.current.onFinish?.(result), onChange: (saved) => latest.current.onChange?.(saved) });
48
65
  return () => table.destroy();
49
66
  // Mounted once per key, as documented above.
50
67
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -6,14 +6,35 @@ import type { KumimojiLanguage, KumimojiLength } from "./kumimoji.types.ts";
6
6
  * each length of game deals. Pure, so the rules page draws it at build time
7
7
  * and the tests hold it to the constants.
8
8
  */
9
- /** One kind of tile in a set: the code the game deals, what is printed on it, what shows in its corner, and how many the set holds. */
9
+ /** One kind of tile in a set: the code the game deals, what is printed on it, what shows in its corner, and how many the set holds.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * import type { MixTile } from "@johnmorrisdotca/kumimoji";
14
+ *
15
+ * const value: MixTile = {code:"c",glyph:"c",forms:"",count:2};
16
+ * console.log(value);
17
+ * ```
18
+ */
10
19
  export type MixTile = {
11
20
  code: string;
12
21
  glyph: string;
13
22
  forms: string;
14
23
  count: number;
15
24
  };
16
- /** A whole set, in its own order (a to z, あ to ん), with what a reader needs to see how uneven it is. */
25
+ /** A whole set, in its own order (a to z, あ to ん), with what a reader needs to see how uneven it is.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * import type { MixShown } from "@johnmorrisdotca/kumimoji";
30
+ * import { mixShown } from "@johnmorrisdotca/kumimoji";
31
+ * import { loadTileWordsFromModule } from "@johnmorrisdotca/kumimoji/words";
32
+ *
33
+ * await loadTileWordsFromModule("english");
34
+ * const value: MixShown = mixShown("english");
35
+ * console.log(value);
36
+ * ```
37
+ */
17
38
  export type MixShown = {
18
39
  tiles: MixTile[];
19
40
  total: number;
@@ -25,11 +46,43 @@ export type MixShown = {
25
46
  /** The tiles with the most, the ones a hand is full of. */
26
47
  commonest: string[];
27
48
  };
28
- /** A language's set as a page shows it: every tile with its count, the total, and which are the rarest and the commonest. */
49
+ /** A language's set as a page shows it: every tile with its count, the total, and which are the rarest and the commonest.
50
+ *
51
+ * @param language - The English or Japanese tile language.
52
+ * @returns A language's set as a page shows it: every tile with its count, the total, and which are the rarest and the commonest.
53
+ * @example
54
+ * ```ts
55
+ * import { mixShown } from "@johnmorrisdotca/kumimoji";
56
+ * import { loadTileWordsFromModule } from "@johnmorrisdotca/kumimoji/words";
57
+ *
58
+ * await loadTileWordsFromModule("english");
59
+ * console.log(mixShown("english").total);
60
+ * ```
61
+ */
29
62
  export declare function mixShown(language: KumimojiLanguage): MixShown;
30
- /** Every hiragana a tile plays as, itself first: は is は, ば and ぱ. None for a kana that is not a tile's own. */
63
+ /** Every hiragana a tile plays as, itself first: は is は, ば and ぱ. None for a kana that is not a tile's own.
64
+ *
65
+ * @param kana - The hiragana reading to map to a base tile.
66
+ * @returns Every hiragana a tile plays as, itself first: は is は, ば and ぱ. None for a kana that is not a tile's own.
67
+ * @example
68
+ * ```ts
69
+ * import { formsOfTile } from "@johnmorrisdotca/kumimoji";
70
+ *
71
+ * console.log(formsOfTile("は"));
72
+ * ```
73
+ */
31
74
  export declare function formsOfTile(kana: string): string[];
32
- /** One length of game at one opening hand: how many tiles it deals from one set and from two, and how many of them are wild at each level. */
75
+ /** One length of game at one opening hand: how many tiles it deals from one set and from two, and how many of them are wild at each level.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * import type { LengthRow } from "@johnmorrisdotca/kumimoji";
80
+ * import { lengthRows } from "@johnmorrisdotca/kumimoji";
81
+ *
82
+ * const value: LengthRow = lengthRows(7)[0];
83
+ * console.log(value);
84
+ * ```
85
+ */
33
86
  export type LengthRow = {
34
87
  length: KumimojiLength;
35
88
  tiles: number;
@@ -37,9 +90,26 @@ export type LengthRow = {
37
90
  doubleTiles: number;
38
91
  wilds: Record<"easy" | "medium" | "hard", number>;
39
92
  };
40
- /** The lengths of game, shortest first. */
93
+ /** The lengths of game, shortest first.
94
+ *
95
+ * @example
96
+ * ```ts
97
+ * import { LENGTHS } from "@johnmorrisdotca/kumimoji";
98
+ * console.log(LENGTHS);
99
+ * ```
100
+ */
41
101
  export declare const LENGTHS: readonly KumimojiLength[];
42
- /** For one opening hand, each length of game: how many tiles it deals, from one set and from two, and how many are wild at each level. */
102
+ /** For one opening hand, each length of game: how many tiles it deals, from one set and from two, and how many are wild at each level.
103
+ *
104
+ * @param hand - The hand size or tile codes, as declared by the function signature.
105
+ * @returns For one opening hand, each length of game: how many tiles it deals, from one set and from two, and how many are wild at each level.
106
+ * @example
107
+ * ```ts
108
+ * import { lengthRows } from "@johnmorrisdotca/kumimoji";
109
+ *
110
+ * console.log(lengthRows(7));
111
+ * ```
112
+ */
43
113
  export declare function lengthRows(hand?: number): LengthRow[];
44
114
  /**
45
115
  * THE TRY-IT ON THE FRONT DOOR: a Kumimoji of ten tiles, played in the
@@ -48,6 +118,12 @@ export declare function lengthRows(hand?: number): LengthRow[];
48
118
  * fixed rather than dealt, so the page is the same for everybody and needs no
49
119
  * generator; `showcase.test.ts` proves it can be finished, with a crossword
50
120
  * checked against the real list.
121
+ *
122
+ * @example
123
+ * ```ts
124
+ * import { TRY_IT } from "@johnmorrisdotca/kumimoji";
125
+ * console.log(TRY_IT);
126
+ * ```
51
127
  */
52
128
  export declare const TRY_IT: {
53
129
  readonly bag: "rotenasdi*";
package/dist/showcase.js CHANGED
@@ -1,7 +1,19 @@
1
1
  import { BASE_KANA, CORNER_FORMS, tileKana } from "./kana.js";
2
2
  import { kanaTileCode } from "./tileFace.js";
3
3
  import { JAPANESE_TILE_MIX, KUMIMOJI_HANDS, TILE_MIX, kumimojiTileCount, kumimojiWildCount } from "./tiles.constants.js";
4
- /** A language's set as a page shows it: every tile with its count, the total, and which are the rarest and the commonest. */
4
+ /** A language's set as a page shows it: every tile with its count, the total, and which are the rarest and the commonest.
5
+ *
6
+ * @param language - The English or Japanese tile language.
7
+ * @returns A language's set as a page shows it: every tile with its count, the total, and which are the rarest and the commonest.
8
+ * @example
9
+ * ```ts
10
+ * import { mixShown } from "@johnmorrisdotca/kumimoji";
11
+ * import { loadTileWordsFromModule } from "@johnmorrisdotca/kumimoji/words";
12
+ *
13
+ * await loadTileWordsFromModule("english");
14
+ * console.log(mixShown("english").total);
15
+ * ```
16
+ */
5
17
  export function mixShown(language) {
6
18
  const tiles = language === "english"
7
19
  ? Object.entries(TILE_MIX).map(([letter, count]) => ({ code: letter, glyph: letter, forms: "", count }))
@@ -26,7 +38,17 @@ export function mixShown(language) {
26
38
  */
27
39
  const HIRAGANA_FIRST = 0x3041;
28
40
  const HIRAGANA_LAST = 0x3096;
29
- /** Every hiragana a tile plays as, itself first: は is は, ば and ぱ. None for a kana that is not a tile's own. */
41
+ /** Every hiragana a tile plays as, itself first: は is は, ば and ぱ. None for a kana that is not a tile's own.
42
+ *
43
+ * @param kana - The hiragana reading to map to a base tile.
44
+ * @returns Every hiragana a tile plays as, itself first: は is は, ば and ぱ. None for a kana that is not a tile's own.
45
+ * @example
46
+ * ```ts
47
+ * import { formsOfTile } from "@johnmorrisdotca/kumimoji";
48
+ *
49
+ * console.log(formsOfTile("は"));
50
+ * ```
51
+ */
30
52
  export function formsOfTile(kana) {
31
53
  if (tileKana(kana) !== kana)
32
54
  return [];
@@ -38,9 +60,26 @@ export function formsOfTile(kana) {
38
60
  }
39
61
  return forms;
40
62
  }
41
- /** The lengths of game, shortest first. */
63
+ /** The lengths of game, shortest first.
64
+ *
65
+ * @example
66
+ * ```ts
67
+ * import { LENGTHS } from "@johnmorrisdotca/kumimoji";
68
+ * console.log(LENGTHS);
69
+ * ```
70
+ */
42
71
  export const LENGTHS = ["short", "medium", "full"];
43
- /** For one opening hand, each length of game: how many tiles it deals, from one set and from two, and how many are wild at each level. */
72
+ /** For one opening hand, each length of game: how many tiles it deals, from one set and from two, and how many are wild at each level.
73
+ *
74
+ * @param hand - The hand size or tile codes, as declared by the function signature.
75
+ * @returns For one opening hand, each length of game: how many tiles it deals, from one set and from two, and how many are wild at each level.
76
+ * @example
77
+ * ```ts
78
+ * import { lengthRows } from "@johnmorrisdotca/kumimoji";
79
+ *
80
+ * console.log(lengthRows(7));
81
+ * ```
82
+ */
44
83
  export function lengthRows(hand = KUMIMOJI_HANDS.classic) {
45
84
  return LENGTHS.map((length) => {
46
85
  const tiles = kumimojiTileCount(hand, length);
@@ -59,5 +98,11 @@ export function lengthRows(hand = KUMIMOJI_HANDS.classic) {
59
98
  * fixed rather than dealt, so the page is the same for everybody and needs no
60
99
  * generator; `showcase.test.ts` proves it can be finished, with a crossword
61
100
  * checked against the real list.
101
+ *
102
+ * @example
103
+ * ```ts
104
+ * import { TRY_IT } from "@johnmorrisdotca/kumimoji";
105
+ * console.log(TRY_IT);
106
+ * ```
62
107
  */
63
108
  export const TRY_IT = { bag: "rotenasdi*", hand: 7 };
package/dist/strings.d.ts CHANGED
@@ -11,10 +11,20 @@
11
11
  * `docs/strings-ja.md` lists the two languages side by side and is made from
12
12
  * this file.
13
13
  */
14
- /** The languages the table speaks: English and Japanese. */
14
+ /** The languages the table speaks: English and Japanese.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import type { KumimojiLocale } from "@johnmorrisdotca/kumimoji/ui";
19
+ *
20
+ * const value: KumimojiLocale = "ja";
21
+ * console.log(value);
22
+ * ```
23
+ */
15
24
  export type KumimojiLocale = "en" | "ja";
16
25
  declare const EN: {
17
26
  dealing: string;
27
+ loadError: string;
18
28
  leftOne: string;
19
29
  left: string;
20
30
  finished: string;
@@ -50,14 +60,53 @@ declare const EN: {
50
60
  english: string;
51
61
  japanese: string;
52
62
  };
53
- /** Every word the table shows, by name: one table of these for each language. */
63
+ /** Every word the table shows, by name: one table of these for each language.
64
+ *
65
+ * @example
66
+ * ```ts
67
+ * import type { KumimojiStrings } from "@johnmorrisdotca/kumimoji/ui";
68
+ * import { kumimojiStrings } from "@johnmorrisdotca/kumimoji/ui";
69
+ *
70
+ * const value: KumimojiStrings = kumimojiStrings("ja");
71
+ * console.log(value);
72
+ * ```
73
+ */
54
74
  export type KumimojiStrings = {
55
75
  [Name in keyof typeof EN]: string;
56
76
  };
57
- /** The table's words in each language it speaks: `KUMIMOJI_STRINGS.en`, `KUMIMOJI_STRINGS.ja`. */
77
+ /** The table's words in each language it speaks: `KUMIMOJI_STRINGS.en`, `KUMIMOJI_STRINGS.ja`.
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * import { KUMIMOJI_STRINGS } from "@johnmorrisdotca/kumimoji/ui";
82
+ * console.log(KUMIMOJI_STRINGS);
83
+ * ```
84
+ */
58
85
  export declare const KUMIMOJI_STRINGS: Readonly<Record<KumimojiLocale, KumimojiStrings>>;
59
- /** A line from a table of strings with its braces filled in: `kumimojiSay(strings.left, { n: 12, time: "1:05" })`. A brace with no value is left as it is. */
86
+ /** A line from a table of strings with its braces filled in: `kumimojiSay(strings.left, { n: 12, time: "1:05" })`. A brace with no value is left as it is.
87
+ *
88
+ * @param line - Text containing named replacement braces.
89
+ * @param values - Replacement text or numbers keyed by brace name.
90
+ * @returns A line from a table of strings with its braces filled in: `kumimojiSay(strings.left, { n: 12, time: "1:05" })`. A brace with no value is left as it is.
91
+ * @example
92
+ * ```ts
93
+ * import { kumimojiSay } from "@johnmorrisdotca/kumimoji/ui";
94
+ *
95
+ * console.log(kumimojiSay("Tile {n}",{n:3}));
96
+ * ```
97
+ */
60
98
  export declare function kumimojiSay(line: string, values?: Readonly<Record<string, string | number>>): string;
61
- /** The table of strings for a locale with a page's own words laid over it. An unknown locale is English. */
99
+ /** The table of strings for a locale with a page's own words laid over it. An unknown locale is English.
100
+ *
101
+ * @param locale - The requested display language tag.
102
+ * @param own - Optional overrides for built-in display words.
103
+ * @returns The table of strings for a locale with a page's own words laid over it. An unknown locale is English.
104
+ * @example
105
+ * ```ts
106
+ * import { kumimojiStrings } from "@johnmorrisdotca/kumimoji/ui";
107
+ *
108
+ * console.log(Object.keys(kumimojiStrings("ja")).length);
109
+ * ```
110
+ */
62
111
  export declare function kumimojiStrings(locale: KumimojiLocale | string | undefined, own?: Partial<KumimojiStrings>): KumimojiStrings;
63
112
  export {};
package/dist/strings.js CHANGED
@@ -13,6 +13,7 @@
13
13
  */
14
14
  const EN = {
15
15
  dealing: "Dealing…",
16
+ loadError: "The word list could not be loaded. Try again.",
16
17
  leftOne: "1 tile left in the bag · {time}",
17
18
  left: "{n} tiles left in the bag · {time}",
18
19
  finished: "Finished in {time}. Every tile laid, every run a word.",
@@ -50,6 +51,7 @@ const EN = {
50
51
  };
51
52
  const JA = {
52
53
  dealing: "配っています…",
54
+ loadError: "単語の一覧を読み込めませんでした。もう一度お試しください。",
53
55
  leftOne: "袋の残り1枚 · {time}",
54
56
  left: "袋の残り{n}枚 · {time}",
55
57
  finished: "{time}で完成しました。すべてのタイルを置き、どの並びも単語になっています。",
@@ -85,13 +87,42 @@ const JA = {
85
87
  english: "英語",
86
88
  japanese: "日本語",
87
89
  };
88
- /** The table's words in each language it speaks: `KUMIMOJI_STRINGS.en`, `KUMIMOJI_STRINGS.ja`. */
90
+ /** The table's words in each language it speaks: `KUMIMOJI_STRINGS.en`, `KUMIMOJI_STRINGS.ja`.
91
+ *
92
+ * @example
93
+ * ```ts
94
+ * import { KUMIMOJI_STRINGS } from "@johnmorrisdotca/kumimoji/ui";
95
+ * console.log(KUMIMOJI_STRINGS);
96
+ * ```
97
+ */
89
98
  export const KUMIMOJI_STRINGS = { en: EN, ja: JA };
90
- /** A line from a table of strings with its braces filled in: `kumimojiSay(strings.left, { n: 12, time: "1:05" })`. A brace with no value is left as it is. */
99
+ /** A line from a table of strings with its braces filled in: `kumimojiSay(strings.left, { n: 12, time: "1:05" })`. A brace with no value is left as it is.
100
+ *
101
+ * @param line - Text containing named replacement braces.
102
+ * @param values - Replacement text or numbers keyed by brace name.
103
+ * @returns A line from a table of strings with its braces filled in: `kumimojiSay(strings.left, { n: 12, time: "1:05" })`. A brace with no value is left as it is.
104
+ * @example
105
+ * ```ts
106
+ * import { kumimojiSay } from "@johnmorrisdotca/kumimoji/ui";
107
+ *
108
+ * console.log(kumimojiSay("Tile {n}",{n:3}));
109
+ * ```
110
+ */
91
111
  export function kumimojiSay(line, values = {}) {
92
112
  return line.replace(/\{(\w+)\}/g, (whole, name) => (name in values ? String(values[name]) : whole));
93
113
  }
94
- /** The table of strings for a locale with a page's own words laid over it. An unknown locale is English. */
114
+ /** The table of strings for a locale with a page's own words laid over it. An unknown locale is English.
115
+ *
116
+ * @param locale - The requested display language tag.
117
+ * @param own - Optional overrides for built-in display words.
118
+ * @returns The table of strings for a locale with a page's own words laid over it. An unknown locale is English.
119
+ * @example
120
+ * ```ts
121
+ * import { kumimojiStrings } from "@johnmorrisdotca/kumimoji/ui";
122
+ *
123
+ * console.log(Object.keys(kumimojiStrings("ja")).length);
124
+ * ```
125
+ */
95
126
  export function kumimojiStrings(locale, own = {}) {
96
127
  const base = typeof locale === "string" && locale.toLowerCase().startsWith("ja") ? JA : EN;
97
128
  return { ...base, ...own };