initial
This commit is contained in:
6
.babelrc
Normal file
6
.babelrc
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
"@babel/preset-env",
|
||||||
|
"@babel/preset-typescript"
|
||||||
|
]
|
||||||
|
}
|
||||||
6
.barrelsby.json
Normal file
6
.barrelsby.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"directory": "./src",
|
||||||
|
"exclude": ["index.ts","**/stories/**"],
|
||||||
|
"delete": true,
|
||||||
|
"exportDefault": false
|
||||||
|
}
|
||||||
12
.editorconfig
Normal file
12
.editorconfig
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# This file is for unifying the coding style for different editors and IDEs.
|
||||||
|
# More information at http://EditorConfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
[{*.json,bower.json,.travis.yml}]
|
||||||
8
.eslintignore
Normal file
8
.eslintignore
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/docs/**
|
||||||
|
**/dist/**
|
||||||
|
**/lib/**
|
||||||
|
**/types/**
|
||||||
|
temp
|
||||||
|
docs
|
||||||
|
dist
|
||||||
|
node_modules
|
||||||
50
.eslintrc.json
Normal file
50
.eslintrc.json
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"extends": ["@pixi/eslint-config"],
|
||||||
|
"plugins": ["jsdoc", "no-mixed-operators"],
|
||||||
|
"settings": {
|
||||||
|
"jsdoc": {
|
||||||
|
"mode": "typescript",
|
||||||
|
"tagNamePreference": {
|
||||||
|
"method": "method",
|
||||||
|
"function": "function",
|
||||||
|
"extends": "extends",
|
||||||
|
"typeParam": "typeParam",
|
||||||
|
"api": "api"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"@typescript-eslint/no-unused-expressions": [1, {"allowShortCircuit": true, "allowTernary": true}],
|
||||||
|
"no-mixed-operators": "off",
|
||||||
|
"no-mixed-operators/no-mixed-operators": 1,
|
||||||
|
"@typescript-eslint/type-annotation-spacing": 1,
|
||||||
|
"jsdoc/multiline-blocks": [
|
||||||
|
1,
|
||||||
|
{ "noMultilineBlocks": true, "minimumLengthForMultiline": 115 }
|
||||||
|
],
|
||||||
|
"jsdoc/check-access": 1,
|
||||||
|
"jsdoc/check-alignment": 1,
|
||||||
|
"jsdoc/check-param-names": 1,
|
||||||
|
"jsdoc/check-property-names": 1,
|
||||||
|
"jsdoc/check-tag-names": 1,
|
||||||
|
"jsdoc/check-types": 1,
|
||||||
|
"jsdoc/check-values": 1,
|
||||||
|
"jsdoc/empty-tags": 1,
|
||||||
|
"jsdoc/implements-on-classes": 1,
|
||||||
|
"jsdoc/no-multi-asterisks": [1, { "allowWhitespace": true }],
|
||||||
|
"jsdoc/require-param": 1,
|
||||||
|
"jsdoc/require-param-description": 0,
|
||||||
|
"jsdoc/require-param-name": 1,
|
||||||
|
"jsdoc/require-param-type": [
|
||||||
|
"warn",
|
||||||
|
{ "contexts": ["TSMethodSignature"] }
|
||||||
|
],
|
||||||
|
"jsdoc/require-property": 1,
|
||||||
|
"jsdoc/require-property-description": 1,
|
||||||
|
"jsdoc/require-property-name": 1,
|
||||||
|
"jsdoc/require-property-type": 1,
|
||||||
|
"jsdoc/require-returns-description": 1,
|
||||||
|
"jsdoc/tag-lines": 1,
|
||||||
|
"jsdoc/valid-types": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
7
.gitattributes
vendored
Normal file
7
.gitattributes
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
*.js text eol=lf
|
||||||
|
*.ts text eol=lf
|
||||||
|
*.json text eol=lf
|
||||||
|
*.yml text eol=lf
|
||||||
|
*.md text eol=lf
|
||||||
|
*.txt text eol=lf
|
||||||
44
.gitignore
vendored
Normal file
44
.gitignore
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# sublime text files
|
||||||
|
*.sublime*
|
||||||
|
*.vscode*
|
||||||
|
*.*~*.TMP
|
||||||
|
test/lib
|
||||||
|
|
||||||
|
|
||||||
|
# temp files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
Desktop.ini
|
||||||
|
npm-debug.log
|
||||||
|
|
||||||
|
# project files
|
||||||
|
.project
|
||||||
|
|
||||||
|
# vim swap files
|
||||||
|
*.sw*
|
||||||
|
|
||||||
|
# emacs temp files
|
||||||
|
*~
|
||||||
|
\#*#
|
||||||
|
|
||||||
|
# project ignores
|
||||||
|
!.gitkeep
|
||||||
|
*__temp
|
||||||
|
node_modules
|
||||||
|
bin/
|
||||||
|
lib/
|
||||||
|
dist/
|
||||||
|
coverage/
|
||||||
|
temp
|
||||||
|
types
|
||||||
|
yarn.lock
|
||||||
|
pnpm-lock.yaml
|
||||||
|
|
||||||
|
# jetBrains IDE ignores
|
||||||
|
.idea
|
||||||
|
.vs-code
|
||||||
|
.eslintcache
|
||||||
|
docs/
|
||||||
|
example.api.json*
|
||||||
|
|
||||||
|
.npmrc
|
||||||
48
.gitlab-ci.yml
Normal file
48
.gitlab-ci.yml
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
image: node:18.18.2
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- install
|
||||||
|
- build
|
||||||
|
- deploy
|
||||||
|
|
||||||
|
variables:
|
||||||
|
NODE_ENV: 'production'
|
||||||
|
|
||||||
|
cache:
|
||||||
|
paths:
|
||||||
|
- node_modules/
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- echo "Setting up environment"
|
||||||
|
- echo "@popiplay:registry=https://gitlab.popiplay.dev/api/v4/projects/fe%2Fnpm%2Fstate-machine/packages/npm/" > .npmrc
|
||||||
|
- echo "//gitlab.popiplay.dev/api/v4/projects/fe%2Fnpm%2Fstate-machine/packages/npm/:_authToken=${CI_JOB_TOKEN}" >> .npmrc
|
||||||
|
|
||||||
|
build:
|
||||||
|
stage: build
|
||||||
|
script:
|
||||||
|
- rm -rf node_modules package-lock.json
|
||||||
|
- npm install --include=dev
|
||||||
|
- npm run build
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- lib/ # Сохраняем собранные файлы в артефакты, чтобы они были доступны на этапе deploy
|
||||||
|
|
||||||
|
publish master:
|
||||||
|
stage: deploy
|
||||||
|
script:
|
||||||
|
- git config --global user.email ${GITLAB_USER_EMAIL}
|
||||||
|
- git config --global user.name ${GITLAB_USER_LOGIN}
|
||||||
|
- npm version patch
|
||||||
|
- npm publish --access=public
|
||||||
|
only:
|
||||||
|
- master # Публиковать только при изменениях в main ветке
|
||||||
|
|
||||||
|
publish branch:
|
||||||
|
stage: deploy
|
||||||
|
script:
|
||||||
|
- git config --global user.email ${GITLAB_USER_EMAIL}
|
||||||
|
- git config --global user.name ${GITLAB_USER_LOGIN}
|
||||||
|
- npm version prerelease --preid=dev
|
||||||
|
- npm publish --access=public
|
||||||
|
except:
|
||||||
|
- master
|
||||||
22377
package-lock.json
generated
Normal file
22377
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
111
package.json
Normal file
111
package.json
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
{
|
||||||
|
"name": "@popiplay/state-machine",
|
||||||
|
"version": "1.0.5",
|
||||||
|
"description": "It is a library that contains slot machines and their components, that are extensible to allow them to be used in any project",
|
||||||
|
"homepage": "https://gitlab.popiplay.dev/fe/npm/state-machine#readme",
|
||||||
|
"bugs": "https://gitlab.popiplay.dev/fe/npm/state-machine/issues",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://gitlab.popiplay.dev/fe/npm/state-machine.git"
|
||||||
|
},
|
||||||
|
"license": "ISC",
|
||||||
|
"author": "Andrey Sharshov <andrey.sharshov@popiplay.com>",
|
||||||
|
"sideEffects": false,
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"import": "./lib/index.mjs",
|
||||||
|
"require": "./lib/index.js"
|
||||||
|
},
|
||||||
|
"./*": "./lib/*"
|
||||||
|
},
|
||||||
|
"main": "./lib/index.js",
|
||||||
|
"module": "./lib/index.mjs",
|
||||||
|
"types": "./lib/index.d.ts",
|
||||||
|
"files": [
|
||||||
|
"lib",
|
||||||
|
"dist/"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"start": "npm i && npm run storybook",
|
||||||
|
"build": "xs build",
|
||||||
|
"clean": "xs clean",
|
||||||
|
"deploy": "xs deploy",
|
||||||
|
"docs": "xs docs && npm run storybook:build",
|
||||||
|
"lint": "xs lint --max-warnings 0",
|
||||||
|
"lint:fix": "xs lint --fix",
|
||||||
|
"prepare": "husky install",
|
||||||
|
"release": "npm i && xs bump,build,docs,publish,git-push",
|
||||||
|
"serve": "xs serve",
|
||||||
|
"storybook": "storybook dev -p 6006",
|
||||||
|
"storybook:build": "storybook build --output-dir docs/storybook",
|
||||||
|
"types": "xs types",
|
||||||
|
"watch": "xs watch",
|
||||||
|
"generate-barrels": "barrelsby --directory ./src --exclude index.ts, stories --delete --exportDefault false --singleQuotes"
|
||||||
|
},
|
||||||
|
"husky": {
|
||||||
|
"hooks": {
|
||||||
|
"pre-commit": "lint-staged"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"*.{ts,js,mjs}": [
|
||||||
|
"npm run lint:fix --"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"extensionConfig": {
|
||||||
|
"lint": [
|
||||||
|
"src"
|
||||||
|
],
|
||||||
|
"docsName": "Popiplay Slot Machines",
|
||||||
|
"docsTitle": "Popiplay Slot Machines",
|
||||||
|
"docsDescription": "API Documentation for Slot Machines components made with PixiJS",
|
||||||
|
"docsKeyword": "PixiJS, SlotMachine, components"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"state",
|
||||||
|
"machine"
|
||||||
|
],
|
||||||
|
"peerDependencies": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/preset-env": "^7.26.0",
|
||||||
|
"@babel/preset-react": "^7.25.9",
|
||||||
|
"@babel/preset-typescript": "^7.26.0",
|
||||||
|
"@chromatic-com/storybook": "^3.2.1",
|
||||||
|
"@mdx-js/loader": "^3.1.0",
|
||||||
|
"@mdx-js/react": "^3.1.0",
|
||||||
|
"@pixi/extension-scripts": "^2.4.1",
|
||||||
|
"@pixi/filter-motion-blur": "^5.1.1",
|
||||||
|
"@pixi/storybook-renderer": "^1.0.0",
|
||||||
|
"@pixi/storybook-webpack5": "^1.0.0",
|
||||||
|
"@popiplay/state-machine": "^1.0.0",
|
||||||
|
"@rollup/plugin-commonjs": "^28.0.1",
|
||||||
|
"@storybook/addon-docs": "^8.4.0",
|
||||||
|
"@storybook/addon-essentials": "^8.4.0",
|
||||||
|
"@storybook/addon-interactions": "^8.4.0",
|
||||||
|
"@storybook/addon-links": "^8.4.0",
|
||||||
|
"@storybook/addon-storysource": "^8.4.0",
|
||||||
|
"@storybook/addon-webpack5-compiler-babel": "^3.0.3",
|
||||||
|
"@storybook/test": "^8.4.0",
|
||||||
|
"@storybook/types": "^8.4.0",
|
||||||
|
"@types/babel__core": "^7.20.5",
|
||||||
|
"@types/jest": "^29.5.14",
|
||||||
|
"babel-loader": "^9.2.1",
|
||||||
|
"eslint": "^8.57.1",
|
||||||
|
"eslint-plugin-jsdoc": "^50.4.3",
|
||||||
|
"eslint-plugin-no-mixed-operators": "^1.1.1",
|
||||||
|
"husky": "^9.1.6",
|
||||||
|
"jest": "^29.7.0",
|
||||||
|
"jest-raw-loader": "^1.0.1",
|
||||||
|
"lint-staged": "^15.2.10",
|
||||||
|
"pixi-spine": "^4.0.4",
|
||||||
|
"pixi.js": "^7.4.2",
|
||||||
|
"storybook": "^8.4.0",
|
||||||
|
"tsc-alias": "^1.8.10",
|
||||||
|
"typescript": "^5.7.2"
|
||||||
|
},
|
||||||
|
"publishConfig": {
|
||||||
|
"@popiplay:registry": "https://gitlab.popiplay.dev/api/v4/projects/fe%2Fnpm%2Fstate-machine/packages/npm/"
|
||||||
|
}
|
||||||
|
}
|
||||||
60
src/core/State.ts
Normal file
60
src/core/State.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* @file State.ts
|
||||||
|
* @description A base class representing a state in a state machine architecture,
|
||||||
|
* with lifecycle hooks for entering, handling input, updating, and leaving the state.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a generic state in a state machine architecture.
|
||||||
|
* Provides lifecycle hooks that can be overridden by subclasses.
|
||||||
|
*/
|
||||||
|
export default class State {
|
||||||
|
/**
|
||||||
|
* The name that uniquely identifies the state.
|
||||||
|
*/
|
||||||
|
public name: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of the State class.
|
||||||
|
* @param name - A string that uniquely identifies the state.
|
||||||
|
*/
|
||||||
|
constructor(name: string) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method called when the state is entered. Intended to set up any state-specific requirements.
|
||||||
|
* To be overridden by subclasses.
|
||||||
|
*/
|
||||||
|
public enter(): void {
|
||||||
|
console.log(`Enter ${this.name}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A hook for handling input when the state is active.
|
||||||
|
* To be overridden by subclasses.
|
||||||
|
*
|
||||||
|
* @param _input - An optional object representing user input.
|
||||||
|
*/
|
||||||
|
public handleInput(_input?: Record<string, any>): void {
|
||||||
|
// Default implementation is a no-op.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A hook for updating the state in the game loop.
|
||||||
|
* To be overridden by subclasses.
|
||||||
|
*
|
||||||
|
* @param _dt - The time elapsed since the last update, in milliseconds.
|
||||||
|
*/
|
||||||
|
public update(_dt: number): void {
|
||||||
|
// Default implementation is a no-op.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method called when the state is exited. Intended to perform cleanup or reset activities.
|
||||||
|
* To be overridden by subclasses.
|
||||||
|
*/
|
||||||
|
public leave(): void {
|
||||||
|
console.log(`Leave ${this.name}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
83
src/core/StateMachine.ts
Normal file
83
src/core/StateMachine.ts
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/**
|
||||||
|
* @file StateMachine.ts
|
||||||
|
* @description A simple state machine implementation for managing state transitions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import State from './State';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a state machine for managing state transitions.
|
||||||
|
* @template T The type of the controlled object or entity.
|
||||||
|
*/
|
||||||
|
export default class StateMachine<T, S extends State = State> {
|
||||||
|
/**
|
||||||
|
* The controlled object or entity.
|
||||||
|
*/
|
||||||
|
public target: T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of states managed by the state machine.
|
||||||
|
*/
|
||||||
|
public states: S[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current active state.
|
||||||
|
*/
|
||||||
|
public currentState: S | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new StateMachine instance.
|
||||||
|
* @param target - The controlled object or entity.
|
||||||
|
*/
|
||||||
|
constructor(target: T) {
|
||||||
|
this.target = target;
|
||||||
|
this.states = [new State("Entry")] as S[];
|
||||||
|
this.currentState = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a list of states to the state machine.
|
||||||
|
* @param states - An array of states to manage.
|
||||||
|
*/
|
||||||
|
public provideStates(states: S[]): void {
|
||||||
|
this.states = states;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transitions the state machine to a specific state by its index in the states array.
|
||||||
|
* @param stateIndex - The index of the state to transition to.
|
||||||
|
* @throws If the index is out of bounds.
|
||||||
|
*/
|
||||||
|
public setState(stateIndex: number): void {
|
||||||
|
if (stateIndex < 0 || stateIndex >= this.states.length) {
|
||||||
|
throw new Error(`State index ${stateIndex} is out of bounds.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.currentState) {
|
||||||
|
this.currentState.leave();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.currentState = this.states[stateIndex];
|
||||||
|
this.currentState.enter();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the current state of the state machine.
|
||||||
|
* @param dt - The time elapsed since the last update in milliseconds.
|
||||||
|
*/
|
||||||
|
public update(dt: number): void {
|
||||||
|
if (this.currentState) {
|
||||||
|
this.currentState.update(dt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles user input and delegates it to the current state.
|
||||||
|
* @param input - An object representing user input.
|
||||||
|
*/
|
||||||
|
public handleInput(input: Record<string, any>): void {
|
||||||
|
if (this.currentState) {
|
||||||
|
this.currentState.handleInput(input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
4
src/index.ts
Normal file
4
src/index.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export { default as StateMachine } from "./core/StateMachine";
|
||||||
|
export * from "./core/StateMachine";
|
||||||
|
export { default as State } from "./core/State";
|
||||||
|
export * from "./core/State";
|
||||||
32
tsconfig.json
Normal file
32
tsconfig.json
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"lib": ["ESNext", "DOM", "ScriptHost"],
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"allowJs": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"sourceMap": false,
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true,
|
||||||
|
"declarationDir": "./lib",
|
||||||
|
"outDir": "./lib",
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"strictNullChecks": false,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"noImplicitOverride": true,
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"baseUrl": "./",
|
||||||
|
"paths": {
|
||||||
|
"src/*": ["src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["./src", "./typings", "./test", "./docs-source"]
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user