react-chess-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.
Files changed (46) hide show
  1. package/README.md +46 -0
  2. package/dist/features/analysis/analysisBoardHighlightColors.d.ts +12 -0
  3. package/dist/features/analysis/analysisUtils.d.ts +4 -0
  4. package/dist/features/analysis/core/AnalysisBoardCore.d.ts +28 -0
  5. package/dist/features/analysis/core/AnalysisChessboardView.d.ts +5 -0
  6. package/dist/features/analysis/core/AnalysisErrorBoundary.d.ts +14 -0
  7. package/dist/features/analysis/core/AnalysisPosition.d.ts +54 -0
  8. package/dist/features/analysis/core/analysisLayoutConfig.d.ts +6 -0
  9. package/dist/features/analysis/core/index.d.ts +7 -0
  10. package/dist/features/analysis/core/renderProps.d.ts +39 -0
  11. package/dist/features/analysis/core/useAnalysisBoardModel.d.ts +36 -0
  12. package/dist/features/analysis/defaults/AnalysisBoard.d.ts +16 -0
  13. package/dist/features/analysis/defaults/AnalysisBoardLayout.d.ts +14 -0
  14. package/dist/features/analysis/defaults/DefaultAnalysisContainer.d.ts +4 -0
  15. package/dist/features/analysis/defaults/DefaultAnalysisSidebar.d.ts +3 -0
  16. package/dist/features/analysis/defaults/EngineEvaluationPanel.d.ts +8 -0
  17. package/dist/features/analysis/defaults/analysisLayout.d.ts +3 -0
  18. package/dist/features/analysis/defaults/analysisModalStyles.d.ts +7 -0
  19. package/dist/features/analysis/defaults/analysisSidebarColors.d.ts +37 -0
  20. package/dist/features/analysis/defaults/analysisSidebarRowStyle.d.ts +8 -0
  21. package/dist/features/analysis/defaults/index.d.ts +9 -0
  22. package/dist/features/analysis/index.d.ts +5 -0
  23. package/dist/features/analysis/types.d.ts +9 -0
  24. package/dist/features/chessboard/HighlightChessboard.d.ts +7 -0
  25. package/dist/features/chessboard/boardSquareHighlightColors.d.ts +9 -0
  26. package/dist/features/chessboard/chessboardTheme.d.ts +27 -0
  27. package/dist/features/chessboard/index.d.ts +3 -0
  28. package/dist/features/engine/StockfishBrowserEngine.d.ts +32 -0
  29. package/dist/features/engine/formatEvaluation.d.ts +18 -0
  30. package/dist/features/engine/index.d.ts +7 -0
  31. package/dist/features/engine/isAnalyzableFen.d.ts +2 -0
  32. package/dist/features/engine/parseUciInfo.d.ts +2 -0
  33. package/dist/features/engine/stockfishUrls.d.ts +8 -0
  34. package/dist/features/engine/types.d.ts +27 -0
  35. package/dist/features/engine/useAnalysisEngine.d.ts +2 -0
  36. package/dist/features/navigation/DefaultPlyNavigation.d.ts +4 -0
  37. package/dist/features/navigation/PlyNavigation.d.ts +6 -0
  38. package/dist/features/navigation/index.d.ts +4 -0
  39. package/dist/features/navigation/plyNavigationStyles.d.ts +12 -0
  40. package/dist/features/navigation/types.d.ts +36 -0
  41. package/dist/index.d.ts +4 -0
  42. package/dist/index.esm.js +1495 -0
  43. package/dist/index.js +1547 -0
  44. package/dist/stories/Chessboard.stories.d.ts +7 -0
  45. package/dist/stories/withThemeProvider.d.ts +7 -0
  46. package/package.json +65 -0
