react-native-chess-kit 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.
Files changed (89) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +168 -0
  3. package/lib/commonjs/board-background.js +49 -0
  4. package/lib/commonjs/board-background.js.map +1 -0
  5. package/lib/commonjs/board-coordinates.js +78 -0
  6. package/lib/commonjs/board-coordinates.js.map +1 -0
  7. package/lib/commonjs/board-drag-ghost.js +110 -0
  8. package/lib/commonjs/board-drag-ghost.js.map +1 -0
  9. package/lib/commonjs/board-legal-dots.js +67 -0
  10. package/lib/commonjs/board-legal-dots.js.map +1 -0
  11. package/lib/commonjs/board-piece.js +74 -0
  12. package/lib/commonjs/board-piece.js.map +1 -0
  13. package/lib/commonjs/board-pieces.js +47 -0
  14. package/lib/commonjs/board-pieces.js.map +1 -0
  15. package/lib/commonjs/board.js +188 -0
  16. package/lib/commonjs/board.js.map +1 -0
  17. package/lib/commonjs/index.js +26 -0
  18. package/lib/commonjs/index.js.map +1 -0
  19. package/lib/commonjs/package.json +1 -0
  20. package/lib/commonjs/types.js +6 -0
  21. package/lib/commonjs/types.js.map +1 -0
  22. package/lib/commonjs/use-board-gesture.js +158 -0
  23. package/lib/commonjs/use-board-gesture.js.map +1 -0
  24. package/lib/commonjs/use-board-pieces.js +195 -0
  25. package/lib/commonjs/use-board-pieces.js.map +1 -0
  26. package/lib/commonjs/use-board-state.js +78 -0
  27. package/lib/commonjs/use-board-state.js.map +1 -0
  28. package/lib/module/board-background.js +44 -0
  29. package/lib/module/board-background.js.map +1 -0
  30. package/lib/module/board-coordinates.js +73 -0
  31. package/lib/module/board-coordinates.js.map +1 -0
  32. package/lib/module/board-drag-ghost.js +104 -0
  33. package/lib/module/board-drag-ghost.js.map +1 -0
  34. package/lib/module/board-legal-dots.js +62 -0
  35. package/lib/module/board-legal-dots.js.map +1 -0
  36. package/lib/module/board-piece.js +69 -0
  37. package/lib/module/board-piece.js.map +1 -0
  38. package/lib/module/board-pieces.js +42 -0
  39. package/lib/module/board-pieces.js.map +1 -0
  40. package/lib/module/board.js +184 -0
  41. package/lib/module/board.js.map +1 -0
  42. package/lib/module/index.js +21 -0
  43. package/lib/module/index.js.map +1 -0
  44. package/lib/module/package.json +1 -0
  45. package/lib/module/types.js +4 -0
  46. package/lib/module/types.js.map +1 -0
  47. package/lib/module/use-board-gesture.js +154 -0
  48. package/lib/module/use-board-gesture.js.map +1 -0
  49. package/lib/module/use-board-pieces.js +189 -0
  50. package/lib/module/use-board-pieces.js.map +1 -0
  51. package/lib/module/use-board-state.js +74 -0
  52. package/lib/module/use-board-state.js.map +1 -0
  53. package/lib/typescript/board-background.d.ts +15 -0
  54. package/lib/typescript/board-background.d.ts.map +1 -0
  55. package/lib/typescript/board-coordinates.d.ts +20 -0
  56. package/lib/typescript/board-coordinates.d.ts.map +1 -0
  57. package/lib/typescript/board-drag-ghost.d.ts +21 -0
  58. package/lib/typescript/board-drag-ghost.d.ts.map +1 -0
  59. package/lib/typescript/board-legal-dots.d.ts +16 -0
  60. package/lib/typescript/board-legal-dots.d.ts.map +1 -0
  61. package/lib/typescript/board-piece.d.ts +36 -0
  62. package/lib/typescript/board-piece.d.ts.map +1 -0
  63. package/lib/typescript/board-pieces.d.ts +22 -0
  64. package/lib/typescript/board-pieces.d.ts.map +1 -0
  65. package/lib/typescript/board.d.ts +17 -0
  66. package/lib/typescript/board.d.ts.map +1 -0
  67. package/lib/typescript/index.d.ts +4 -0
  68. package/lib/typescript/index.d.ts.map +1 -0
  69. package/lib/typescript/types.d.ts +88 -0
  70. package/lib/typescript/types.d.ts.map +1 -0
  71. package/lib/typescript/use-board-gesture.d.ts +46 -0
  72. package/lib/typescript/use-board-gesture.d.ts.map +1 -0
  73. package/lib/typescript/use-board-pieces.d.ts +23 -0
  74. package/lib/typescript/use-board-pieces.d.ts.map +1 -0
  75. package/lib/typescript/use-board-state.d.ts +35 -0
  76. package/lib/typescript/use-board-state.d.ts.map +1 -0
  77. package/package.json +73 -0
  78. package/src/board-background.tsx +46 -0
  79. package/src/board-coordinates.tsx +98 -0
  80. package/src/board-drag-ghost.tsx +132 -0
  81. package/src/board-legal-dots.tsx +73 -0
  82. package/src/board-piece.tsx +104 -0
  83. package/src/board-pieces.tsx +56 -0
  84. package/src/board.tsx +203 -0
  85. package/src/index.ts +39 -0
  86. package/src/types.ts +114 -0
  87. package/src/use-board-gesture.ts +201 -0
  88. package/src/use-board-pieces.ts +158 -0
  89. package/src/use-board-state.ts +104 -0
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+
3
+ import React, { forwardRef, useState, useCallback, useImperativeHandle, useEffect } from 'react';
4
+ import { View } from 'react-native';
5
+ import { GestureDetector } from 'react-native-gesture-handler';
6
+ import { useBoardPieces } from './use-board-pieces';
7
+ import { useBoardState } from './use-board-state';
8
+ import { useBoardGesture } from './use-board-gesture';
9
+ import { BoardBackground } from './board-background';
10
+ import { BoardCoordinates } from './board-coordinates';
11
+ import { BoardLegalDots } from './board-legal-dots';
12
+ import { BoardPiecesLayer } from './board-pieces';
13
+ import { BoardDragGhost } from './board-drag-ghost';
14
+
15
+ /**
16
+ * High-performance custom chess board built on Reanimated + Gesture Handler.
17
+ *
18
+ * Architecture:
19
+ * - 1 gesture handler (vs 32 in typical implementations)
20
+ * - ~40 components mounted (vs ~281)
21
+ * - ~75 native views (vs ~470)
22
+ * - 0 React Context providers
23
+ * - 0 re-renders during drag (pure worklet — only 2 shared value writes per frame)
24
+ *
25
+ * Follows chess.com/lichess pattern: single gesture receiver on the board,
26
+ * coordinate math to determine touched piece, shared values for drag state.
27
+ */
28
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
29
+ export const Board = /*#__PURE__*/forwardRef(function Board({
30
+ fen,
31
+ orientation,
32
+ boardSize,
33
+ gestureEnabled,
34
+ player,
35
+ onMove,
36
+ colors,
37
+ moveDuration,
38
+ withLetters,
39
+ withNumbers,
40
+ renderPiece,
41
+ showLegalMoves,
42
+ moveMethod
43
+ }, ref) {
44
+ const squareSize = boardSize / 8;
45
+
46
+ // --- Piece data from FEN ---
47
+ const pieces = useBoardPieces(fen);
48
+
49
+ // --- Chess.js for legal move validation ---
50
+ const boardState = useBoardState(fen);
51
+
52
+ // Sync internal chess.js when parent changes FEN (puzzle reset, opponent move, etc.)
53
+ // Must be in useEffect — side effects during render violate React's rules
54
+ // and can fire multiple times in concurrent mode.
55
+ useEffect(() => {
56
+ boardState.loadFen(fen);
57
+ }, [fen, boardState]);
58
+
59
+ // --- Selection state (triggers legal dots display) ---
60
+ const [selectedSquare, setSelectedSquare] = useState(null);
61
+ const [legalMoves, setLegalMoves] = useState([]);
62
+
63
+ // Default piece renderer (no-op if parent provides renderPiece)
64
+ const defaultRenderPiece = useCallback((code, size) => /*#__PURE__*/_jsx(View, {
65
+ style: {
66
+ width: size,
67
+ height: size,
68
+ backgroundColor: 'rgba(0,0,0,0.3)'
69
+ }
70
+ }), []);
71
+ const pieceRenderer = renderPiece ?? defaultRenderPiece;
72
+
73
+ // --- Gesture callbacks ---
74
+ const handlePieceSelected = useCallback(square => {
75
+ setSelectedSquare(square);
76
+ if (showLegalMoves) {
77
+ setLegalMoves(boardState.getLegalMoves(square));
78
+ }
79
+ }, [showLegalMoves, boardState]);
80
+ const handleSelectionCleared = useCallback(() => {
81
+ setSelectedSquare(null);
82
+ setLegalMoves([]);
83
+ }, []);
84
+ const handlePieceMoved = useCallback((from, to) => {
85
+ // Clear selection and legal dots
86
+ setSelectedSquare(null);
87
+ setLegalMoves([]);
88
+
89
+ // Notify parent — parent decides whether to accept/reject
90
+ onMove?.({
91
+ from,
92
+ to
93
+ });
94
+ }, [onMove]);
95
+
96
+ // --- Single centralized gesture ---
97
+ const {
98
+ gesture,
99
+ gestureState
100
+ } = useBoardGesture({
101
+ squareSize,
102
+ orientation,
103
+ gestureEnabled,
104
+ player,
105
+ moveMethod,
106
+ pieces,
107
+ callbacks: {
108
+ onPieceSelected: handlePieceSelected,
109
+ onPieceMoved: handlePieceMoved,
110
+ onSelectionCleared: handleSelectionCleared
111
+ },
112
+ selectedSquare,
113
+ legalMoves
114
+ });
115
+
116
+ // --- Imperative ref for parent (move, highlight, reset, undo) ---
117
+ useImperativeHandle(ref, () => ({
118
+ move: move => {
119
+ // Pre-apply to internal chess.js so subsequent getLegalMoves calls
120
+ // reflect the new position. The parent will also update the FEN prop,
121
+ // which triggers useBoardPieces -> piece position animates via shared values.
122
+ boardState.applyMove(move.from, move.to);
123
+ },
124
+ highlight: (_square, _color) => {
125
+ // Highlights are handled by overlay layers in the consuming app,
126
+ // not internally — this is a no-op stub for API compatibility.
127
+ // Use the Board's overlay API or render your own highlight layer.
128
+ },
129
+ clearHighlights: () => {
130
+ // Same as highlight — handled by overlay layer
131
+ },
132
+ resetBoard: newFen => {
133
+ boardState.loadFen(newFen);
134
+ setSelectedSquare(null);
135
+ setLegalMoves([]);
136
+ },
137
+ undo: () => {
138
+ boardState.undoMove();
139
+ setSelectedSquare(null);
140
+ setLegalMoves([]);
141
+ }
142
+ }));
143
+ return /*#__PURE__*/_jsx(GestureDetector, {
144
+ gesture: gesture,
145
+ children: /*#__PURE__*/_jsxs(View, {
146
+ style: {
147
+ width: boardSize,
148
+ height: boardSize
149
+ },
150
+ children: [/*#__PURE__*/_jsx(BoardBackground, {
151
+ boardSize: boardSize,
152
+ lightColor: colors.light,
153
+ darkColor: colors.dark
154
+ }), /*#__PURE__*/_jsx(BoardCoordinates, {
155
+ boardSize: boardSize,
156
+ orientation: orientation,
157
+ lightColor: colors.light,
158
+ darkColor: colors.dark,
159
+ withLetters: withLetters,
160
+ withNumbers: withNumbers
161
+ }), showLegalMoves && /*#__PURE__*/_jsx(BoardLegalDots, {
162
+ legalMoves: legalMoves,
163
+ squareSize: squareSize,
164
+ orientation: orientation
165
+ }), /*#__PURE__*/_jsx(BoardPiecesLayer, {
166
+ pieces: pieces,
167
+ squareSize: squareSize,
168
+ orientation: orientation,
169
+ moveDuration: moveDuration,
170
+ renderPiece: pieceRenderer,
171
+ activeSquare: gestureState.activeSquare,
172
+ isDragging: gestureState.isDragging
173
+ }), /*#__PURE__*/_jsx(BoardDragGhost, {
174
+ squareSize: squareSize,
175
+ isDragging: gestureState.isDragging,
176
+ dragX: gestureState.dragX,
177
+ dragY: gestureState.dragY,
178
+ dragPieceCode: gestureState.dragPieceCode,
179
+ renderPiece: pieceRenderer
180
+ })]
181
+ })
182
+ });
183
+ });
184
+ //# sourceMappingURL=board.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","forwardRef","useState","useCallback","useImperativeHandle","useEffect","View","GestureDetector","useBoardPieces","useBoardState","useBoardGesture","BoardBackground","BoardCoordinates","BoardLegalDots","BoardPiecesLayer","BoardDragGhost","jsx","_jsx","jsxs","_jsxs","Board","fen","orientation","boardSize","gestureEnabled","player","onMove","colors","moveDuration","withLetters","withNumbers","renderPiece","showLegalMoves","moveMethod","ref","squareSize","pieces","boardState","loadFen","selectedSquare","setSelectedSquare","legalMoves","setLegalMoves","defaultRenderPiece","code","size","style","width","height","backgroundColor","pieceRenderer","handlePieceSelected","square","getLegalMoves","handleSelectionCleared","handlePieceMoved","from","to","gesture","gestureState","callbacks","onPieceSelected","onPieceMoved","onSelectionCleared","move","applyMove","highlight","_square","_color","clearHighlights","resetBoard","newFen","undo","undoMove","children","lightColor","light","darkColor","dark","activeSquare","isDragging","dragX","dragY","dragPieceCode"],"sourceRoot":"..\\..\\src","sources":["board.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ // react-native-chess-kit
4
+ // High-performance chess board for React Native
5
+
6
+ // ---------------------------------------------------------------------------
7
+ // Main component
8
+ // ---------------------------------------------------------------------------
9
+
10
+ export { Board } from './board';
11
+
12
+ // ---------------------------------------------------------------------------
13
+ // Types
14
+ // ---------------------------------------------------------------------------
15
+
16
+ // ---------------------------------------------------------------------------
17
+ // Utility functions (useful for overlay positioning)
18
+ // ---------------------------------------------------------------------------
19
+
20
+ export { squareToXY, xyToSquare } from './use-board-pieces';
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Board","squareToXY","xyToSquare"],"sourceRoot":"..\\..\\src","sources":["index.ts"],"mappings":";;AAAA;AACA;;AAEA;AACA;AACA;;AAEA,SAASA,KAAK,QAAQ,SAAS;;AAE/B;AACA;AACA;;AAuBA;AACA;AACA;;AAEA,SAASC,UAAU,EAAEC,UAAU,QAAQ,oBAAoB","ignoreList":[]}
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+
3
+ export {};
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"..\\..\\src","sources":["types.ts"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+
3
+ import { useMemo, useCallback, useRef } from 'react';
4
+ import { Gesture } from 'react-native-gesture-handler';
5
+ import { useSharedValue, runOnJS } from 'react-native-reanimated';
6
+ import { xyToSquare } from './use-board-pieces';
7
+ /**
8
+ * Single centralized gesture handler for the entire board.
9
+ *
10
+ * Instead of 32 separate Gesture.Pan() handlers (one per piece), we use ONE
11
+ * handler on the board container. Touch -> coordinate math -> which piece.
12
+ *
13
+ * Supports three modes:
14
+ * - 'drag': drag piece to target square
15
+ * - 'click': tap source piece, then tap target square
16
+ * - 'both': drag or click (default)
17
+ *
18
+ * All drag position tracking uses shared values — zero JS bridge calls,
19
+ * zero re-renders during drag. Only the final move triggers JS via runOnJS.
20
+ *
21
+ * The gesture object is STABLE (only recreated when squareSize, orientation,
22
+ * gestureEnabled, player, or moveMethod change). Frequently-changing data
23
+ * (pieces, selectedSquare, legalMoves) is read from refs via runOnJS bridge
24
+ * functions, avoiding costly gesture teardown/rebuild on every move.
25
+ */
26
+ export function useBoardGesture({
27
+ squareSize,
28
+ orientation,
29
+ gestureEnabled,
30
+ player,
31
+ moveMethod,
32
+ pieces,
33
+ callbacks,
34
+ selectedSquare,
35
+ legalMoves
36
+ }) {
37
+ // Shared values for drag tracking — updated on UI thread only
38
+ const activeSquare = useSharedValue(null);
39
+ const dragX = useSharedValue(0);
40
+ const dragY = useSharedValue(0);
41
+ const isDragging = useSharedValue(false);
42
+ const dragPieceCode = useSharedValue(null);
43
+ const gestureState = {
44
+ activeSquare,
45
+ dragX,
46
+ dragY,
47
+ isDragging,
48
+ dragPieceCode
49
+ };
50
+
51
+ // --- Refs for frequently-changing data (read from JS thread via runOnJS) ---
52
+ // These update every move but do NOT cause gesture object recreation.
53
+ const piecesRef = useRef(pieces);
54
+ piecesRef.current = pieces;
55
+ const selectedSquareRef = useRef(selectedSquare);
56
+ selectedSquareRef.current = selectedSquare;
57
+ const legalMovesRef = useRef(legalMoves);
58
+ legalMovesRef.current = legalMoves;
59
+ const callbacksRef = useRef(callbacks);
60
+ callbacksRef.current = callbacks;
61
+
62
+ // --- JS-thread bridge functions called from worklets via runOnJS ---
63
+ // These read current values from refs, so they always have fresh data.
64
+
65
+ const handleBegin = useCallback((touchX, touchY) => {
66
+ const square = xyToSquare(touchX, touchY, squareSize, orientation);
67
+ const currentPieces = piecesRef.current;
68
+ const currentSelected = selectedSquareRef.current;
69
+ const currentLegalMoves = legalMovesRef.current;
70
+ const cbs = callbacksRef.current;
71
+ const canClick = moveMethod !== 'drag';
72
+
73
+ // Build lookup for the current touch
74
+ const piece = currentPieces.find(p => p.square === square);
75
+ const isPlayerPiece = piece ? player === 'both' || (piece.color === 'w' ? 'white' : 'black') === player : false;
76
+
77
+ // Click-to-move: second tap on a legal target square
78
+ const legalSquares = new Set(currentLegalMoves.map(m => m.square));
79
+ if (canClick && currentSelected && legalSquares.has(square)) {
80
+ cbs.onPieceMoved(currentSelected, square);
81
+ activeSquare.value = null;
82
+ isDragging.value = false;
83
+ dragPieceCode.value = null;
84
+ return;
85
+ }
86
+ if (isPlayerPiece && piece) {
87
+ // Tapped/started dragging a player piece
88
+ activeSquare.value = square;
89
+ dragX.value = touchX;
90
+ dragY.value = touchY;
91
+ dragPieceCode.value = piece.code;
92
+ cbs.onPieceSelected(square);
93
+ } else {
94
+ // Tapped empty square or opponent piece — clear selection
95
+ activeSquare.value = null;
96
+ dragPieceCode.value = null;
97
+ if (currentSelected) {
98
+ cbs.onSelectionCleared();
99
+ }
100
+ }
101
+ }, [squareSize, orientation, player, moveMethod, activeSquare, dragX, dragY, isDragging, dragPieceCode]);
102
+ const handleEnd = useCallback((touchX, touchY) => {
103
+ const fromSquare = activeSquare.value;
104
+ if (!fromSquare) return;
105
+ const toSquare = xyToSquare(touchX, touchY, squareSize, orientation);
106
+ isDragging.value = false;
107
+ if (fromSquare !== toSquare) {
108
+ callbacksRef.current.onPieceMoved(fromSquare, toSquare);
109
+ }
110
+ activeSquare.value = null;
111
+ dragPieceCode.value = null;
112
+ }, [squareSize, orientation, activeSquare, isDragging, dragPieceCode]);
113
+
114
+ // --- Build the gesture (STABLE — only changes on layout/config changes) ---
115
+ const canDrag = moveMethod !== 'click';
116
+ const gesture = useMemo(() => {
117
+ return Gesture.Pan().enabled(gestureEnabled).minDistance(0) // Also detect taps (zero-distance pans)
118
+ .onBegin(e => {
119
+ 'worklet';
120
+
121
+ // Bridge to JS for piece lookup + selection logic
122
+ runOnJS(handleBegin)(e.x, e.y);
123
+ }).onStart(() => {
124
+ 'worklet';
125
+
126
+ if (!canDrag || !activeSquare.value) return;
127
+ isDragging.value = true;
128
+ }).onUpdate(e => {
129
+ 'worklet';
130
+
131
+ if (!canDrag || !isDragging.value) return;
132
+ // Only 2 shared value writes — no JS bridge, no re-renders
133
+ dragX.value = e.x;
134
+ dragY.value = e.y;
135
+ }).onEnd(e => {
136
+ 'worklet';
137
+
138
+ if (!isDragging.value || !activeSquare.value) return;
139
+ runOnJS(handleEnd)(e.x, e.y);
140
+ }).onFinalize(() => {
141
+ 'worklet';
142
+
143
+ // Safety reset if gesture was interrupted
144
+ isDragging.value = false;
145
+ });
146
+ }, [gestureEnabled, canDrag, handleBegin, handleEnd,
147
+ // Shared values are stable refs — listed for exhaustive-deps but don't cause recreations
148
+ activeSquare, dragX, dragY, isDragging]);
149
+ return {
150
+ gesture,
151
+ gestureState
152
+ };
153
+ }
154
+ //# sourceMappingURL=use-board-gesture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useMemo","useCallback","useRef","Gesture","useSharedValue","runOnJS","xyToSquare","useBoardGesture","squareSize","orientation","gestureEnabled","player","moveMethod","pieces","callbacks","selectedSquare","legalMoves","activeSquare","dragX","dragY","isDragging","dragPieceCode","gestureState","piecesRef","current","selectedSquareRef","legalMovesRef","callbacksRef","handleBegin","touchX","touchY","square","currentPieces","currentSelected","currentLegalMoves","cbs","canClick","piece","find","p","isPlayerPiece","color","legalSquares","Set","map","m","has","onPieceMoved","value","code","onPieceSelected","onSelectionCleared","handleEnd","fromSquare","toSquare","canDrag","gesture","Pan","enabled","minDistance","onBegin","e","x","y","onStart","onUpdate","onEnd","onFinalize"],"sourceRoot":"..\\..\\src","sources":["use-board-gesture.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+
3
+ import { useMemo, useRef } from 'react';
4
+ const FEN_PIECE_MAP = {
5
+ p: {
6
+ code: 'bp',
7
+ color: 'b'
8
+ },
9
+ r: {
10
+ code: 'br',
11
+ color: 'b'
12
+ },
13
+ n: {
14
+ code: 'bn',
15
+ color: 'b'
16
+ },
17
+ b: {
18
+ code: 'bb',
19
+ color: 'b'
20
+ },
21
+ q: {
22
+ code: 'bq',
23
+ color: 'b'
24
+ },
25
+ k: {
26
+ code: 'bk',
27
+ color: 'b'
28
+ },
29
+ P: {
30
+ code: 'wp',
31
+ color: 'w'
32
+ },
33
+ R: {
34
+ code: 'wr',
35
+ color: 'w'
36
+ },
37
+ N: {
38
+ code: 'wn',
39
+ color: 'w'
40
+ },
41
+ B: {
42
+ code: 'wb',
43
+ color: 'w'
44
+ },
45
+ Q: {
46
+ code: 'wq',
47
+ color: 'w'
48
+ },
49
+ K: {
50
+ code: 'wk',
51
+ color: 'w'
52
+ }
53
+ };
54
+ const FILES = 'abcdefgh';
55
+
56
+ /**
57
+ * Parse the piece-placement part of a FEN string into an array of pieces.
58
+ * Pure function — no React dependencies, suitable for worklets if needed.
59
+ */
60
+ function parseFenPieces(fen) {
61
+ const placement = fen.split(' ')[0];
62
+ const ranks = placement.split('/');
63
+ const pieces = [];
64
+ for (let rankIdx = 0; rankIdx < ranks.length; rankIdx++) {
65
+ const rank = ranks[rankIdx];
66
+ let fileIdx = 0;
67
+ for (const char of rank) {
68
+ if (char >= '1' && char <= '8') {
69
+ fileIdx += parseInt(char, 10);
70
+ continue;
71
+ }
72
+ const mapping = FEN_PIECE_MAP[char];
73
+ if (mapping) {
74
+ // FEN ranks are from rank 8 (index 0) down to rank 1 (index 7)
75
+ const square = `${FILES[fileIdx]}${8 - rankIdx}`;
76
+ pieces.push({
77
+ code: mapping.code,
78
+ square,
79
+ color: mapping.color
80
+ });
81
+ }
82
+ fileIdx++;
83
+ }
84
+ }
85
+ return pieces;
86
+ }
87
+
88
+ /**
89
+ * Convert square notation to pixel coordinates (top-left corner).
90
+ * Orientation-aware: flips the board when playing as black.
91
+ */
92
+ export function squareToXY(square, squareSize, orientation) {
93
+ 'worklet';
94
+
95
+ const fileIdx = square.charCodeAt(0) - 97; // 'a'=0 .. 'h'=7
96
+ const rankIdx = parseInt(square[1], 10) - 1; // '1'=0 .. '8'=7
97
+
98
+ const col = orientation === 'white' ? fileIdx : 7 - fileIdx;
99
+ const row = orientation === 'white' ? 7 - rankIdx : rankIdx;
100
+ return {
101
+ x: col * squareSize,
102
+ y: row * squareSize
103
+ };
104
+ }
105
+
106
+ /**
107
+ * Convert pixel coordinates to a square notation string.
108
+ * Clamps to board bounds. Orientation-aware.
109
+ */
110
+ export function xyToSquare(x, y, squareSize, orientation) {
111
+ 'worklet';
112
+
113
+ const col = Math.max(0, Math.min(7, Math.floor(x / squareSize)));
114
+ const row = Math.max(0, Math.min(7, Math.floor(y / squareSize)));
115
+ const fileIdx = orientation === 'white' ? col : 7 - col;
116
+ const rankIdx = orientation === 'white' ? 7 - row : row;
117
+
118
+ // String.fromCharCode not available in worklets — use lookup
119
+ const files = 'abcdefgh';
120
+ return `${files[fileIdx]}${rankIdx + 1}`;
121
+ }
122
+
123
+ /**
124
+ * Manages the piece list derived from FEN, with stable IDs for React keys.
125
+ *
126
+ * Stable IDs prevent unmount/remount cycles when pieces change position.
127
+ * A piece keeps its ID as long as it exists on the board — only capture
128
+ * (removal) or promotion (code change) creates a new ID.
129
+ */
130
+ export function useBoardPieces(fen) {
131
+ // Track piece-code counters across renders for stable ID assignment
132
+ const idCounterRef = useRef({});
133
+ const prevPiecesRef = useRef([]);
134
+ return useMemo(() => {
135
+ const parsed = parseFenPieces(fen);
136
+ const prev = prevPiecesRef.current;
137
+ const prevBySquare = new Map(prev.map(p => [p.square, p]));
138
+
139
+ // Try to reuse IDs from previous render:
140
+ // 1. Same code on same square -> keep ID (piece didn't move)
141
+ // 2. Same code moved to a new square -> find unmatched previous piece of same code
142
+ const usedPrevIds = new Set();
143
+ const result = [];
144
+
145
+ // First pass: exact square matches (piece stayed or appeared on same square)
146
+ const unmatched = [];
147
+ for (const p of parsed) {
148
+ const existing = prevBySquare.get(p.square);
149
+ if (existing && existing.code === p.code && !usedPrevIds.has(existing.id)) {
150
+ usedPrevIds.add(existing.id);
151
+ result.push({
152
+ ...p,
153
+ id: existing.id
154
+ });
155
+ } else {
156
+ unmatched.push(p);
157
+ }
158
+ }
159
+
160
+ // Second pass: match unmatched pieces by code to previous pieces that moved
161
+ for (const p of unmatched) {
162
+ let matchedId = null;
163
+ for (const prevPiece of prev) {
164
+ if (prevPiece.code === p.code && !usedPrevIds.has(prevPiece.id)) {
165
+ matchedId = prevPiece.id;
166
+ usedPrevIds.add(prevPiece.id);
167
+ break;
168
+ }
169
+ }
170
+ if (matchedId) {
171
+ result.push({
172
+ ...p,
173
+ id: matchedId
174
+ });
175
+ } else {
176
+ // New piece (promotion, or first render) — assign fresh ID
177
+ const counter = idCounterRef.current;
178
+ counter[p.code] = (counter[p.code] ?? 0) + 1;
179
+ result.push({
180
+ ...p,
181
+ id: `${p.code}-${counter[p.code]}`
182
+ });
183
+ }
184
+ }
185
+ prevPiecesRef.current = result;
186
+ return result;
187
+ }, [fen]);
188
+ }
189
+ //# sourceMappingURL=use-board-pieces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useMemo","useRef","FEN_PIECE_MAP","p","code","color","r","n","b","q","k","P","R","N","B","Q","K","FILES","parseFenPieces","fen","placement","split","ranks","pieces","rankIdx","length","rank","fileIdx","char","parseInt","mapping","square","push","squareToXY","squareSize","orientation","charCodeAt","col","row","x","y","xyToSquare","Math","max","min","floor","files","useBoardPieces","idCounterRef","prevPiecesRef","parsed","prev","current","prevBySquare","Map","map","usedPrevIds","Set","result","unmatched","existing","get","has","id","add","matchedId","prevPiece","counter"],"sourceRoot":"..\\..\\src","sources":["use-board-pieces.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+
3
+ import { useRef, useCallback } from 'react';
4
+ import { Chess } from 'chess.js';
5
+ /**
6
+ * Manages the internal chess.js instance for legal move validation.
7
+ *
8
+ * This mirrors the visual board state. When the parent passes a new FEN,
9
+ * the internal chess.js is synced. Legal move queries and move application
10
+ * happen against this instance.
11
+ *
12
+ * The chess.js instance lives in a ref — no React state, no re-renders.
13
+ */
14
+ export function useBoardState(initialFen) {
15
+ const chessRef = useRef(null);
16
+ if (!chessRef.current) chessRef.current = new Chess(initialFen);
17
+ const getLegalMoves = useCallback(square => {
18
+ try {
19
+ const moves = chessRef.current.moves({
20
+ square: square,
21
+ verbose: true
22
+ });
23
+ return moves.map(m => ({
24
+ square: m.to,
25
+ isCapture: m.captured !== undefined
26
+ }));
27
+ } catch {
28
+ return [];
29
+ }
30
+ }, []);
31
+ const isPlayerPiece = useCallback((square, pieces, player) => {
32
+ const piece = pieces.find(p => p.square === square);
33
+ if (!piece) return false;
34
+ if (player === 'both') return true;
35
+ const pieceColor = piece.color === 'w' ? 'white' : 'black';
36
+ return pieceColor === player;
37
+ }, []);
38
+ const applyMove = useCallback((from, to, promotion) => {
39
+ try {
40
+ chessRef.current.move({
41
+ from: from,
42
+ to: to,
43
+ promotion: promotion
44
+ });
45
+ return {
46
+ applied: true,
47
+ fen: chessRef.current.fen()
48
+ };
49
+ } catch {
50
+ return {
51
+ applied: false
52
+ };
53
+ }
54
+ }, []);
55
+ const undoMove = useCallback(() => {
56
+ const result = chessRef.current.undo();
57
+ return result ? chessRef.current.fen() : null;
58
+ }, []);
59
+ const loadFen = useCallback(fen => {
60
+ chessRef.current.load(fen);
61
+ }, []);
62
+ const getFen = useCallback(() => chessRef.current.fen(), []);
63
+ const getTurn = useCallback(() => chessRef.current.turn(), []);
64
+ return {
65
+ getLegalMoves,
66
+ isPlayerPiece,
67
+ applyMove,
68
+ undoMove,
69
+ loadFen,
70
+ getFen,
71
+ getTurn
72
+ };
73
+ }
74
+ //# sourceMappingURL=use-board-state.js.map