@alepot55/chessboardjs 2.2.1 → 2.3.2

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 (81) hide show
  1. package/.eslintrc.json +227 -0
  2. package/.github/instructions/copilot-instuctions.md +1671 -0
  3. package/README.md +125 -401
  4. package/assets/themes/alepot/theme.json +42 -0
  5. package/assets/themes/default/theme.json +42 -0
  6. package/chessboard.bundle.js +708 -58
  7. package/config/jest.config.js +15 -0
  8. package/config/rollup.config.js +35 -0
  9. package/dist/chessboard.cjs.js +10476 -0
  10. package/dist/chessboard.css +197 -0
  11. package/dist/chessboard.esm.js +10407 -0
  12. package/dist/chessboard.iife.js +10481 -0
  13. package/dist/chessboard.umd.js +10482 -0
  14. package/jest.config.js +2 -7
  15. package/package.json +18 -3
  16. package/rollup.config.js +2 -11
  17. package/{chessboard.move.js → src/components/Move.js} +3 -3
  18. package/src/components/Piece.js +273 -0
  19. package/{chessboard.square.js → src/components/Square.js} +60 -7
  20. package/src/constants/index.js +15 -0
  21. package/src/constants/positions.js +62 -0
  22. package/src/core/Chessboard.js +1930 -0
  23. package/src/core/ChessboardConfig.js +458 -0
  24. package/src/core/ChessboardFactory.js +385 -0
  25. package/src/core/index.js +141 -0
  26. package/src/errors/ChessboardError.js +133 -0
  27. package/src/errors/index.js +15 -0
  28. package/src/errors/messages.js +189 -0
  29. package/src/index.js +103 -0
  30. package/src/services/AnimationService.js +180 -0
  31. package/src/services/BoardService.js +156 -0
  32. package/src/services/CoordinateService.js +355 -0
  33. package/src/services/EventService.js +807 -0
  34. package/src/services/MoveService.js +594 -0
  35. package/src/services/PieceService.js +303 -0
  36. package/src/services/PositionService.js +237 -0
  37. package/src/services/ValidationService.js +673 -0
  38. package/src/services/index.js +14 -0
  39. package/src/styles/animations.css +46 -0
  40. package/{chessboard.css → src/styles/board.css} +3 -0
  41. package/src/styles/index.css +4 -0
  42. package/src/styles/pieces.css +66 -0
  43. package/src/utils/animations.js +37 -0
  44. package/{chess.js → src/utils/chess.js} +16 -16
  45. package/src/utils/coordinates.js +62 -0
  46. package/src/utils/cross-browser.js +150 -0
  47. package/src/utils/logger.js +422 -0
  48. package/src/utils/performance.js +311 -0
  49. package/src/utils/validation.js +458 -0
  50. package/tests/unit/chessboard-config-animations.test.js +106 -0
  51. package/tests/unit/chessboard-robust.test.js +163 -0
  52. package/tests/unit/chessboard.test.js +183 -0
  53. package/chessboard.config.js +0 -147
  54. package/chessboard.js +0 -979
  55. package/chessboard.piece.js +0 -115
  56. package/test/chessboard.test.js +0 -128
  57. /package/{alepot_theme → assets/themes/alepot}/bb.svg +0 -0
  58. /package/{alepot_theme → assets/themes/alepot}/bw.svg +0 -0
  59. /package/{alepot_theme → assets/themes/alepot}/kb.svg +0 -0
  60. /package/{alepot_theme → assets/themes/alepot}/kw.svg +0 -0
  61. /package/{alepot_theme → assets/themes/alepot}/nb.svg +0 -0
  62. /package/{alepot_theme → assets/themes/alepot}/nw.svg +0 -0
  63. /package/{alepot_theme → assets/themes/alepot}/pb.svg +0 -0
  64. /package/{alepot_theme → assets/themes/alepot}/pw.svg +0 -0
  65. /package/{alepot_theme → assets/themes/alepot}/qb.svg +0 -0
  66. /package/{alepot_theme → assets/themes/alepot}/qw.svg +0 -0
  67. /package/{alepot_theme → assets/themes/alepot}/rb.svg +0 -0
  68. /package/{alepot_theme → assets/themes/alepot}/rw.svg +0 -0
  69. /package/{default_pieces → assets/themes/default}/bb.svg +0 -0
  70. /package/{default_pieces → assets/themes/default}/bw.svg +0 -0
  71. /package/{default_pieces → assets/themes/default}/kb.svg +0 -0
  72. /package/{default_pieces → assets/themes/default}/kw.svg +0 -0
  73. /package/{default_pieces → assets/themes/default}/nb.svg +0 -0
  74. /package/{default_pieces → assets/themes/default}/nw.svg +0 -0
  75. /package/{default_pieces → assets/themes/default}/pb.svg +0 -0
  76. /package/{default_pieces → assets/themes/default}/pw.svg +0 -0
  77. /package/{default_pieces → assets/themes/default}/qb.svg +0 -0
  78. /package/{default_pieces → assets/themes/default}/qw.svg +0 -0
  79. /package/{default_pieces → assets/themes/default}/rb.svg +0 -0
  80. /package/{default_pieces → assets/themes/default}/rw.svg +0 -0
  81. /package/{.babelrc → config/.babelrc} +0 -0
