@slugbugblue/trax-cli 0.11.0 → 0.12.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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @slugbugblue/trax
2
2
 
3
+ ## 0.12.0 - 2025-11-08
4
+
5
+ - Fix a rare bug that could alter player names of existing games
6
+ - The `version` command now also shows version of some dependencies
7
+ - Update dependencies
8
+ - Update code to meet new xo guidelines
9
+
3
10
  ## 0.11.0 - 2023-03-25
4
11
 
5
12
  - Pull CLI from `@slugbugblue/trax` into its own repository
@@ -15,11 +22,9 @@
15
22
  ## 0.9.0 - 2023-02-05
16
23
 
17
24
  - CLI improvements:
18
-
19
25
  - Puzzle information is now stored as notes, to make it searchable
20
26
 
21
27
  - More puzzles:
22
-
23
28
  - Martin M. S. Pedersen contributed eleven new puzzles
24
29
 
25
30
  ## 0.8.0 - 2022-12-29
@@ -29,7 +34,6 @@
29
34
  ## 0.7.0 - 2022-12-27
30
35
 
31
36
  - Added a `notes` command to the CLI to add comments to a game
32
-
33
37
  - all comments are included in the output generated by the `export` command
34
38
  - the latest comment can be used as a text filter by the `list` command
35
39
  - the latest comment is displayed by the `view` and `list` commands
@@ -37,32 +41,27 @@
37
41
  ## 0.6.0 - 2022-12-14
38
42
 
39
43
  - Added shared `puzzles` commands to the CLI:
40
-
41
44
  - `trax ls puzzles`: see all the puzzles
42
45
  - `trax new puzzle`: start a new puzzle
43
46
 
44
47
  ## 0.5.0 - 2022-12-05
45
48
 
46
49
  - Added `puzzles` to the CLI:
47
-
48
50
  - `trax puzzles ls`: see all the puzzles
49
51
  - `trax puzzle new`: start a new puzzle
50
52
 
51
53
  ## 0.4.0 - 2022-11-25
52
54
 
53
55
  - Utilize the newly added move suggestions from `trax-analyst` to the CLI
54
-
55
56
  - added the `suggest` CLI command for quick access to a random suggestion
56
57
 
57
58
  - Use font glyphs for text bubbles in `tty.js` only if one of the following
58
59
  environment variables are defined and non-empty:
59
-
60
60
  - `NERDFONT`, `POWERLINE`, `P9K_TTY`, `P9K_SSH`
61
61
 
62
62
  ## 0.3.0 - 2022-09-22
63
63
 
64
64
  - Added the initial work on `trax-analyst`
65
-
66
65
  - added the `analyze` CLI command to see an analysis
67
66
 
68
67
  ## 0.2.0 - 2022-04-24
package/README.md CHANGED
@@ -150,7 +150,7 @@ Trax][gnutrax] for over two decades, and has a lot of expertise in this area.
150
150
 
151
151
  ## License
152
152
 
153
- Copyright 2019-2023 Chad Transtrum
153
+ Copyright 2019-2025 Chad Transtrum
154
154
 
155
155
  Licensed under the Apache License, Version 2.0 (the "License"); you may not use
