lettras 0.1.0 → 0.2.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.
@@ -15,6 +15,21 @@ export interface GenerateInput {
15
15
  fill?: string;
16
16
  }
17
17
  export interface Placement { word: string; r: number; c: number; dr: number; dc: number; length: number }
18
+ export interface FillInput {
19
+ grid: string[][];
20
+ lang?: string;
21
+ accents?: boolean;
22
+ seed?: number;
23
+ empty?: string;
24
+ words?: string[];
25
+ }
26
+ export interface FillOutput {
27
+ grid: string[][];
28
+ filled: number;
29
+ seed: number;
30
+ ambiguous: string[];
31
+ engineVersion: string;
32
+ }
18
33
  export interface GenerateOutput {
19
34
  grid: string[][];
20
35
  placements: Placement[];
@@ -27,6 +42,11 @@ export interface GenerateOutput {
27
42
 
28
43
 
29
44
 
45
+ /**
46
+ * `fill(inputJson) -> outputJson`: random letters for the empty cells of a grid. Throws on invalid input.
47
+ */
48
+ export function fill(input_json: string): string;
49
+
30
50
  /**
31
51
  * `generate(inputJson) -> outputJson`. Throws on invalid input.
32
52
  */
@@ -41,6 +61,7 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
41
61
 
42
62
  export interface InitOutput {
43
63
  readonly memory: WebAssembly.Memory;
64
+ readonly fill: (a: number, b: number, c: number) => void;
44
65
  readonly generate: (a: number, b: number, c: number) => void;
45
66
  readonly renderPuzzle: (a: number, b: number, c: number) => void;
46
67
  readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
@@ -1,5 +1,37 @@
1
1
  /* @ts-self-types="./lettras_engine.d.ts" */
2
2
 
3
+ /**
4
+ * `fill(inputJson) -> outputJson`: random letters for the empty cells of a grid. Throws on invalid input.
5
+ * @param {string} input_json
6
+ * @returns {string}
7
+ */
8
+ export function fill(input_json) {
9
+ let deferred3_0;
10
+ let deferred3_1;
11
+ try {
12
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
13
+ const ptr0 = passStringToWasm0(input_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
14
+ const len0 = WASM_VECTOR_LEN;
15
+ wasm.fill(retptr, ptr0, len0);
16
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
17
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
18
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
19
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
20
+ var ptr2 = r0;
21
+ var len2 = r1;
22
+ if (r3) {
23
+ ptr2 = 0; len2 = 0;
24
+ throw takeObject(r2);
25
+ }
26
+ deferred3_0 = ptr2;
27
+ deferred3_1 = len2;
28
+ return getStringFromWasm0(ptr2, len2);
29
+ } finally {
30
+ wasm.__wbindgen_add_to_stack_pointer(16);
31
+ wasm.__wbindgen_export3(deferred3_0, deferred3_1, 1);
32
+ }
33
+ }
34
+
3
35
  /**
4
36
  * `generate(inputJson) -> outputJson`. Throws on invalid input.
5
37
  * @param {string} input_json
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lettras",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Word-search generator for 6 languages with native accented letters (es, en, pt, fr, de, it). Runs locally via WebAssembly. Library and CLI.",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
package/src/index.d.ts CHANGED
@@ -1,9 +1,21 @@
1
- import type { GenerateInput, GenerateOutput, Placement, Position } from '../engine/index.js';
1
+ import type { FillInput, FillOutput, GenerateInput, GenerateOutput, Placement, Position } from '../engine/index.js';
2
2
 
3
- export type { GenerateInput, GenerateOutput, Placement, Position };
3
+ export type { FillInput, FillOutput, GenerateInput, GenerateOutput, Placement, Position };
4
+
5
+ /** Options for {@link fill}: everything in {@link FillInput} except the grid. */
6
+ export type FillOptions = Omit<FillInput, 'grid'>;
4
7
 
5
8
  /** Generate a word-search puzzle locally (WebAssembly). Same input and seed give the same grid. */
6
9
  export function generate(input: GenerateInput): GenerateOutput;
7
10
 
11
+ /**
12
+ * Fill the empty cells with random letters, in the given language, with accents on or off.
13
+ * Pass the puzzle from `generate()` to protect its words from accidental copies. Without a `seed` the
14
+ * filler is different every call.
15
+ */
16
+ export function fill(puzzle: GenerateOutput, options?: FillOptions): FillOutput;
17
+ export function fill(grid: string[][], options?: FillOptions): FillOutput;
18
+ export function fill(input: FillInput, options?: FillOptions): FillOutput;
19
+
8
20
  /** Plain-text view of a puzzle (grid and word bank). */
9
21
  export function render(output: GenerateOutput): string;
package/src/index.js CHANGED
@@ -1,8 +1,9 @@
1
- import { generate as generateRaw, renderPuzzle as renderRaw } from '../engine/index.js';
1
+ import { generate as generateRaw, fill as fillRaw, renderPuzzle as renderRaw } from '../engine/index.js';
2
2
 
3
3
  /**
4
4
  * Generate a word-search puzzle. Runs locally (WebAssembly), no network needed.
5
- * Deterministic: the same input and seed give the same grid.
5
+ * Deterministic: the same input and seed give the same grid. Empty cells hold `-` (or `fill`);
6
+ * pass the result to `fill()` to complete it with random letters.
6
7
  * @param {import('../engine/index.js').GenerateInput} input
7
8
  * @returns {import('../engine/index.js').GenerateOutput}
8
9
  */
@@ -10,6 +11,31 @@ export function generate(input) {
10
11
  return JSON.parse(generateRaw(JSON.stringify(input)));
11
12
  }
12
13
 
14
+ function randomSeed() {
15
+ return globalThis.crypto.getRandomValues(new Uint32Array(1))[0];
16
+ }
17
+
18
+ /**
19
+ * Fill the empty cells of a grid with random letters.
20
+ *
21
+ * Pass the puzzle from `generate()` (its hidden words are then protected from accidental copies), or just a
22
+ * matrix. Letters follow the language's letter frequency; `accents: false` limits them to A-Z. Without a `seed`
23
+ * the filler is different every call; with one it is repeatable.
24
+ *
25
+ * @param {string[][] | import('../engine/index.js').GenerateOutput | import('../engine/index.js').FillInput} source
26
+ * @param {Omit<import('../engine/index.js').FillInput, 'grid'>} [options]
27
+ * @returns {import('../engine/index.js').FillOutput}
28
+ */
29
+ export function fill(source, options = {}) {
30
+ let base;
31
+ if (Array.isArray(source)) base = { grid: source };
32
+ else if ('placements' in source) base = { grid: source.grid, words: source.words }; // a puzzle: keep its own seed out of it
33
+ else base = { ...source };
34
+ const input = { ...base, ...options };
35
+ if (input.seed === undefined) input.seed = randomSeed();
36
+ return JSON.parse(fillRaw(JSON.stringify(input)));
37
+ }
38
+
13
39
  /**
14
40
  * Plain-text view of a puzzle (grid and word bank), for terminals and logs.
15
41
  * @param {import('../engine/index.js').GenerateOutput} output