@@ -0,0 +1,385 @@
1
+ /**
2
+ * Chessboard factory for creating and managing chessboard instances
3
+ * @module core/ChessboardFactory
4
+ * @since 2.0.0
5
+ */
6
+
7
+ import { Chessboard } from './Chessboard.js';
8
+ import { ChessboardConfig } from './ChessboardConfig.js';
9
+ import { ValidationService } from '../services/ValidationService.js';
10
+ import { ConfigurationError } from '../errors/ChessboardError.js';
11
+ import { logger } from '../utils/logger.js';
12
+ import { PerformanceMonitor } from '../utils/performance.js';
13
+
14
+ /**
15
+ * Factory class for creating and managing chessboard instances
16
+ * Implements the Factory pattern with instance management
17
+ * @class
18
+ */
19
+ export class ChessboardFactory {
20
+ /**
21
+ * Creates a new ChessboardFactory instance
22
+ */
23
+ constructor() {
24
+ this.instances = new Map();
25
+ this.validationService = new ValidationService();
26
+ this.performanceMonitor = new PerformanceMonitor();
27
+ this.logger = logger.child('ChessboardFactory');
28
+
29
+ // Default configuration templates
30
+ this.templates = new Map();
31
+ this._initializeDefaultTemplates();
32
+ }
33
+
34
+ /**
35
+ * Initializes default configuration templates
36
+ * @private
37
+ */
38
+ _initializeDefaultTemplates() {
39
+ // Basic template
40
+ this.templates.set('basic', {
41
+ size: 400,
42
+ draggable: true,
43
+ hints: true,
44
+ clickable: true,
45
+ moveHighlight: true,
46
+ animationStyle: 'simultaneous'
47
+ });
48
+
49
+ // Tournament template
50
+ this.templates.set('tournament', {
51
+ size: 500,
52
+ draggable: false,
53
+ hints: false,
54
+ clickable: true,
55
+ moveHighlight: true,
56
+ onlyLegalMoves: true,
57
+ animationStyle: 'sequential'
58
+ });
59
+
60
+ // Analysis template
61
+ this.templates.set('analysis', {
62
+ size: 600,
63
+ draggable: true,
64
+ hints: true,
65
+ clickable: true,
66
+ moveHighlight: true,
67
+ mode: 'analysis',
68
+ animationStyle: 'simultaneous'
69
+ });
70
+
71
+ // Puzzle template
72
+ this.templates.set('puzzle', {
73
+ size: 450,
74
+ draggable: true,
75
+ hints: true,
76
+ clickable: true,
77
+ moveHighlight: true,
78
+ onlyLegalMoves: true,
79
+ animationStyle: 'sequential'
80
+ });
81
+
82
+ // Demo template
83
+ this.templates.set('demo', {
84
+ size: 'auto',
85
+ draggable: false,
86
+ hints: false,
87
+ clickable: false,
88
+ moveHighlight: true,
89
+ animationStyle: 'simultaneous'
90
+ });
91
+ }
92
+
93
+ /**
94
+ * Creates a new chessboard instance
95
+ * @param {string} containerId - Container element ID
96
+ * @param {Object} [config={}] - Configuration options
97
+ * @param {string} [template] - Template name to use
98
+ * @returns {Chessboard} Chessboard instance
99
+ * @throws {ConfigurationError} If configuration is invalid
100
+ */
101
+ create(containerId, config = {}, template = null) {
102
+ this.performanceMonitor.startMeasure('chessboard-creation');
103
+
104
+ try {
105
+ // Validate container ID
106
+ if (!containerId || typeof containerId !== 'string') {
107
+ throw new ConfigurationError('Container ID must be a non-empty string', 'containerId', containerId);
108
+ }
109
+
110
+ // Check if container exists
111
+ const container = document.getElementById(containerId);
112
+ if (!container) {
113
+ throw new ConfigurationError(`Container element not found: ${containerId}`, 'containerId', containerId);
114
+ }
115
+
116
+ // Merge configuration with template if specified
117
+ let finalConfig = { ...config };
118
+ if (template) {
119
+ const templateConfig = this.templates.get(template);
120
+ if (!templateConfig) {
121
+ this.logger.warn(`Template "${template}" not found, using default configuration`);
122
+ } else {
123
+ finalConfig = { ...templateConfig, ...config };
124
+ this.logger.info(`Using template "${template}" for chessboard creation`);
125
+ }
126
+ }
127
+
128
+ // Set container ID
129
+ finalConfig.id = containerId;
130
+
131
+ // Validate configuration
132
+ this.validationService.validateConfig(finalConfig);
133
+
134
+ // Create chessboard instance
135
+ const chessboard = new Chessboard(finalConfig);
136
+
137
+ // Store instance for management
138
+ this.instances.set(containerId, {
139
+ instance: chessboard,
140
+ config: finalConfig,
141
+ template,
142
+ createdAt: new Date(),
143
+ container
144
+ });
145
+
146
+ this.performanceMonitor.endMeasure('chessboard-creation');
147
+ this.logger.info(`Created chessboard instance for container: ${containerId}`, {
148
+ template,
149
+ configKeys: Object.keys(finalConfig)
150
+ });
151
+
152
+ return chessboard;
153
+ } catch (error) {
154
+ this.performanceMonitor.endMeasure('chessboard-creation');
155
+ this.logger.error('Failed to create chessboard instance', { containerId, error });
156
+ throw error;
157
+ }
158
+ }
159
+
160
+ /**
161
+ * Creates a chessboard using a predefined template
162
+ * @param {string} containerId - Container element ID
163
+ * @param {string} templateName - Template name
164
+ * @param {Object} [overrides={}] - Configuration overrides
165
+ * @returns {Chessboard} Chessboard instance
166
+ */
167
+ createFromTemplate(containerId, templateName, overrides = {}) {
168
+ return this.create(containerId, overrides, templateName);
169
+ }
170
+
171
+ /**
172
+ * Gets an existing chessboard instance
173
+ * @param {string} containerId - Container element ID
174
+ * @returns {Chessboard|null} Chessboard instance or null if not found
175
+ */
176
+ getInstance(containerId) {
177
+ const instance = this.instances.get(containerId);
178
+ return instance ? instance.instance : null;
179
+ }
180
+
181
+ /**
182
+ * Gets information about an instance
183
+ * @param {string} containerId - Container element ID
184
+ * @returns {Object|null} Instance information or null if not found
185
+ */
186
+ getInstanceInfo(containerId) {
187
+ const instance = this.instances.get(containerId);
188
+ if (!instance) {
189
+ return null;
190
+ }
191
+
192
+ return {
193
+ containerId,
194
+ template: instance.template,
195
+ createdAt: instance.createdAt,
196
+ config: { ...instance.config }
197
+ };
198
+ }
199
+
200
+ /**
201
+ * Destroys a chessboard instance
202
+ * @param {string} containerId - Container element ID
203
+ * @returns {boolean} True if instance was destroyed, false if not found
204
+ */
205
+ destroy(containerId) {
206
+ const instance = this.instances.get(containerId);
207
+ if (!instance) {
208
+ this.logger.warn(`Instance not found for destruction: ${containerId}`);
209
+ return false;
210
+ }
211
+
212
+ try {
213
+ // Destroy the chessboard instance
214
+ instance.instance.destroy();
215
+
216
+ // Remove from instances map
217
+ this.instances.delete(containerId);
218
+
219
+ this.logger.info(`Destroyed chessboard instance: ${containerId}`);
220
+ return true;
221
+ } catch (error) {
222
+ this.logger.error(`Failed to destroy chessboard instance: ${containerId}`, { error });
223
+ return false;
224
+ }
225
+ }
226
+
227
+ /**
228
+ * Destroys all chessboard instances
229
+ */
230
+ destroyAll() {
231
+ const containerIds = Array.from(this.instances.keys());
232
+ let destroyed = 0;
233
+
234
+ for (const containerId of containerIds) {
235
+ if (this.destroy(containerId)) {
236
+ destroyed++;
237
+ }
238
+ }
239
+
240
+ this.logger.info(`Destroyed ${destroyed} chessboard instances`);
241
+ }
242
+
243
+ /**
244
+ * Lists all active chessboard instances
245
+ * @returns {Array} Array of instance information
246
+ */
247
+ listInstances() {
248
+ return Array.from(this.instances.keys()).map(containerId =>
249
+ this.getInstanceInfo(containerId)
250
+ );
251
+ }
252
+
253
+ /**
254
+ * Registers a new configuration template
255
+ * @param {string} name - Template name
256
+ * @param {Object} config - Template configuration
257
+ * @throws {ConfigurationError} If template name or config is invalid
258
+ */
259
+ registerTemplate(name, config) {
260
+ if (!name || typeof name !== 'string') {
261
+ throw new ConfigurationError('Template name must be a non-empty string', 'name', name);
262
+ }
263
+
264
+ if (!config || typeof config !== 'object') {
265
+ throw new ConfigurationError('Template configuration must be an object', 'config', config);
266
+ }
267
+
268
+ // Validate template configuration
269
+ this.validationService.validateConfig(config);
270
+
271
+ this.templates.set(name, { ...config });
272
+ this.logger.info(`Registered template: ${name}`, { configKeys: Object.keys(config) });
273
+ }
274
+
275
+ /**
276
+ * Removes a configuration template
277
+ * @param {string} name - Template name
278
+ * @returns {boolean} True if template was removed, false if not found
279
+ */
280
+ removeTemplate(name) {
281
+ const removed = this.templates.delete(name);
282
+ if (removed) {
283
+ this.logger.info(`Removed template: ${name}`);
284
+ }
285
+ return removed;
286
+ }
287
+
288
+ /**
289
+ * Gets a configuration template
290
+ * @param {string} name - Template name
291
+ * @returns {Object|null} Template configuration or null if not found
292
+ */
293
+ getTemplate(name) {
294
+ const template = this.templates.get(name);
295
+ return template ? { ...template } : null;
296
+ }
297
+
298
+ /**
299
+ * Lists all available templates
300
+ * @returns {Array} Array of template names
301
+ */
302
+ listTemplates() {
303
+ return Array.from(this.templates.keys());
304
+ }
305
+
306
+ /**
307
+ * Creates multiple chessboard instances from a configuration array
308
+ * @param {Array} configurations - Array of configuration objects
309
+ * @returns {Array} Array of created chessboard instances
310
+ */
311
+ createMultiple(configurations) {
312
+ const instances = [];
313
+ const errors = [];
314
+
315
+ for (const config of configurations) {
316
+ try {
317
+ const { containerId, template, ...options } = config;
318
+ const instance = this.create(containerId, options, template);
319
+ instances.push({ containerId, instance, success: true });
320
+ } catch (error) {
321
+ errors.push({ containerId: config.containerId, error, success: false });
322
+ this.logger.error(`Failed to create instance for ${config.containerId}`, { error });
323
+ }
324
+ }
325
+
326
+ if (errors.length > 0) {
327
+ this.logger.warn(`Failed to create ${errors.length} out of ${configurations.length} instances`);
328
+ }
329
+
330
+ return { instances, errors };
331
+ }
332
+
333
+ /**
334
+ * Gets factory statistics
335
+ * @returns {Object} Factory statistics
336
+ */
337
+ getStats() {
338
+ const stats = {
339
+ activeInstances: this.instances.size,
340
+ availableTemplates: this.templates.size,
341
+ performance: this.performanceMonitor.getMetrics(),
342
+ validation: this.validationService.getCacheStats()
343
+ };
344
+
345
+ return stats;
346
+ }
347
+
348
+ /**
349
+ * Cleans up factory resources
350
+ */
351
+ destroy() {
352
+ this.destroyAll();
353
+ this.validationService.destroy();
354
+ this.performanceMonitor.destroy();
355
+ this.templates.clear();
356
+ }
357
+ }
358
+
359
+ /**
360
+ * Default factory instance
361
+ * @type {ChessboardFactory}
362
+ */
363
+ export const chessboardFactory = new ChessboardFactory();
364
+
365
+ /**
366
+ * Convenience method to create a chessboard instance
367
+ * @param {string} containerId - Container element ID
368
+ * @param {Object} [config={}] - Configuration options
369
+ * @param {string} [template] - Template name to use
370
+ * @returns {Chessboard} Chessboard instance
371
+ */
372
+ export function createChessboard(containerId, config = {}, template = null) {
373
+ return chessboardFactory.create(containerId, config, template);
374
+ }
375
+
376
+ /**
377
+ * Convenience method to create a chessboard from template
378
+ * @param {string} containerId - Container element ID
379
+ * @param {string} templateName - Template name
380
+ * @param {Object} [overrides={}] - Configuration overrides
381
+ * @returns {Chessboard} Chessboard instance
382
+ */
383
+ export function createChessboardFromTemplate(containerId, templateName, overrides = {}) {
384
+ return chessboardFactory.createFromTemplate(containerId, templateName, overrides);
385
+ }
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Chessboard.js - A beautiful, customizable chessboard widget
3
+ * Entry point for the core library
4
+ * @module core
5
+ * @since 2.0.0
6
+ */
7
+
8
+ import ChessboardClass from './Chessboard.js';
9
+ import ChessboardConfig from './ChessboardConfig.js';
10
+ import {
11
+ ChessboardFactory,
12
+ chessboardFactory,
13
+ createChessboard,
14
+ createChessboardFromTemplate
15
+ } from './ChessboardFactory.js';
16
+ import { logger } from '../utils/logger.js';
17
+
18
+ /**
19
+ * Main Chessboard factory function for backward compatibility
20
+ * Supports both legacy and modern calling conventions
21
+ * @param {string|Object} containerElm - Container element ID or configuration object
22
+ * @param {Object} [config={}] - Configuration options (when first param is string)
23
+ * @returns {ChessboardClass} Chessboard instance
24
+ */
25
+ function Chessboard(containerElm, config = {}) {
26
+ const factoryLogger = logger.child('ChessboardFactory');
27
+
28
+ try {
29
+ // If first parameter is an object, treat it as config
30
+ if (typeof containerElm === 'object' && containerElm !== null) {
31
+ factoryLogger.debug('Creating chessboard with config object');
32
+ return new ChessboardClass(containerElm);
33
+ }
34
+
35
+ // Otherwise, treat first parameter as element ID
36
+ if (typeof containerElm === 'string') {
37
+ factoryLogger.debug('Creating chessboard with element ID', { elementId: containerElm });
38
+ const fullConfig = { ...config, id: containerElm };
39
+ return new ChessboardClass(fullConfig);
40
+ }
41
+
42
+ throw new Error('Invalid parameters: first parameter must be string or object');
43
+ } catch (error) {
44
+ factoryLogger.error('Failed to create chessboard instance', { error });
45
+ throw error;
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Wrapper class that handles both calling conventions
51
+ * Provides enhanced error handling and logging
52
+ * @class
53
+ * @extends ChessboardClass
54
+ */
55
+ class ChessboardWrapper extends ChessboardClass {
56
+ /**
57
+ * Creates a new ChessboardWrapper instance
58
+ * @param {string|Object} containerElm - Container element ID or configuration object
59
+ * @param {Object} [config={}] - Configuration options
60
+ */
61
+ constructor(containerElm, config = {}) {
62
+ const instanceLogger = logger.child('ChessboardWrapper');
63
+
64
+ try {
65
+ // If first parameter is an object, treat it as config
66
+ if (typeof containerElm === 'object' && containerElm !== null) {
67
+ instanceLogger.debug('Initializing with config object');
68
+ super(containerElm);
69
+ } else if (typeof containerElm === 'string') {
70
+ // Otherwise, treat first parameter as element ID
71
+ instanceLogger.debug('Initializing with element ID', { elementId: containerElm });
72
+ const fullConfig = { ...config, id: containerElm };
73
+ super(fullConfig);
74
+ } else {
75
+ throw new Error('Invalid constructor parameters');
76
+ }
77
+ } catch (error) {
78
+ instanceLogger.error('Failed to initialize ChessboardWrapper', { error });
79
+ throw error;
80
+ }
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Refactored Chessboard API - see Chessboard.js for full method docs
86
+ * @typedef {import('./Chessboard.js').Chessboard} Chessboard
87
+ */
88
+
89
+ // --- STATIC/FACTORY METHODS ---
90
+ /**
91
+ * Create a new Chessboard instance
92
+ * @param {string|Object} containerElm
93
+ * @param {Object} [config]
94
+ * @returns {Chessboard}
95
+ */
96
+ Chessboard.create = createChessboard;
97
+ /**
98
+ * Create a Chessboard from a template
99
+ * @param {string|Object} containerElm
100
+ * @param {string} templateName
101
+ * @param {Object} [config]
102
+ * @returns {Chessboard}
103
+ */
104
+ Chessboard.fromTemplate = createChessboardFromTemplate;
105
+ Chessboard.factory = chessboardFactory;
106
+
107
+ // --- INSTANCE MANAGEMENT ---
108
+ Chessboard.getInstance = (containerId) => chessboardFactory.getInstance(containerId);
109
+ Chessboard.destroyInstance = (containerId) => chessboardFactory.destroy(containerId);
110
+ Chessboard.destroyAll = () => chessboardFactory.destroyAll();
111
+ Chessboard.listInstances = () => chessboardFactory.listInstances();
112
+
113
+ // --- TEMPLATE MANAGEMENT ---
114
+ Chessboard.registerTemplate = (name, config) => chessboardFactory.registerTemplate(name, config);
115
+ Chessboard.removeTemplate = (name) => chessboardFactory.removeTemplate(name);
116
+ Chessboard.getTemplate = (name) => chessboardFactory.getTemplate(name);
117
+ Chessboard.listTemplates = () => chessboardFactory.listTemplates();
118
+
119
+ // --- STATS & DEBUG ---
120
+ Chessboard.getStats = () => chessboardFactory.getStats();
121
+
122
+ // --- DEPRECATED/LEGACY ALIASES ---
123
+ /**
124
+ * @deprecated Use Chessboard.create instead
125
+ */
126
+ Chessboard.Class = ChessboardWrapper;
127
+ Chessboard.Chessboard = ChessboardWrapper;
128
+ Chessboard.Config = ChessboardConfig;
129
+ Chessboard.Factory = ChessboardFactory;
130
+
131
+ // --- EXPORTS ---
132
+ export {
133
+ Chessboard,
134
+ ChessboardConfig,
135
+ ChessboardFactory,
136
+ chessboardFactory,
137
+ createChessboard,
138
+ createChessboardFromTemplate
139
+ };
140
+
141
+ export default Chessboard;
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Custom error classes for better error handling
3
+ * @module errors/ChessboardError
4
+ * @since 2.0.0
5
+ */
6
+
7
+ import { ERROR_CODES } from './messages.js';
8
+
9
+ /**
10
+ * Base error class for all chessboard-related errors
11
+ * @class
12
+ * @extends Error
13
+ */
14
+ export class ChessboardError extends Error {
15
+ /**
16
+ * Creates a new ChessboardError instance
17
+ * @param {string} message - Error message
18
+ * @param {string} code - Error code from ERROR_CODES
19
+ * @param {Object} [context={}] - Additional context information
20
+ */
21
+ constructor(message, code, context = {}) {
22
+ super(message);
23
+ this.name = 'ChessboardError';
24
+ this.code = code;
25
+ this.context = context;
26
+ this.timestamp = new Date().toISOString();
27
+
28
+ // Maintain stack trace for debugging
29
+ if (Error.captureStackTrace) {
30
+ Error.captureStackTrace(this, ChessboardError);
31
+ }
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Error thrown when validation fails
37
+ * @class
38
+ * @extends ChessboardError
39
+ */
40
+ export class ValidationError extends ChessboardError {
41
+ /**
42
+ * Creates a new ValidationError instance
43
+ * @param {string} message - Error message
44
+ * @param {string} field - Field that failed validation
45
+ * @param {*} value - Value that failed validation
46
+ */
47
+ constructor(message, field, value) {
48
+ super(message, ERROR_CODES.VALIDATION_ERROR, { field, value });
49
+ this.name = 'ValidationError';
50
+ this.field = field;
51
+ this.value = value;
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Error thrown when configuration is invalid
57
+ * @class
58
+ * @extends ChessboardError
59
+ */
60
+ export class ConfigurationError extends ChessboardError {
61
+ /**
62
+ * Creates a new ConfigurationError instance
63
+ * @param {string} message - Error message
64
+ * @param {string} configKey - Configuration key that is invalid
65
+ * @param {*} configValue - Configuration value that is invalid
66
+ */
67
+ constructor(message, configKey, configValue) {
68
+ super(message, ERROR_CODES.CONFIG_ERROR, { configKey, configValue });
69
+ this.name = 'ConfigurationError';
70
+ this.configKey = configKey;
71
+ this.configValue = configValue;
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Error thrown when a move is invalid or fails
77
+ * @class
78
+ * @extends ChessboardError
79
+ */
80
+ export class MoveError extends ChessboardError {
81
+ /**
82
+ * Creates a new MoveError instance
83
+ * @param {string} message - Error message
84
+ * @param {string} from - Source square
85
+ * @param {string} to - Target square
86
+ * @param {string} [piece] - Piece being moved
87
+ */
88
+ constructor(message, from, to, piece) {
89
+ super(message, ERROR_CODES.MOVE_ERROR, { from, to, piece });
90
+ this.name = 'MoveError';
91
+ this.from = from;
92
+ this.to = to;
93
+ this.piece = piece;
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Error thrown when DOM operations fail
99
+ * @class
100
+ * @extends ChessboardError
101
+ */
102
+ export class DOMError extends ChessboardError {
103
+ /**
104
+ * Creates a new DOMError instance
105
+ * @param {string} message - Error message
106
+ * @param {string} elementId - Element ID that caused the error
107
+ */
108
+ constructor(message, elementId) {
109
+ super(message, ERROR_CODES.DOM_ERROR, { elementId });
110
+ this.name = 'DOMError';
111
+ this.elementId = elementId;
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Error thrown when piece operations fail
117
+ * @class
118
+ * @extends ChessboardError
119
+ */
120
+ export class PieceError extends ChessboardError {
121
+ /**
122
+ * Creates a new PieceError instance
123
+ * @param {string} message - Error message
124
+ * @param {string} pieceId - Piece ID that caused the error
125
+ * @param {string} [square] - Square where the error occurred
126
+ */
127
+ constructor(message, pieceId, square) {
128
+ super(message, ERROR_CODES.PIECE_ERROR, { pieceId, square });
129
+ this.name = 'PieceError';
130
+ this.pieceId = pieceId;
131
+ this.square = square;
132
+ }
133
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Error handling module exports
3
+ * @module errors
4
+ * @since 2.0.0
5
+ */
6
+
7
+ export { ERROR_MESSAGES, ERROR_CODES } from './messages.js';
8
+ export {
9
+ ChessboardError,
10
+ ValidationError,
11
+ ConfigurationError,
12
+ MoveError,
13
+ DOMError,
14
+ PieceError
15
+ } from './ChessboardError.js';