@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.
- package/.eslintrc.json +227 -0
- package/.github/instructions/copilot-instuctions.md +1671 -0
- package/README.md +125 -401
- package/assets/themes/alepot/theme.json +42 -0
- package/assets/themes/default/theme.json +42 -0
- package/chessboard.bundle.js +708 -58
- package/config/jest.config.js +15 -0
- package/config/rollup.config.js +35 -0
- package/dist/chessboard.cjs.js +10476 -0
- package/dist/chessboard.css +197 -0
- package/dist/chessboard.esm.js +10407 -0
- package/dist/chessboard.iife.js +10481 -0
- package/dist/chessboard.umd.js +10482 -0
- package/jest.config.js +2 -7
- package/package.json +18 -3
- package/rollup.config.js +2 -11
- package/{chessboard.move.js → src/components/Move.js} +3 -3
- package/src/components/Piece.js +273 -0
- package/{chessboard.square.js → src/components/Square.js} +60 -7
- package/src/constants/index.js +15 -0
- package/src/constants/positions.js +62 -0
- package/src/core/Chessboard.js +1930 -0
- package/src/core/ChessboardConfig.js +458 -0
- package/src/core/ChessboardFactory.js +385 -0
- package/src/core/index.js +141 -0
- package/src/errors/ChessboardError.js +133 -0
- package/src/errors/index.js +15 -0
- package/src/errors/messages.js +189 -0
- package/src/index.js +103 -0
- package/src/services/AnimationService.js +180 -0
- package/src/services/BoardService.js +156 -0
- package/src/services/CoordinateService.js +355 -0
- package/src/services/EventService.js +807 -0
- package/src/services/MoveService.js +594 -0
- package/src/services/PieceService.js +303 -0
- package/src/services/PositionService.js +237 -0
- package/src/services/ValidationService.js +673 -0
- package/src/services/index.js +14 -0
- package/src/styles/animations.css +46 -0
- package/{chessboard.css → src/styles/board.css} +3 -0
- package/src/styles/index.css +4 -0
- package/src/styles/pieces.css +66 -0
- package/src/utils/animations.js +37 -0
- package/{chess.js → src/utils/chess.js} +16 -16
- package/src/utils/coordinates.js +62 -0
- package/src/utils/cross-browser.js +150 -0
- package/src/utils/logger.js +422 -0
- package/src/utils/performance.js +311 -0
- package/src/utils/validation.js +458 -0
- package/tests/unit/chessboard-config-animations.test.js +106 -0
- package/tests/unit/chessboard-robust.test.js +163 -0
- package/tests/unit/chessboard.test.js +183 -0
- package/chessboard.config.js +0 -147
- package/chessboard.js +0 -979
- package/chessboard.piece.js +0 -115
- package/test/chessboard.test.js +0 -128
- /package/{alepot_theme → assets/themes/alepot}/bb.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/bw.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/kb.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/kw.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/nb.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/nw.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/pb.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/pw.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/qb.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/qw.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/rb.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/rw.svg +0 -0
- /package/{default_pieces → assets/themes/default}/bb.svg +0 -0
- /package/{default_pieces → assets/themes/default}/bw.svg +0 -0
- /package/{default_pieces → assets/themes/default}/kb.svg +0 -0
- /package/{default_pieces → assets/themes/default}/kw.svg +0 -0
- /package/{default_pieces → assets/themes/default}/nb.svg +0 -0
- /package/{default_pieces → assets/themes/default}/nw.svg +0 -0
- /package/{default_pieces → assets/themes/default}/pb.svg +0 -0
- /package/{default_pieces → assets/themes/default}/pw.svg +0 -0
- /package/{default_pieces → assets/themes/default}/qb.svg +0 -0
- /package/{default_pieces → assets/themes/default}/qw.svg +0 -0
- /package/{default_pieces → assets/themes/default}/rb.svg +0 -0
- /package/{default_pieces → assets/themes/default}/rw.svg +0 -0
- /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';
|