hyperchess-core 0.1.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/LICENSE +674 -0
- package/README.md +83 -0
- package/dist/board/create.d.ts +13 -0
- package/dist/board/create.d.ts.map +1 -0
- package/dist/board/create.js +21 -0
- package/dist/board/create.js.map +1 -0
- package/dist/board/hfen.d.ts +31 -0
- package/dist/board/hfen.d.ts.map +1 -0
- package/dist/board/hfen.js +181 -0
- package/dist/board/hfen.js.map +1 -0
- package/dist/board/index.d.ts +6 -0
- package/dist/board/index.d.ts.map +1 -0
- package/dist/board/index.js +11 -0
- package/dist/board/index.js.map +1 -0
- package/dist/board/move.d.ts +16 -0
- package/dist/board/move.d.ts.map +1 -0
- package/dist/board/move.js +43 -0
- package/dist/board/move.js.map +1 -0
- package/dist/board/undo.d.ts +4 -0
- package/dist/board/undo.d.ts.map +1 -0
- package/dist/board/undo.js +22 -0
- package/dist/board/undo.js.map +1 -0
- package/dist/board/validate.d.ts +7 -0
- package/dist/board/validate.d.ts.map +1 -0
- package/dist/board/validate.js +14 -0
- package/dist/board/validate.js.map +1 -0
- package/dist/game/add-move.d.ts +7 -0
- package/dist/game/add-move.d.ts.map +1 -0
- package/dist/game/add-move.js +78 -0
- package/dist/game/add-move.js.map +1 -0
- package/dist/game/index.d.ts +21 -0
- package/dist/game/index.d.ts.map +1 -0
- package/dist/game/index.js +58 -0
- package/dist/game/index.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/io/hsan-exporter.d.ts +10 -0
- package/dist/io/hsan-exporter.d.ts.map +1 -0
- package/dist/io/hsan-exporter.js +70 -0
- package/dist/io/hsan-exporter.js.map +1 -0
- package/dist/io/hsan-parser.d.ts +12 -0
- package/dist/io/hsan-parser.d.ts.map +1 -0
- package/dist/io/hsan-parser.js +118 -0
- package/dist/io/hsan-parser.js.map +1 -0
- package/dist/io/index.d.ts +3 -0
- package/dist/io/index.d.ts.map +1 -0
- package/dist/io/index.js +8 -0
- package/dist/io/index.js.map +1 -0
- package/dist/moves/index.d.ts +22 -0
- package/dist/moves/index.d.ts.map +1 -0
- package/dist/moves/index.js +39 -0
- package/dist/moves/index.js.map +1 -0
- package/dist/standalone.d.ts +64 -0
- package/dist/standalone.d.ts.map +1 -0
- package/dist/standalone.js +323 -0
- package/dist/standalone.js.map +1 -0
- package/dist/types/board.d.ts +38 -0
- package/dist/types/board.d.ts.map +1 -0
- package/dist/types/board.js +7 -0
- package/dist/types/board.js.map +1 -0
- package/dist/types/game.d.ts +45 -0
- package/dist/types/game.d.ts.map +1 -0
- package/dist/types/game.js +7 -0
- package/dist/types/game.js.map +1 -0
- package/dist/types/move.d.ts +24 -0
- package/dist/types/move.d.ts.map +1 -0
- package/dist/types/move.js +7 -0
- package/dist/types/move.js.map +1 -0
- package/dist/types/piece.d.ts +50 -0
- package/dist/types/piece.d.ts.map +1 -0
- package/dist/types/piece.js +29 -0
- package/dist/types/piece.js.map +1 -0
- package/dist/utils/square-notation.d.ts +14 -0
- package/dist/utils/square-notation.d.ts.map +1 -0
- package/dist/utils/square-notation.js +27 -0
- package/dist/utils/square-notation.js.map +1 -0
- package/dist/wasm/engine.d.ts +23 -0
- package/dist/wasm/engine.d.ts.map +1 -0
- package/dist/wasm/engine.js +37 -0
- package/dist/wasm/engine.js.map +1 -0
- package/dist/wasm/snapshot.d.ts +47 -0
- package/dist/wasm/snapshot.d.ts.map +1 -0
- package/dist/wasm/snapshot.js +125 -0
- package/dist/wasm/snapshot.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
// src/board/hfen.ts
|
|
2
|
+
var IDENTITY_START_TYPE = {
|
|
3
|
+
A: "E",
|
|
4
|
+
B: "H",
|
|
5
|
+
C: "R",
|
|
6
|
+
D: "N",
|
|
7
|
+
E: "B",
|
|
8
|
+
F: "Q",
|
|
9
|
+
G: "K",
|
|
10
|
+
H: "B",
|
|
11
|
+
I: "N",
|
|
12
|
+
J: "R",
|
|
13
|
+
K: "H",
|
|
14
|
+
L: "E",
|
|
15
|
+
M: "P",
|
|
16
|
+
N: "P",
|
|
17
|
+
O: "P",
|
|
18
|
+
P: "P",
|
|
19
|
+
Q: "P",
|
|
20
|
+
R: "P",
|
|
21
|
+
S: "P",
|
|
22
|
+
T: "P",
|
|
23
|
+
U: "P",
|
|
24
|
+
V: "P",
|
|
25
|
+
W: "P",
|
|
26
|
+
X: "P"
|
|
27
|
+
};
|
|
28
|
+
var PROMOTION_TYPES = "QRBNEH";
|
|
29
|
+
function identityStartType(identity) {
|
|
30
|
+
return IDENTITY_START_TYPE[identity.toUpperCase()];
|
|
31
|
+
}
|
|
32
|
+
function isIdentityChar(c) {
|
|
33
|
+
return c.length === 1 && IDENTITY_START_TYPE[c.toUpperCase()] !== void 0;
|
|
34
|
+
}
|
|
35
|
+
function parseHfenPosition(position) {
|
|
36
|
+
const squares = new Array(144).fill(void 0);
|
|
37
|
+
const ranks = position.split("/");
|
|
38
|
+
if (ranks.length !== 12) {
|
|
39
|
+
throw new Error(`HFEN position needs 12 ranks, got ${ranks.length}`);
|
|
40
|
+
}
|
|
41
|
+
const identityMode = /[ACDFGIJLMOSTUVWXacdfgijlmostuvwx]/.test(position);
|
|
42
|
+
ranks.forEach((rankStr, rankFromTop) => {
|
|
43
|
+
const rank = 11 - rankFromTop;
|
|
44
|
+
let file = 0;
|
|
45
|
+
const tokens = rankStr.match(/[A-Za-z]:[A-Za-z]|[A-Za-z]|\d+/g) ?? [];
|
|
46
|
+
if (tokens.join("") !== rankStr) {
|
|
47
|
+
throw new Error(`Malformed HFEN rank ${rank + 1}: ${rankStr}`);
|
|
48
|
+
}
|
|
49
|
+
for (const token of tokens) {
|
|
50
|
+
if (/^\d+$/.test(token)) {
|
|
51
|
+
file += parseInt(token, 10);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (file >= 12) {
|
|
55
|
+
throw new Error(`Too many squares on HFEN rank ${rank + 1}`);
|
|
56
|
+
}
|
|
57
|
+
let identity;
|
|
58
|
+
let typeChar;
|
|
59
|
+
if (token.length === 3) {
|
|
60
|
+
identity = token[0];
|
|
61
|
+
typeChar = token[2];
|
|
62
|
+
if (!PROMOTION_TYPES.includes(typeChar.toUpperCase())) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`Invalid \`id:Type\` type letter '${typeChar}' in ${token}: the type half must be one of ${PROMOTION_TYPES.split("").join(" ")}`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
const identityIsWhite = identity === identity.toUpperCase();
|
|
68
|
+
const typeIsWhite = typeChar === typeChar.toUpperCase();
|
|
69
|
+
if (identityIsWhite !== typeIsWhite) {
|
|
70
|
+
throw new Error(`Type override ${token} changes piece color`);
|
|
71
|
+
}
|
|
72
|
+
} else if (identityMode && isIdentityChar(token)) {
|
|
73
|
+
identity = token;
|
|
74
|
+
typeChar = token;
|
|
75
|
+
} else {
|
|
76
|
+
typeChar = token;
|
|
77
|
+
}
|
|
78
|
+
const color = typeChar === typeChar.toUpperCase() ? "white" : "black";
|
|
79
|
+
const type = token.length === 3 || !identity ? typeChar.toUpperCase() : identityStartType(identity);
|
|
80
|
+
if (!type) {
|
|
81
|
+
throw new Error(`Invalid HFEN piece character: ${token}`);
|
|
82
|
+
}
|
|
83
|
+
squares[rank * 12 + file] = identity ? { type, color, identity } : { type, color };
|
|
84
|
+
file += 1;
|
|
85
|
+
}
|
|
86
|
+
if (file !== 12) {
|
|
87
|
+
throw new Error(`HFEN rank ${rank + 1} has ${file} squares, expected 12`);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
return squares;
|
|
91
|
+
}
|
|
92
|
+
function serializeSquare(piece) {
|
|
93
|
+
const typeChar = piece.color === "white" ? piece.type : piece.type.toLowerCase();
|
|
94
|
+
if (!piece.identity) {
|
|
95
|
+
return typeChar;
|
|
96
|
+
}
|
|
97
|
+
if (identityStartType(piece.identity) === piece.type) {
|
|
98
|
+
return piece.identity;
|
|
99
|
+
}
|
|
100
|
+
return `${piece.identity}:${typeChar}`;
|
|
101
|
+
}
|
|
102
|
+
function getBoardHfen(board) {
|
|
103
|
+
const rankSegments = [];
|
|
104
|
+
for (let rank = 11; rank >= 0; rank--) {
|
|
105
|
+
let segment = "";
|
|
106
|
+
let emptyCount = 0;
|
|
107
|
+
for (let file = 0; file < 12; file++) {
|
|
108
|
+
const piece = board.pieces[rank * 12 + file];
|
|
109
|
+
if (!piece) {
|
|
110
|
+
emptyCount++;
|
|
111
|
+
} else {
|
|
112
|
+
if (emptyCount > 0) {
|
|
113
|
+
segment += emptyCount;
|
|
114
|
+
emptyCount = 0;
|
|
115
|
+
}
|
|
116
|
+
segment += serializeSquare(piece);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (emptyCount > 0) segment += emptyCount;
|
|
120
|
+
rankSegments.push(segment);
|
|
121
|
+
}
|
|
122
|
+
let hfen = rankSegments.join("/");
|
|
123
|
+
hfen += ` ${board.toMove === "white" ? "w" : "b"}`;
|
|
124
|
+
const castling = (board.castlingRights.whiteKingSide ? "K" : "") + (board.castlingRights.whiteQueenSide ? "Q" : "") + (board.castlingRights.blackKingSide ? "k" : "") + (board.castlingRights.blackQueenSide ? "q" : "");
|
|
125
|
+
hfen += ` ${castling || "-"}`;
|
|
126
|
+
if (board.enPassantSquare === -1) {
|
|
127
|
+
hfen += " -";
|
|
128
|
+
} else {
|
|
129
|
+
const col = String.fromCharCode("a".charCodeAt(0) + board.enPassantSquare % 12);
|
|
130
|
+
const row = Math.floor(board.enPassantSquare / 12) + 1;
|
|
131
|
+
hfen += ` ${col}${row}`;
|
|
132
|
+
}
|
|
133
|
+
hfen += ` ${board.halfmoveClock}`;
|
|
134
|
+
hfen += ` ${board.fullmoveNumber}`;
|
|
135
|
+
return hfen;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// src/board/undo.ts
|
|
139
|
+
function undoMove(board) {
|
|
140
|
+
if (board.history.length === 0) {
|
|
141
|
+
throw new Error("No moves to undo");
|
|
142
|
+
}
|
|
143
|
+
const lastState = board.history[board.history.length - 1];
|
|
144
|
+
return {
|
|
145
|
+
pieces: lastState.pieces,
|
|
146
|
+
toMove: lastState.toMove,
|
|
147
|
+
enPassantSquare: lastState.enPassantSquare,
|
|
148
|
+
castlingRights: lastState.castlingRights,
|
|
149
|
+
halfmoveClock: lastState.halfmoveClock,
|
|
150
|
+
fullmoveNumber: lastState.fullmoveNumber,
|
|
151
|
+
history: board.history.slice(0, -1)
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// src/utils/square-notation.ts
|
|
156
|
+
function algebraicToSquare(algebraic) {
|
|
157
|
+
const file = algebraic.charCodeAt(0) - "a".charCodeAt(0);
|
|
158
|
+
const rank = parseInt(algebraic.slice(1), 10) - 1;
|
|
159
|
+
return rank * 12 + file;
|
|
160
|
+
}
|
|
161
|
+
function squareToAlgebraic(square) {
|
|
162
|
+
const file = String.fromCharCode("a".charCodeAt(0) + square % 12);
|
|
163
|
+
const rank = Math.floor(square / 12) + 1;
|
|
164
|
+
return `${file}${rank}`;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// src/wasm/snapshot.ts
|
|
168
|
+
var ENCODE_PIECE_ORDER = ["P", "N", "B", "R", "Q", "K", "E", "H"];
|
|
169
|
+
function decodePieceByte(byte) {
|
|
170
|
+
if (byte === 0) return void 0;
|
|
171
|
+
const color = byte <= 8 ? "white" : "black";
|
|
172
|
+
const type = ENCODE_PIECE_ORDER[(byte <= 8 ? byte : byte - 8) - 1];
|
|
173
|
+
return { type, color };
|
|
174
|
+
}
|
|
175
|
+
function parseCastlingRights(castlingStr) {
|
|
176
|
+
return {
|
|
177
|
+
whiteKingSide: castlingStr.includes("K"),
|
|
178
|
+
whiteQueenSide: castlingStr.includes("Q"),
|
|
179
|
+
blackKingSide: castlingStr.includes("k"),
|
|
180
|
+
blackQueenSide: castlingStr.includes("q")
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
function parseEnPassant(enPassantStr) {
|
|
184
|
+
if (enPassantStr === "-") return -1;
|
|
185
|
+
const match = enPassantStr.match(/^([a-l])(1[0-2]|[1-9])$/);
|
|
186
|
+
if (!match) return -1;
|
|
187
|
+
return algebraicToSquare(match[1] + match[2]);
|
|
188
|
+
}
|
|
189
|
+
function snapshotFromWasmBoard(wasmBoard, history = []) {
|
|
190
|
+
const hfen = wasmBoard.hfen();
|
|
191
|
+
const hfenParts = hfen.split(" ");
|
|
192
|
+
const [positionStr, toMoveStr, castlingStr, enPassantStr, halfmoveStr, fullmoveStr] = hfenParts;
|
|
193
|
+
const pieces = Array.from(wasmBoard.encode()).map(decodePieceByte);
|
|
194
|
+
let identities;
|
|
195
|
+
try {
|
|
196
|
+
identities = parseHfenPosition(positionStr);
|
|
197
|
+
} catch {
|
|
198
|
+
identities = void 0;
|
|
199
|
+
}
|
|
200
|
+
if (identities) {
|
|
201
|
+
for (let sq = 0; sq < pieces.length; sq++) {
|
|
202
|
+
const identity = identities[sq]?.identity;
|
|
203
|
+
const piece = pieces[sq];
|
|
204
|
+
if (piece && identity) {
|
|
205
|
+
pieces[sq] = { ...piece, identity };
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return {
|
|
210
|
+
pieces,
|
|
211
|
+
toMove: toMoveStr === "w" ? "white" : "black",
|
|
212
|
+
enPassantSquare: parseEnPassant(enPassantStr),
|
|
213
|
+
castlingRights: parseCastlingRights(castlingStr),
|
|
214
|
+
halfmoveClock: parseInt(halfmoveStr, 10),
|
|
215
|
+
fullmoveNumber: parseInt(fullmoveStr || "1", 10),
|
|
216
|
+
history
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
function moveToUci(move) {
|
|
220
|
+
const promo = move.promotion ? move.promotion.toLowerCase() : "";
|
|
221
|
+
return `${squareToAlgebraic(move.from)}${squareToAlgebraic(move.to)}${promo}`;
|
|
222
|
+
}
|
|
223
|
+
function uciToMove(uci, board) {
|
|
224
|
+
const match = uci.match(/^([a-l](?:1[0-2]|[1-9]))([a-l](?:1[0-2]|[1-9]))([qrbneh])?$/);
|
|
225
|
+
if (!match) {
|
|
226
|
+
throw new Error(`Invalid UCI move string: ${uci}`);
|
|
227
|
+
}
|
|
228
|
+
const from = algebraicToSquare(match[1]);
|
|
229
|
+
const to = algebraicToSquare(match[2]);
|
|
230
|
+
const promotion = match[3] ? match[3].toUpperCase() : void 0;
|
|
231
|
+
const piece = board.pieces[from];
|
|
232
|
+
const move = { from, to, promotion };
|
|
233
|
+
if (piece?.type === "K" && Math.abs(from % 12 - to % 12) === 2) {
|
|
234
|
+
move.isCastling = true;
|
|
235
|
+
}
|
|
236
|
+
if (piece?.type === "P" && to === board.enPassantSquare && board.pieces[to] === void 0) {
|
|
237
|
+
move.isEnPassant = true;
|
|
238
|
+
}
|
|
239
|
+
return move;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// src/standalone.ts
|
|
243
|
+
var wasmBoardCtor = null;
|
|
244
|
+
async function initHyperchessCoreStandalone(wasmInput) {
|
|
245
|
+
const mod = await import("hyperchess-wasm/web");
|
|
246
|
+
await mod.default(wasmInput);
|
|
247
|
+
wasmBoardCtor = mod.WasmBoard;
|
|
248
|
+
}
|
|
249
|
+
function requireWasmBoardCtor() {
|
|
250
|
+
if (!wasmBoardCtor) {
|
|
251
|
+
throw new Error(
|
|
252
|
+
"HyperChess WASM engine not initialized \u2014 call and await initHyperchessCoreStandalone() once before using any other function from hyperchess-core/standalone."
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
return wasmBoardCtor;
|
|
256
|
+
}
|
|
257
|
+
function loadWasmBoard(hfen) {
|
|
258
|
+
const Ctor = requireWasmBoardCtor();
|
|
259
|
+
if (!hfen) {
|
|
260
|
+
return new Ctor();
|
|
261
|
+
}
|
|
262
|
+
const board = Ctor.from_hfen(hfen);
|
|
263
|
+
if (!board) {
|
|
264
|
+
throw new Error(`Invalid HFEN: ${hfen}`);
|
|
265
|
+
}
|
|
266
|
+
return board;
|
|
267
|
+
}
|
|
268
|
+
function createBoard(hfen) {
|
|
269
|
+
return snapshotFromWasmBoard(loadWasmBoard(hfen));
|
|
270
|
+
}
|
|
271
|
+
function applyMove(board, move) {
|
|
272
|
+
const piece = board.pieces[move.from];
|
|
273
|
+
if (!piece) {
|
|
274
|
+
throw new Error(`No piece at source square ${move.from}`);
|
|
275
|
+
}
|
|
276
|
+
const wasmBoard = loadWasmBoard(getBoardHfen(board));
|
|
277
|
+
const applied = wasmBoard.apply_move(moveToUci(move));
|
|
278
|
+
if (!applied) {
|
|
279
|
+
throw new Error(`Illegal move: ${move.from} -> ${move.to}`);
|
|
280
|
+
}
|
|
281
|
+
const history = [
|
|
282
|
+
...board.history,
|
|
283
|
+
{
|
|
284
|
+
pieces: [...board.pieces],
|
|
285
|
+
toMove: board.toMove,
|
|
286
|
+
enPassantSquare: board.enPassantSquare,
|
|
287
|
+
castlingRights: { ...board.castlingRights },
|
|
288
|
+
halfmoveClock: board.halfmoveClock,
|
|
289
|
+
fullmoveNumber: board.fullmoveNumber
|
|
290
|
+
}
|
|
291
|
+
];
|
|
292
|
+
return snapshotFromWasmBoard(wasmBoard, history);
|
|
293
|
+
}
|
|
294
|
+
function generateLegalMoves(board) {
|
|
295
|
+
const wasmBoard = loadWasmBoard(getBoardHfen(board));
|
|
296
|
+
const uci = wasmBoard.legal_moves();
|
|
297
|
+
if (uci === "") return [];
|
|
298
|
+
return uci.split(" ").map((m) => uciToMove(m, board));
|
|
299
|
+
}
|
|
300
|
+
function isLegalMove(board, move) {
|
|
301
|
+
return generateLegalMoves(board).some((m) => m.from === move.from && m.to === move.to);
|
|
302
|
+
}
|
|
303
|
+
function isInCheck(board) {
|
|
304
|
+
return loadWasmBoard(getBoardHfen(board)).in_check();
|
|
305
|
+
}
|
|
306
|
+
function isCheckmate(board) {
|
|
307
|
+
return loadWasmBoard(getBoardHfen(board)).termination() === "checkmate";
|
|
308
|
+
}
|
|
309
|
+
function isStalemate(board) {
|
|
310
|
+
return loadWasmBoard(getBoardHfen(board)).termination() === "stalemate";
|
|
311
|
+
}
|
|
312
|
+
export {
|
|
313
|
+
applyMove,
|
|
314
|
+
createBoard,
|
|
315
|
+
generateLegalMoves,
|
|
316
|
+
getBoardHfen,
|
|
317
|
+
initHyperchessCoreStandalone,
|
|
318
|
+
isCheckmate,
|
|
319
|
+
isInCheck,
|
|
320
|
+
isLegalMove,
|
|
321
|
+
isStalemate,
|
|
322
|
+
undoMove
|
|
323
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standalone.js","sourceRoot":"","sources":["../src/standalone.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Color } from './move';
|
|
2
|
+
import { Piece } from './piece';
|
|
3
|
+
/** Represents the state of a single board */
|
|
4
|
+
export interface Board {
|
|
5
|
+
/** Pieces on board: square index → piece (or undefined if empty) */
|
|
6
|
+
pieces: (Piece | undefined)[];
|
|
7
|
+
/** Whose turn to move */
|
|
8
|
+
toMove: Color;
|
|
9
|
+
/** En passant target square (or -1 if none) */
|
|
10
|
+
enPassantSquare: number;
|
|
11
|
+
/** Castling rights: bitmask for White-King-Side, etc */
|
|
12
|
+
castlingRights: CastlingRights;
|
|
13
|
+
/** Halfmove clock for 50-move rule */
|
|
14
|
+
halfmoveClock: number;
|
|
15
|
+
/** Full move number */
|
|
16
|
+
fullmoveNumber: number;
|
|
17
|
+
/** Move history (for undo) */
|
|
18
|
+
history: BoardState[];
|
|
19
|
+
}
|
|
20
|
+
/** Castling availability */
|
|
21
|
+
export interface CastlingRights {
|
|
22
|
+
whiteKingSide: boolean;
|
|
23
|
+
whiteQueenSide: boolean;
|
|
24
|
+
blackKingSide: boolean;
|
|
25
|
+
blackQueenSide: boolean;
|
|
26
|
+
}
|
|
27
|
+
/** Snapshot of board state for undo */
|
|
28
|
+
export interface BoardState {
|
|
29
|
+
pieces: (Piece | undefined)[];
|
|
30
|
+
toMove: Color;
|
|
31
|
+
enPassantSquare: number;
|
|
32
|
+
castlingRights: CastlingRights;
|
|
33
|
+
halfmoveClock: number;
|
|
34
|
+
fullmoveNumber: number;
|
|
35
|
+
}
|
|
36
|
+
/** HFEN notation (HFEN-I format) */
|
|
37
|
+
export type HfenString = string;
|
|
38
|
+
//# sourceMappingURL=board.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board.d.ts","sourceRoot":"","sources":["../../src/types/board.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC/B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,6CAA6C;AAC7C,MAAM,WAAW,KAAK;IACpB,oEAAoE;IACpE,MAAM,EAAE,CAAC,KAAK,GAAG,SAAS,CAAC,EAAE,CAAC;IAE9B,yBAAyB;IACzB,MAAM,EAAE,KAAK,CAAC;IAEd,+CAA+C;IAC/C,eAAe,EAAE,MAAM,CAAC;IAExB,wDAAwD;IACxD,cAAc,EAAE,cAAc,CAAC;IAE/B,sCAAsC;IACtC,aAAa,EAAE,MAAM,CAAC;IAEtB,uBAAuB;IACvB,cAAc,EAAE,MAAM,CAAC;IAEvB,8BAA8B;IAC9B,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAED,4BAA4B;AAC5B,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,uCAAuC;AACvC,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,CAAC,KAAK,GAAG,SAAS,CAAC,EAAE,CAAC;IAC9B,MAAM,EAAE,KAAK,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,cAAc,CAAC;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,oCAAoC;AACpC,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board.js","sourceRoot":"","sources":["../../src/types/board.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,oCAAoC;AACpC,yCAAyC;AACzC,iBAAiB;AACjB,+CAA+C"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Board, HfenString } from './board';
|
|
2
|
+
import { Move, AlgebraicMove } from './move';
|
|
3
|
+
/** Represents a complete game */
|
|
4
|
+
export interface Game {
|
|
5
|
+
/** Current board state */
|
|
6
|
+
board: Board;
|
|
7
|
+
/** All moves played (in algebraic notation) */
|
|
8
|
+
moves: AlgebraicMove[];
|
|
9
|
+
/** Metadata about the game */
|
|
10
|
+
metadata: GameMetadata;
|
|
11
|
+
/** Game status */
|
|
12
|
+
status: GameStatus;
|
|
13
|
+
/**
|
|
14
|
+
* The HFEN the game started from, if not the default position. Needed so
|
|
15
|
+
* `removeLastMove` can replay from the correct origin instead of silently
|
|
16
|
+
* falling back to the default starting position.
|
|
17
|
+
*/
|
|
18
|
+
startHfen?: HfenString;
|
|
19
|
+
}
|
|
20
|
+
/** Game metadata */
|
|
21
|
+
export interface GameMetadata {
|
|
22
|
+
event?: string;
|
|
23
|
+
site?: string;
|
|
24
|
+
date?: string;
|
|
25
|
+
round?: string;
|
|
26
|
+
white?: string;
|
|
27
|
+
black?: string;
|
|
28
|
+
whiteElo?: number;
|
|
29
|
+
blackElo?: number;
|
|
30
|
+
result?: GameResult;
|
|
31
|
+
timeControl?: string;
|
|
32
|
+
}
|
|
33
|
+
/** Possible game outcomes */
|
|
34
|
+
export type GameResult = '1-0' | '0-1' | '1/2-1/2' | '*';
|
|
35
|
+
/** Game status */
|
|
36
|
+
export type GameStatus = 'active' | 'checkmate' | 'stalemate' | 'draw' | 'resigned';
|
|
37
|
+
/** Additional game info */
|
|
38
|
+
export interface GameInfo {
|
|
39
|
+
legalMoves: Move[];
|
|
40
|
+
inCheck: boolean;
|
|
41
|
+
inCheckmate: boolean;
|
|
42
|
+
inStalemate: boolean;
|
|
43
|
+
canClaimDraw: boolean;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=game.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"game.d.ts","sourceRoot":"","sources":["../../src/types/game.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAE7C,iCAAiC;AACjC,MAAM,WAAW,IAAI;IACnB,0BAA0B;IAC1B,KAAK,EAAE,KAAK,CAAC;IAEb,+CAA+C;IAC/C,KAAK,EAAE,aAAa,EAAE,CAAC;IAEvB,8BAA8B;IAC9B,QAAQ,EAAE,YAAY,CAAC;IAEvB,kBAAkB;IAClB,MAAM,EAAE,UAAU,CAAC;IAEnB;;;;OAIG;IACH,SAAS,CAAC,EAAE,UAAU,CAAC;CACxB;AAED,oBAAoB;AACpB,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,6BAA6B;AAC7B,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,GAAG,GAAG,CAAC;AAEzD,kBAAkB;AAClB,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,GAAG,MAAM,GAAG,UAAU,CAAC;AAEpF,2BAA2B;AAC3B,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,IAAI,EAAE,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;CACvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"game.js","sourceRoot":"","sources":["../../src/types/game.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,oCAAoC;AACpC,wCAAwC;AACxC,iBAAiB;AACjB,+CAA+C"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Color/side in the game */
|
|
2
|
+
export type Color = 'white' | 'black';
|
|
3
|
+
/** Square coordinate (0-143 for 12x12 board) */
|
|
4
|
+
export type Square = number;
|
|
5
|
+
/** Promotion piece type */
|
|
6
|
+
export type PromotionPiece = 'Q' | 'R' | 'B' | 'N' | 'E' | 'H';
|
|
7
|
+
/** Represents a single move */
|
|
8
|
+
export interface Move {
|
|
9
|
+
from: Square;
|
|
10
|
+
to: Square;
|
|
11
|
+
promotion?: PromotionPiece;
|
|
12
|
+
isEnPassant?: boolean;
|
|
13
|
+
isCastling?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/** Move in algebraic notation (e.g., "e2e4", "a7a8=Q") */
|
|
16
|
+
export type AlgebraicMove = string;
|
|
17
|
+
/**
|
|
18
|
+
* Move in HSAN — this SDK's algebraic notation (e.g., "e4", "Nxf3"). Named
|
|
19
|
+
* distinctly from standard chess's SAN since disambiguation, piece letters,
|
|
20
|
+
* and square range all differ on this 12x12 board with Eagle/Hawk pieces —
|
|
21
|
+
* "SAN" on its own would misleadingly imply plain standard-chess notation.
|
|
22
|
+
*/
|
|
23
|
+
export type HsanMove = string;
|
|
24
|
+
//# sourceMappingURL=move.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"move.d.ts","sourceRoot":"","sources":["../../src/types/move.ts"],"names":[],"mappings":"AAMA,6BAA6B;AAC7B,MAAM,MAAM,KAAK,GAAG,OAAO,GAAG,OAAO,CAAC;AAEtC,gDAAgD;AAChD,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC;AAE5B,2BAA2B;AAC3B,MAAM,MAAM,cAAc,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAE/D,+BAA+B;AAC/B,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,0DAA0D;AAC1D,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC;AAEnC;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"move.js","sourceRoot":"","sources":["../../src/types/move.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,oCAAoC;AACpC,wCAAwC;AACxC,iBAAiB;AACjB,+CAA+C"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Color } from './move';
|
|
2
|
+
/** Piece type (side-agnostic) */
|
|
3
|
+
export type PieceType = 'P' | 'N' | 'B' | 'R' | 'Q' | 'K' | 'E' | 'H';
|
|
4
|
+
/** Represents a piece on the board */
|
|
5
|
+
export interface Piece {
|
|
6
|
+
type: PieceType;
|
|
7
|
+
color: Color;
|
|
8
|
+
/**
|
|
9
|
+
* The piece's stable HFEN-I identity character, when known.
|
|
10
|
+
*
|
|
11
|
+
* Identity is *which individual piece* this is — the pawn that started on
|
|
12
|
+
* a3 stays `M` for the whole game, including after it promotes. It is
|
|
13
|
+
* metadata: it never affects legality or move generation.
|
|
14
|
+
*
|
|
15
|
+
* Optional because a board built from a legacy, type-only HFEN has no
|
|
16
|
+
* identity to carry. When it IS present, `getBoardHfen` round-trips it, so
|
|
17
|
+
* the SDK stops silently discarding identity every time it re-serializes a
|
|
18
|
+
* position for the engine.
|
|
19
|
+
*/
|
|
20
|
+
identity?: string;
|
|
21
|
+
}
|
|
22
|
+
/** Piece position on board */
|
|
23
|
+
export interface PiecePlacement {
|
|
24
|
+
piece: Piece;
|
|
25
|
+
square: number;
|
|
26
|
+
}
|
|
27
|
+
/** Piece symbols for display */
|
|
28
|
+
export declare const PIECE_SYMBOLS: {
|
|
29
|
+
white: {
|
|
30
|
+
P: string;
|
|
31
|
+
N: string;
|
|
32
|
+
B: string;
|
|
33
|
+
R: string;
|
|
34
|
+
Q: string;
|
|
35
|
+
K: string;
|
|
36
|
+
E: string;
|
|
37
|
+
H: string;
|
|
38
|
+
};
|
|
39
|
+
black: {
|
|
40
|
+
P: string;
|
|
41
|
+
N: string;
|
|
42
|
+
B: string;
|
|
43
|
+
R: string;
|
|
44
|
+
Q: string;
|
|
45
|
+
K: string;
|
|
46
|
+
E: string;
|
|
47
|
+
H: string;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=piece.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"piece.d.ts","sourceRoot":"","sources":["../../src/types/piece.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAE/B,iCAAiC;AACjC,MAAM,MAAM,SAAS,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEtE,sCAAsC;AACtC,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC;IAEb;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,8BAA8B;AAC9B,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,gCAAgC;AAChC,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;CAqBzB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
// HyperChess Core — hyperchess-core
|
|
3
|
+
// File: packages/core/src/types/piece.ts
|
|
4
|
+
// Version: 1.0.0
|
|
5
|
+
// Copyright (c) 2026 HyperChess Developer Team
|
|
6
|
+
/** Piece symbols for display */
|
|
7
|
+
export const PIECE_SYMBOLS = {
|
|
8
|
+
white: {
|
|
9
|
+
P: '♙',
|
|
10
|
+
N: '♘',
|
|
11
|
+
B: '♗',
|
|
12
|
+
R: '♖',
|
|
13
|
+
Q: '♕',
|
|
14
|
+
K: '♔',
|
|
15
|
+
E: '🦅',
|
|
16
|
+
H: '🦅',
|
|
17
|
+
},
|
|
18
|
+
black: {
|
|
19
|
+
P: '♟',
|
|
20
|
+
N: '♞',
|
|
21
|
+
B: '♝',
|
|
22
|
+
R: '♜',
|
|
23
|
+
Q: '♛',
|
|
24
|
+
K: '♚',
|
|
25
|
+
E: '🦅',
|
|
26
|
+
H: '🦅',
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=piece.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"piece.js","sourceRoot":"","sources":["../../src/types/piece.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,oCAAoC;AACpC,yCAAyC;AACzC,iBAAiB;AACjB,+CAA+C;AAiC/C,gCAAgC;AAChC,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,KAAK,EAAE;QACL,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,IAAI;QACP,CAAC,EAAE,IAAI;KACR;IACD,KAAK,EAAE;QACL,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,IAAI;QACP,CAAC,EAAE,IAAI;KACR;CACF,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** A file letter (a-l) followed by a rank of 1-12 (10-12 are two digits). */
|
|
2
|
+
export declare const SQUARE_TOKEN = "[a-l](?:1[0-2]|[1-9])";
|
|
3
|
+
/** Convert an algebraic square (e.g. "e4", "a12") to a square index (0-143). */
|
|
4
|
+
export declare function algebraicToSquare(algebraic: string): number;
|
|
5
|
+
/**
|
|
6
|
+
* Convert a square index to algebraic notation (e.g. 0 → "a1", 131 → "l11").
|
|
7
|
+
*
|
|
8
|
+
* Ranks 10-12 are two digits on this 12x12 board — building the rank via
|
|
9
|
+
* char-code arithmetic (as if it were always a single digit) silently
|
|
10
|
+
* produces non-digit garbage for those ranks; plain integer math + string
|
|
11
|
+
* concatenation is required instead.
|
|
12
|
+
*/
|
|
13
|
+
export declare function squareToAlgebraic(square: number): string;
|
|
14
|
+
//# sourceMappingURL=square-notation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"square-notation.d.ts","sourceRoot":"","sources":["../../src/utils/square-notation.ts"],"names":[],"mappings":"AAMA,6EAA6E;AAC7E,eAAO,MAAM,YAAY,0BAA0B,CAAC;AAEpD,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAI3D;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAIxD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
// HyperChess Core — hyperchess-core
|
|
3
|
+
// File: packages/core/src/utils/square-notation.ts
|
|
4
|
+
// Version: 1.0.0
|
|
5
|
+
// Copyright (c) 2026 HyperChess Developer Team
|
|
6
|
+
/** A file letter (a-l) followed by a rank of 1-12 (10-12 are two digits). */
|
|
7
|
+
export const SQUARE_TOKEN = '[a-l](?:1[0-2]|[1-9])';
|
|
8
|
+
/** Convert an algebraic square (e.g. "e4", "a12") to a square index (0-143). */
|
|
9
|
+
export function algebraicToSquare(algebraic) {
|
|
10
|
+
const file = algebraic.charCodeAt(0) - 'a'.charCodeAt(0);
|
|
11
|
+
const rank = parseInt(algebraic.slice(1), 10) - 1;
|
|
12
|
+
return rank * 12 + file;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Convert a square index to algebraic notation (e.g. 0 → "a1", 131 → "l11").
|
|
16
|
+
*
|
|
17
|
+
* Ranks 10-12 are two digits on this 12x12 board — building the rank via
|
|
18
|
+
* char-code arithmetic (as if it were always a single digit) silently
|
|
19
|
+
* produces non-digit garbage for those ranks; plain integer math + string
|
|
20
|
+
* concatenation is required instead.
|
|
21
|
+
*/
|
|
22
|
+
export function squareToAlgebraic(square) {
|
|
23
|
+
const file = String.fromCharCode('a'.charCodeAt(0) + (square % 12));
|
|
24
|
+
const rank = Math.floor(square / 12) + 1;
|
|
25
|
+
return `${file}${rank}`;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=square-notation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"square-notation.js","sourceRoot":"","sources":["../../src/utils/square-notation.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,oCAAoC;AACpC,mDAAmD;AACnD,iBAAiB;AACjB,+CAA+C;AAE/C,6EAA6E;AAC7E,MAAM,CAAC,MAAM,YAAY,GAAG,uBAAuB,CAAC;AAEpD,gFAAgF;AAChF,MAAM,UAAU,iBAAiB,CAAC,SAAiB;IACjD,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;IAClD,OAAO,IAAI,GAAG,EAAE,GAAG,IAAI,CAAC;AAC1B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IACzC,OAAO,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { WasmBoard } from 'hyperchess-wasm';
|
|
2
|
+
export { snapshotFromWasmBoard, moveToUci, uciToMove } from './snapshot';
|
|
3
|
+
/**
|
|
4
|
+
* Loads a `WasmBoard` from the Rust engine — starting position if `hfen` is
|
|
5
|
+
* omitted, or parses `hfen` (throws via wasm-pack's `Option::None` → JS
|
|
6
|
+
* `undefined` if it's invalid; callers should check).
|
|
7
|
+
*
|
|
8
|
+
* Imports from the package root, not a specific wasm-pack target subpath:
|
|
9
|
+
* `hyperchess-wasm`'s package.json resolves this to the `nodejs` target
|
|
10
|
+
* under Node (loads synchronously via `fs`) and the `bundler` target
|
|
11
|
+
* everywhere else (a real bundler's module graph resolution is already
|
|
12
|
+
* async, so no explicit init call is needed here either — see
|
|
13
|
+
* docs/sdk-plan/WASM-MIGRATION-PLAN.md Phase 5).
|
|
14
|
+
*
|
|
15
|
+
* NOT usable for a bundler-free browser deployment (a bare
|
|
16
|
+
* `<script type="module">` import with no build step) — the `bundler`
|
|
17
|
+
* target this resolves to there fails to even load (it does a raw
|
|
18
|
+
* `import ... from "./x.wasm"`, which needs a bundler to handle). See
|
|
19
|
+
* `../standalone.ts` for that case instead, which uses the `web` target
|
|
20
|
+
* with an explicit async init and deliberately does NOT import this module.
|
|
21
|
+
*/
|
|
22
|
+
export declare function loadWasmBoard(hfen?: string): WasmBoard;
|
|
23
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/wasm/engine.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEzE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAStD"}
|