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