Compare commits
No commits in common. "main" and "v2.0.3" have entirely different histories.
16 changed files with 50 additions and 496 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -4,7 +4,3 @@ node_modules/
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
|
||||||
dist/
|
dist/
|
||||||
|
|
||||||
# direnv
|
|
||||||
.envrc
|
|
||||||
.direnv/
|
|
||||||
|
|
6
.vim/coc-settings.json
Normal file
6
.vim/coc-settings.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"deno.enable": true,
|
||||||
|
"deno.lint": true,
|
||||||
|
"deno.unstable": false,
|
||||||
|
"tsserver.enable": false
|
||||||
|
}
|
58
Makefile
58
Makefile
|
@ -1,58 +0,0 @@
|
||||||
DENO := deno
|
|
||||||
COV := $(DENO) coverage cov_profile
|
|
||||||
FMT := $(DENO) fmt *.ts examples/*.ts
|
|
||||||
NPM_PUB := npm publish
|
|
||||||
|
|
||||||
D2 := wd2
|
|
||||||
DIAGRAMS := \
|
|
||||||
turnstile \
|
|
||||||
project
|
|
||||||
|
|
||||||
dev: fmt tests cov
|
|
||||||
|
|
||||||
ci: fmt-check tests-cov
|
|
||||||
|
|
||||||
tests: clean
|
|
||||||
$(DENO) test --coverage=cov_profile *.test.ts
|
|
||||||
|
|
||||||
tests-cov: tests
|
|
||||||
$(COV) --lcov > cov_profile/cov.lcov
|
|
||||||
|
|
||||||
cov:
|
|
||||||
$(COV)
|
|
||||||
|
|
||||||
fmt:
|
|
||||||
$(FMT)
|
|
||||||
|
|
||||||
fmt-check:
|
|
||||||
$(FMT) --check
|
|
||||||
|
|
||||||
build: clean | $(DIAGRAMS)
|
|
||||||
tsc && tsc -p tsconfig.cjs.json
|
|
||||||
|
|
||||||
clean:
|
|
||||||
@echo clean test coverage data
|
|
||||||
rm -rf cov_profile
|
|
||||||
@echo clean build target
|
|
||||||
rm -rf dist
|
|
||||||
@echo clean diagrams
|
|
||||||
rm -rf assets/*.svg
|
|
||||||
|
|
||||||
define d2rule
|
|
||||||
$(1)_args := $(D2) $$($(1)_theme_args) assets/$(1).d2 assets/$(1).svg
|
|
||||||
|
|
||||||
$(1): ; $$($(1)_args)
|
|
||||||
$(1)-w: ; $$($(1)_args) -w
|
|
||||||
endef
|
|
||||||
|
|
||||||
$(foreach d2name,$(DIAGRAMS),$(eval $(call d2rule,$(d2name))))
|
|
||||||
|
|
||||||
dry-pub:
|
|
||||||
$(NPM_PUB) --dry-run
|
|
||||||
|
|
||||||
pub:
|
|
||||||
$(NPM_PUB)
|
|
||||||
|
|
||||||
help:
|
|
||||||
cat Makefile
|
|
||||||
|
|
11
README.md
11
README.md
|
@ -26,23 +26,28 @@ const sm = new StateMachineBuilder()
|
||||||
.build(locked);
|
.build(locked);
|
||||||
```
|
```
|
||||||
|
|
||||||
You can find more examples [here](./examples/README.md)
|
You can find the full example in the [examples](./examples/) folder.
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
## Deno
|
## Deno
|
||||||
|
|
||||||
if you use the [Deno](https://deno.land), just add the following to your
|
if you use the [Deno](https://deno.land), just add following to your
|
||||||
`import_map.json`
|
`import_map.json`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"imports": {
|
"imports": {
|
||||||
"it-fsm": "https://git.pleshevski.ru/pleshevskiy/it-fsm/raw/tag/v2.0.3/fsm.ts"
|
"it-fsm": "https://git.pleshevski.ru/pleshevskiy/it-fsm/src/commit/e3796c92639e3483a2a2a01a89912561561e796f/fsm.ts"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
or you can use branch instead
|
||||||
|
`https://git.pleshevski.ru/pleshevskiy/paren/raw/branch/main/`
|
||||||
|
|
||||||
|
> **Note**: I recommend to use a specific commit instead of branch
|
||||||
|
|
||||||
## Node.js
|
## Node.js
|
||||||
|
|
||||||
If you use the Node.js or in a browser as ES module, you may need to install it
|
If you use the Node.js or in a browser as ES module, you may need to install it
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
# port: 43333
|
|
||||||
# layout: dagre
|
|
||||||
# theme: 101
|
|
||||||
# pad: 0
|
|
||||||
# sketch: true
|
|
||||||
|
|
||||||
direction: right
|
|
||||||
|
|
||||||
Project: {
|
|
||||||
pen: Pending {
|
|
||||||
shape: circle
|
|
||||||
width: 110
|
|
||||||
}
|
|
||||||
act: Active {
|
|
||||||
shape: circle
|
|
||||||
style.fill: "#9ae49a"
|
|
||||||
width: 110
|
|
||||||
}
|
|
||||||
com: Completed {
|
|
||||||
shape: circle
|
|
||||||
style.fill: "#eaea7e"
|
|
||||||
width: 110
|
|
||||||
}
|
|
||||||
arc: Archived {
|
|
||||||
shape: circle
|
|
||||||
style.fill: "#ff7e7e"
|
|
||||||
width: 110
|
|
||||||
}
|
|
||||||
|
|
||||||
pen -> act: Activate
|
|
||||||
pen -> arc: Archive
|
|
||||||
|
|
||||||
act -> com: Complete
|
|
||||||
|
|
||||||
arc -> pen: Restore
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 313 KiB |
|
@ -1,26 +0,0 @@
|
||||||
# port: 43334
|
|
||||||
# layout: elk
|
|
||||||
# theme: 101
|
|
||||||
# pad: 0
|
|
||||||
# sketch: true
|
|
||||||
|
|
||||||
direction: right
|
|
||||||
|
|
||||||
Turnstile: {
|
|
||||||
l: Locked {
|
|
||||||
shape: circle
|
|
||||||
style.fill: "#fd7373"
|
|
||||||
width: 110
|
|
||||||
}
|
|
||||||
u: Unlocked {
|
|
||||||
shape: circle
|
|
||||||
style.fill: "#59c061"
|
|
||||||
width: 110
|
|
||||||
}
|
|
||||||
|
|
||||||
l -> l: push
|
|
||||||
u -> l: push
|
|
||||||
|
|
||||||
l -> u: coin
|
|
||||||
u -> u: coin
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 307 KiB |
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"version": "2",
|
|
||||||
"remote": {
|
|
||||||
"https://deno.land/std@0.165.0/fmt/colors.ts": "9e36a716611dcd2e4865adea9c4bec916b5c60caad4cdcdc630d4974e6bb8bd4",
|
|
||||||
"https://deno.land/std@0.165.0/testing/_diff.ts": "a23e7fc2b4d8daa3e158fa06856bedf5334ce2a2831e8bf9e509717f455adb2c",
|
|
||||||
"https://deno.land/std@0.165.0/testing/_format.ts": "cd11136e1797791045e639e9f0f4640d5b4166148796cad37e6ef75f7d7f3832",
|
|
||||||
"https://deno.land/std@0.165.0/testing/asserts.ts": "1e340c589853e82e0807629ba31a43c84ebdcdeca910c4a9705715dfdb0f5ce8"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
# Examples
|
|
||||||
|
|
||||||
## Turnstile
|
|
||||||
|
|
||||||
An example of a simple mechanism that can be modeled by a state machine is a
|
|
||||||
turnstile. A turnstile, used to control access to subways and amusement park
|
|
||||||
rides, is a gate with three rotating arms at waist height, one across the
|
|
||||||
entryway. Initially the arms are locked, blocking the entry, preventing patrons
|
|
||||||
from passing through. Depositing a coin or token in a slot on the turnstile
|
|
||||||
unlocks the arms, allowing a single customer to push through. After the customer
|
|
||||||
passes through, the arms are locked again until another coin is inserted.
|
|
||||||
|
|
||||||
![Turnstile diagram](https://git.pleshevski.ru/pleshevskiy/it-fsm/raw/branch/main/assets/turnstile.svg)
|
|
||||||
|
|
||||||
```sh
|
|
||||||
deno run ./examples/turnstile.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
## Project
|
|
||||||
|
|
||||||
This is more complex example illustrate all features of this library
|
|
||||||
|
|
||||||
![Project diagram](https://git.pleshevski.ru/pleshevskiy/it-fsm/raw/branch/main/assets/project.svg)
|
|
||||||
|
|
||||||
```sh
|
|
||||||
deno run ./examples/project.ts
|
|
||||||
```
|
|
|
@ -35,7 +35,6 @@ const smbProject = new StateMachineBuilder<
|
||||||
.withTransitions([
|
.withTransitions([
|
||||||
[ProjectStatus.Pending, [ProjectStatus.Active, ProjectStatus.Archived]],
|
[ProjectStatus.Pending, [ProjectStatus.Active, ProjectStatus.Archived]],
|
||||||
[ProjectStatus.Active, [ProjectStatus.Completed]],
|
[ProjectStatus.Active, [ProjectStatus.Completed]],
|
||||||
[ProjectStatus.Archived, [ProjectStatus.Pending]],
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
141
flake.lock
141
flake.lock
|
@ -1,141 +0,0 @@
|
||||||
{
|
|
||||||
"nodes": {
|
|
||||||
"flake-utils": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1676283394,
|
|
||||||
"narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "3db36a8b464d0c4532ba1c7dda728f4576d6d073",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-utils_2": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1676283394,
|
|
||||||
"narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "3db36a8b464d0c4532ba1c7dda728f4576d6d073",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-utils_3": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1667395993,
|
|
||||||
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1676518424,
|
|
||||||
"narHash": "sha256-OsJSBwl9Hayh/bmxDtUyxm2U6btaBHuLvviE9KpMmwQ=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "a592a97fcedae7a06b8506623b25fd38a032ad13",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"ref": "nixpkgs-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_2": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1676518424,
|
|
||||||
"narHash": "sha256-OsJSBwl9Hayh/bmxDtUyxm2U6btaBHuLvviE9KpMmwQ=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "a592a97fcedae7a06b8506623b25fd38a032ad13",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"id": "nixpkgs",
|
|
||||||
"type": "indirect"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_3": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1669261230,
|
|
||||||
"narHash": "sha256-AjddxRPd5y5jge77281P3O8+Cnafj842Xg59rwV4x+0=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "8e8b5f3b1e899bf5d250279578c0283705b8cdb4",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"id": "nixpkgs",
|
|
||||||
"type": "indirect"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-utils": "flake-utils",
|
|
||||||
"nixpkgs": "nixpkgs",
|
|
||||||
"wd2": "wd2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tools": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-utils": "flake-utils_3",
|
|
||||||
"nixpkgs": "nixpkgs_3"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1676488781,
|
|
||||||
"narHash": "sha256-lP2UWGwangM1OSBOx0EFXOtnSBuyTJn3yza3Ujb9/C8=",
|
|
||||||
"ref": "refs/heads/main",
|
|
||||||
"rev": "5f07d4e256c1d8caefd52563737b1e3c023b5d35",
|
|
||||||
"revCount": 21,
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://git.pleshevski.ru/mynix/tools"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://git.pleshevski.ru/mynix/tools"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"wd2": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-utils": "flake-utils_2",
|
|
||||||
"nixpkgs": "nixpkgs_2",
|
|
||||||
"tools": "tools"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1676583860,
|
|
||||||
"narHash": "sha256-LuGEJMECOtqFJHw65ErtEDa7MnF5e+QmiGO583ZK9BE=",
|
|
||||||
"ref": "refs/heads/main",
|
|
||||||
"rev": "1e05739a5e39b982e3670997a3845ab9741f4ca1",
|
|
||||||
"revCount": 13,
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://git.pleshevski.ru/pleshevskiy/wd2"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://git.pleshevski.ru/pleshevskiy/wd2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": "root",
|
|
||||||
"version": 7
|
|
||||||
}
|
|
24
flake.nix
24
flake.nix
|
@ -1,24 +0,0 @@
|
||||||
{
|
|
||||||
inputs = {
|
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
|
||||||
wd2.url = "git+https://git.pleshevski.ru/pleshevskiy/wd2";
|
|
||||||
};
|
|
||||||
|
|
||||||
outputs = { self, nixpkgs, flake-utils, wd2, ... }:
|
|
||||||
flake-utils.lib.eachDefaultSystem (system:
|
|
||||||
let
|
|
||||||
pkgs = import nixpkgs { inherit system; };
|
|
||||||
in
|
|
||||||
{
|
|
||||||
devShells.default = pkgs.mkShell {
|
|
||||||
packages = with pkgs; [
|
|
||||||
d2 # to format .d2 files
|
|
||||||
wd2.packages.${system}.default
|
|
||||||
deno
|
|
||||||
nodejs-18_x
|
|
||||||
nodePackages.typescript
|
|
||||||
];
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -17,9 +17,9 @@
|
||||||
|
|
||||||
import {
|
import {
|
||||||
assertEquals,
|
assertEquals,
|
||||||
assertRejects,
|
|
||||||
assertThrows,
|
assertThrows,
|
||||||
} from "https://deno.land/std@0.165.0/testing/asserts.ts";
|
assertThrowsAsync,
|
||||||
|
} from "https://deno.land/std@0.105.0/testing/asserts.ts";
|
||||||
import * as fsm from "./fsm.ts";
|
import * as fsm from "./fsm.ts";
|
||||||
|
|
||||||
enum ProjectStatus {
|
enum ProjectStatus {
|
||||||
|
@ -168,7 +168,7 @@ Deno.test("should throw error if transition to the state doesn't exist", () => {
|
||||||
const sm = new fsm.StateMachineBuilder()
|
const sm = new fsm.StateMachineBuilder()
|
||||||
.withStates(Object.values(ProjectStatus))
|
.withStates(Object.values(ProjectStatus))
|
||||||
.build(ProjectStatus.Pending);
|
.build(ProjectStatus.Pending);
|
||||||
assertRejects(
|
assertThrowsAsync(
|
||||||
() => sm.tryChangeState(ProjectStatus.Active, null),
|
() => sm.tryChangeState(ProjectStatus.Active, null),
|
||||||
fsm.FsmError,
|
fsm.FsmError,
|
||||||
`cannot change state from "${ProjectStatus.Pending}" to "${ProjectStatus.Active}"`,
|
`cannot change state from "${ProjectStatus.Pending}" to "${ProjectStatus.Active}"`,
|
||||||
|
@ -195,7 +195,7 @@ Deno.test("should throw error if beforeExit action returns false", () => {
|
||||||
[ProjectStatus.Pending, [ProjectStatus.Active]],
|
[ProjectStatus.Pending, [ProjectStatus.Active]],
|
||||||
])
|
])
|
||||||
.build(ProjectStatus.Pending);
|
.build(ProjectStatus.Pending);
|
||||||
assertRejects(
|
assertThrowsAsync(
|
||||||
() => sm.tryChangeState(ProjectStatus.Active, null),
|
() => sm.tryChangeState(ProjectStatus.Active, null),
|
||||||
fsm.FsmError,
|
fsm.FsmError,
|
||||||
`cannot change state from "${ProjectStatus.Pending}" to "${ProjectStatus.Active}"`,
|
`cannot change state from "${ProjectStatus.Pending}" to "${ProjectStatus.Active}"`,
|
||||||
|
|
25
makefile
Normal file
25
makefile
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
DENO := deno
|
||||||
|
COV := $(DENO) coverage cov_profile
|
||||||
|
FMT := $(DENO) fmt *.ts examples/*.ts
|
||||||
|
|
||||||
|
dev: fmt tests cov
|
||||||
|
|
||||||
|
ci: fmt-check tests-cov
|
||||||
|
|
||||||
|
tests: clean
|
||||||
|
$(DENO) test --coverage=cov_profile *.test.ts
|
||||||
|
|
||||||
|
tests-cov: tests
|
||||||
|
$(COV) --lcov > cov_profile/cov.lcov
|
||||||
|
|
||||||
|
cov:
|
||||||
|
$(COV)
|
||||||
|
|
||||||
|
fmt:
|
||||||
|
$(FMT)
|
||||||
|
|
||||||
|
fmt-check:
|
||||||
|
$(FMT) --check
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf cov_profile dist
|
|
@ -4,7 +4,10 @@
|
||||||
"description": "Simple finite state machine for nodejs",
|
"description": "Simple finite state machine for nodejs",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepublishOnly": "make build"
|
"build": "tsc && tsc -p tsconfig.cjs.json",
|
||||||
|
"check": "tsc --noEmit && tsc -p tsconfig.cjs.json --noEmit",
|
||||||
|
"clean": "rm -rf ./dist",
|
||||||
|
"prepublishOnly": "npm run clean && npm run build"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -25,6 +28,9 @@
|
||||||
"url": "https://github.com/pleshevskiy/it-fsm/issues"
|
"url": "https://github.com/pleshevskiy/it-fsm/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://git.pleshevski.ru/pleshevskiy/it-fsm#readme",
|
"homepage": "https://git.pleshevski.ru/pleshevskiy/it-fsm#readme",
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^4.9.3"
|
||||||
|
},
|
||||||
"main": "./dist/cjs/fsm.js",
|
"main": "./dist/cjs/fsm.js",
|
||||||
"module": "./dist/esm/fsm.js",
|
"module": "./dist/esm/fsm.js",
|
||||||
"types": "./dist/esm/fsm.d.ts",
|
"types": "./dist/esm/fsm.d.ts",
|
||||||
|
|
Loading…
Reference in a new issue