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