package/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # react-chess-core
2
+
3
+ ```bash
4
+ npm install
5
+ npm run build
6
+ ```
7
+
8
+ Shared **chessboard** (theme + `HighlightChessboard`) and **browser Stockfish** utilities. Used by `react-chess-puzzle-kit` and (planned) `react-chess-explorer`.
9
+
10
+ Storybook: `npm run storybook` → http://localhost:6007
11
+
12
+ ---
13
+
14
+ ## Migration phases (Option B)
15
+
16
+ | Phase | Status | Work |
17
+ |-------|--------|------|
18
+ | **1** | Done | Scaffold package, Rollup, Storybook |
19
+ | **2** | Done | Board + engine source live in this repo |
20
+ | **3** | Done | `react-chess-puzzle-kit` depends on `file:../react-chess-core`, re-export for compatibility |
21
+ | **4** | Done | Remove duplicate shim files from puzzle-kit; slim public API (no core re-exports from puzzle-kit) |
22
+ | **5** | In progress | `react-chess-explorer` scaffold (core only); requirements → `docs/REQUIREMENTS.md` |
23
+
24
+ ---
25
+
26
+ ## Install (consumers)
27
+
28
+ ```bash
29
+ npm install react-chess-core
30
+ ```
31
+
32
+ **Peer dependencies:** `react`, `react-chessboard`, `chess.js`
33
+
34
+ For Stockfish in the browser:
35
+
36
+ ```bash
37
+ npm install stockfish
38
+ npm run copy:stockfish # in your app, or copy WASM to public/stockfish/
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Exports
44
+
45
+ - **Chessboard:** `ThemeProvider`, `useChessboardTheme`, `HighlightChessboard`, `boardSquareHighlightColors`
46
+ - **Engine:** `useAnalysisEngine`, `StockfishBrowserEngine`, `EngineEvaluationPanel`, `isAnalyzableFen`, types/helpers
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Square overlay colors for analysis board replay (last move highlight).
3
+ */
4
+ export declare const analysisBoardHighlightColors: {
5
+ readonly lastMove: {
6
+ readonly light: "rgba(253, 216, 53, 0.55)";
7
+ readonly dark: "rgba(144, 202, 249, 0.5)";
8
+ };
9
+ };
10
+ export declare const getLastMoveSquareStyles: (from: string, to: string, theme: "light" | "dark") => Record<string, {
11
+ backgroundColor: string;
12
+ }>;
@@ -0,0 +1,4 @@
1
+ import { Chess } from 'chess.js';
2
+ /** Apply a UCI move (e.g. `e7e8q`) without throwing. */
3
+ export declare function applyUciMove(chess: Chess, uci: string): boolean;
4
+ export declare function getCheckSquareFromChess(chess: Chess): string;
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import { AnalysisContainerRenderProps, AnalysisMainRenderProps, AnalysisSidebarRenderProps, EngineEvaluationRenderProps } from './renderProps';
3
+ import { AnalysisEngineOptions } from '../../engine/types';
4
+ import { AnalysisBoardModel, UseAnalysisBoardModelArgs } from './useAnalysisBoardModel';
5
+ export type AnalysisBoardCoreProps = UseAnalysisBoardModelArgs & {
6
+ engine?: AnalysisEngineOptions;
7
+ /** Host-owned shell (modal, page layout, etc.). */
8
+ renderContainer: (props: AnalysisContainerRenderProps) => React.ReactNode;
9
+ /** Host-owned grid/placement of board + sidebar (no library default). */
10
+ renderMain: (props: AnalysisMainRenderProps) => React.ReactNode;
11
+ renderSidebar: (props: AnalysisSidebarRenderProps) => React.ReactNode;
12
+ renderEngineEvaluation: (props: EngineEvaluationRenderProps) => React.ReactNode;
13
+ };
14
+ /**
15
+ * Analysis logic + composition only: hook, board node, sidebar/engine slots.
16
+ * No layout divs — use {@link renderMain} (e.g. `AnalysisBoardLayout` from `analysis/defaults` or a host layout).
17
+ */
18
+ export declare const AnalysisBoardCore: ({ renderContainer, renderMain, renderSidebar, renderEngineEvaluation, ...modelArgs }: AnalysisBoardCoreProps) => React.JSX.Element;
19
+ type AnalysisBoardCoreViewProps = {
20
+ model: AnalysisBoardModel;
21
+ renderContainer: AnalysisBoardCoreProps['renderContainer'];
22
+ renderMain: AnalysisBoardCoreProps['renderMain'];
23
+ renderSidebar: AnalysisBoardCoreProps['renderSidebar'];
24
+ renderEngineEvaluation: AnalysisBoardCoreProps['renderEngineEvaluation'];
25
+ };
26
+ /** Pure composition (no layout styles) for testing and reuse. */
27
+ export declare const AnalysisBoardCoreView: ({ model, renderContainer, renderMain, renderSidebar, renderEngineEvaluation, }: AnalysisBoardCoreViewProps) => React.ReactNode;
28
+ export type { AnalysisBoardModel, UseAnalysisBoardModelArgs };
@@ -0,0 +1,5 @@
1
+ import { AnalysisBoardModel } from './useAnalysisBoardModel';
2
+ /** Draggable analysis board (no surrounding layout chrome). */
3
+ export declare const AnalysisChessboardView: ({ model }: {
4
+ model: AnalysisBoardModel;
5
+ }) => import("react").JSX.Element;
@@ -0,0 +1,14 @@
1
+ import { Component, ReactNode } from 'react';
2
+ type AnalysisErrorBoundaryProps = {
3
+ children: ReactNode;
4
+ onClose?: () => void;
5
+ };
6
+ type AnalysisErrorBoundaryState = {
7
+ error: Error | null;
8
+ };
9
+ export declare class AnalysisErrorBoundary extends Component<AnalysisErrorBoundaryProps, AnalysisErrorBoundaryState> {
10
+ state: AnalysisErrorBoundaryState;
11
+ static getDerivedStateFromError(error: Error): AnalysisErrorBoundaryState;
12
+ render(): string | number | boolean | Iterable<ReactNode> | import("react").JSX.Element | null | undefined;
13
+ }
14
+ export {};
@@ -0,0 +1,54 @@
1
+ import type { AnalysisContext } from '../types';
2
+ export type SolutionMoveDisplay = {
3
+ ply: number;
4
+ uci: string;
5
+ san: string;
6
+ };
7
+ export type AnalysisHistoryRow = {
8
+ key: string;
9
+ label: string;
10
+ indent: number;
11
+ kind: 'start' | 'main' | 'variation';
12
+ mainPly: number;
13
+ variationIndex: number;
14
+ };
15
+ export declare class AnalysisPosition {
16
+ private chess;
17
+ private readonly initialFen;
18
+ private readonly solutionMoves;
19
+ private readonly solutionSans;
20
+ private mainPly;
21
+ private variation;
22
+ private variationCursor;
23
+ constructor(context: AnalysisContext);
24
+ private static buildSolutionSans;
25
+ private static applySolutionMove;
26
+ private fenAtMainPly;
27
+ private rebuildChess;
28
+ private findLegalMove;
29
+ private uciFromVerboseMove;
30
+ private matchesMainMove;
31
+ getNavPly(): number;
32
+ getMaxNavPly(): number;
33
+ /** @deprecated Use getNavPly */
34
+ getPly(): number;
35
+ /** @deprecated Use getMaxNavPly */
36
+ getMaxPly(): number;
37
+ getSolutionSans(): SolutionMoveDisplay[];
38
+ getHistoryRows(): AnalysisHistoryRow[];
39
+ isHistoryRowSelected(row: AnalysisHistoryRow): boolean;
40
+ selectHistoryRow(row: AnalysisHistoryRow): void;
41
+ selectMainLine(ply: number): void;
42
+ /** @deprecated Use selectMainLine or goToNavPly */
43
+ goToPly(ply: number): void;
44
+ goToNavPly(navPly: number): void;
45
+ tryPlayMove(sourceSquare: string, targetSquare: string, piece: string): boolean;
46
+ next(): boolean;
47
+ prev(): boolean;
48
+ getLastMoveSquares(): {
49
+ from: string;
50
+ to: string;
51
+ } | null;
52
+ fen(): string;
53
+ getCheckSquare(): string;
54
+ }
@@ -0,0 +1,6 @@
1
+ /** Host-provided dimensions for analysis board + sidebar grid (defaults package only). */
2
+ export type AnalysisLayoutConfig = {
3
+ boardWidth: number;
4
+ sidebarWidth: number;
5
+ columnGap: number;
6
+ };
@@ -0,0 +1,7 @@
1
+ export * from './AnalysisErrorBoundary';
2
+ export * from './analysisLayoutConfig';
3
+ export * from './AnalysisBoardCore';
4
+ export * from './AnalysisChessboardView';
5
+ export * from './AnalysisPosition';
6
+ export * from './renderProps';
7
+ export * from './useAnalysisBoardModel';
@@ -0,0 +1,39 @@
1
+ import type { ReactNode } from 'react';
2
+ import { EngineEvaluation } from '../../engine/types';
3
+ import { AnalysisHistoryRow, SolutionMoveDisplay } from './AnalysisPosition';
4
+ import { AnalysisBoardModel } from './useAnalysisBoardModel';
5
+ export type AnalysisControls = {
6
+ visible: boolean;
7
+ openAnalysis: () => void;
8
+ };
9
+ export type EngineEvaluationRenderProps = {
10
+ fen: string;
11
+ evaluation: EngineEvaluation;
12
+ theme: 'light' | 'dark';
13
+ };
14
+ export type AnalysisSidebarRenderProps = {
15
+ /** Main-line moves (legacy; prefer historyRows). */
16
+ moves: SolutionMoveDisplay[];
17
+ historyRows: AnalysisHistoryRow[];
18
+ isHistoryRowSelected: (row: AnalysisHistoryRow) => boolean;
19
+ onSelectHistoryRow: (row: AnalysisHistoryRow) => void;
20
+ ply: number;
21
+ maxPly: number;
22
+ onSelectPly: (ply: number) => void;
23
+ theme: 'light' | 'dark';
24
+ /** Host-rendered engine UI from `renderEngineEvaluation`. */
25
+ engineEvaluationPanel: ReactNode | null;
26
+ };
27
+ export type AnalysisContainerRenderProps = {
28
+ theme: 'light' | 'dark';
29
+ onClose: () => void;
30
+ children: ReactNode;
31
+ /** Used by {@link DefaultAnalysisContainer} for overlay dismiss (ignored by most hosts). */
32
+ onBackdropMouseDown?: () => void;
33
+ };
34
+ /** Place board + sidebar inside the analysis shell (host or default grid). */
35
+ export type AnalysisMainRenderProps = {
36
+ model: AnalysisBoardModel;
37
+ board: ReactNode;
38
+ sidebar: ReactNode;
39
+ };
@@ -0,0 +1,36 @@
1
+ import { AnalysisHistoryRow, SolutionMoveDisplay } from './AnalysisPosition';
2
+ import type { AnalysisContext } from '../types';
3
+ import { AnalysisEngineOptions, EngineEvaluation } from '../../engine';
4
+ export type UseAnalysisBoardModelArgs = {
5
+ analysisContext: AnalysisContext;
6
+ onClose: () => void;
7
+ theme: 'light' | 'dark';
8
+ /** Chessboard pixel width (host-controlled). */
9
+ boardWidth: number;
10
+ engine?: AnalysisEngineOptions;
11
+ };
12
+ export type AnalysisBoardModel = {
13
+ theme: 'light' | 'dark';
14
+ boardWidth: number;
15
+ analysisContext: AnalysisContext;
16
+ fen: string;
17
+ ply: number;
18
+ maxPly: number;
19
+ historyRows: AnalysisHistoryRow[];
20
+ solutionSans: SolutionMoveDisplay[];
21
+ boardOrientation: 'white' | 'black';
22
+ engineEvaluation: EngineEvaluation;
23
+ engineEnabled: boolean;
24
+ lastMove: {
25
+ from: string;
26
+ to: string;
27
+ } | null;
28
+ checkSquare: string | null;
29
+ onSelectPly: (ply: number) => void;
30
+ onSelectHistoryRow: (row: AnalysisHistoryRow) => void;
31
+ isHistoryRowSelected: (row: AnalysisHistoryRow) => boolean;
32
+ onPieceDrop: (sourceSquare: string, targetSquare: string, piece: string) => boolean;
33
+ onBackdropMouseDown: () => void;
34
+ onClose: () => void;
35
+ };
36
+ export declare const useAnalysisBoardModel: ({ analysisContext, onClose, theme, boardWidth, engine, }: UseAnalysisBoardModelArgs) => AnalysisBoardModel;
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import { AnalysisBoardCoreProps } from '../core/AnalysisBoardCore';
3
+ import { AnalysisLayoutConfig } from '../core/analysisLayoutConfig';
4
+ import { AnalysisContainerRenderProps, AnalysisMainRenderProps, AnalysisSidebarRenderProps, EngineEvaluationRenderProps } from '../core/renderProps';
5
+ export interface AnalysisBoardProps extends Omit<AnalysisBoardCoreProps, 'renderContainer' | 'renderMain' | 'renderSidebar' | 'renderEngineEvaluation' | 'boardWidth'> {
6
+ layout?: AnalysisLayoutConfig;
7
+ renderContainer?: (props: AnalysisContainerRenderProps) => React.ReactNode;
8
+ renderMain?: (props: AnalysisMainRenderProps) => React.ReactNode;
9
+ renderSidebar?: (props: AnalysisSidebarRenderProps) => React.ReactNode;
10
+ renderEngineEvaluation?: (props: EngineEvaluationRenderProps) => React.ReactNode;
11
+ }
12
+ /**
13
+ * Full analysis UI with library defaults: modal shell, grid layout, sidebar, engine panel.
14
+ * For host-owned UI only, use {@link AnalysisBoardCore} and pass all render props.
15
+ */
16
+ export declare const AnalysisBoard: ({ layout, renderContainer, renderMain, renderSidebar, renderEngineEvaluation, engine, ...modelArgs }: AnalysisBoardProps) => React.JSX.Element;
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { AnalysisLayoutConfig } from '../core/analysisLayoutConfig';
3
+ import { AnalysisBoardModel } from '../core/useAnalysisBoardModel';
4
+ export type AnalysisBoardLayoutProps = {
5
+ layout: AnalysisLayoutConfig;
6
+ model: AnalysisBoardModel;
7
+ board: React.ReactNode;
8
+ sidebar: React.ReactNode;
9
+ };
10
+ /**
11
+ * Optional grid helper: board column + sidebar column.
12
+ * Hosts may use this in `renderMain` or supply their own layout.
13
+ */
14
+ export declare const AnalysisBoardLayout: ({ layout, model, board, sidebar, }: AnalysisBoardLayoutProps) => React.JSX.Element;
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { AnalysisContainerRenderProps } from '../core/renderProps';
3
+ /** Default full-screen modal shell for analysis (library preset UI). */
4
+ export declare const DefaultAnalysisContainer: ({ theme, onClose, onBackdropMouseDown, children, }: AnalysisContainerRenderProps) => React.JSX.Element;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { AnalysisSidebarRenderProps } from '../core/renderProps';
3
+ export declare const DefaultAnalysisSidebar: ({ historyRows, isHistoryRowSelected, onSelectHistoryRow, ply, maxPly, onSelectPly, theme, engineEvaluationPanel, }: AnalysisSidebarRenderProps) => React.JSX.Element;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import type { EngineEvaluation } from '../../engine/types';
3
+ export interface EngineEvaluationPanelProps {
4
+ fen: string;
5
+ evaluation: EngineEvaluation;
6
+ theme: 'light' | 'dark';
7
+ }
8
+ export declare const EngineEvaluationPanel: ({ fen, evaluation, theme, }: EngineEvaluationPanelProps) => React.JSX.Element;
@@ -0,0 +1,3 @@
1
+ import { AnalysisLayoutConfig } from '../core/analysisLayoutConfig';
2
+ /** Library default grid; hosts should pass their own {@link AnalysisLayoutConfig}. */
3
+ export declare const DEFAULT_ANALYSIS_LAYOUT: AnalysisLayoutConfig;
@@ -0,0 +1,7 @@
1
+ import { CSSProperties } from 'react';
2
+ export type AnalysisModalStyles = {
3
+ panel: CSSProperties;
4
+ title: CSSProperties;
5
+ closeButton: CSSProperties;
6
+ };
7
+ export declare const getAnalysisModalStyles: (theme: "light" | "dark") => AnalysisModalStyles;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Move-list colors for the analysis board sidebar.
3
+ * Tweak values here when iterating on history row striping.
4
+ */
5
+ export declare const analysisSidebarColors: {
6
+ /** Selected move row */
7
+ readonly activeMove: {
8
+ readonly light: "rgba(119, 177, 212, 1)";
9
+ readonly dark: "rgba(90, 159, 190, 1)";
10
+ };
11
+ /** Start row */
12
+ readonly start: {
13
+ readonly light: "#e8e8e8";
14
+ readonly dark: "#262626";
15
+ };
16
+ /** Alternating main-line rows (index 0 = darker, 1 = lighter). */
17
+ readonly mainStripe: readonly [{
18
+ readonly light: "#c9c9c9";
19
+ readonly dark: "#1c1c1c";
20
+ }, {
21
+ readonly light: "#f2f2f2";
22
+ readonly dark: "#383838";
23
+ }];
24
+ /** Alternating user-variation rows (high-contrast striping like puzzle UI). */
25
+ readonly variationStripe: readonly [{
26
+ readonly light: "rgba(216, 216, 216, 1)";
27
+ readonly dark: "rgba(200, 200, 200, 1)";
28
+ }, {
29
+ readonly light: "rgba(255, 255, 255, 1)";
30
+ readonly dark: "rgba(255, 255, 255, 1)";
31
+ }];
32
+ /** Text on variation rows (light backgrounds need dark type). */
33
+ readonly variationText: {
34
+ readonly light: "rgba(0, 0, 0, 0.87)";
35
+ readonly dark: "rgba(0, 0, 0, 0.87)";
36
+ };
37
+ };
@@ -0,0 +1,8 @@
1
+ import { AnalysisHistoryRow } from '../core/AnalysisPosition';
2
+ export type SidebarRowBandCounters = {
3
+ main: number;
4
+ variation: number;
5
+ };
6
+ export declare const createSidebarRowBandCounters: () => SidebarRowBandCounters;
7
+ /** Background for one analysis history row; mutates `bands` while iterating rows in order. */
8
+ export declare const getSidebarRowBackground: (theme: "light" | "dark", row: AnalysisHistoryRow, bands: SidebarRowBandCounters) => string;
@@ -0,0 +1,9 @@
1
+ export * from './analysisModalStyles';
2
+ export * from './analysisSidebarColors';
3
+ export * from './analysisSidebarRowStyle';
4
+ export * from './analysisLayout';
5
+ export * from './AnalysisBoard';
6
+ export * from './AnalysisBoardLayout';
7
+ export * from './DefaultAnalysisContainer';
8
+ export * from './DefaultAnalysisSidebar';
9
+ export * from './EngineEvaluationPanel';
@@ -0,0 +1,5 @@
1
+ export * from './analysisBoardHighlightColors';
2
+ export * from './analysisUtils';
3
+ export * from './types';
4
+ export * from './core';
5
+ export * from './defaults';
@@ -0,0 +1,9 @@
1
+ /** Input for {@link AnalysisPosition} and the analysis board UI. */
2
+ export type AnalysisContext = {
3
+ initialFen: string;
4
+ /** Main line in UCI notation (e.g. full game or puzzle solution). */
5
+ solutionMoves: string[];
6
+ /** Ply index to open at (0 = start position). */
7
+ currentPly: number;
8
+ boardOrientation: 'white' | 'black';
9
+ };
@@ -0,0 +1,7 @@
1
+ export interface HighlightChessboardProps {
2
+ checkSquare: string;
3
+ hintSquare: string | null;
4
+ incorrectMoveSquare: string | null;
5
+ [key: string]: any;
6
+ }
7
+ export declare const HighlightChessboard: ({ checkSquare, hintSquare, incorrectMoveSquare, customSquareStyles: extraSquareStyles, ...props }: HighlightChessboardProps) => import("react").JSX.Element;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Square overlay colors for puzzle boards (check, hint, incorrect).
3
+ */
4
+ export declare const boardSquareHighlightColors: {
5
+ readonly check: "rgba(255, 127, 127, 0.8)";
6
+ readonly hint: "rgba(119, 177, 212, 0.75)";
7
+ /** Muted red — softer than the in-check highlight. */
8
+ readonly incorrect: "rgba(140, 38, 38, 0.82)";
9
+ };
@@ -0,0 +1,27 @@
1
+ import { ReactNode } from 'react';
2
+ interface ChessboardThemeContextType {
3
+ customDarkSquareStyle: {
4
+ backgroundColor: string;
5
+ };
6
+ customLightSquareStyle: {
7
+ backgroundColor: string;
8
+ };
9
+ }
10
+ export declare const ChessboardThemeContext: import("react").Context<ChessboardThemeContextType | undefined>;
11
+ export declare const useChessboardTheme: () => ChessboardThemeContextType;
12
+ /** @deprecated Use {@link useChessboardTheme}. */
13
+ export declare const useTheme: () => ChessboardThemeContextType;
14
+ export declare const getStylesForTheme: (theme: "light" | "dark") => {
15
+ customDarkSquareStyle: {
16
+ backgroundColor: string;
17
+ };
18
+ customLightSquareStyle: {
19
+ backgroundColor: string;
20
+ };
21
+ };
22
+ export type ThemeProviderProps = {
23
+ children?: ReactNode;
24
+ theme: 'light' | 'dark';
25
+ };
26
+ export declare const ThemeProvider: ({ children, theme }: ThemeProviderProps) => import("react").JSX.Element;
27
+ export {};
@@ -0,0 +1,3 @@
1
+ export * from './chessboardTheme';
2
+ export * from './HighlightChessboard';
3
+ export * from './boardSquareHighlightColors';
@@ -0,0 +1,32 @@
1
+ import { EngineEvaluation } from './types';
2
+ export declare const splitWorkerLines: (data: unknown) => string[];
3
+ export { resolveStockfishWorkerUrl, resolveStockfishWasmUrl, resolveStockfishScriptUrl } from './stockfishUrls';
4
+ export declare class StockfishBrowserEngine {
5
+ private readonly scriptUrl;
6
+ private worker;
7
+ private ready;
8
+ private disposed;
9
+ private lifecycleGeneration;
10
+ private evaluation;
11
+ private lineMap;
12
+ private listeners;
13
+ private analysisFen;
14
+ private analysisGeneration;
15
+ private pendingSearch;
16
+ private dispatchedSearchGeneration;
17
+ private searching;
18
+ constructor(scriptUrl: string);
19
+ subscribe(listener: (evaluation: EngineEvaluation) => void): () => void;
20
+ getEvaluation(): EngineEvaluation;
21
+ private assertWasmReachable;
22
+ init(): Promise<void>;
23
+ private handleWorkerFailure;
24
+ private handshake;
25
+ private waitForLine;
26
+ analyze(fen: string, depth: number, multiPv: number): void;
27
+ private dispatchPendingSearch;
28
+ stop(): void;
29
+ dispose(): void;
30
+ private handleLine;
31
+ private setEvaluation;
32
+ }
@@ -0,0 +1,18 @@
1
+ /** Parse a UCI token (e2e4, e7e8q) into a chess.js move object. */
2
+ export declare const parseUciMove: (uci: string) => {
3
+ from: string;
4
+ to: string;
5
+ promotion?: string;
6
+ } | null;
7
+ /** Coerce engine PV data to UCI move tokens (handles array or space-separated string). */
8
+ export declare const normalizePvMoves: (pv: unknown) => string[];
9
+ /** Apply UCI moves from a FEN and return SAN for each legal move in order. */
10
+ export declare const uciPvToSan: (fen: string, pv: unknown) => string[];
11
+ /** Normalize UCI eval (side to move) to White's perspective. */
12
+ export declare const normalizeEvalForWhite: (fen: string, centipawns: number | null, mate: number | null) => {
13
+ centipawns: number | null;
14
+ mate: number | null;
15
+ };
16
+ export declare const formatEvaluation: (centipawns: number | null, mate: number | null) => string;
17
+ /** Principal variation as space-separated SAN (from the given FEN). */
18
+ export declare const formatPvPreview: (fen: string, pv: unknown, maxMoves?: number) => string;
@@ -0,0 +1,7 @@
1
+ export * from './types';
2
+ export * from './stockfishUrls';
3
+ export * from './formatEvaluation';
4
+ export * from './parseUciInfo';
5
+ export * from './StockfishBrowserEngine';
6
+ export * from './isAnalyzableFen';
7
+ export * from './useAnalysisEngine';
@@ -0,0 +1,2 @@
1
+ /** Stockfish can trap on finished positions; skip analysis when the game is over. */
2
+ export declare const isAnalyzableFen: (fen: string) => boolean;
@@ -0,0 +1,2 @@
1
+ import { EngineLine } from './types';
2
+ export declare const parseUciInfoLine: (line: string) => EngineLine | null;
@@ -0,0 +1,8 @@
1
+ /** Resolve a public asset path against the current page (honors CRA `PUBLIC_URL`). */
2
+ export declare const resolveStockfishScriptUrl: (scriptUrl: string, baseHref?: string) => string;
3
+ export declare const resolveStockfishWasmUrl: (scriptUrl: string, baseHref?: string) => string;
4
+ /**
5
+ * Worker URL for stockfish.js (see examples/loadEngine.js in the stockfish package).
6
+ * Stockfish derives the sibling `.wasm` URL from the worker script pathname.
7
+ */
8
+ export declare const resolveStockfishWorkerUrl: (scriptUrl: string, baseHref?: string) => string;
@@ -0,0 +1,27 @@
1
+ export type EngineStatus = 'idle' | 'loading' | 'analyzing' | 'error';
2
+ export type EngineLine = {
3
+ multipv: number;
4
+ depth: number;
5
+ /** Centipawns from side to move (UCI). */
6
+ centipawns: number | null;
7
+ mate: number | null;
8
+ /** Principal variation in UCI notation. */
9
+ pv: string[];
10
+ };
11
+ export type EngineEvaluation = {
12
+ status: EngineStatus;
13
+ depth: number;
14
+ lines: EngineLine[];
15
+ /** FEN this evaluation was computed for (omit when unknown). */
16
+ fen?: string;
17
+ error?: string;
18
+ };
19
+ export declare const emptyEngineEvaluation: () => EngineEvaluation;
20
+ export type AnalysisEngineOptions = {
21
+ enabled?: boolean;
22
+ depth?: number;
23
+ multiPv?: number;
24
+ /** URL to stockfish-18-lite-single.js (host must serve .wasm alongside it). */
25
+ scriptUrl?: string;
26
+ };
27
+ export declare const DEFAULT_STOCKFISH_SCRIPT_URL = "/stockfish/stockfish-18-lite-single.js";
@@ -0,0 +1,2 @@
1
+ import { AnalysisEngineOptions, EngineEvaluation } from './types';
2
+ export declare const useAnalysisEngine: (fen: string, options?: AnalysisEngineOptions) => EngineEvaluation;
@@ -0,0 +1,4 @@
1
+ import type { PlyNavigationRenderProps } from './types';
2
+ /** Library-default ply navigation (inline styles). */
3
+ export declare const DefaultPlyNavigation: ({ plyIndex, totalPly, canPrev, canNext, onGoFirst, onGoPrev, onGoNext, onGoLast, onGoTo, theme, showScrubber, showPlyLabel, }: PlyNavigationRenderProps) => import("react").JSX.Element;
4
+ export declare const defaultRenderPlyNavigation: (props: PlyNavigationRenderProps) => import("react").JSX.Element;
@@ -0,0 +1,6 @@
1
+ import type { PlyNavigationProps } from './types';
2
+ /**
3
+ * Step through a fixed move list. Omit {@link PlyNavigationProps.renderPlyNavigation}
4
+ * for the default inline-styled UI, or pass a custom renderer (e.g. MUI controls).
5
+ */
6
+ export declare const PlyNavigation: ({ plyIndex, totalPly, canPrev, canNext, onGoFirst, onGoPrev, onGoNext, onGoLast, onGoTo, theme, showScrubber, showPlyLabel, renderPlyNavigation, }: PlyNavigationProps) => import("react").ReactNode;
@@ -0,0 +1,4 @@
1
+ export { PlyNavigation } from './PlyNavigation';
2
+ export { DefaultPlyNavigation, defaultRenderPlyNavigation, } from './DefaultPlyNavigation';
3
+ export { navRowStyle, navButtonStyle, scrubberInputStyle, plyLabelStyle, palette as plyNavigationPalette, } from './plyNavigationStyles';
4
+ export type { PlyNavigationModel, PlyNavigationProps, PlyNavigationRenderProps, PlyNavigationTheme, } from './types';
@@ -0,0 +1,12 @@
1
+ import type { CSSProperties } from 'react';
2
+ import type { PlyNavigationTheme } from './types';
3
+ export type PlyNavigationPalette = {
4
+ text: string;
5
+ border: string;
6
+ surface: string;
7
+ };
8
+ export declare const navRowStyle: CSSProperties;
9
+ export declare const scrubberInputStyle: CSSProperties;
10
+ export declare const plyLabelStyle: CSSProperties;
11
+ export declare function palette(theme: PlyNavigationTheme): PlyNavigationPalette;
12
+ export declare function navButtonStyle(colors: PlyNavigationPalette): CSSProperties;