cm-engine-runner 1.2.4 → 2.0.1

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/README.md CHANGED
@@ -4,28 +4,18 @@ A JavaScript module to act as a framework for running chess engines in the brows
4
4
 
5
5
  ## Working engines
6
6
 
7
- ### Stockfish 10
7
+ ### Stockfish 18
8
8
 
9
- - File: `engines/stockfish-v10-niklasf.js`
10
- - Type: WebWorker
11
- - Stockfish version: 10
12
- - Latest Version with WebWorker
13
- - https://github.com/niklasf/stockfish.js
9
+ - npm package: `stockfish` (v18.0.5)
10
+ - File: `node_modules/stockfish/bin/stockfish-18-lite-single.js`
11
+ - Type: WASM (single-threaded lite variant)
12
+ - https://github.com/nmrugg/stockfish.js
14
13
 
15
14
  ### Polyglot opening books
16
15
 
17
16
  - An engine to play moves from a polyglot (.bin) openings file.
18
17
  - https://github.com/shaack/cm-polyglot
19
18
 
20
- ### Stockfish 14
21
-
22
- Not implemented yet, does not work in Safari as of 2021-12-12
23
-
24
- - Type: WASM
25
- - Stockfish version: 14
26
- - Latest js version, multithreaded
27
- - https://github.com/nmrugg/stockfish.js
28
-
29
19
  ## Stockfish Skill Levels
30
20
 
31
21
  this.uciCmd('setoption name Skill Level value ' + (LEVELS[props.level][1]))
package/index.html CHANGED
@@ -33,7 +33,7 @@
33
33
  const positionEndGame = "8/8/8/2k5/4K3/8/8/8"
34
34
  console.log("polyglot", positionEndGame, await polyglotRunner.calculateMove(positionEndGame))
35
35
 
36
- const stockfishRunner = new StockfishRunner({workerUrl: "./node_modules/stockfish/src/stockfish-17.1-lite-single-03e3232.js", responseDelay: 0, debug: true})
36
+ const stockfishRunner = new StockfishRunner({workerUrl: "./node_modules/stockfish/bin/stockfish-18-lite-single.js", responseDelay: 0, debug: true})
37
37
  console.log("stockfish", await stockfishRunner.calculateMove(startingFewMoves))
38
38
  const postitionBlackWillWin = "4k3/3r4/8/8/8/8/6K1/8 w - - 0 1"
39
39
  console.log("stockfish", await stockfishRunner.calculateMove(postitionBlackWillWin, {level: 1}))
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "cm-engine-runner",
3
3
  "description": "Abstraction layer to run chess engines, supports opening books",
4
- "version": "1.2.4",
4
+ "version": "2.0.1",
5
5
  "type": "module",
6
6
  "main": "index.js",
7
7
  "scripts": {
@@ -24,10 +24,10 @@
24
24
  },
25
25
  "homepage": "https://github.com/shaack/cm-chess-engine-adapter#readme",
26
26
  "devDependencies": {
27
- "teevi": "^2.2.4"
27
+ "teevi": "^2.3.0"
28
28
  },
29
29
  "dependencies": {
30
30
  "cm-polyglot": "^1.1.0",
31
- "stockfish": "^17.1.0"
31
+ "stockfish": "^18.0.5"
32
32
  }
33
33
  }
@@ -22,10 +22,6 @@ export class EngineRunner {
22
22
  Object.assign(this.props, props)
23
23
  this.engineState = ENGINE_STATE.LOADING
24
24
  this.initialized = this.init()
25
- /**
26
- * @deprecated 2023-04-11 use `this.initialized` instead
27
- */
28
- this.initialization = this.initialized
29
25
  }
30
26
 
