@echecs/pgn
Version:
Parse PGN (Portable Game Notation) chess games into structured JavaScript objects. Zero dependencies, strict TypeScript, no-throw API.
106 lines • 2.9 kB
TypeScript
//#region src/types.d.ts
type File = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h';
type Piece = 'B' | 'K' | 'N' | 'P' | 'Q' | 'R';
type Rank = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8';
type Result = '1-0' | '0-1' | '1/2-1/2' | '?';
type Square = `${File}${Rank}`;
type Disambiguation = Square | File | Rank;
type AnnotationColor = 'B' | 'C' | 'G' | 'O' | 'R' | 'Y';
interface Arrow {
color: AnnotationColor;
from: string;
to: string;
}
interface SquareAnnotation {
color: AnnotationColor;
square: string;
}
type Eval = {
depth?: number;
type: 'cp';
value: number;
} | {
depth?: number;
type: 'mate';
value: number;
};
interface Meta {
Result?: Result;
[key: string]: string | undefined;
}
interface Move {
annotations?: string[];
arrows?: Arrow[];
capture?: boolean;
castling?: boolean;
check?: boolean;
checkmate?: boolean;
clock?: number;
comment?: string;
eval?: Eval;
from?: Disambiguation;
piece: Piece;
promotion?: Piece;
squares?: SquareAnnotation[];
to: Square;
variants?: Variation;
}
type MovePair = [number, Move | undefined, Move?];
type MoveList = MovePair[];
interface PGN {
meta: Meta;
moves: MoveList;
result: 1 | 0 | 0.5 | '?';
}
type Variation = MoveList[];
interface ParseError {
column: number;
line: number;
message: string;
offset: number;
}
interface ParseOptions {
onError?: (error: ParseError) => void;
onWarning?: (warning: ParseWarning) => void;
}
interface ParseWarning {
column: number;
line: number;
message: string;
offset: number;
}
//#endregion
//#region src/parse.d.ts
/**
* Parse a PGN string into an array of games
*
* @param input
*/
declare function parse(input: string, options?: ParseOptions): PGN[];
//#endregion
//#region src/stream.d.ts
interface StringReadableStream {
getReader(): {
read(): Promise<{
done: boolean;
value: string | undefined;
}>;
releaseLock(): void;
};
}
/**
* Stream-parse a PGN AsyncIterable or Web Streams ReadableStream, yielding
* one PGN object per game. Memory usage stays proportional to one game at a time.
*
* @param input - Any AsyncIterable<string> or ReadableStream<string>
* (Node.js readable stream, fetch body piped through TextDecoderStream, etc.)
* @param options - Optional. Pass `onError` to observe parse failures instead of
* silently skipping malformed games. Not called for truncated streams (input
* ending without a result token).
*/
declare function stream(input: AsyncIterable<string> | StringReadableStream, options?: ParseOptions): AsyncGenerator<PGN>;
//#endregion
//#region src/stringify.d.ts
declare function stringify(input: PGN | PGN[], options?: ParseOptions): string;
//#endregion
export { type AnnotationColor, type Arrow, type Eval, type PGN, type ParseError, type ParseOptions, type ParseWarning, type SquareAnnotation, parse as default, stream, stringify };