156
156
  the files in this project except in compliance with the License. You may obtain
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slugbugblue/trax-cli",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "Trax command line interface",
5
5
  "keywords": [
6
6
  "trax",
@@ -15,9 +15,7 @@
15
15
  "types": "./src/types.d.ts",
16
16
  "exports": {
17
17
  ".": "./src/cli.js",
18
- "./utils": "./src/utils.js",
19
- "./version": "./src/version.js",
20
- "./version.js": "./src/version.js"
18
+ "./utils": "./src/utils.js"
21
19
  },
22
20
  "repository": "gitlab:slugbugblue/trax-cli",
23
21
  "bin": {
@@ -25,27 +23,26 @@
25
23
  },
26
24
  "scripts": {
27
25
  "genversion": "genversion --es6 src/version.js",
28
- "git-add": "git add src/version.js benchmark/benchmarks.json",
26
+ "git-add": "git add src/version.js",
29
27
  "test": "xo",
30
- "prepare": "husky install",
28
+ "prepare": "husky",
31
29
  "preversion": "npm test",
32
30
  "version": "npm run genversion ; npm run git-add",
33
31
  "postversion": "git push && git push --tags && npm publish"
34
32
  },
35
33
  "dependencies": {
36
- "@slugbugblue/trax": "^0.21.0",
37
- "@slugbugblue/trax-analyst": "^0.11.0",
34
+ "@slugbugblue/trax": "^1.0.0",
35
+ "@slugbugblue/trax-analyst": "^0.13.0",
38
36
  "@slugbugblue/trax-puzzles": "^0.5.0",
39
37
  "@slugbugblue/trax-tty": "^1.0.0",
40
38
  "env-paths": "^3.0.0",
41
- "make-dir": "^3.1.0",
42
39
  "yaml": "^2.0.0-11"
43
40
  },
44
41
  "devDependencies": {
45
42
  "genversion": "^3.0.2",
46
- "husky": "^8.0.3",
47
- "prettier": "^2.6.1",
48
- "xo": "0.*"
43
+ "husky": "^9.0.1",
44
+ "prettier": "^3.2.0",
45
+ "xo": "^1.2.3"
49
46
  },
50
47
  "type": "module",
51
48
  "engines": {
@@ -61,6 +58,7 @@
61
58
  },
62
59
  "xo": {
63
60
  "prettier": true,
61
+ "space": true,
64
62
  "rules": {
65
63
  "curly": [
66
64
  "error",
package/src/cli.js CHANGED
@@ -18,13 +18,11 @@
18
18
 
19
19
  import process from 'node:process'
20
20
  import repl from 'node:repl'
21
-
22
21
  import YAML from 'yaml'
23
-
24
22
  import { Trax } from '@slugbugblue/trax'
25
- import { version } from '@slugbugblue/trax-cli/version'
23
+ import { version as traxVersion } from '@slugbugblue/trax/version'
24
+ import { version as analystVersion } from '@slugbugblue/trax-analyst'
26
25
  import * as tty from '@slugbugblue/trax-tty'
27
-
28
26
  // Load all the commands as individual plugins
29
27
  import { analyzeCmd } from './cmds/analyze.js'
30
28
  import { deleteCmd } from './cmds/delete.js'
@@ -45,6 +43,7 @@ import { selectCmd } from './cmds/select.js'
45
43
  import { suggestCmd } from './cmds/suggest.js'
46
44
  import { undoCmd } from './cmds/undo.js'
47
45
  import { viewCmd } from './cmds/view.js'
46
+ import { version } from './version.js'
48
47
 
49
48
  // Because typeof [] and null are both 'object'. is([], 'arr') => true
50
49
  const is = (variable, type) =>
@@ -60,7 +59,15 @@ const versionCmd = {
60
59
  opts: ['--version', '-v'],
61
60
  desc: 'display version number',
62
61
  help: 'Print out the current version of this program.',
63
- fn: (CLI) => CLI.out('Trax CLI v' + version),
62
+ fn: (CLI) =>
63
+ CLI.out(
64
+ [
65
+ `Trax: engine v${traxVersion}`,
66
+ `analyst v${analystVersion}`,
67
+ `tty v${tty.version}`,
68
+ `cli v${version}`,
69
+ ].join(' | '),
70
+ ),
64
71
  }
65
72
 
66
73
  const quitCmd = {
@@ -121,12 +128,12 @@ const newId = (DATA) => {
121
128
  * @type Colorer
122
129
  */
123
130
  // @ts-ignore
124
- const color = (text, def) => {
131
+ const color = (text, defaultColor) => {
125
132
  let out = ''
126
133
  let quote = false
127
134
  let id = false
128
- const colors = [def]
129
- const c = (t) => tty.color(t, colors[colors.length - 1] || CLI.COLORS.default)
135
+ const colors = [defaultColor]
136
+ const c = (t) => tty.color(t, colors.at(-1) || CLI.COLORS.default)
130
137
  const short = (t) => tty.color(t, CLI.COLORS.short) + c()
131
138
  for (const char of text) {
132
139
  switch (char) {
@@ -190,7 +197,7 @@ const color = (text, def) => {
190
197
  }
191
198
  }
192
199
 
193
- return tty.color(out, def || CLI.COLORS.default)
200
+ return tty.color(out, defaultColor || CLI.COLORS.default)
194
201
  }
195
202
 
196
203
  // Internal representations of files
@@ -286,7 +293,7 @@ const CLI = {
286
293
  },
287
294
 
288
295
  load(id) {
289
- if (!id) id = Object.keys(DATA.games || {})[0]
296
+ id ||= Object.keys(DATA.games || {})[0]
290
297
  if (id && DATA.games?.[id] && DATA.games[id].rules) {
291
298
  if (id !== String(CONFIG.id)) {
292
299
  CONFIG.id = id
@@ -294,7 +301,7 @@ const CLI = {
294
301
  }
295
302
 
296
303
  const game = CLI.GAME
297
- if (!game.players) game.players = ['white', 'black']
304
+ game.players ||= ['white', 'black']
298
305
  CLI.TRAX = new Trax(game.rules, game.moves, 'cli')
299
306
  }
300
307
  },
@@ -376,8 +383,8 @@ const CLI = {
376
383
  },
377
384
 
378
385
  puzzleSolved(id) {
379
- DATA.puzzles = DATA.puzzles || {}
380
- DATA.puzzles[id] = DATA.puzzles[id] || { attempts: 1, solved: 0 }
386
+ DATA.puzzles ||= {}
387
+ DATA.puzzles[id] ||= { attempts: 1, solved: 0 }
381
388
  DATA.puzzles[id].solved += 1
382
389
  },
383
390
 
@@ -586,7 +593,7 @@ const expand = (completions, match) => {
586
593
  const completer = (line) => {
587
594
  const words = line.split(/\s+/).filter(Boolean)
588
595
 
589
- let match = words.slice(-1)[0] || ''
596
+ let match = words.at(-1) || ''
590
597
  const previous = new Set(words.slice(1, -1).map((s) => s.toLowerCase()))
591
598
  if (line.endsWith(' ')) {
592
599
  previous.add(match.toLowerCase())
@@ -614,11 +621,9 @@ const completer = (line) => {
614
621
  const word = completions[i]
615
622
  if (word.includes('|')) {
616
623
  const comps = word.split('|')
617
- if (comps.some((c) => previous.has(c.toLowerCase()))) {
618
- completions[i] = ''
619
- } else {
620
- completions[i] = comps
621
- }
624
+ completions[i] = comps.some((c) => previous.has(c.toLowerCase()))
625
+ ? ''
626
+ : comps
622
627
  }
623
628
  }
624
629
 
@@ -44,7 +44,7 @@ const selectAnyGame = (CLI) => {
44
44
 
45
45
  deleteCmd.fn = (CLI, id, force = 'x') => {
46
46
  const current = String(CLI.GAME.id)
47
- if (!id) id = current
47
+ id ||= current
48
48
  if ('force'.startsWith(id)) {
49
49
  id = current
50
50
  force = 'force'
package/src/cmds/help.js CHANGED
@@ -29,7 +29,7 @@ export const helpCmd = {
29
29
  }
30
30
 
31
31
  // Find the length of the printable characters of the string
32
- const length = (text) => text.replace(/[<">]/g, '').length
32
+ const length = (text) => text.replaceAll(/[<">]/g, '').length
33
33
 
34
34
  helpCmd.fn = (CLI, word) => {
35
35
  // If we are looking for help on a particular commands, get that command
@@ -17,10 +17,7 @@
17
17
 
18
18
  import fs from 'node:fs/promises'
19
19
  import process from 'node:process'
20
-
21
20
  import envPaths from 'env-paths'
22
- import makeDir from 'make-dir'
23
-
24
21
  import { Trax } from '@slugbugblue/trax'
25
22
  import { puzzles, sources } from '@slugbugblue/trax-puzzles'
26
23
 
@@ -51,7 +48,7 @@ const expandPath = (name) => {
51
48
  const getPath = async (path) => {
52
49
  if (path in PATHS) return PATHS[path]
53
50
  if (path in paths) {
54
- const realPath = await makeDir(paths[path])
51
+ const realPath = await fs.mkdir(paths[path], { recursive: true })
55
52
  PATHS[path] = realPath
56
53
  return realPath
57
54
  }
@@ -93,24 +90,21 @@ export const getFile = async (filetype, filename, variable, decode) => {
93
90
  return variable
94
91
  }
95
92
 
96
- export const saveFile = (filetype, filename, data) => {
97
- getPath(filetype).then((path) => {
98
- if (path) {
99
- const parts = filename.split('.')
100
- parts.splice(1, 0, hexy())
101
- const tmpfile = path + '/' + parts.join('.')
102
- filename = path + '/' + filename
103
- fs.writeFile(tmpfile, data)
104
- .then(() => {
105
- fs.rm(filename, { force: true, maxRetries: 5 })
106
- .then(() => {
107
- fs.rename(tmpfile, filename).catch(fsOuch)
108
- })
109
- .catch(fsOuch)
110
- })
111
- .catch(fsOuch)
93
+ export const saveFile = async (filetype, filename, data) => {
94
+ const path = await getPath(filetype)
95
+ if (path) {
96
+ const parts = filename.split('.')
97
+ parts.splice(1, 0, hexy())
98
+ const tmpfile = path + '/' + parts.join('.')
99
+ filename = path + '/' + filename
100
+ try {
101
+ await fs.writeFile(tmpfile, data)
102
+ await fs.rm(filename, { force: true, maxRetries: 5 })
103
+ await fs.rename(tmpfile, filename)
104
+ } catch (error) {
105
+ fsOuch(error)
112
106
  }
113
- })
107
+ }
114
108
  }
115
109
 
116
110
  export const importCmd = {
@@ -182,7 +176,7 @@ const interpretFile = (CLI, content) => {
182
176
  })
183
177
  } else {
184
178
  trax.playMoves(moves.filter(Boolean))
185
- moves.splice(0, moves.length)
179
+ moves.splice(0)
186
180
  }
187
181
  }
188
182
 
@@ -243,12 +237,12 @@ importCmd.fn = async (CLI, filename) => {
243
237
  * @returns {string} - Notes formatted for this move, or empty string if none
244
238
  */
245
239
  const gameNotes = (move, notes) => {
246
- notes = notes || []
240
+ notes ||= []
247
241
  const moveNotes = notes.filter((n) => n.move === move)
248
242
  if (moveNotes.length === 0) return ''
249
243
  return (
250
244
  '; ' +
251
- moveNotes.map((n) => n.note.replace(/\n/g, '\n; ')).join('\n; ') +
245
+ moveNotes.map((n) => n.note.replaceAll('\n', '\n; ')).join('\n; ') +
252
246
  '\n'
253
247
  )
254
248
  }
@@ -299,7 +293,7 @@ const interleaveNotation = (moves, notes) => {
299
293
  return content
300
294
  }
301
295
 
302
- exportCmd.fn = (CLI, id, filename) => {
296
+ exportCmd.fn = async (CLI, id, filename) => {
303
297
  cli = CLI
304
298
  let game = CLI.GAME
305
299
  if (id) {
@@ -345,13 +339,17 @@ exportCmd.fn = (CLI, id, filename) => {
345
339
 
346
340
  content += interleaveNotation(trax.moves, game.notes)
347
341
 
348
- if (filename) filename = filename.replace(/[^ a-z\d.~/]/g, '')
342
+ filename &&= filename.replaceAll(/[^ a-z\d.~/]/g, '')
349
343
  if (filename) {
350
344
  const fname = filename.split('/').pop()
351
345
  if (!fname) filename += game.rules + game.id
352
346
  if (!fname.includes('.')) filename += '.trx'
353
347
  CLI.out(CLI.color('Exporting #' + game.id + ' to ') + filename)
354
- fs.writeFile(expandPath(filename), content).catch(fsOuch)
348
+ try {
349
+ fs.writeFile(expandPath(filename), content)
350
+ } catch (error) {
351
+ fsOuch(error)
352
+ }
355
353
  } else {
356
354
  CLI.out(content)
357
355
  }
@@ -373,9 +371,11 @@ export const findFiles = (path) => {
373
371
  if (!FOLDERS[prefix]) {
374
372
  FOLDERS[prefix] = []
375
373
  fs.readdir(folder, { withFileTypes: true })
374
+ // eslint-disable-next-line promise/prefer-await-to-then
376
375
  .then((dir) => {
377
- // This is all happening asynchronously, so we have to call findFiles
378
- // at least twice before we get any useful information ...
376
+ // At this point, everything is happening asynchronously,
377
+ // so we have to call findFiles at least twice before we
378
+ // get any useful information ...
379
379
  const entries = []
380
380
  for (const entry of dir) {
381
381
  if (entry.isDirectory() && !entry.name.startsWith('.')) {
@@ -387,7 +387,10 @@ export const findFiles = (path) => {
387
387
 
388
388
  FOLDERS[prefix] = entries
389
389
  })
390
- .catch(() => {})
390
+ // eslint-disable-next-line promise/prefer-await-to-then
391
+ .catch(() => {
392
+ // Errors are unimportant and should be silently ignored
393
+ })
391
394
  }
392
395
 
393
396
  return FOLDERS[prefix]
package/src/cmds/list.js CHANGED
@@ -16,7 +16,6 @@
16
16
  // CLI list command
17
17
 
18
18
  import process from 'node:process'
19
-
20
19
  import { Trax } from '@slugbugblue/trax'
21
20
 
22
21
  export const listCmd = {
package/src/cmds/new.js CHANGED
@@ -29,6 +29,7 @@ export const newCmd = {
29
29
 
30
30
  // Okay, yes, this is silly
31
31
  const pairs = [
32
+ ['Aang', 'Katara'],
32
33
  ['Abbott', 'Costello'],
33
34
  ['Adam', 'Eve'],
34
35
  ['Anne Boleyn', 'Henry VIII'],
@@ -38,14 +39,20 @@ const pairs = [
38
39
  ['Bert', 'Ernie'],
39
40
  ['Bonnie', 'Clyde'],
40
41
  ['Calvin', 'Hobbes'],
42
+ ['Chandler', 'Monica'],
43
+ ['Chewbacca', 'R2-D2'],
41
44
  ['Chip', 'Dale'],
42
45
  ['Donald', 'Daisy'],
46
+ ['Depp', 'Heard'],
43
47
  ['Fred', 'Barney'],
44
48
  ['Fred', 'George'],
45
49
  ['Frodo', 'Samwise'],
50
+ ['Hamilton', 'Burr'],
46
51
  ['Han', 'Chewie'],
47
52
  ['Harry', 'Ron'],
53
+ ['Holmes', 'Moriarty'],
48
54
  ['Holmes', 'Watson'],
55
+ ['Iñigo', 'Fezzik'],
49
56
  ['Jekyll', 'Hyde'],
50
57
  ['Jim', 'Pam'],
51
58
  ['Joe', 'Volcano'],
@@ -62,14 +69,16 @@ const pairs = [
62
69
  ['Miss Piggy', 'Kermit'],
63
70
  ['Mork', 'Mindy'],
64
71
  ['Obi-Wan', 'Anakin'],
72
+ ['p1', 'p2'],
65
73
  ['Pan', 'Hook'],
66
74
  ['Phineas', 'Ferb'],
67
75
  ['player 1', 'player 2'],
68
- ['p1', 'p2'],
76
+ ['Potter', 'Voldemort'],
69
77
  ['R2-D2', 'C-3PO'],
70
78
  ['Ren', 'Stimpy'],
71
79
  ['Rick', 'Morty'],
72
80
  ['Romeo', 'Juliet'],
81
+ ['Ross', 'Rachel'],
73
82
  ['Shaggy', 'Scooby'],
74
83
  ['Shrek', 'Fiona'],
75
84
  ['Simon', 'Garfunkel'],
@@ -84,12 +93,13 @@ const pairs = [
84
93
  ['Tweety', 'Sylvester'],
85
94
  ['Waldorf', 'Statler'],
86
95
  ['Wallace', 'Gromit'],
96
+ ['Westley', 'Buttercup'],
87
97
  ['white', 'black'],
88
98
  ['Woody', 'Buzz'],
89
99
  ]
90
100
 
91
101
  const pairUp = () => {
92
- const duo = pairs[Math.floor(Math.random() * pairs.length)]
102
+ const duo = [...pairs[Math.floor(Math.random() * pairs.length)]]
93
103
  if (duo[0].toLowerCase() !== duo[0] && Math.random() < 0.5) duo.reverse()
94
104
  return duo
95
105
  }
package/src/cmds/notes.js CHANGED
@@ -16,7 +16,7 @@ export const notesCmd = {
16
16
 
17
17
  notesCmd.fn = (CLI, id, ...note) => {
18
18
  const current = String(CLI.GAME.id)
19
- if (!id) id = current
19
+ id ||= current
20
20
  if (!/^#?\d+$/.test(id)) {
21
21
  note.unshift(id)
22
22
  id = current
@@ -31,7 +31,7 @@ export const playCmd = {
31
31
  help: [
32
32
  'Enter the move in standard Trax notation. The final character of the',
33
33
  'notation can be replaced with a letter for ease of entering at the',
34
- 'command line. Use <s> for "/", <b> for "\\", and <p> for "+".',
34
+ String.raw`command line. Use <s> for "/", <b> for "\", and <p> for "+".`,
35
35
  'Multiple moves can be submitted at once. Move numbers are optional,',
36
36
  'but if included, they will be checked for accuracy.',
37
37
  ],
@@ -53,19 +53,19 @@ const showPuzzle = (CLI, id, started = false) => {
53
53
  if (puzzle.title) out += CLI.color(puzzle.title) + '\n'
54
54
  if (puzzle.desc) out += CLI.color.help(puzzle.desc) + '\n'
55
55
  out += CLI.color(players[puzzle.player - 1] + ' to win by move ' + puzzle.max)
56
- const src = sources[puzzle.src]
56
+ const source = sources[puzzle.src]
57
57
 
58
- if (src) {
59
- let source = '\nPuzzle '
60
- source += src.copyright
61
- ? 'copyright ' + src.copyright + ' by'
58
+ if (source) {
59
+ let text = '\nPuzzle '
60
+ text += source.copyright
61
+ ? 'copyright ' + source.copyright + ' by'
62
62
  : 'courtesy of'
63
- source += ' ' + src.name
64
- const url = src.url ? ' ' + CLI.color.help(src.url) : ''
65
- out += CLI.color.white(source) + url
66
- if (src.license) {
67
- out += '\n' + CLI.color.optional('License: ' + src.license)
68
- if (src.licenseUrl) out += CLI.color.black(' ' + src.licenseUrl)
63
+ text += ' ' + source.name
64
+ const url = source.url ? ' ' + CLI.color.help(source.url) : ''
65
+ out += CLI.color.white(text) + url
66
+ if (source.license) {
67
+ out += '\n' + CLI.color.optional('License: ' + source.license)
68
+ if (source.licenseUrl) out += CLI.color.black(' ' + source.licenseUrl)
69
69
  }
70
70
  }
71
71
 
package/src/types.d.ts CHANGED
@@ -4,15 +4,12 @@
4
4
  * @license Apache-2.0
5
5
  */
6
6
 
7
- /** Color is a single character to represent white or black. */
8
- type Color = 'w' | 'b'
9
-
10
7
  /** Colorize is a fancy function for colorizing text. */
11
- type Colorize = (text: string, def?: string | number) => string
8
+ type Colorize = (text: string, defaultColor?: string | number) => string
12
9
 
13
10
  /** Colorer is a little too fancy. Hence the gnarly typescript. */
14
11
  type Colorer = {
15
- (text: string, def?: string | number): string
12
+ (text: string, defaultColor?: string | number): string
16
13
  black: Colorize
17
14
  command: Colorize
18
15
  default: Colorize
@@ -34,72 +31,3 @@ type GameNote = {
34
31
 
35
32
  /** Notes saved in the game object in the CLI. */
36
33
  type GameNotes = GameNote[]
37
-
38
- /** Treat the save state as an opaque object,
39
- * produced by save() and fed into restore().
40
- */
41
- type SaveState = {
42
- id: string
43
- move: number
44
- turn: number
45
- over: boolean
46
- left: number
47
- right: number
48
- top: number
49
- bottom: number
50
- notation: string
51
- tiles: string
52
- path: string
53
- invalid: boolean
54
- }
55
-
56
- /** Representations of the different ways a tile can curve.
57
- * Matches the symbols used in Trax notation.
58
- */
59
- type Slash = '/' | '\\' | '+'
60
-
61
- /** Threat definition. */
62
- type Threat = {
63
- depth: number
64
- pattern: string
65
- rx: RegExp
66
- value: number
67
- }
68
-
69
- /** A single tile on the board. */
70
- type Tile = {
71
- id: TileId
72
- loc: Point
73
- type: TileType
74
- move: number
75
- seq: number
76
- }
77
-
78
- /** When a tile is dropped, this object represents the results. */
79
- type TileDrop = {
80
- dropped: Tile[]
81
- notation: string
82
- valid: boolean
83
- }
84
-
85
- /** A TileId is just a string. */
86
- type TileId = string
87
-
88
- /** Invalid tiles are represented by 'x'. */
89
- type TileType = ValidTiles | 'x'
90
-
91
- /** All of the variants supported by the engine. */
92
- type TraxVariant = 'trax' | 'traxloop' | 'trax8'
93
-
94
- /** Tile type names are determined by listing the line color at each edge,
95
- * starting from the top and going clockwise, and then sorted alphabetically
96
- * and given a single letter name, so 'bbww' becomes 'a', which gives us six
97
- * different tile names: a-f, as follows:
98
- * a b c d e f
99
- * +--#--+ +--#--+ +--#--+ +--o--+ +--o--+ +--o--+
100
- * | # | | # | | # | | o | | o | | o |
101
- * oo ## ooo#ooo ## oo oo ## ####### ## oo
102
- * | o | | # | | o | | # | | o | | # |
103
- * +--o--+ +--#--+ +--o--+ +--#--+ +--o--+ +--#--+
104
- */
105
- type ValidTiles = 'a' | 'b' | 'c' | 'd' | 'e' | 'f'
package/src/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '0.11.0'
2
+ export const version = '0.12.0'
package/.rgignore DELETED
@@ -1,2 +0,0 @@
1
- node_modules
2
- package-lock.json