31
27
  init() {
@@ -37,9 +37,12 @@ export class StockfishRunner extends EngineRunner {
37
37
  }
38
38
 
39
39
  init() {
40
- return new Promise((resolve) => {
40
+ return new Promise((resolve, reject) => {
41
41
  const listener = (event) => {
42
42
  this.workerListener(event)
43
+ if (this.engineState === ENGINE_STATE.READY) {
44
+ resolve()
45
+ }
43
46
  }
44
47
  if (this.engineWorker) {
45
48
  this.engineWorker.removeEventListener("message", listener)
@@ -47,11 +50,13 @@ export class StockfishRunner extends EngineRunner {
47
50
  }
48
51
  this.engineWorker = new Worker(this.props.workerUrl)
49
52
  this.engineWorker.addEventListener("message", listener)
53
+ this.engineWorker.addEventListener("error", () => {
54
+ reject(new Error("Engine worker failed to load from: " + this.props.workerUrl))
55
+ })
50
56
 
51
57
  this.uciCmd('uci')
52
58
  this.uciCmd('ucinewgame')
53
59
  this.uciCmd('isready')
54
- resolve()
55
60
  })
56
61
  }
57
62
 
@@ -80,8 +85,8 @@ export class StockfishRunner extends EngineRunner {
80
85
  }
81
86
  this.score = tmpScore
82
87
  }
83
- // match = line.match(/^bestmove ([a-h][1-8])([a-h][1-8])([qrbk])?/) // ponder is not always included
84
- match = line.match(/^bestmove ([a-h][1-8])([a-h][1-8])([qrbk])?( ponder ([a-h][1-8])?([a-h][1-8])?)?/)
88
+ // match = line.match(/^bestmove ([a-h][1-8])([a-h][1-8])([qrbn])?/) // ponder is not always included
89
+ match = line.match(/^bestmove ([a-h][1-8])([a-h][1-8])([qrbn])?( ponder ([a-h][1-8])?([a-h][1-8])?)?/)
85
90
  if (match) {
86
91
  this.engineState = ENGINE_STATE.READY
87
92
  if (match[4] !== undefined) {
@@ -1,10 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(tree:*)",
5
- "Bash(wc:*)",
6
- "WebFetch(domain:github.com)",
7
- "Bash(npm install:*)"
8
- ]
9
- }
10
- }
package/CLAUDE.md DELETED
@@ -1,57 +0,0 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## Project Overview
6
-
7
- cm-engine-runner is a lightweight JavaScript library for running chess engines in the browser. It provides an abstraction layer supporting multiple backends: Stockfish (via WebWorkers) and Polyglot opening books.
8
-
9
- ## Development Commands
10
-
11
- ```bash
12
- # Install dependencies
13
- npm install
14
-
15
- # Run the demo/test page
16
- # Open index.html in a browser (uses importmap for ES6 module resolution)
17
- ```
18
-
19
- No build step is required - the library uses pure ES6 modules that run directly in browsers.
20
-
21
- ## Architecture
22
-
23
- The project uses an **adapter pattern** with a base class and engine-specific implementations:
24
-
25
- ```
26
- EngineRunner (base class)
27
- ├── StockfishRunner → WebWorker → Stockfish WASM engine
28
- └── PolyglotRunner → cm-polyglot → Opening book (.bin)
29
- ```
30
-
31
- ### Core Files
32
-
33
- - `src/EngineRunner.js` - Abstract base class defining the interface and state machine (`ENGINE_STATE`: LOADING, LOADED, READY, THINKING)
34
- - `src/StockfishRunner.js` - Stockfish adapter implementing UCI protocol communication, skill levels 1-20 with depth mapping
35
- - `src/PolyglotRunner.js` - Polyglot opening book reader with probability-weighted move selection
36
- - `engines/stockfish-v10-niklasf.js` - Compiled Stockfish v10 engine (runs in WebWorker)
37
-
38
- ### API Pattern
39
-
40
- All adapters share this interface:
41
- ```javascript
42
- runner.calculateMove(fen, props) → Promise<{from, to, promotion?, score?, ponder?}>
43
- ```
44
-
45
- ### Adding a New Engine
46
-
47
- 1. Extend `EngineRunner` class
48
- 2. Implement `init()` to set up the engine
49
- 3. Implement `calculateMove(fen, props)` returning a Promise with move data
50
- 4. Manage engine state via `ENGINE_STATE` constants
51
-
52
- ## Key Implementation Details
53
-
54
- - Uses `importmap` in index.html for browser-based ES6 module resolution (no bundler)
55
- - StockfishRunner communicates with the engine via `postMessage` using UCI protocol
56
- - `responseDelay` prop adds artificial delay for UX purposes
57
- - `debug` prop enables console logging