@mirasen/chessboard 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/LICENSE +21 -0
- package/README.md +96 -0
- package/assets/pieces/chessnut/ATTRIBUTION.md +13 -0
- package/assets/pieces/chessnut/LICENSE.txt +202 -0
- package/assets/pieces/chessnut/bB.svg +58 -0
- package/assets/pieces/chessnut/bK.svg +51 -0
- package/assets/pieces/chessnut/bN.svg +19 -0
- package/assets/pieces/chessnut/bP.svg +17 -0
- package/assets/pieces/chessnut/bQ.svg +97 -0
- package/assets/pieces/chessnut/bR.svg +34 -0
- package/assets/pieces/chessnut/wB.svg +61 -0
- package/assets/pieces/chessnut/wK.svg +71 -0
- package/assets/pieces/chessnut/wN.svg +19 -0
- package/assets/pieces/chessnut/wP.svg +17 -0
- package/assets/pieces/chessnut/wQ.svg +40 -0
- package/assets/pieces/chessnut/wR.svg +38 -0
- package/dist/animation/planner.d.ts +6 -0
- package/dist/animation/planner.js +128 -0
- package/dist/animation/render/fade.d.ts +7 -0
- package/dist/animation/render/fade.js +24 -0
- package/dist/animation/render/move.d.ts +7 -0
- package/dist/animation/render/move.js +28 -0
- package/dist/animation/render/plan.d.ts +14 -0
- package/dist/animation/render/plan.js +69 -0
- package/dist/animation/render/static.d.ts +7 -0
- package/dist/animation/render/static.js +21 -0
- package/dist/animation/render/types.d.ts +21 -0
- package/dist/animation/render/types.js +1 -0
- package/dist/animation/types.d.ts +46 -0
- package/dist/animation/types.js +6 -0
- package/dist/extensions/animation/factory.d.ts +3 -0
- package/dist/extensions/animation/factory.js +88 -0
- package/dist/extensions/animation/types.d.ts +11 -0
- package/dist/extensions/animation/types.js +1 -0
- package/dist/extensions/factory/main.d.ts +2 -0
- package/dist/extensions/factory/main.js +101 -0
- package/dist/extensions/factory/runtime.d.ts +5 -0
- package/dist/extensions/factory/runtime.js +43 -0
- package/dist/extensions/first-party/active-target/factory.d.ts +2 -0
- package/dist/extensions/first-party/active-target/factory.js +109 -0
- package/dist/extensions/first-party/active-target/types.d.ts +25 -0
- package/dist/extensions/first-party/active-target/types.js +15 -0
- package/dist/extensions/first-party/board-events/factory.d.ts +2 -0
- package/dist/extensions/first-party/board-events/factory.js +65 -0
- package/dist/extensions/first-party/board-events/types.d.ts +27 -0
- package/dist/extensions/first-party/board-events/types.js +2 -0
- package/dist/extensions/first-party/common/helpers.d.ts +8 -0
- package/dist/extensions/first-party/common/helpers.js +33 -0
- package/dist/extensions/first-party/common/types.d.ts +10 -0
- package/dist/extensions/first-party/common/types.js +1 -0
- package/dist/extensions/first-party/last-move/factory.d.ts +2 -0
- package/dist/extensions/first-party/last-move/factory.js +106 -0
- package/dist/extensions/first-party/last-move/types.d.ts +19 -0
- package/dist/extensions/first-party/last-move/types.js +6 -0
- package/dist/extensions/first-party/legal-moves/factory.d.ts +2 -0
- package/dist/extensions/first-party/legal-moves/factory.js +101 -0
- package/dist/extensions/first-party/legal-moves/types.d.ts +29 -0
- package/dist/extensions/first-party/legal-moves/types.js +19 -0
- package/dist/extensions/first-party/main-renderer/animation/factory.d.ts +4 -0
- package/dist/extensions/first-party/main-renderer/animation/factory.js +35 -0
- package/dist/extensions/first-party/main-renderer/animation/render.d.ts +7 -0
- package/dist/extensions/first-party/main-renderer/animation/render.js +46 -0
- package/dist/extensions/first-party/main-renderer/animation/types.d.ts +24 -0
- package/dist/extensions/first-party/main-renderer/animation/types.js +1 -0
- package/dist/extensions/first-party/main-renderer/animation/update.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/animation/update.js +40 -0
- package/dist/extensions/first-party/main-renderer/board/factory.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/board/factory.js +16 -0
- package/dist/extensions/first-party/main-renderer/board/render.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/board/render.js +24 -0
- package/dist/extensions/first-party/main-renderer/board/types.d.ts +10 -0
- package/dist/extensions/first-party/main-renderer/board/types.js +1 -0
- package/dist/extensions/first-party/main-renderer/board/update.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/board/update.js +27 -0
- package/dist/extensions/first-party/main-renderer/coordinates/factory.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/coordinates/factory.js +9 -0
- package/dist/extensions/first-party/main-renderer/coordinates/render.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/coordinates/render.js +60 -0
- package/dist/extensions/first-party/main-renderer/coordinates/types.d.ts +8 -0
- package/dist/extensions/first-party/main-renderer/coordinates/types.js +1 -0
- package/dist/extensions/first-party/main-renderer/drag/factory.d.ts +4 -0
- package/dist/extensions/first-party/main-renderer/drag/factory.js +23 -0
- package/dist/extensions/first-party/main-renderer/drag/render.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/drag/render.js +27 -0
- package/dist/extensions/first-party/main-renderer/drag/types.d.ts +16 -0
- package/dist/extensions/first-party/main-renderer/drag/types.js +1 -0
- package/dist/extensions/first-party/main-renderer/drag/update.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/drag/update.js +23 -0
- package/dist/extensions/first-party/main-renderer/factory.d.ts +2 -0
- package/dist/extensions/first-party/main-renderer/factory.js +95 -0
- package/dist/extensions/first-party/main-renderer/normalize.d.ts +4 -0
- package/dist/extensions/first-party/main-renderer/normalize.js +27 -0
- package/dist/extensions/first-party/main-renderer/pieces/factory.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/pieces/factory.js +27 -0
- package/dist/extensions/first-party/main-renderer/pieces/render.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/pieces/render.js +45 -0
- package/dist/extensions/first-party/main-renderer/pieces/suppress.d.ts +5 -0
- package/dist/extensions/first-party/main-renderer/pieces/suppress.js +9 -0
- package/dist/extensions/first-party/main-renderer/pieces/types.d.ts +20 -0
- package/dist/extensions/first-party/main-renderer/pieces/types.js +1 -0
- package/dist/extensions/first-party/main-renderer/pieces/update.d.ts +6 -0
- package/dist/extensions/first-party/main-renderer/pieces/update.js +31 -0
- package/dist/extensions/first-party/main-renderer/types/extension.d.ts +15 -0
- package/dist/extensions/first-party/main-renderer/types/extension.js +10 -0
- package/dist/extensions/first-party/main-renderer/types/input.d.ts +4 -0
- package/dist/extensions/first-party/main-renderer/types/input.js +1 -0
- package/dist/extensions/first-party/main-renderer/types/instance.d.ts +16 -0
- package/dist/extensions/first-party/main-renderer/types/instance.js +1 -0
- package/dist/extensions/first-party/main-renderer/types/internal.d.ts +17 -0
- package/dist/extensions/first-party/main-renderer/types/internal.js +30 -0
- package/dist/extensions/first-party/main-renderer/types/template.d.ts +5 -0
- package/dist/extensions/first-party/main-renderer/types/template.js +1 -0
- package/dist/extensions/first-party/selected-square/factory.d.ts +2 -0
- package/dist/extensions/first-party/selected-square/factory.js +88 -0
- package/dist/extensions/first-party/selected-square/types.d.ts +18 -0
- package/dist/extensions/first-party/selected-square/types.js +6 -0
- package/dist/extensions/index.d.ts +8 -0
- package/dist/extensions/index.js +6 -0
- package/dist/extensions/invalidation/factory.d.ts +2 -0
- package/dist/extensions/invalidation/factory.js +22 -0
- package/dist/extensions/invalidation/types.d.ts +11 -0
- package/dist/extensions/invalidation/types.js +1 -0
- package/dist/extensions/types/basic/animation.d.ts +28 -0
- package/dist/extensions/types/basic/animation.js +6 -0
- package/dist/extensions/types/basic/events.d.ts +34 -0
- package/dist/extensions/types/basic/events.js +7 -0
- package/dist/extensions/types/basic/mount.d.ts +7 -0
- package/dist/extensions/types/basic/mount.js +14 -0
- package/dist/extensions/types/basic/render.d.ts +9 -0
- package/dist/extensions/types/basic/render.js +1 -0
- package/dist/extensions/types/basic/transient-visuals.d.ts +10 -0
- package/dist/extensions/types/basic/transient-visuals.js +1 -0
- package/dist/extensions/types/basic/update.d.ts +16 -0
- package/dist/extensions/types/basic/update.js +11 -0
- package/dist/extensions/types/context/animation.d.ts +31 -0
- package/dist/extensions/types/context/animation.js +9 -0
- package/dist/extensions/types/context/render.d.ts +6 -0
- package/dist/extensions/types/context/render.js +1 -0
- package/dist/extensions/types/context/transient-visuals.d.ts +7 -0
- package/dist/extensions/types/context/transient-visuals.js +1 -0
- package/dist/extensions/types/context/ui-move.d.ts +16 -0
- package/dist/extensions/types/context/ui-move.js +1 -0
- package/dist/extensions/types/context/update.d.ts +25 -0
- package/dist/extensions/types/context/update.js +10 -0
- package/dist/extensions/types/extension.d.ts +40 -0
- package/dist/extensions/types/extension.js +1 -0
- package/dist/extensions/types/main.d.ts +44 -0
- package/dist/extensions/types/main.js +1 -0
- package/dist/extensions/types/surface/commands.d.ts +26 -0
- package/dist/extensions/types/surface/commands.js +1 -0
- package/dist/extensions/types/surface/events.d.ts +5 -0
- package/dist/extensions/types/surface/events.js +1 -0
- package/dist/extensions/types/surface/main.d.ts +10 -0
- package/dist/extensions/types/surface/main.js +1 -0
- package/dist/extensions/types/surface/transient-visuals.d.ts +4 -0
- package/dist/extensions/types/surface/transient-visuals.js +1 -0
- package/dist/extensions/types/wrapper.d.ts +26 -0
- package/dist/extensions/types/wrapper.js +11 -0
- package/dist/extensions/update.d.ts +4 -0
- package/dist/extensions/update.js +29 -0
- package/dist/helpers/util.d.ts +1 -0
- package/dist/helpers/util.js +9 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +1 -0
- package/dist/layout/factory.d.ts +2 -0
- package/dist/layout/factory.js +33 -0
- package/dist/layout/geometry/factory.d.ts +12 -0
- package/dist/layout/geometry/factory.js +33 -0
- package/dist/layout/geometry/types.d.ts +20 -0
- package/dist/layout/geometry/types.js +1 -0
- package/dist/layout/helpers.d.ts +4 -0
- package/dist/layout/helpers.js +6 -0
- package/dist/layout/mutation.d.ts +6 -0
- package/dist/layout/mutation.js +1 -0
- package/dist/layout/reducers.d.ts +2 -0
- package/dist/layout/reducers.js +30 -0
- package/dist/layout/types.d.ts +23 -0
- package/dist/layout/types.js +1 -0
- package/dist/mutation/pipeline.d.ts +2 -0
- package/dist/mutation/pipeline.js +36 -0
- package/dist/mutation/session.d.ts +3 -0
- package/dist/mutation/session.js +66 -0
- package/dist/mutation/types.d.ts +26 -0
- package/dist/mutation/types.js +1 -0
- package/dist/render/factory.d.ts +2 -0
- package/dist/render/factory.js +117 -0
- package/dist/render/mount.d.ts +3 -0
- package/dist/render/mount.js +28 -0
- package/dist/render/rendering/animation.d.ts +13 -0
- package/dist/render/rendering/animation.js +92 -0
- package/dist/render/rendering/helpers.d.ts +3 -0
- package/dist/render/rendering/helpers.js +10 -0
- package/dist/render/rendering/state.d.ts +4 -0
- package/dist/render/rendering/state.js +48 -0
- package/dist/render/rendering/visuals.d.ts +3 -0
- package/dist/render/rendering/visuals.js +21 -0
- package/dist/render/scheduler/scheduler.d.ts +2 -0
- package/dist/render/scheduler/scheduler.js +53 -0
- package/dist/render/scheduler/types.d.ts +12 -0
- package/dist/render/scheduler/types.js +1 -0
- package/dist/render/svg/factory.d.ts +4 -0
- package/dist/render/svg/factory.js +38 -0
- package/dist/render/svg/helpers.d.ts +18 -0
- package/dist/render/svg/helpers.js +34 -0
- package/dist/render/types.d.ts +42 -0
- package/dist/render/types.js +1 -0
- package/dist/runtime/factory/helpers.d.ts +6 -0
- package/dist/runtime/factory/helpers.js +42 -0
- package/dist/runtime/factory/input.d.ts +3 -0
- package/dist/runtime/factory/input.js +98 -0
- package/dist/runtime/factory/main.d.ts +2 -0
- package/dist/runtime/factory/main.js +182 -0
- package/dist/runtime/factory/ui-move.d.ts +4 -0
- package/dist/runtime/factory/ui-move.js +84 -0
- package/dist/runtime/input/adapter/factory.d.ts +2 -0
- package/dist/runtime/input/adapter/factory.js +55 -0
- package/dist/runtime/input/adapter/helpers.d.ts +5 -0
- package/dist/runtime/input/adapter/helpers.js +23 -0
- package/dist/runtime/input/adapter/pointer.d.ts +13 -0
- package/dist/runtime/input/adapter/pointer.js +97 -0
- package/dist/runtime/input/adapter/types.d.ts +16 -0
- package/dist/runtime/input/adapter/types.js +1 -0
- package/dist/runtime/input/controller/factory.d.ts +2 -0
- package/dist/runtime/input/controller/factory.js +32 -0
- package/dist/runtime/input/controller/helpers.d.ts +3 -0
- package/dist/runtime/input/controller/helpers.js +12 -0
- package/dist/runtime/input/controller/pointer.d.ts +7 -0
- package/dist/runtime/input/controller/pointer.js +104 -0
- package/dist/runtime/input/controller/transient-visuals.d.ts +3 -0
- package/dist/runtime/input/controller/transient-visuals.js +12 -0
- package/dist/runtime/input/controller/types.d.ts +25 -0
- package/dist/runtime/input/controller/types.js +1 -0
- package/dist/runtime/layout.d.ts +2 -0
- package/dist/runtime/layout.js +10 -0
- package/dist/runtime/lifecycle.d.ts +12 -0
- package/dist/runtime/lifecycle.js +49 -0
- package/dist/runtime/mutation/extension-update.d.ts +2 -0
- package/dist/runtime/mutation/extension-update.js +26 -0
- package/dist/runtime/mutation/factory.d.ts +2 -0
- package/dist/runtime/mutation/factory.js +47 -0
- package/dist/runtime/mutation/interaction.d.ts +2 -0
- package/dist/runtime/mutation/interaction.js +34 -0
- package/dist/runtime/mutation/invalidation.d.ts +0 -0
- package/dist/runtime/mutation/invalidation.js +2 -0
- package/dist/runtime/mutation/last-move.d.ts +3 -0
- package/dist/runtime/mutation/last-move.js +19 -0
- package/dist/runtime/mutation/layout.d.ts +2 -0
- package/dist/runtime/mutation/layout.js +8 -0
- package/dist/runtime/mutation/pipeline.d.ts +22 -0
- package/dist/runtime/mutation/pipeline.js +1 -0
- package/dist/runtime/mutation/request-render.d.ts +2 -0
- package/dist/runtime/mutation/request-render.js +29 -0
- package/dist/runtime/mutation/run.d.ts +2 -0
- package/dist/runtime/mutation/run.js +3 -0
- package/dist/runtime/mutation/types.d.ts +14 -0
- package/dist/runtime/mutation/types.js +1 -0
- package/dist/runtime/types/main.d.ts +36 -0
- package/dist/runtime/types/main.js +1 -0
- package/dist/runtime/types/ui-move.d.ts +9 -0
- package/dist/runtime/types/ui-move.js +1 -0
- package/dist/state/board/check.d.ts +27 -0
- package/dist/state/board/check.js +148 -0
- package/dist/state/board/coords.d.ts +4 -0
- package/dist/state/board/coords.js +9 -0
- package/dist/state/board/denormalize.d.ts +11 -0
- package/dist/state/board/denormalize.js +77 -0
- package/dist/state/board/factory.d.ts +3 -0
- package/dist/state/board/factory.js +46 -0
- package/dist/state/board/mutation.d.ts +9 -0
- package/dist/state/board/mutation.js +1 -0
- package/dist/state/board/normalize.d.ts +8 -0
- package/dist/state/board/normalize.js +76 -0
- package/dist/state/board/piece.d.ts +3 -0
- package/dist/state/board/piece.js +11 -0
- package/dist/state/board/position.d.ts +4 -0
- package/dist/state/board/position.js +94 -0
- package/dist/state/board/reducers.d.ts +8 -0
- package/dist/state/board/reducers.js +80 -0
- package/dist/state/board/types/input.d.ts +35 -0
- package/dist/state/board/types/input.js +1 -0
- package/dist/state/board/types/internal.d.ts +54 -0
- package/dist/state/board/types/internal.js +17 -0
- package/dist/state/board/types/main.d.ts +18 -0
- package/dist/state/board/types/main.js +1 -0
- package/dist/state/board/types/output.d.ts +5 -0
- package/dist/state/board/types/output.js +1 -0
- package/dist/state/board/types/template.d.ts +23 -0
- package/dist/state/board/types/template.js +1 -0
- package/dist/state/change/factory.d.ts +2 -0
- package/dist/state/change/factory.js +28 -0
- package/dist/state/change/helpers.d.ts +8 -0
- package/dist/state/change/helpers.js +86 -0
- package/dist/state/change/mutation.d.ts +6 -0
- package/dist/state/change/mutation.js +1 -0
- package/dist/state/change/reducers.d.ts +5 -0
- package/dist/state/change/reducers.js +16 -0
- package/dist/state/change/types.d.ts +17 -0
- package/dist/state/change/types.js +1 -0
- package/dist/state/factory.d.ts +2 -0
- package/dist/state/factory.js +24 -0
- package/dist/state/interaction/factory.d.ts +2 -0
- package/dist/state/interaction/factory.js +83 -0
- package/dist/state/interaction/helpers.d.ts +4 -0
- package/dist/state/interaction/helpers.js +16 -0
- package/dist/state/interaction/movability.d.ts +5 -0
- package/dist/state/interaction/movability.js +87 -0
- package/dist/state/interaction/mutation.d.ts +11 -0
- package/dist/state/interaction/mutation.js +1 -0
- package/dist/state/interaction/normalize.d.ts +5 -0
- package/dist/state/interaction/normalize.js +50 -0
- package/dist/state/interaction/reducers.d.ts +11 -0
- package/dist/state/interaction/reducers.js +81 -0
- package/dist/state/interaction/types/input.d.ts +18 -0
- package/dist/state/interaction/types/input.js +1 -0
- package/dist/state/interaction/types/internal.d.ts +35 -0
- package/dist/state/interaction/types/internal.js +1 -0
- package/dist/state/interaction/types/main.d.ts +33 -0
- package/dist/state/interaction/types/main.js +1 -0
- package/dist/state/types.d.ts +30 -0
- package/dist/state/types.js +1 -0
- package/dist/state/view/factory.d.ts +2 -0
- package/dist/state/view/factory.js +24 -0
- package/dist/state/view/mutation.d.ts +5 -0
- package/dist/state/view/mutation.js +1 -0
- package/dist/state/view/reducers.d.ts +3 -0
- package/dist/state/view/reducers.js +6 -0
- package/dist/state/view/types/internal.d.ts +6 -0
- package/dist/state/view/types/internal.js +1 -0
- package/dist/state/view/types/main.d.ts +12 -0
- package/dist/state/view/types/main.js +1 -0
- package/dist/wrapper/factory.d.ts +3 -0
- package/dist/wrapper/factory.js +61 -0
- package/dist/wrapper/types.d.ts +56 -0
- package/dist/wrapper/types.js +1 -0
- package/package.json +98 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ReadonlyDeep } from 'type-fest';
|
|
2
|
+
import type { NonEmptyPieceCode, Square } from '../state/board/types/internal';
|
|
3
|
+
export interface AnimationTrackMove {
|
|
4
|
+
id: number;
|
|
5
|
+
pieceCode: NonEmptyPieceCode;
|
|
6
|
+
fromSq: Square;
|
|
7
|
+
toSq: Square;
|
|
8
|
+
effect: 'move';
|
|
9
|
+
}
|
|
10
|
+
export interface AnimationTrackFade {
|
|
11
|
+
id: number;
|
|
12
|
+
pieceCode: NonEmptyPieceCode;
|
|
13
|
+
sq: Square;
|
|
14
|
+
effect: 'fade-in' | 'fade-out';
|
|
15
|
+
}
|
|
16
|
+
export interface AnimationTrackStatic {
|
|
17
|
+
id: number;
|
|
18
|
+
pieceCode: NonEmptyPieceCode;
|
|
19
|
+
sq: Square;
|
|
20
|
+
effect: 'static';
|
|
21
|
+
}
|
|
22
|
+
export type AnimationTrack = AnimationTrackMove | AnimationTrackFade | AnimationTrackStatic;
|
|
23
|
+
export interface AnimationPlan {
|
|
24
|
+
sessionId: number;
|
|
25
|
+
tracks: AnimationTrack[];
|
|
26
|
+
}
|
|
27
|
+
export interface AnimationSession {
|
|
28
|
+
id: number;
|
|
29
|
+
tracks: AnimationTrack[];
|
|
30
|
+
startTime: number;
|
|
31
|
+
duration: number;
|
|
32
|
+
}
|
|
33
|
+
export type AnimationSessionSnapshot = ReadonlyDeep<AnimationSession>;
|
|
34
|
+
export interface AnimationTrackMoveExclude {
|
|
35
|
+
fromSq: Square;
|
|
36
|
+
toSq: Square;
|
|
37
|
+
}
|
|
38
|
+
export interface AnimationTrackSquareExclude {
|
|
39
|
+
sq: Square;
|
|
40
|
+
}
|
|
41
|
+
export type AnimationTrackExclude = AnimationTrackMoveExclude | AnimationTrackSquareExclude;
|
|
42
|
+
export declare function isMoveExclude(e: AnimationTrackExclude): e is AnimationTrackMoveExclude;
|
|
43
|
+
export declare function isSquareExclude(e: AnimationTrackExclude): e is AnimationTrackSquareExclude;
|
|
44
|
+
export interface CalculateAnimationTracksOptions {
|
|
45
|
+
exclude?: AnimationTrackExclude[];
|
|
46
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { ExtensionAnimationControllerInternalSurface, ExtensionAnimationSessionInternalSurface, ExtensionAnimationSessionSubmitOptions } from '../types/basic/animation';
|
|
2
|
+
export declare function createExtensionAnimationSession(id: number, options: ExtensionAnimationSessionSubmitOptions): ExtensionAnimationSessionInternalSurface;
|
|
3
|
+
export declare function createExtensionAnimationController(): ExtensionAnimationControllerInternalSurface;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { ANIMATION_SESSION_STATUS_ALL } from '../types/basic/animation';
|
|
2
|
+
function createExtensionAnimationSessionInternal(id, options) {
|
|
3
|
+
return {
|
|
4
|
+
id,
|
|
5
|
+
startTime: performance.now(),
|
|
6
|
+
duration: options.duration,
|
|
7
|
+
status: 'submitted',
|
|
8
|
+
pendingCleanup: false
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export function createExtensionAnimationSession(id, options) {
|
|
12
|
+
const internalState = createExtensionAnimationSessionInternal(id, options);
|
|
13
|
+
return {
|
|
14
|
+
id: internalState.id,
|
|
15
|
+
startTime: internalState.startTime,
|
|
16
|
+
duration: internalState.duration,
|
|
17
|
+
get status() {
|
|
18
|
+
return internalState.status;
|
|
19
|
+
},
|
|
20
|
+
get elapsedTime() {
|
|
21
|
+
return performance.now() - internalState.startTime;
|
|
22
|
+
},
|
|
23
|
+
get progress() {
|
|
24
|
+
return Math.min(1, (performance.now() - internalState.startTime) / internalState.duration);
|
|
25
|
+
},
|
|
26
|
+
get pendingCleanup() {
|
|
27
|
+
return internalState.pendingCleanup;
|
|
28
|
+
},
|
|
29
|
+
setStatus(newStatus) {
|
|
30
|
+
internalState.status = newStatus;
|
|
31
|
+
},
|
|
32
|
+
markPendingCleanup() {
|
|
33
|
+
internalState.pendingCleanup = true;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function createExtensionAnimationControllerInternal() {
|
|
38
|
+
return {
|
|
39
|
+
sessions: new Map()
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
let gSessionId = 0;
|
|
43
|
+
export function createExtensionAnimationController() {
|
|
44
|
+
const internalState = createExtensionAnimationControllerInternal();
|
|
45
|
+
return {
|
|
46
|
+
submit(options) {
|
|
47
|
+
gSessionId++;
|
|
48
|
+
const session = createExtensionAnimationSession(gSessionId, options);
|
|
49
|
+
internalState.sessions.set(gSessionId, session);
|
|
50
|
+
// Logic to start the animation can be added here
|
|
51
|
+
return session;
|
|
52
|
+
},
|
|
53
|
+
cancel(sessionId) {
|
|
54
|
+
const session = internalState.sessions.get(sessionId);
|
|
55
|
+
if (session) {
|
|
56
|
+
session.setStatus('cancelled');
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
getAll(status) {
|
|
60
|
+
const stati = status
|
|
61
|
+
? // If iterable
|
|
62
|
+
typeof status === 'string'
|
|
63
|
+
? new Set([status])
|
|
64
|
+
: new Set([...status])
|
|
65
|
+
: ANIMATION_SESSION_STATUS_ALL;
|
|
66
|
+
const result = [];
|
|
67
|
+
for (const session of internalState.sessions.values()) {
|
|
68
|
+
if (stati.has(session.status)) {
|
|
69
|
+
result.push(session);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
},
|
|
74
|
+
remove(sessionId) {
|
|
75
|
+
if (typeof sessionId === 'number') {
|
|
76
|
+
internalState.sessions.delete(sessionId);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
for (const id of sessionId) {
|
|
80
|
+
internalState.sessions.delete(id);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
clear() {
|
|
85
|
+
internalState.sessions.clear();
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ExtensionAnimationSessionInternalSurface, ExtensionAnimationSessionStatus } from '../types/basic/animation';
|
|
2
|
+
export interface ExtensionAnimationSessionInternal {
|
|
3
|
+
readonly id: number;
|
|
4
|
+
readonly startTime: DOMHighResTimeStamp;
|
|
5
|
+
readonly duration: number;
|
|
6
|
+
status: ExtensionAnimationSessionStatus;
|
|
7
|
+
pendingCleanup: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface ExtensionAnimationControllerInternal {
|
|
10
|
+
readonly sessions: Map<number, ExtensionAnimationSessionInternalSurface>;
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { createExtensionAnimationController } from '../animation/factory';
|
|
2
|
+
import { createExtensionInvalidationState } from '../invalidation/factory';
|
|
3
|
+
import { extensionSystemUpdateState, extensionSystemUpdateUIMoveRequest } from '../update';
|
|
4
|
+
import { createExtensionRuntimeSurface } from './runtime';
|
|
5
|
+
function createExtensionSystemInternal(getInternalState, options) {
|
|
6
|
+
const extensions = new Map();
|
|
7
|
+
const extensionsArray = options.extensions ?? [];
|
|
8
|
+
for (const extensionDef of extensionsArray) {
|
|
9
|
+
if (extensions.has(extensionDef.id)) {
|
|
10
|
+
throw new Error(`Duplicate extension id found: ${extensionDef.id}`);
|
|
11
|
+
}
|
|
12
|
+
const instance = extensionDef.createInstance({
|
|
13
|
+
runtimeSurface: createExtensionRuntimeSurface(getInternalState, options.extensionRuntimeSurfaceCommands, extensionDef)
|
|
14
|
+
});
|
|
15
|
+
const record = {
|
|
16
|
+
id: extensionDef.id,
|
|
17
|
+
definition: extensionDef,
|
|
18
|
+
instance,
|
|
19
|
+
invalidation: createExtensionInvalidationState(),
|
|
20
|
+
animation: createExtensionAnimationController()
|
|
21
|
+
};
|
|
22
|
+
extensions.set(extensionDef.id, record);
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
extensions,
|
|
26
|
+
transientVisualsSubscribers: new Set(),
|
|
27
|
+
eventSubscribers: new Map(),
|
|
28
|
+
currentFrame: null
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function createExtensionSystem(options) {
|
|
32
|
+
let internalState = null;
|
|
33
|
+
function getInternalState() {
|
|
34
|
+
if (!internalState) {
|
|
35
|
+
throw new Error('Extension system internal state is not initialized');
|
|
36
|
+
}
|
|
37
|
+
return internalState;
|
|
38
|
+
}
|
|
39
|
+
internalState = createExtensionSystemInternal(getInternalState, options);
|
|
40
|
+
return {
|
|
41
|
+
getSharedDataForRenderSystem() {
|
|
42
|
+
return {
|
|
43
|
+
extensions: internalState.extensions,
|
|
44
|
+
transientVisualsSubscribers: internalState.transientVisualsSubscribers
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
get hasSubmittedAnimations() {
|
|
48
|
+
for (const ext of internalState.extensions.values()) {
|
|
49
|
+
if (ext.animation.getAll('submitted').length > 0) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return false;
|
|
54
|
+
},
|
|
55
|
+
get currentFrame() {
|
|
56
|
+
return internalState.currentFrame;
|
|
57
|
+
},
|
|
58
|
+
getPublicRecord() {
|
|
59
|
+
const publicRecord = {};
|
|
60
|
+
for (const [id, extRecord] of internalState.extensions.entries()) {
|
|
61
|
+
if ('getPublic' in extRecord.instance) {
|
|
62
|
+
// We know that if getPublic exists, then the instance has a public API, so this type assertion is safe
|
|
63
|
+
const instanceWithPublic = extRecord.instance;
|
|
64
|
+
publicRecord[id] = instanceWithPublic.getPublic();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return publicRecord;
|
|
68
|
+
},
|
|
69
|
+
onUpdate(request) {
|
|
70
|
+
extensionSystemUpdateState(internalState, request);
|
|
71
|
+
},
|
|
72
|
+
onUIMoveRequest(context) {
|
|
73
|
+
extensionSystemUpdateUIMoveRequest(internalState, context);
|
|
74
|
+
},
|
|
75
|
+
onUnmount() {
|
|
76
|
+
internalState.transientVisualsSubscribers.clear();
|
|
77
|
+
internalState.eventSubscribers.clear();
|
|
78
|
+
internalState.currentFrame = null;
|
|
79
|
+
for (const extensionRec of internalState.extensions.values()) {
|
|
80
|
+
extensionRec.invalidation.clear();
|
|
81
|
+
extensionRec.animation.clear();
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
onDestroy() {
|
|
85
|
+
// We assume that the onUnmout was already called by runtime, but let's still validate
|
|
86
|
+
for (const extensionRec of internalState.extensions.values()) {
|
|
87
|
+
extensionRec.instance.destroy();
|
|
88
|
+
const onUnmountCalled = [
|
|
89
|
+
extensionRec.invalidation.dirtyLayers === 0,
|
|
90
|
+
extensionRec.animation.getAll().length === 0
|
|
91
|
+
].every(Boolean);
|
|
92
|
+
if (!onUnmountCalled) {
|
|
93
|
+
throw new Error(`Extension ${extensionRec.id} was not properly unmounted before destroy. Please make sure to call onUnmount before onDestroy to allow the extension to clean up its state and resources.`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// So we just clear the extension map to release references to extension definitions and instances and allow them to be garbage collected
|
|
97
|
+
// Cause they also have back reference to our surface to manipulate the core state
|
|
98
|
+
internalState.extensions.clear();
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { AnyExtensionDefinition } from '../types/extension';
|
|
2
|
+
import type { GetInternalState } from '../types/main';
|
|
3
|
+
import type { ExtensionRuntimeSurfaceCommands } from '../types/surface/commands';
|
|
4
|
+
import type { ExtensionRuntimeSurface } from '../types/surface/main';
|
|
5
|
+
export declare function createExtensionRuntimeSurface(getInternalState: GetInternalState, commands: ExtensionRuntimeSurfaceCommands, extensionDef: AnyExtensionDefinition): ExtensionRuntimeSurface;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import assert from '@ktarmyshov/assert';
|
|
2
|
+
function createExtensionRuntimeSurfaceTransientVisuals(getInternalState, extensionDef) {
|
|
3
|
+
return {
|
|
4
|
+
subscribe() {
|
|
5
|
+
const internalState = getInternalState();
|
|
6
|
+
internalState.transientVisualsSubscribers.add(extensionDef.id);
|
|
7
|
+
},
|
|
8
|
+
unsubscribe() {
|
|
9
|
+
const internalState = getInternalState();
|
|
10
|
+
internalState.transientVisualsSubscribers.delete(extensionDef.id);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function createExtensionRuntimeSurfaceAnimation(getInternalState, extensionDef) {
|
|
15
|
+
function getController() {
|
|
16
|
+
const internalState = getInternalState();
|
|
17
|
+
const controller = internalState.extensions.get(extensionDef.id)?.animation;
|
|
18
|
+
assert(controller, 'Extension animation controller not found');
|
|
19
|
+
return controller;
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
submit(options) {
|
|
23
|
+
const controller = getController();
|
|
24
|
+
return controller.submit(options);
|
|
25
|
+
},
|
|
26
|
+
cancel(sessionId) {
|
|
27
|
+
const controller = getController();
|
|
28
|
+
controller.cancel(sessionId);
|
|
29
|
+
},
|
|
30
|
+
getAll(status) {
|
|
31
|
+
const controller = getController();
|
|
32
|
+
return controller.getAll(status);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export function createExtensionRuntimeSurface(getInternalState, commands, extensionDef) {
|
|
37
|
+
// @ts-expect-error We will implement events later, for now we just return empty object for it to satisfy the interface
|
|
38
|
+
return {
|
|
39
|
+
commands,
|
|
40
|
+
animation: createExtensionRuntimeSurfaceAnimation(getInternalState, extensionDef),
|
|
41
|
+
transientVisuals: createExtensionRuntimeSurfaceTransientVisuals(getInternalState, extensionDef)
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import assert from '@ktarmyshov/assert';
|
|
2
|
+
import { toMerged } from 'es-toolkit';
|
|
3
|
+
import { createSvgElement, updateElementAttributes } from '../../../render/svg/helpers';
|
|
4
|
+
import { isUpdateContextRenderable } from '../../types/context/update';
|
|
5
|
+
import { extensionCreateInternalBase, extensionDestroy, extensionMount, extensionUnmount } from '../common/helpers';
|
|
6
|
+
import { DEFAULT_CONFIG, EXTENSION_ID, EXTENSION_SLOTS } from './types';
|
|
7
|
+
export function createActiveTarget(config = {}) {
|
|
8
|
+
const mergedConfig = toMerged(DEFAULT_CONFIG, config);
|
|
9
|
+
return {
|
|
10
|
+
id: EXTENSION_ID,
|
|
11
|
+
slots: EXTENSION_SLOTS,
|
|
12
|
+
createInstance() {
|
|
13
|
+
return createActiveTargetInstance(mergedConfig);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function createActiveTargetInternal(config) {
|
|
18
|
+
return {
|
|
19
|
+
...extensionCreateInternalBase(),
|
|
20
|
+
svgRect: null,
|
|
21
|
+
svgCircle: null,
|
|
22
|
+
config
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function extensionClean(state) {
|
|
26
|
+
state.svgRect = null;
|
|
27
|
+
state.svgCircle = null;
|
|
28
|
+
}
|
|
29
|
+
function createActiveTargetInstance(config) {
|
|
30
|
+
const internalState = createActiveTargetInternal(config);
|
|
31
|
+
return {
|
|
32
|
+
id: EXTENSION_ID,
|
|
33
|
+
mount(env) {
|
|
34
|
+
extensionMount(internalState, env.slotRoots);
|
|
35
|
+
},
|
|
36
|
+
onUpdate(context) {
|
|
37
|
+
const needsRender = context.mutation.hasMutation({
|
|
38
|
+
causes: ['layout.refreshGeometry'],
|
|
39
|
+
// we really need almost all: setDrag, updateTarget, clear, clearActive, so just take all interaction mutations
|
|
40
|
+
prefixes: ['state.interaction.']
|
|
41
|
+
}) && isUpdateContextRenderable(context);
|
|
42
|
+
if (!needsRender) {
|
|
43
|
+
return; // no-op
|
|
44
|
+
}
|
|
45
|
+
context.invalidation.markDirty(1 /* DirtyLayer.Highlight */);
|
|
46
|
+
},
|
|
47
|
+
render(context) {
|
|
48
|
+
assert(context.invalidation.dirtyLayers !== 0, 'Render should only be called when there are dirty layers');
|
|
49
|
+
// For AI: `release-targeting` is also represented by `dragSession`.
|
|
50
|
+
// `dragSession` here is the active interaction session, not only lifted-piece drag.
|
|
51
|
+
const square = context.currentFrame.state.interaction.dragSession?.targetSquare;
|
|
52
|
+
if (square === undefined || square === null) {
|
|
53
|
+
if (internalState.svgRect !== null) {
|
|
54
|
+
internalState.svgRect.remove();
|
|
55
|
+
internalState.svgRect = null;
|
|
56
|
+
assert(internalState.svgCircle, 'svgCircle should be available if svgRect is available');
|
|
57
|
+
internalState.svgCircle.remove();
|
|
58
|
+
internalState.svgCircle = null;
|
|
59
|
+
}
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const geometry = context.currentFrame.layout.geometry;
|
|
63
|
+
const r = geometry.squareRect(square);
|
|
64
|
+
const rectAttributes = {
|
|
65
|
+
x: r.x.toString(),
|
|
66
|
+
y: r.y.toString(),
|
|
67
|
+
width: r.size.toString(),
|
|
68
|
+
height: r.size.toString(),
|
|
69
|
+
fill: internalState.config.squareColor.color,
|
|
70
|
+
'fill-opacity': internalState.config.squareColor.opacity.toString(),
|
|
71
|
+
'shape-rendering': 'crispEdges'
|
|
72
|
+
};
|
|
73
|
+
const radius = geometry.squareSize * internalState.config.halo.radiusRatio;
|
|
74
|
+
const centerX = r.x + r.size / 2;
|
|
75
|
+
const centerY = r.y + r.size / 2;
|
|
76
|
+
const haloAttributes = {
|
|
77
|
+
cx: centerX.toString(),
|
|
78
|
+
cy: centerY.toString(),
|
|
79
|
+
r: radius.toString(),
|
|
80
|
+
fill: internalState.config.halo.color.color,
|
|
81
|
+
'fill-opacity': internalState.config.halo.color.opacity.toString()
|
|
82
|
+
};
|
|
83
|
+
if (internalState.svgRect === null) {
|
|
84
|
+
assert(internalState.slotRoots, 'Slot roots should be available when render is called');
|
|
85
|
+
internalState.svgRect = createSvgElement(internalState.slotRoots.underPieces, 'rect', {
|
|
86
|
+
'data-chessboard-id': 'active-target-square-highlight',
|
|
87
|
+
...rectAttributes
|
|
88
|
+
});
|
|
89
|
+
internalState.svgCircle = createSvgElement(internalState.slotRoots.overPieces, 'circle', {
|
|
90
|
+
'data-chessboard-id': 'active-target-halo',
|
|
91
|
+
...haloAttributes
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
updateElementAttributes(internalState.svgRect, rectAttributes);
|
|
96
|
+
assert(internalState.svgCircle, 'svgCircle should be available if svgRect is available');
|
|
97
|
+
updateElementAttributes(internalState.svgCircle, haloAttributes);
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
unmount() {
|
|
101
|
+
extensionUnmount(internalState);
|
|
102
|
+
extensionClean(internalState);
|
|
103
|
+
},
|
|
104
|
+
destroy() {
|
|
105
|
+
extensionDestroy(internalState);
|
|
106
|
+
extensionClean(internalState);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { PartialDeep } from 'type-fest';
|
|
2
|
+
import { ExtensionDefinition, ExtensionInstance } from '../../types/extension';
|
|
3
|
+
import { ExtensionInternal, OpaqueColor } from '../common/types';
|
|
4
|
+
export declare const EXTENSION_SLOTS: readonly ["underPieces", "overPieces"];
|
|
5
|
+
export type ExtensionSlotsType = typeof EXTENSION_SLOTS;
|
|
6
|
+
export declare const EXTENSION_ID: "activeTarget";
|
|
7
|
+
export interface ActiveTargetConfig {
|
|
8
|
+
squareColor: OpaqueColor;
|
|
9
|
+
halo: {
|
|
10
|
+
color: OpaqueColor;
|
|
11
|
+
radiusRatio: number;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export declare const DEFAULT_CONFIG: ActiveTargetConfig;
|
|
15
|
+
export type ActiveTargetInitConfig = PartialDeep<ActiveTargetConfig>;
|
|
16
|
+
export type ActiveTargetDefinition = ExtensionDefinition<typeof EXTENSION_ID, typeof EXTENSION_SLOTS, never>;
|
|
17
|
+
export type ActiveTargetInstance = ExtensionInstance<typeof EXTENSION_ID, typeof EXTENSION_SLOTS, never>;
|
|
18
|
+
export interface ActiveTargetInstanceInternal extends ExtensionInternal<ExtensionSlotsType> {
|
|
19
|
+
svgRect: SVGRectElement | null;
|
|
20
|
+
svgCircle: SVGCircleElement | null;
|
|
21
|
+
readonly config: ActiveTargetConfig;
|
|
22
|
+
}
|
|
23
|
+
export declare const enum DirtyLayer {
|
|
24
|
+
Highlight = 1
|
|
25
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const EXTENSION_SLOTS = ['underPieces', 'overPieces'];
|
|
2
|
+
export const EXTENSION_ID = 'activeTarget';
|
|
3
|
+
export const DEFAULT_CONFIG = {
|
|
4
|
+
squareColor: {
|
|
5
|
+
color: 'rgba(255, 255, 0)',
|
|
6
|
+
opacity: 0.4
|
|
7
|
+
},
|
|
8
|
+
halo: {
|
|
9
|
+
color: {
|
|
10
|
+
color: 'rgba(0, 0, 0)',
|
|
11
|
+
opacity: 0.2
|
|
12
|
+
},
|
|
13
|
+
radiusRatio: 1.2
|
|
14
|
+
}
|
|
15
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { denormalizeMove } from '../../../state/board/denormalize';
|
|
2
|
+
import { extensionCreateInternalBase, extensionDestroy, extensionUnmount } from '../common/helpers';
|
|
3
|
+
import { EXTENSION_ID, EXTENSION_SLOTS } from './types';
|
|
4
|
+
export function createBoardEvents() {
|
|
5
|
+
return {
|
|
6
|
+
id: EXTENSION_ID,
|
|
7
|
+
slots: EXTENSION_SLOTS,
|
|
8
|
+
createInstance() {
|
|
9
|
+
return createBoardEventsInstance();
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function createBoardEventsInternal() {
|
|
14
|
+
return {
|
|
15
|
+
...extensionCreateInternalBase(),
|
|
16
|
+
onUIMove: null,
|
|
17
|
+
onRawUpdate: null
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function extensionClean(state) {
|
|
21
|
+
state.onUIMove = null;
|
|
22
|
+
state.onRawUpdate = null;
|
|
23
|
+
}
|
|
24
|
+
function createBoardEventsInstancePublic(state) {
|
|
25
|
+
return {
|
|
26
|
+
setOnUIMove(callback) {
|
|
27
|
+
state.onUIMove = callback;
|
|
28
|
+
},
|
|
29
|
+
setOnRawUpdate(callback) {
|
|
30
|
+
state.onRawUpdate = callback;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function createBoardEventsInstance() {
|
|
35
|
+
const internalState = createBoardEventsInternal();
|
|
36
|
+
const publicInterface = createBoardEventsInstancePublic(internalState);
|
|
37
|
+
return {
|
|
38
|
+
id: EXTENSION_ID,
|
|
39
|
+
mount() { },
|
|
40
|
+
onUpdate(context) {
|
|
41
|
+
if (internalState.onRawUpdate) {
|
|
42
|
+
internalState.onRawUpdate({
|
|
43
|
+
previousFrame: context.previousFrame,
|
|
44
|
+
mutation: context.mutation,
|
|
45
|
+
currentFrame: context.currentFrame
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (context.mutation.hasMutation({ causes: ['state.change.setLastMove'] }) &&
|
|
49
|
+
context.currentFrame.state.change.lastMove) {
|
|
50
|
+
internalState.onUIMove?.(denormalizeMove(context.currentFrame.state.change.lastMove));
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
getPublic() {
|
|
54
|
+
return publicInterface;
|
|
55
|
+
},
|
|
56
|
+
unmount() {
|
|
57
|
+
extensionUnmount(internalState);
|
|
58
|
+
extensionClean(internalState);
|
|
59
|
+
},
|
|
60
|
+
destroy() {
|
|
61
|
+
extensionDestroy(internalState);
|
|
62
|
+
extensionClean(internalState);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { RuntimeReadonlyMutationSession } from '../../../runtime/mutation/types';
|
|
2
|
+
import { MoveOutput } from '../../../state/board/types/output';
|
|
3
|
+
import { ExtensionSlotSvgRoots } from '../../types/basic/mount';
|
|
4
|
+
import { UpdateFrameSnapshot } from '../../types/basic/update';
|
|
5
|
+
import { ExtensionDefinition, ExtensionInstance } from '../../types/extension';
|
|
6
|
+
import { ExtensionInternal } from '../common/types';
|
|
7
|
+
export declare const EXTENSION_SLOTS: readonly [];
|
|
8
|
+
export type ExtensionSlotsType = typeof EXTENSION_SLOTS;
|
|
9
|
+
export declare const EXTENSION_ID: "events";
|
|
10
|
+
export type BoardEventsDefinition = ExtensionDefinition<typeof EXTENSION_ID, typeof EXTENSION_SLOTS, BoardEventsPublic>;
|
|
11
|
+
export type OnUIMoveCallback = (move: MoveOutput) => void;
|
|
12
|
+
export interface OnRawUpdateContext {
|
|
13
|
+
readonly previousFrame: UpdateFrameSnapshot | null;
|
|
14
|
+
readonly mutation: RuntimeReadonlyMutationSession;
|
|
15
|
+
readonly currentFrame: UpdateFrameSnapshot;
|
|
16
|
+
}
|
|
17
|
+
export type OnRawUpdateCallback = (context: OnRawUpdateContext) => void;
|
|
18
|
+
export interface BoardEventsPublic {
|
|
19
|
+
setOnUIMove(callback: OnUIMoveCallback | null): void;
|
|
20
|
+
setOnRawUpdate(callback: OnRawUpdateCallback | null): void;
|
|
21
|
+
}
|
|
22
|
+
export type BoardEventsInstance = ExtensionInstance<typeof EXTENSION_ID, typeof EXTENSION_SLOTS, BoardEventsPublic>;
|
|
23
|
+
export type BoardEventsSlotRoots = ExtensionSlotSvgRoots<typeof EXTENSION_SLOTS>;
|
|
24
|
+
export interface BoardEventsInstanceInternal extends ExtensionInternal<ExtensionSlotsType> {
|
|
25
|
+
onUIMove: OnUIMoveCallback | null;
|
|
26
|
+
onRawUpdate: OnRawUpdateCallback | null;
|
|
27
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ExtensionSlotName } from '../../types/basic/mount';
|
|
2
|
+
import { ExtensionInternal } from './types';
|
|
3
|
+
export declare function extensionCreateInternalBase<TSlots extends readonly ExtensionSlotName[]>(): ExtensionInternal<TSlots>;
|
|
4
|
+
export declare function extensionIsMounted<TSlots extends readonly ExtensionSlotName[]>(state: ExtensionInternal<TSlots>): boolean;
|
|
5
|
+
export declare function extensionIsDestroyed<TSlots extends readonly ExtensionSlotName[]>(state: ExtensionInternal<TSlots>): boolean;
|
|
6
|
+
export declare function extensionMount<TSlots extends readonly ExtensionSlotName[]>(state: ExtensionInternal<TSlots>, slotRoots: NonNullable<ExtensionInternal<TSlots>['slotRoots']>): void;
|
|
7
|
+
export declare function extensionUnmount<TSlots extends readonly ExtensionSlotName[]>(state: ExtensionInternal<TSlots>): void;
|
|
8
|
+
export declare function extensionDestroy<TSlots extends readonly ExtensionSlotName[]>(state: ExtensionInternal<TSlots>): void;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import assert from '@ktarmyshov/assert';
|
|
2
|
+
import { clearElementChildren } from '../../../render/svg/helpers';
|
|
3
|
+
export function extensionCreateInternalBase() {
|
|
4
|
+
return {
|
|
5
|
+
slotRoots: null,
|
|
6
|
+
destroyed: false
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export function extensionIsMounted(state) {
|
|
10
|
+
return state.slotRoots !== null;
|
|
11
|
+
}
|
|
12
|
+
export function extensionIsDestroyed(state) {
|
|
13
|
+
return state.destroyed;
|
|
14
|
+
}
|
|
15
|
+
export function extensionMount(state, slotRoots) {
|
|
16
|
+
assert(!extensionIsMounted(state), 'Extension is already mounted');
|
|
17
|
+
assert(!extensionIsDestroyed(state), 'Extension is destroyed');
|
|
18
|
+
state.slotRoots = slotRoots;
|
|
19
|
+
}
|
|
20
|
+
export function extensionUnmount(state) {
|
|
21
|
+
assert(extensionIsMounted(state), 'Extension is not mounted');
|
|
22
|
+
for (const slotRoot of Object.values(state.slotRoots ?? {})) {
|
|
23
|
+
clearElementChildren(slotRoot);
|
|
24
|
+
}
|
|
25
|
+
state.slotRoots = null;
|
|
26
|
+
}
|
|
27
|
+
export function extensionDestroy(state) {
|
|
28
|
+
assert(!extensionIsDestroyed(state), 'Extension is already destroyed');
|
|
29
|
+
if (extensionIsMounted(state)) {
|
|
30
|
+
extensionUnmount(state);
|
|
31
|
+
}
|
|
32
|
+
state.destroyed = true;
|
|
33
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ExtensionSlotName, ExtensionSlotSvgRoots } from '../../types/basic/mount';
|
|
2
|
+
export interface ExtensionInternal<TSlots extends readonly ExtensionSlotName[]> {
|
|
3
|
+
slotRoots: ExtensionSlotSvgRoots<TSlots> | null;
|
|
4
|
+
destroyed: boolean;
|
|
5
|
+
}
|
|
6
|
+
export type AnyExtensionInternal = ExtensionInternal<readonly ExtensionSlotName[]>;
|
|
7
|
+
export interface OpaqueColor {
|
|
8
|
+
color: string;
|
|
9
|
+
opacity: number;
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|