@mirasen/chessboard 1.0.0-rc.0 → 1.0.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.
- package/CHANGELOG.md +14 -0
- package/README.md +45 -27
- package/dist/extensions/build/index.d.ts +21 -0
- package/dist/extensions/build/index.js +9 -0
- package/dist/extensions/first-party/active-target/factory.js +4 -4
- package/dist/extensions/first-party/active-target/types.d.ts +2 -2
- package/dist/extensions/first-party/active-target/types.js +4 -1
- package/dist/extensions/first-party/auto-promote/types.d.ts +0 -2
- package/dist/extensions/first-party/board-events/types.d.ts +0 -2
- package/dist/extensions/first-party/common/helpers.d.ts +7 -7
- package/dist/extensions/first-party/common/helpers.js +11 -11
- package/dist/extensions/first-party/common/types.d.ts +2 -3
- package/dist/extensions/first-party/last-move/factory.js +4 -4
- package/dist/extensions/first-party/last-move/types.d.ts +2 -2
- package/dist/extensions/first-party/legal-moves/factory.js +4 -4
- package/dist/extensions/first-party/legal-moves/types.d.ts +2 -2
- package/dist/extensions/first-party/main-renderer/factory.js +4 -4
- package/dist/extensions/first-party/main-renderer/types/instance.d.ts +2 -2
- package/dist/extensions/first-party/promotion/factory.js +4 -4
- package/dist/extensions/first-party/promotion/types/main.d.ts +2 -2
- package/dist/extensions/first-party/selected-square/factory.js +4 -4
- package/dist/extensions/first-party/selected-square/types.d.ts +2 -2
- package/dist/extensions/index.d.ts +1 -8
- package/dist/extensions/index.js +1 -6
- package/dist/index.d.ts +1 -2
- package/package.json +9 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @mirasen/chessboard
|
|
2
2
|
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 2609920: First v1.0.0 release with the new extension-driven architecture, built-in chess interaction baseline, promotion flow, and auto-promote support.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 31364b7: dependabot: directory '/', update @sveltejs/kit
|
|
12
|
+
- 31364b7: dependabot: directory '/', update @vitest/browser-playwright
|
|
13
|
+
- 31364b7: dependabot: directory '/', update eslint-plugin-svelte
|
|
14
|
+
- 31364b7: dependabot: directory '/', update svelte
|
|
15
|
+
- 2609920: Added promotion and auto-promotion to queen extensions
|
|
16
|
+
|
|
3
17
|
## 1.0.0-rc.0
|
|
4
18
|
|
|
5
19
|
### Major Changes
|
package/README.md
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
[](https://www.npmjs.com/package/@mirasen/chessboard)
|
|
2
2
|
[](https://github.com/mirasen-io/chessboard/actions/workflows/ci.yml)
|
|
3
|
-
[](https://sonarcloud.io/summary/new_code?id=mirasen-io_chessboard)
|
|
4
|
-
[](https://sonarcloud.io/summary/new_code?id=mirasen-io_chessboard)
|
|
5
3
|
[](./LICENSE)
|
|
6
4
|
|
|
7
5
|
# @mirasen/chessboard
|
|
@@ -77,10 +75,21 @@ board.setMovability({
|
|
|
77
75
|
});
|
|
78
76
|
```
|
|
79
77
|
|
|
80
|
-
### Explicit
|
|
78
|
+
### Explicit extensions
|
|
81
79
|
|
|
82
80
|
```ts
|
|
83
|
-
import { createBoard } from '@mirasen/chessboard';
|
|
81
|
+
import { createBoard, type Chessboard, type ChessboardExtensionInput } from '@mirasen/chessboard';
|
|
82
|
+
|
|
83
|
+
const extensionList = [
|
|
84
|
+
// Always add renderer first, otherwise nothing will be rendered
|
|
85
|
+
'renderer',
|
|
86
|
+
'lastMove',
|
|
87
|
+
// Keep autoPromote before promotion, otherwise promotion may defer the move first
|
|
88
|
+
'autoPromote',
|
|
89
|
+
'promotion'
|
|
90
|
+
// customExtensionDefinition
|
|
91
|
+
] as const satisfies readonly ChessboardExtensionInput[];
|
|
92
|
+
let board: Chessboard<typeof extensionList> | null = null;
|
|
84
93
|
|
|
85
94
|
const element = document.getElementById('board');
|
|
86
95
|
|
|
@@ -88,20 +97,9 @@ if (!element) {
|
|
|
88
97
|
throw new Error('Missing board element');
|
|
89
98
|
}
|
|
90
99
|
|
|
91
|
-
|
|
100
|
+
board = createBoard({
|
|
92
101
|
element,
|
|
93
|
-
extensions:
|
|
94
|
-
// Always add renderer first, otherwise nothing will be rendered
|
|
95
|
-
'renderer',
|
|
96
|
-
'selectedSquare',
|
|
97
|
-
'activeTarget',
|
|
98
|
-
'legalMoves',
|
|
99
|
-
'lastMove',
|
|
100
|
-
'events',
|
|
101
|
-
// Keep autoPromote before promotion, otherwise promotion may defer the move first
|
|
102
|
-
'autoPromote',
|
|
103
|
-
'promotion'
|
|
104
|
-
]
|
|
102
|
+
extensions: extensionList
|
|
105
103
|
});
|
|
106
104
|
```
|
|
107
105
|
|
|
@@ -226,6 +224,22 @@ These are separate extensions on purpose:
|
|
|
226
224
|
|
|
227
225
|
This separation is a good example of the architecture: common chess UX can be built in without collapsing everything into one hardcoded board layer.
|
|
228
226
|
|
|
227
|
+
```ts
|
|
228
|
+
import { createBoard } from '@mirasen/chessboard';
|
|
229
|
+
|
|
230
|
+
const element = document.getElementById('board');
|
|
231
|
+
|
|
232
|
+
if (!element) {
|
|
233
|
+
throw new Error('Missing board element');
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const board = createBoard({
|
|
237
|
+
element
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
board.extensions.autoPromote.toQueen = true;
|
|
241
|
+
```
|
|
242
|
+
|
|
229
243
|
## Architecture
|
|
230
244
|
|
|
231
245
|
`@mirasen/chessboard` is built around explicit boundaries:
|
|
@@ -255,19 +269,23 @@ A board that handles everything internally without clean boundaries becomes diff
|
|
|
255
269
|
- clean internal architecture
|
|
256
270
|
- extension-driven feature growth
|
|
257
271
|
|
|
258
|
-
##
|
|
272
|
+
## Project direction
|
|
259
273
|
|
|
260
|
-
|
|
274
|
+
This platform is being built as a foundation for richer chess learning and interaction workflows, but the board itself is designed to stand as a serious open-source UI platform in its own right.
|
|
261
275
|
|
|
262
|
-
##
|
|
276
|
+
## Artwork
|
|
263
277
|
|
|
264
|
-
|
|
278
|
+
### Chessnut piece set
|
|
265
279
|
|
|
266
|
-
|
|
267
|
-
- documentation expansion
|
|
268
|
-
- more examples
|
|
269
|
-
- further polish toward final `1.0.0`
|
|
280
|
+
This project uses the Chessnut chess piece set.
|
|
270
281
|
|
|
271
|
-
|
|
282
|
+
This is the current default piece set used by the library.
|
|
272
283
|
|
|
273
|
-
|
|
284
|
+
- Author: Alexis Luengas — https://github.com/LexLuengas
|
|
285
|
+
- Source: https://github.com/LexLuengas/chessnut-pieces
|
|
286
|
+
- License: Apache License 2.0 — https://github.com/LexLuengas/chessnut-pieces/blob/master/LICENSE.txt
|
|
287
|
+
|
|
288
|
+
For details, see:
|
|
289
|
+
|
|
290
|
+
- [./assets/pieces/chessnut/ATTRIBUTION.md](./assets/pieces/chessnut/ATTRIBUTION.md)
|
|
291
|
+
- [./assets/pieces/chessnut/LICENSE.txt](./assets/pieces/chessnut/LICENSE.txt)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export { clearElementChildren, createSvgElement, updateElementAttributes } from '../../render/svg/helpers.js';
|
|
2
|
+
export type { RuntimeReadonlyMutationSession } from '../../runtime/mutation/types.js';
|
|
3
|
+
export { isNonEmptyPieceCode } from '../../state/board/check.js';
|
|
4
|
+
export { fileOf, rankOf, squareOf } from '../../state/board/coords.js';
|
|
5
|
+
export { denormalizeMove } from '../../state/board/denormalize.js';
|
|
6
|
+
export { normalizePiece } from '../../state/board/normalize.js';
|
|
7
|
+
export { fromPieceCode, toPieceCode } from '../../state/board/piece.js';
|
|
8
|
+
export type { ColorCode, EmptyPieceCode, NonEmptyPieceCode, PieceCode, RoleCode, RolePromotionCode, Square, SquareFile, SquareRank } from '../../state/board/types/internal.js';
|
|
9
|
+
export type { MoveOutput } from '../../state/board/types/output.js';
|
|
10
|
+
export type { MovabilityModeCode } from '../../state/interaction/types/internal.js';
|
|
11
|
+
export { extensionCreateInternalBase, extensionDestroyBase, extensionIsDestroyedBase, extensionIsMountedBase, extensionMountBase, extensionUnmountBase } from '../first-party/common/helpers.js';
|
|
12
|
+
export type { ExtensionInternalBase, OpaqueColor } from '../first-party/common/types.js';
|
|
13
|
+
export type { PieceUrlsInput } from '../first-party/main-renderer/types/input.js';
|
|
14
|
+
export type { PieceUrls } from '../first-party/main-renderer/types/internal.js';
|
|
15
|
+
export type { PromotionPieceCode } from '../first-party/promotion/types/internal.js';
|
|
16
|
+
export type { ExtensionSlotName, ExtensionSlotSvgRoots } from '../types/basic/mount.js';
|
|
17
|
+
export { isFrameMounted, isFrameRenderable } from '../types/basic/update.js';
|
|
18
|
+
export type { UpdateFrameSnapshot } from '../types/basic/update.js';
|
|
19
|
+
export { isUpdateContextMounted, isUpdateContextRenderable } from '../types/context/update.js';
|
|
20
|
+
export type { ExtensionCreateInstanceOptions, ExtensionDefinition, ExtensionInstance } from '../types/extension.js';
|
|
21
|
+
export type { ExtensionRuntimeSurface } from '../types/surface/main.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { clearElementChildren, createSvgElement, updateElementAttributes } from '../../render/svg/helpers.js';
|
|
2
|
+
export { isNonEmptyPieceCode } from '../../state/board/check.js';
|
|
3
|
+
export { fileOf, rankOf, squareOf } from '../../state/board/coords.js';
|
|
4
|
+
export { denormalizeMove } from '../../state/board/denormalize.js';
|
|
5
|
+
export { normalizePiece } from '../../state/board/normalize.js';
|
|
6
|
+
export { fromPieceCode, toPieceCode } from '../../state/board/piece.js';
|
|
7
|
+
export { extensionCreateInternalBase, extensionDestroyBase, extensionIsDestroyedBase, extensionIsMountedBase, extensionMountBase, extensionUnmountBase } from '../first-party/common/helpers.js';
|
|
8
|
+
export { isFrameMounted, isFrameRenderable } from '../types/basic/update.js';
|
|
9
|
+
export { isUpdateContextMounted, isUpdateContextRenderable } from '../types/context/update.js';
|
|
@@ -2,7 +2,7 @@ import assert from '@ktarmyshov/assert';
|
|
|
2
2
|
import { toMerged } from 'es-toolkit';
|
|
3
3
|
import { createSvgElement, updateElementAttributes } from '../../../render/svg/helpers.js';
|
|
4
4
|
import { isUpdateContextRenderable } from '../../types/context/update.js';
|
|
5
|
-
import { extensionCreateInternalBase,
|
|
5
|
+
import { extensionCreateInternalBase, extensionDestroyBase, extensionMountBase, extensionUnmountBase } from '../common/helpers.js';
|
|
6
6
|
import { DEFAULT_CONFIG, EXTENSION_ID, EXTENSION_SLOTS } from './types.js';
|
|
7
7
|
export function createActiveTarget(config = {}) {
|
|
8
8
|
const mergedConfig = toMerged(DEFAULT_CONFIG, config);
|
|
@@ -31,7 +31,7 @@ function createActiveTargetInstance(config) {
|
|
|
31
31
|
return {
|
|
32
32
|
id: EXTENSION_ID,
|
|
33
33
|
mount(env) {
|
|
34
|
-
|
|
34
|
+
extensionMountBase(internalState, env.slotRoots);
|
|
35
35
|
},
|
|
36
36
|
onUpdate(context) {
|
|
37
37
|
const needsRender = context.mutation.hasMutation({
|
|
@@ -98,11 +98,11 @@ function createActiveTargetInstance(config) {
|
|
|
98
98
|
}
|
|
99
99
|
},
|
|
100
100
|
unmount() {
|
|
101
|
-
|
|
101
|
+
extensionUnmountBase(internalState);
|
|
102
102
|
extensionClean(internalState);
|
|
103
103
|
},
|
|
104
104
|
destroy() {
|
|
105
|
-
|
|
105
|
+
extensionDestroyBase(internalState);
|
|
106
106
|
extensionClean(internalState);
|
|
107
107
|
}
|
|
108
108
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PartialDeep } from 'type-fest';
|
|
2
2
|
import { ExtensionDefinition, ExtensionInstance } from '../../types/extension.js';
|
|
3
|
-
import {
|
|
3
|
+
import { ExtensionInternalBase, OpaqueColor } from '../common/types.js';
|
|
4
4
|
export declare const EXTENSION_SLOTS: readonly ["underPieces", "overPieces"];
|
|
5
5
|
export type ExtensionSlotsType = typeof EXTENSION_SLOTS;
|
|
6
6
|
export declare const EXTENSION_ID: "activeTarget";
|
|
@@ -15,7 +15,7 @@ export declare const DEFAULT_CONFIG: ActiveTargetConfig;
|
|
|
15
15
|
export type ActiveTargetInitConfig = PartialDeep<ActiveTargetConfig>;
|
|
16
16
|
export type ActiveTargetDefinition = ExtensionDefinition<typeof EXTENSION_ID, typeof EXTENSION_SLOTS, never>;
|
|
17
17
|
export type ActiveTargetInstance = ExtensionInstance<typeof EXTENSION_ID, typeof EXTENSION_SLOTS, never>;
|
|
18
|
-
export interface ActiveTargetInstanceInternal extends
|
|
18
|
+
export interface ActiveTargetInstanceInternal extends ExtensionInternalBase<ExtensionSlotsType> {
|
|
19
19
|
svgRect: SVGRectElement | null;
|
|
20
20
|
svgCircle: SVGCircleElement | null;
|
|
21
21
|
readonly config: ActiveTargetConfig;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ExtensionSlotSvgRoots } from '../../types/basic/mount.js';
|
|
2
1
|
import { ExtensionDefinition, ExtensionInstance } from '../../types/extension.js';
|
|
3
2
|
export declare const EXTENSION_SLOTS: readonly [];
|
|
4
3
|
export type ExtensionSlotsType = typeof EXTENSION_SLOTS;
|
|
@@ -8,7 +7,6 @@ export interface AutoPromotePublic {
|
|
|
8
7
|
toQueen: boolean;
|
|
9
8
|
}
|
|
10
9
|
export type AutoPromoteInstance = ExtensionInstance<typeof EXTENSION_ID, typeof EXTENSION_SLOTS, AutoPromotePublic>;
|
|
11
|
-
export type AutoPromoteSlotRoots = ExtensionSlotSvgRoots<typeof EXTENSION_SLOTS>;
|
|
12
10
|
export interface AutoPromoteInstanceInternal {
|
|
13
11
|
toQueen: boolean;
|
|
14
12
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { RuntimeReadonlyMutationSession } from '../../../runtime/mutation/types.js';
|
|
2
2
|
import { MoveOutput } from '../../../state/board/types/output.js';
|
|
3
|
-
import { ExtensionSlotSvgRoots } from '../../types/basic/mount.js';
|
|
4
3
|
import { UpdateFrameSnapshot } from '../../types/basic/update.js';
|
|
5
4
|
import { ExtensionDefinition, ExtensionInstance } from '../../types/extension.js';
|
|
6
5
|
export declare const EXTENSION_SLOTS: readonly [];
|
|
@@ -19,7 +18,6 @@ export interface BoardEventsPublic {
|
|
|
19
18
|
setOnRawUpdate(callback: OnRawUpdateCallback | null): void;
|
|
20
19
|
}
|
|
21
20
|
export type BoardEventsInstance = ExtensionInstance<typeof EXTENSION_ID, typeof EXTENSION_SLOTS, BoardEventsPublic>;
|
|
22
|
-
export type BoardEventsSlotRoots = ExtensionSlotSvgRoots<typeof EXTENSION_SLOTS>;
|
|
23
21
|
export interface BoardEventsInstanceInternal {
|
|
24
22
|
onUIMove: OnUIMoveCallback | null;
|
|
25
23
|
onRawUpdate: OnRawUpdateCallback | null;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ExtensionSlotName } from '../../types/basic/mount.js';
|
|
2
|
-
import {
|
|
3
|
-
export declare function extensionCreateInternalBase<TSlots extends readonly ExtensionSlotName[]>():
|
|
4
|
-
export declare function
|
|
5
|
-
export declare function
|
|
6
|
-
export declare function
|
|
7
|
-
export declare function
|
|
8
|
-
export declare function
|
|
2
|
+
import { ExtensionInternalBase } from './types.js';
|
|
3
|
+
export declare function extensionCreateInternalBase<TSlots extends readonly ExtensionSlotName[]>(): ExtensionInternalBase<TSlots>;
|
|
4
|
+
export declare function extensionIsMountedBase<TSlots extends readonly ExtensionSlotName[]>(state: ExtensionInternalBase<TSlots>): boolean;
|
|
5
|
+
export declare function extensionIsDestroyedBase<TSlots extends readonly ExtensionSlotName[]>(state: ExtensionInternalBase<TSlots>): boolean;
|
|
6
|
+
export declare function extensionMountBase<TSlots extends readonly ExtensionSlotName[]>(state: ExtensionInternalBase<TSlots>, slotRoots: NonNullable<ExtensionInternalBase<TSlots>['slotRoots']>): void;
|
|
7
|
+
export declare function extensionUnmountBase<TSlots extends readonly ExtensionSlotName[]>(state: ExtensionInternalBase<TSlots>): void;
|
|
8
|
+
export declare function extensionDestroyBase<TSlots extends readonly ExtensionSlotName[]>(state: ExtensionInternalBase<TSlots>): void;
|
|
@@ -6,28 +6,28 @@ export function extensionCreateInternalBase() {
|
|
|
6
6
|
destroyed: false
|
|
7
7
|
};
|
|
8
8
|
}
|
|
9
|
-
export function
|
|
9
|
+
export function extensionIsMountedBase(state) {
|
|
10
10
|
return state.slotRoots !== null;
|
|
11
11
|
}
|
|
12
|
-
export function
|
|
12
|
+
export function extensionIsDestroyedBase(state) {
|
|
13
13
|
return state.destroyed;
|
|
14
14
|
}
|
|
15
|
-
export function
|
|
16
|
-
assert(!
|
|
17
|
-
assert(!
|
|
15
|
+
export function extensionMountBase(state, slotRoots) {
|
|
16
|
+
assert(!extensionIsMountedBase(state), 'Extension is already mounted');
|
|
17
|
+
assert(!extensionIsDestroyedBase(state), 'Extension is destroyed');
|
|
18
18
|
state.slotRoots = slotRoots;
|
|
19
19
|
}
|
|
20
|
-
export function
|
|
21
|
-
assert(
|
|
20
|
+
export function extensionUnmountBase(state) {
|
|
21
|
+
assert(extensionIsMountedBase(state), 'Extension is not mounted');
|
|
22
22
|
for (const slotRoot of Object.values(state.slotRoots ?? {})) {
|
|
23
23
|
clearElementChildren(slotRoot);
|
|
24
24
|
}
|
|
25
25
|
state.slotRoots = null;
|
|
26
26
|
}
|
|
27
|
-
export function
|
|
28
|
-
assert(!
|
|
29
|
-
if (
|
|
30
|
-
|
|
27
|
+
export function extensionDestroyBase(state) {
|
|
28
|
+
assert(!extensionIsDestroyedBase(state), 'Extension is already destroyed');
|
|
29
|
+
if (extensionIsMountedBase(state)) {
|
|
30
|
+
extensionUnmountBase(state);
|
|
31
31
|
}
|
|
32
32
|
state.destroyed = true;
|
|
33
33
|
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { ExtensionSlotName, ExtensionSlotSvgRoots } from '../../types/basic/mount.js';
|
|
2
|
-
export interface
|
|
2
|
+
export interface ExtensionInternalBase<TSlots extends readonly ExtensionSlotName[]> {
|
|
3
3
|
slotRoots: ExtensionSlotSvgRoots<TSlots> | null;
|
|
4
4
|
destroyed: boolean;
|
|
5
5
|
}
|
|
6
|
-
export type AnyExtensionInternal = ExtensionInternal<readonly ExtensionSlotName[]>;
|
|
7
6
|
export interface OpaqueColor {
|
|
8
7
|
color: string;
|
|
9
|
-
opacity: number;
|
|
8
|
+
opacity: number | string;
|
|
10
9
|
}
|
|
@@ -2,7 +2,7 @@ import assert from '@ktarmyshov/assert';
|
|
|
2
2
|
import { toMerged } from 'es-toolkit';
|
|
3
3
|
import { createSvgElement, updateElementAttributes } from '../../../render/svg/helpers.js';
|
|
4
4
|
import { isUpdateContextRenderable } from '../../types/context/update.js';
|
|
5
|
-
import { extensionCreateInternalBase,
|
|
5
|
+
import { extensionCreateInternalBase, extensionDestroyBase, extensionMountBase, extensionUnmountBase } from '../common/helpers.js';
|
|
6
6
|
import { DEFAULT_CONFIG, EXTENSION_ID, EXTENSION_SLOTS } from './types.js';
|
|
7
7
|
export function createLastMove(config = {}) {
|
|
8
8
|
const mergedConfig = toMerged(DEFAULT_CONFIG, config);
|
|
@@ -31,7 +31,7 @@ function createLastMoveInstance(config) {
|
|
|
31
31
|
return {
|
|
32
32
|
id: EXTENSION_ID,
|
|
33
33
|
mount(env) {
|
|
34
|
-
|
|
34
|
+
extensionMountBase(internalState, env.slotRoots);
|
|
35
35
|
},
|
|
36
36
|
onUpdate(context) {
|
|
37
37
|
const needsRender = context.mutation.hasMutation({
|
|
@@ -95,11 +95,11 @@ function createLastMoveInstance(config) {
|
|
|
95
95
|
}
|
|
96
96
|
},
|
|
97
97
|
unmount() {
|
|
98
|
-
|
|
98
|
+
extensionUnmountBase(internalState);
|
|
99
99
|
extensionClean(internalState);
|
|
100
100
|
},
|
|
101
101
|
destroy() {
|
|
102
|
-
|
|
102
|
+
extensionDestroyBase(internalState);
|
|
103
103
|
extensionClean(internalState);
|
|
104
104
|
}
|
|
105
105
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PartialDeep } from 'type-fest';
|
|
2
2
|
import { ExtensionDefinition, ExtensionInstance } from '../../types/extension.js';
|
|
3
|
-
import {
|
|
3
|
+
import { ExtensionInternalBase, OpaqueColor } from '../common/types.js';
|
|
4
4
|
export declare const EXTENSION_SLOTS: readonly ["underPieces"];
|
|
5
5
|
export type ExtensionSlotsType = typeof EXTENSION_SLOTS;
|
|
6
6
|
export declare const EXTENSION_ID: "lastMove";
|
|
@@ -9,7 +9,7 @@ export declare const DEFAULT_CONFIG: LastMoveConfig;
|
|
|
9
9
|
export type LastMoveInitConfig = PartialDeep<LastMoveConfig>;
|
|
10
10
|
export type LastMoveDefinition = ExtensionDefinition<typeof EXTENSION_ID, typeof EXTENSION_SLOTS, never>;
|
|
11
11
|
export type LastMoveInstance = ExtensionInstance<typeof EXTENSION_ID, typeof EXTENSION_SLOTS, never>;
|
|
12
|
-
export interface LastMoveInstanceInternal extends
|
|
12
|
+
export interface LastMoveInstanceInternal extends ExtensionInternalBase<ExtensionSlotsType> {
|
|
13
13
|
svgRectFrom: SVGRectElement | null;
|
|
14
14
|
svgRectTo: SVGRectElement | null;
|
|
15
15
|
readonly config: LastMoveConfig;
|
|
@@ -4,7 +4,7 @@ import { clearElementChildren, createSvgElement } from '../../../render/svg/help
|
|
|
4
4
|
import { isNonEmptyPieceCode } from '../../../state/board/check.js';
|
|
5
5
|
import { fromPieceCode } from '../../../state/board/piece.js';
|
|
6
6
|
import { isUpdateContextRenderable } from '../../types/context/update.js';
|
|
7
|
-
import { extensionCreateInternalBase,
|
|
7
|
+
import { extensionCreateInternalBase, extensionDestroyBase, extensionMountBase, extensionUnmountBase } from '../common/helpers.js';
|
|
8
8
|
import { DEFAULT_CONFIG, EXTENSION_ID, EXTENSION_SLOTS } from './types.js';
|
|
9
9
|
export function createLegalMoves(config = {}) {
|
|
10
10
|
const mergedConfig = toMerged(DEFAULT_CONFIG, config);
|
|
@@ -31,7 +31,7 @@ function createLegalMovesInstance(config) {
|
|
|
31
31
|
return {
|
|
32
32
|
id: EXTENSION_ID,
|
|
33
33
|
mount(env) {
|
|
34
|
-
|
|
34
|
+
extensionMountBase(internalState, env.slotRoots);
|
|
35
35
|
},
|
|
36
36
|
onUpdate(context) {
|
|
37
37
|
const needsRender = context.mutation.hasMutation({
|
|
@@ -90,11 +90,11 @@ function createLegalMovesInstance(config) {
|
|
|
90
90
|
}
|
|
91
91
|
},
|
|
92
92
|
unmount() {
|
|
93
|
-
|
|
93
|
+
extensionUnmountBase(internalState);
|
|
94
94
|
extensionClean(internalState);
|
|
95
95
|
},
|
|
96
96
|
destroy() {
|
|
97
|
-
|
|
97
|
+
extensionDestroyBase(internalState);
|
|
98
98
|
extensionClean(internalState);
|
|
99
99
|
}
|
|
100
100
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PartialDeep } from 'type-fest';
|
|
2
2
|
import { ExtensionDefinition, ExtensionInstance } from '../../types/extension.js';
|
|
3
|
-
import {
|
|
3
|
+
import { ExtensionInternalBase, OpaqueColor } from '../common/types.js';
|
|
4
4
|
export declare const EXTENSION_SLOTS: readonly ["overPieces"];
|
|
5
5
|
export type ExtensionSlotsType = typeof EXTENSION_SLOTS;
|
|
6
6
|
export declare const EXTENSION_ID: "legalMoves";
|
|
@@ -19,7 +19,7 @@ export declare const DEFAULT_CONFIG: LegalMovesConfig;
|
|
|
19
19
|
export type LegalMovesInitConfig = PartialDeep<LegalMovesConfig>;
|
|
20
20
|
export type LegalMovesDefinition = ExtensionDefinition<typeof EXTENSION_ID, typeof EXTENSION_SLOTS, never>;
|
|
21
21
|
export type LegalMovesInstance = ExtensionInstance<typeof EXTENSION_ID, typeof EXTENSION_SLOTS, never>;
|
|
22
|
-
export interface LegalMovesInstanceInternal extends
|
|
22
|
+
export interface LegalMovesInstanceInternal extends ExtensionInternalBase<ExtensionSlotsType> {
|
|
23
23
|
destroyed: boolean;
|
|
24
24
|
svgCircles: SVGCircleElement[];
|
|
25
25
|
readonly config: LegalMovesConfig;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toMerged } from 'es-toolkit';
|
|
2
|
-
import { extensionCreateInternalBase,
|
|
2
|
+
import { extensionCreateInternalBase, extensionDestroyBase, extensionMountBase, extensionUnmountBase } from '../common/helpers.js';
|
|
3
3
|
import { createMainRendererAnimation } from './animation/factory.js';
|
|
4
4
|
import { createMainRendererBoard } from './board/factory.js';
|
|
5
5
|
import { createMainRendererCoordinates } from './coordinates/factory.js';
|
|
@@ -51,7 +51,7 @@ function createMainRendererInstance(options, config) {
|
|
|
51
51
|
return {
|
|
52
52
|
id: EXTENSION_ID,
|
|
53
53
|
mount(env) {
|
|
54
|
-
|
|
54
|
+
extensionMountBase(internalState, env.slotRoots);
|
|
55
55
|
},
|
|
56
56
|
onUpdate(context) {
|
|
57
57
|
internalState.board.onUpdate(context);
|
|
@@ -85,11 +85,11 @@ function createMainRendererInstance(options, config) {
|
|
|
85
85
|
},
|
|
86
86
|
unmount() {
|
|
87
87
|
extensionUnmountLocal(internalState);
|
|
88
|
-
|
|
88
|
+
extensionUnmountBase(internalState);
|
|
89
89
|
},
|
|
90
90
|
destroy() {
|
|
91
91
|
extensionUnmountLocal(internalState);
|
|
92
|
-
|
|
92
|
+
extensionDestroyBase(internalState);
|
|
93
93
|
}
|
|
94
94
|
};
|
|
95
95
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { ExtensionRuntimeSurface } from '../../../types/surface/main.js';
|
|
2
|
-
import {
|
|
2
|
+
import { ExtensionInternalBase } from '../../common/types.js';
|
|
3
3
|
import { MainRendererAnimation } from '../animation/types.js';
|
|
4
4
|
import { MainRendererBoard } from '../board/types.js';
|
|
5
5
|
import { MainRendererCoordinates } from '../coordinates/types.js';
|
|
6
6
|
import { MainRendererDrag } from '../drag/types.js';
|
|
7
7
|
import { MainRendererPieces } from '../pieces/types.js';
|
|
8
8
|
import { ExtensionSlotsType } from './extension.js';
|
|
9
|
-
export interface MainRendererInstanceInternal extends
|
|
9
|
+
export interface MainRendererInstanceInternal extends ExtensionInternalBase<ExtensionSlotsType> {
|
|
10
10
|
readonly board: MainRendererBoard;
|
|
11
11
|
readonly coordinates: MainRendererCoordinates;
|
|
12
12
|
readonly pieces: MainRendererPieces;
|
|
@@ -3,7 +3,7 @@ import { createSvgElement, updateElementAttributes } from '../../../render/svg/h
|
|
|
3
3
|
import { fileOf, rankOf, squareOf } from '../../../state/board/coords.js';
|
|
4
4
|
import { toPieceCode } from '../../../state/board/piece.js';
|
|
5
5
|
import { isUpdateContextRenderable } from '../../types/context/update.js';
|
|
6
|
-
import { extensionCreateInternalBase,
|
|
6
|
+
import { extensionCreateInternalBase, extensionDestroyBase, extensionMountBase, extensionUnmountBase } from '../common/helpers.js';
|
|
7
7
|
import { normalizePromotionConfig } from './normalize.js';
|
|
8
8
|
import { EXTENSION_ID, EXTENSION_SLOTS } from './types/main.js';
|
|
9
9
|
export function createPromotion(config = {}) {
|
|
@@ -57,7 +57,7 @@ function createPromotionInstance(options, config) {
|
|
|
57
57
|
return {
|
|
58
58
|
id: EXTENSION_ID,
|
|
59
59
|
mount(env) {
|
|
60
|
-
|
|
60
|
+
extensionMountBase(internalState, env.slotRoots);
|
|
61
61
|
},
|
|
62
62
|
onUIMoveRequest(context) {
|
|
63
63
|
const request = context.request;
|
|
@@ -208,11 +208,11 @@ function createPromotionInstance(options, config) {
|
|
|
208
208
|
internalState.runtimeSurface.commands.cancelDeferredUIMoveRequest();
|
|
209
209
|
},
|
|
210
210
|
unmount() {
|
|
211
|
-
|
|
211
|
+
extensionUnmountBase(internalState);
|
|
212
212
|
extensionClean(internalState);
|
|
213
213
|
},
|
|
214
214
|
destroy() {
|
|
215
|
-
|
|
215
|
+
extensionDestroyBase(internalState);
|
|
216
216
|
extensionClean(internalState);
|
|
217
217
|
}
|
|
218
218
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RolePromotionCode, Square } from '../../../../state/board/types/internal.js';
|
|
2
2
|
import { ExtensionDefinition, ExtensionInstance } from '../../../types/extension.js';
|
|
3
3
|
import { ExtensionRuntimeSurface } from '../../../types/surface/main.js';
|
|
4
|
-
import {
|
|
4
|
+
import { ExtensionInternalBase } from '../../common/types.js';
|
|
5
5
|
import { PromotionConfig } from './internal.js';
|
|
6
6
|
export declare const EXTENSION_SLOTS: readonly ["animation"];
|
|
7
7
|
export type ExtensionSlotsType = typeof EXTENSION_SLOTS;
|
|
@@ -12,7 +12,7 @@ export interface PromotionPieceNode {
|
|
|
12
12
|
readonly svg: SVGImageElement;
|
|
13
13
|
readonly rect: SVGRectElement;
|
|
14
14
|
}
|
|
15
|
-
export interface PromotionInstanceInternal extends
|
|
15
|
+
export interface PromotionInstanceInternal extends ExtensionInternalBase<ExtensionSlotsType> {
|
|
16
16
|
readonly config: PromotionConfig;
|
|
17
17
|
readonly svgPromotionPieces: Map<RolePromotionCode, PromotionPieceNode>;
|
|
18
18
|
readonly activePromotionSquares: Map<Square, RolePromotionCode>;
|
|
@@ -2,7 +2,7 @@ import assert from '@ktarmyshov/assert';
|
|
|
2
2
|
import { toMerged } from 'es-toolkit';
|
|
3
3
|
import { createSvgElement, updateElementAttributes } from '../../../render/svg/helpers.js';
|
|
4
4
|
import { isUpdateContextRenderable } from '../../types/context/update.js';
|
|
5
|
-
import { extensionCreateInternalBase,
|
|
5
|
+
import { extensionCreateInternalBase, extensionDestroyBase, extensionMountBase, extensionUnmountBase } from '../common/helpers.js';
|
|
6
6
|
import { DEFAULT_CONFIG, EXTENSION_ID, EXTENSION_SLOTS } from './types.js';
|
|
7
7
|
export function createSelectedSquare(config = {}) {
|
|
8
8
|
const mergedConfig = toMerged(DEFAULT_CONFIG, config);
|
|
@@ -29,7 +29,7 @@ function createSelectedSquareInstance(config) {
|
|
|
29
29
|
return {
|
|
30
30
|
id: EXTENSION_ID,
|
|
31
31
|
mount(env) {
|
|
32
|
-
|
|
32
|
+
extensionMountBase(internalState, env.slotRoots);
|
|
33
33
|
},
|
|
34
34
|
onUpdate(context) {
|
|
35
35
|
const needsRender = context.mutation.hasMutation({
|
|
@@ -77,11 +77,11 @@ function createSelectedSquareInstance(config) {
|
|
|
77
77
|
}
|
|
78
78
|
},
|
|
79
79
|
unmount() {
|
|
80
|
-
|
|
80
|
+
extensionUnmountBase(internalState);
|
|
81
81
|
extensionClean(internalState);
|
|
82
82
|
},
|
|
83
83
|
destroy() {
|
|
84
|
-
|
|
84
|
+
extensionDestroyBase(internalState);
|
|
85
85
|
extensionClean(internalState);
|
|
86
86
|
}
|
|
87
87
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PartialDeep } from 'type-fest';
|
|
2
2
|
import { ExtensionDefinition, ExtensionInstance } from '../../types/extension.js';
|
|
3
|
-
import {
|
|
3
|
+
import { ExtensionInternalBase, OpaqueColor } from '../common/types.js';
|
|
4
4
|
export declare const EXTENSION_SLOTS: readonly ["underPieces"];
|
|
5
5
|
export type ExtensionSlotsType = typeof EXTENSION_SLOTS;
|
|
6
6
|
export declare const EXTENSION_ID: "selectedSquare";
|
|
@@ -9,7 +9,7 @@ export declare const DEFAULT_CONFIG: SelectedSquareConfig;
|
|
|
9
9
|
export type SelectedSquareInitConfig = PartialDeep<SelectedSquareConfig>;
|
|
10
10
|
export type SelectedSquareDefinition = ExtensionDefinition<typeof EXTENSION_ID, typeof EXTENSION_SLOTS, never>;
|
|
11
11
|
export type SelectedSquareInstance = ExtensionInstance<typeof EXTENSION_ID, typeof EXTENSION_SLOTS, never>;
|
|
12
|
-
export interface SelectedSquareInstanceInternal extends
|
|
12
|
+
export interface SelectedSquareInstanceInternal extends ExtensionInternalBase<ExtensionSlotsType> {
|
|
13
13
|
svgRect: SVGRectElement | null;
|
|
14
14
|
readonly config: SelectedSquareConfig;
|
|
15
15
|
}
|
|
@@ -1,8 +1 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { createBoardEvents } from './first-party/board-events/factory.js';
|
|
3
|
-
export { createLastMove } from './first-party/last-move/factory.js';
|
|
4
|
-
export { createLegalMoves } from './first-party/legal-moves/factory.js';
|
|
5
|
-
export { createMainRenderer } from './first-party/main-renderer/factory.js';
|
|
6
|
-
export { createSelectedSquare } from './first-party/selected-square/factory.js';
|
|
7
|
-
export type { AnyExtensionDefinition, ExtensionDefinitionId, ExtensionDefinitionPublicApi } from './types/extension.js';
|
|
8
|
-
export type { builtInExtensionFactoryMap, BuiltInExtensionId } from './types/wrapper.js';
|
|
1
|
+
export { builtInExtensionFactoryMap, type BuiltInExtensionId } from './types/wrapper.js';
|
package/dist/extensions/index.js
CHANGED
|
@@ -1,6 +1 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { createBoardEvents } from './first-party/board-events/factory.js';
|
|
3
|
-
export { createLastMove } from './first-party/last-move/factory.js';
|
|
4
|
-
export { createLegalMoves } from './first-party/legal-moves/factory.js';
|
|
5
|
-
export { createMainRenderer } from './first-party/main-renderer/factory.js';
|
|
6
|
-
export { createSelectedSquare } from './first-party/selected-square/factory.js';
|
|
1
|
+
export { builtInExtensionFactoryMap } from './types/wrapper.js';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export { createBoard } from './wrapper/factory.js';
|
|
2
|
-
export type { Chessboard, ChessboardExtensionInput, ChessboardInitOptions
|
|
2
|
+
export type { Chessboard, ChessboardExtensionInput, ChessboardInitOptions } from './wrapper/types.js';
|
|
3
3
|
export type { MoveRequestInput, PiecePositionRecordString } from './state/board/types/input.js';
|
|
4
|
-
export type { RuntimeStateInitOptions } from './state/types.js';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mirasen/chessboard",
|
|
3
3
|
"description": "Framework-agnostic TypeScript chessboard platform with real chess interaction built in.",
|
|
4
|
-
"version": "1.0.0
|
|
4
|
+
"version": "1.0.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Mirasen",
|
|
@@ -38,7 +38,11 @@
|
|
|
38
38
|
"types": "./dist/extensions/index.d.ts",
|
|
39
39
|
"import": "./dist/extensions/index.js"
|
|
40
40
|
},
|
|
41
|
-
"./
|
|
41
|
+
"./extensions/build": {
|
|
42
|
+
"types": "./dist/extensions/build/index.d.ts",
|
|
43
|
+
"import": "./dist/extensions/build/index.js"
|
|
44
|
+
},
|
|
45
|
+
"./unstable/*": {
|
|
42
46
|
"types": "./dist/*.d.ts",
|
|
43
47
|
"import": "./dist/*.js"
|
|
44
48
|
}
|
|
@@ -52,10 +56,8 @@
|
|
|
52
56
|
"lint": "prettier --check . && eslint .",
|
|
53
57
|
"check": "tsc --skipLibCheck --noEmit",
|
|
54
58
|
"check:test": "tsc --project tsconfig-test.json --skipLibCheck --noEmit",
|
|
55
|
-
"test": "
|
|
56
|
-
"
|
|
57
|
-
"coverage": "echo 'No tests for now...'",
|
|
58
|
-
"coverage-backup": "vitest run --coverage",
|
|
59
|
+
"test": "npm run check:test && vitest run --run",
|
|
60
|
+
"coverage": "vitest run --coverage",
|
|
59
61
|
"changeset:version": "changeset version && npm install && npm run format && git add --all",
|
|
60
62
|
"changeset:publish": "changeset publish"
|
|
61
63
|
},
|
|
@@ -91,7 +93,7 @@
|
|
|
91
93
|
"vitest": "^4.0.18"
|
|
92
94
|
},
|
|
93
95
|
"engines": {
|
|
94
|
-
"node": ">=
|
|
96
|
+
"node": ">=20"
|
|
95
97
|
},
|
|
96
98
|
"dependencies": {
|
|
97
99
|
"@echecs/fen": "^2.1.0",
|