├── .github └── workflows │ └── npm_publish.yml ├── .gitignore ├── .npmignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── esbuild.js ├── index.d.ts ├── jsconfig.json ├── package-lock.json ├── package.json ├── src ├── lib │ ├── flags.js │ ├── machines.js │ └── utils.js └── svate.js └── test ├── public └── index.html └── src ├── App.svelte ├── EndlessMachine.svelte ├── Flag.svelte ├── Flagset.svelte ├── Machine.svelte └── app.js /.github/workflows/npm_publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish on NPM 2 | 3 | on: 4 | push: 5 | paths: 6 | - 'package.json' 7 | 8 | jobs: 9 | publish-npm: 10 | name: Publishing on NPM 11 | runs-on: ubuntu-18.04 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: Setup Node 15 | uses: actions/setup-node@v2 16 | with: 17 | node-version: 15 18 | registry-url: https://registry.npmjs.org/ 19 | - name: Installing NPM deps 20 | run: npm install 21 | - name: Build modules 22 | run: npm run build 23 | - name: Publishing on NPM 24 | run: npm publish 25 | env: 26 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | test/public/bundle.* -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | src 3 | test 4 | esbuild.js 5 | jsconfig.json -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.1.4 - 2021-03-21 4 | 5 | ### Documentation 6 | 7 | - Fix terms in readme [`f2bbaec8`](https://github.com/AlexxNB/svate/commit/f2bbaec8f6c472e1a4db1e0d30767683fad80165) 8 | - Update changelog [`b791e897`](https://github.com/AlexxNB/svate/commit/b791e897e9141089fc5b301559cb052a4b8e261b) 9 | 10 | ## 0.1.3 - 2021-03-21 11 | 12 | ### Documentation 13 | 14 | - Update changelog [`de78636e`](https://github.com/AlexxNB/svate/commit/de78636e37cfbfe72a38410b94287c66bd0d0f46) 15 | 16 | ## 0.1.2 - 2021-03-20 17 | 18 | ### Features 19 | 20 | - 🏷️ Add types definition [`a7923fdd`](https://github.com/AlexxNB/svate/commit/a7923fddc5d19931fd352fa70693e94fed49d559) 21 | 22 | ### Documentation 23 | 24 | - Update changelog [`7ddd7721`](https://github.com/AlexxNB/svate/commit/7ddd7721dba01471edbd313c4bcad0644bf7504e) 25 | 26 | ## 0.1.1 - 2021-03-19 27 | 28 | ### Documentation 29 | 30 | - ✏️ Fix typos [`8f1493cd`](https://github.com/AlexxNB/svate/commit/8f1493cd445672e239132017ba1c985f090c4ce8) 31 | - Update changelog [`13478eb9`](https://github.com/AlexxNB/svate/commit/13478eb975f27b81cffad94d47f84ed1135104ab) 32 | 33 | ## 0.1.0 - 2021-03-19 34 | 35 | ### Features 36 | 37 | - Add set method to set value for all flags [`c6964fc7`](https://github.com/AlexxNB/svate/commit/c6964fc76232bc3db8d29cb53ad5d4371419fd7b) 38 | - Initial commit [`f3f9a602`](https://github.com/AlexxNB/svate/commit/f3f9a602e364e360bef10ebfc8494eecd75d12e3) 39 | 40 | ### Documentation 41 | 42 | - 📝 Add readme [`251d87d2`](https://github.com/AlexxNB/svate/commit/251d87d24609f0a580c8f8b4647c1603e7efe3b8) 43 | 44 | ### Other 45 | 46 | - Initial commit [`15749e18`](https://github.com/AlexxNB/svate/commit/15749e18dd85ed8f0e4af7fe634dc0e0b3b805db) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Alexey Schebelev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # svate 2 | 3 | Set of state machines for Svelte applications based on internal Svelte's store. 4 | 5 | ## Content 6 | 7 | Set includes four types of state machines: 8 | 9 | * `machine` - simple state machine 10 | * `endlessMachine` - same as `machine` but can move through list's edges 11 | * `flag` - simple flag 12 | * `flagset` - set of flags 13 | 14 | ## State machines 15 | 16 | You can use one of `machine` or `endlessMachine`, which are very similar. They allows to choose state from the list of ones. Only the difference is that `machine` doesn't allow to move through edges of the list. For example, calling `myMachine.next()` when current state is last in list will do nothing. But in case of `endlessMachine` state will change to the one from start of the list. 17 | 18 | ```html 19 | 24 | 25 | This is page {$pages}. 26 | 27 | {#if $isLast}It is last page!{/if} 28 | 29 | 30 | 31 | 32 | ``` 33 | ### machine initializing 34 | 35 | `machine(list,[initial]) | endlessMachine(list,[initial])` – parameter `list` is an array of states. Each element may be any type. The `initial` is a value from the list which will be used as initial state, default is first element of the list. 36 | 37 | ### machine API 38 | 39 | * `subscribe()` – Svelte store subscription function. Returns current state in its callback. 40 | * `next()` – switch to the next state 41 | * `back()` – switch to the previous state 42 | * `first()` – switch to the first state 43 | * `last()` – switch to the last state 44 | * `set(state)` – switch to the state with name `state` 45 | * `index(num)` – switch to the state with index `num`. Index starts from 0. 46 | * `states` – array of the states, same as initial one. 47 | * `current` – returns current state. 48 | * `isFirst` – returns Svelte's store which will give `true` when state will be first in the list or `false` in other cases. 49 | * `isLast` – returns Svelte's store which will give `true` when state will be last in the list or `false` in other cases. 50 | 51 | ## Flag 52 | 53 | Simple Svelte store which has a state `true` or `false`; 54 | 55 | ```html 56 | 59 | 60 | Flag is {$myflag ? 'on' : 'off'}! 61 | 62 | 63 | 64 | 65 | ``` 66 | ### flag initializing 67 | 68 | `flag(initial)` – parameter `initial` is set default state for the flag. 69 | 70 | ### flag API 71 | 72 | * `subscribe()` – Svelte store subscription function. Returns current flag's state in its callback. 73 | * `on()` – set state to `true` value. 74 | * `off()` – set state to `false` value. 75 | * `toggle()` – toggle state value from `false` to `true` or vise versa. 76 | * `set(state)` – set state to the provided `state` value. 77 | * `lock()` – lock the flag. Any method will not be able to change the flag's state. 78 | * `unlock()` – unlock a locked flag. 79 | * `state` – returns current state of the flag. 80 | * `locked` – returns Svelte's store which will give `true` when flag is locked or `false` in other case. 81 | 82 | ## Flagset 83 | 84 | Set of flags in one Svelte's store. 85 | 86 | ```html 87 | 94 | 95 | Flag X is {$myflags.x ? 'on' : 'off'} 96 | Flag Y is {$myflags.y ? 'on' : 'off'} 97 | Flag Z is {$myflags.z ? 'on' : 'off'} 98 | 99 | 100 | 101 | 102 | ``` 103 | 104 | ### flagset initializing 105 | 106 | `flagset(initial)` – parameter `initial` is an object with names and initial states. 107 | 108 | ### flagset API 109 | 110 | * `subscribe()` – Svelte store subscription function. Returns current state of all flags in its callback. 111 | * `[name]` – methods to manipulate with flag `name`: 112 | - `on()` – set state of the flag to `true` value. 113 | - `off()` – set state of the flag to `false` value. 114 | - `toggle()` – toggle state value from `false` to `true` or vise versa. 115 | - `set(state)` – set state to the provided `state` value. 116 | - `state` – returns current state of the flag. 117 | * `set`|`$` – methods to use with whole flagset: 118 | - `on()` – set state of all flags to `true` value. 119 | - `off()` – set state of all flags to `false` value. 120 | - `toggle()` – toggle state of all flags. 121 | - `reset()` – set initial state for each flag. 122 | - `set(state)` – set state of all flags to the provided `state` value. 123 | - `lock()` – lock the flagset. Any method will not be able to change the any flag in the set. 124 | - `unlock()` – unlock a locked flagset. 125 | - `locked` – returns Svelte's store which will give `true` when flagset is locked or `false` in other case. 126 | - `list` – returns array of flag's names. -------------------------------------------------------------------------------- /esbuild.js: -------------------------------------------------------------------------------- 1 | const {build} = require(`esbuild`); 2 | const { derver } = require("derver"); 3 | const sveltePlugin = require(`esbuild-svelte`); 4 | const pkg = require(`./package.json`); 5 | 6 | const DEV = process.argv.includes('--dev'); 7 | 8 | const SRC = 'src/svate.js'; 9 | 10 | const svelte = sveltePlugin({ 11 | compileOptions:{ 12 | css: true 13 | } 14 | }); 15 | 16 | // Build IIFE-module 17 | !DEV && build({ 18 | entryPoints: [SRC], 19 | outfile: pkg.cdn, 20 | format: 'iife', 21 | bundle: true, 22 | minify: true, 23 | sourcemap: true, 24 | plugins: [svelte], 25 | globalName: 'svate' 26 | }) 27 | 28 | // Build ES-module 29 | build({ 30 | entryPoints: [SRC], 31 | outfile: pkg.module, 32 | format: 'esm', 33 | bundle: true, 34 | minify: !DEV, 35 | sourcemap: true, 36 | incremental: DEV, 37 | external: [ 38 | ...Object.keys(pkg.dependencies||{}), 39 | ...Object.keys(pkg.peerDependencies||{}), 40 | ] 41 | }).then( bundle_module => { 42 | DEV && build({ 43 | entryPoints: ['test/src/app.js'], 44 | outfile: 'test/public/bundle.js', 45 | format: 'iife', 46 | bundle: true, 47 | minify: true, 48 | sourcemap: 'inline', 49 | incremental: true, 50 | plugins: [svelte] 51 | }).then( bundle_app =>{ 52 | derver({ 53 | dir: 'test/public', 54 | watch:['test/public','test/src','src'], 55 | onwatch: async (lr,item)=>{ 56 | if(item == 'src'){ 57 | lr.prevent(); 58 | await bundle_module.rebuild().catch(err => lr.error(err.message,'Module compile error')); 59 | await bundle_app.rebuild().catch(err => lr.error(err.message,'Test app compile error')); 60 | } 61 | if(item == 'test/src'){ 62 | lr.prevent(); 63 | await bundle_app.rebuild().catch(err => lr.error(err.message,'Test app compile error')); 64 | } 65 | } 66 | }) 67 | }) 68 | }) -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | interface BoolStore{ 2 | subscribe(handler: (state: bool) => void) 3 | } 4 | 5 | interface StateMachine { 6 | /** Svelte store subscription function. Returns current state in its callback. */ 7 | subscribe(handler: (state: any) => void) 8 | /** Switch to the next state */ 9 | next(): void 10 | /** Switch to the previous state */ 11 | back(): void 12 | /** Switch to the first state */ 13 | first(): void 14 | /** Switch to the last state */ 15 | last(): void 16 | /** Switch to the state with specified value */ 17 | set(value:any): void 18 | /** Switch to the state by specified index, which starts from 0. */ 19 | index(index:number): void 20 | /** Array of the states */ 21 | states: any[] 22 | /** Current state */ 23 | current: any 24 | /** Svelte's store which will give `true` when state will be first in the list or `false` in other cases. */ 25 | isFirst: BoolStore 26 | /** Svelte's store which will give `true` when state will be last in the list or `false` in other cases. */ 27 | isLast: BoolStore 28 | } 29 | 30 | interface Flag { 31 | /** Svelte store subscription function. Returns current flag's state in its callback. */ 32 | subscribe(handler: (state: boolean) => void) 33 | /** Set state to `true` value */ 34 | on(): void 35 | /** Set state to `false` value */ 36 | off(): void 37 | /** Toggle state value from `false` to `true` or vise versa */ 38 | toggle(): void 39 | /** Set state to the provided `state` value */ 40 | set(value:boolean): void 41 | /** Lock the flag. Any method will not be able to change the flag's state. */ 42 | lock(): void 43 | /** Unlock a locked flag */ 44 | unlock(): void 45 | /** Current state of the flag */ 46 | state: boolean 47 | /** Svelte's store which will give `true` when flag is locked or `false` in other case */ 48 | locked: BoolStore 49 | } 50 | 51 | interface FlagsetFlag { 52 | /** Set state to `true` value */ 53 | on(): void 54 | /** Set state to `false` value */ 55 | off(): void 56 | /** Toggle state value from `false` to `true` or vise versa */ 57 | toggle(): void 58 | /** Set state to the provided `state` value */ 59 | set(value:boolean): void 60 | /** Current state of the flag */ 61 | state: boolean 62 | } 63 | 64 | interface Flagset { 65 | /** Svelte store subscription function. Returns current state of all flags in its callback. */ 66 | subscribe(handler: (state: boolean) => void) 67 | /** Methods to manipulate flag */ 68 | flag: Record 69 | /** Set state of all flags to `true` value */ 70 | on():void 71 | /** Set state of all flags to `false` value */ 72 | off():void 73 | /** Toggle state of all flags */ 74 | toggle():void 75 | /** Revert to initial state for each flag */ 76 | reset():void 77 | /** Set state of all flags to the provided `state` value */ 78 | set(value:boolean):void 79 | /** Lock the flagset. Any method will not be able to change the any flag in the set. */ 80 | lock():void 81 | /** Unlock a locked flagset */ 82 | unlock():void 83 | /** Svelte's store which will give `true` when flagset is locked or `false` in other case */ 84 | locked: BoolStore 85 | /** Array of flag's names */ 86 | list:string[] 87 | } 88 | 89 | /** Create finite state machine */ 90 | export function machine(states:any[]): StateMachine 91 | /** Create infinite state machine */ 92 | export function endlessMachine(states:any[]): StateMachine 93 | /** Create simple flag */ 94 | export function flag(initial:boolean): Flag 95 | /** Create set of flags */ 96 | export function flagset(initial:Record): Flagset -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "baseURL":".", 3 | "compilerOptions": { 4 | "paths": { 5 | "@svate": ["./dist/svate.js"], 6 | "@lib/*": ["./src/lib/*"] 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svate", 3 | "version": "0.1.6", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "svate", 9 | "version": "0.1.6", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "derver": "^0.4.19", 13 | "esbuild": "^0.13.3", 14 | "esbuild-svelte": "^0.5.6", 15 | "svelte": "^3.43.0" 16 | }, 17 | "peerDependencies": { 18 | "svelte": "3.x" 19 | } 20 | }, 21 | "node_modules/derver": { 22 | "version": "0.4.19", 23 | "resolved": "https://registry.npmjs.org/derver/-/derver-0.4.19.tgz", 24 | "integrity": "sha512-qDxXQd+qqOthqx1R1xr6K/C4kB6CT6H5yR4zJqyleo6BNJWqiSOFdsNNL5oFXMK6/5QPihrzTUsaYiDbMSNt1g==", 25 | "dev": true, 26 | "bin": { 27 | "derver": "bin/derver" 28 | } 29 | }, 30 | "node_modules/esbuild": { 31 | "version": "0.13.3", 32 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.13.3.tgz", 33 | "integrity": "sha512-98xovMLKnyhv3gcReUuAEi5Ig1rK6SIgvsJuBIcfwzqGSEHsV8UJjMlmkhHoHMf9XZybMpE9Zax8AA8f7i2hlQ==", 34 | "dev": true, 35 | "hasInstallScript": true, 36 | "bin": { 37 | "esbuild": "bin/esbuild" 38 | }, 39 | "optionalDependencies": { 40 | "esbuild-android-arm64": "0.13.3", 41 | "esbuild-darwin-64": "0.13.3", 42 | "esbuild-darwin-arm64": "0.13.3", 43 | "esbuild-freebsd-64": "0.13.3", 44 | "esbuild-freebsd-arm64": "0.13.3", 45 | "esbuild-linux-32": "0.13.3", 46 | "esbuild-linux-64": "0.13.3", 47 | "esbuild-linux-arm": "0.13.3", 48 | "esbuild-linux-arm64": "0.13.3", 49 | "esbuild-linux-mips64le": "0.13.3", 50 | "esbuild-linux-ppc64le": "0.13.3", 51 | "esbuild-openbsd-64": "0.13.3", 52 | "esbuild-sunos-64": "0.13.3", 53 | "esbuild-windows-32": "0.13.3", 54 | "esbuild-windows-64": "0.13.3", 55 | "esbuild-windows-arm64": "0.13.3" 56 | } 57 | }, 58 | "node_modules/esbuild-android-arm64": { 59 | "version": "0.13.3", 60 | "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.13.3.tgz", 61 | "integrity": "sha512-jc9E8vGTHkzb0Vwl74H8liANV9BWsqtzLHaKvcsRgf1M+aVCBSF0gUheduAKfDsbDMT0judeMLhwBP34EUesTA==", 62 | "cpu": [ 63 | "arm64" 64 | ], 65 | "dev": true, 66 | "optional": true, 67 | "os": [ 68 | "android" 69 | ] 70 | }, 71 | "node_modules/esbuild-darwin-64": { 72 | "version": "0.13.3", 73 | "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.13.3.tgz", 74 | "integrity": "sha512-8bG3Zq+ZNuLlIJebOO2+weI7P2LVf33sOzaUfHj8MuJ+1Ixe4KtQxfYp7qhFnP6xP2ToJaYHxGUfLeiUCEz9hw==", 75 | "cpu": [ 76 | "x64" 77 | ], 78 | "dev": true, 79 | "optional": true, 80 | "os": [ 81 | "darwin" 82 | ] 83 | }, 84 | "node_modules/esbuild-darwin-arm64": { 85 | "version": "0.13.3", 86 | "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.3.tgz", 87 | "integrity": "sha512-5E81eImYtTgh8pY7Gq4WQHhWkR/LvYadUXmuYeZBiP+3ADZJZcG60UFceZrjqNPaFOWKr/xmh4aNocwagEubcA==", 88 | "cpu": [ 89 | "arm64" 90 | ], 91 | "dev": true, 92 | "optional": true, 93 | "os": [ 94 | "darwin" 95 | ] 96 | }, 97 | "node_modules/esbuild-freebsd-64": { 98 | "version": "0.13.3", 99 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.3.tgz", 100 | "integrity": "sha512-ou+f91KkTGexi8HvF/BdtsITL6plbciQfZGys7QX6/QEwyE96PmL5KnU6ZQwoU7E99Ts6Sc9bUDq8HXJubKtBA==", 101 | "cpu": [ 102 | "x64" 103 | ], 104 | "dev": true, 105 | "optional": true, 106 | "os": [ 107 | "freebsd" 108 | ] 109 | }, 110 | "node_modules/esbuild-freebsd-arm64": { 111 | "version": "0.13.3", 112 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.3.tgz", 113 | "integrity": "sha512-F1zV7nySjHswJuvIgjkiG5liZ63MeazDGXGKViTCeegjZ71sAhOChcaGhKcu6vq9+vqZxlfEi1fmXlx6Pc3coQ==", 114 | "cpu": [ 115 | "arm64" 116 | ], 117 | "dev": true, 118 | "optional": true, 119 | "os": [ 120 | "freebsd" 121 | ] 122 | }, 123 | "node_modules/esbuild-linux-32": { 124 | "version": "0.13.3", 125 | "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.13.3.tgz", 126 | "integrity": "sha512-mHHc2v6uLrHH4zaaq5RB/5IWzgimEJ1HGldzf1qtGI513KZWfH0HRRQ8p1di4notJgBn7tDzWQ1f34ZHy69viQ==", 127 | "cpu": [ 128 | "ia32" 129 | ], 130 | "dev": true, 131 | "optional": true, 132 | "os": [ 133 | "linux" 134 | ] 135 | }, 136 | "node_modules/esbuild-linux-64": { 137 | "version": "0.13.3", 138 | "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.13.3.tgz", 139 | "integrity": "sha512-FJ1De2O89mrOuqtaEXu41qIYJU6R41F+OA6vheNwcAQcX8fu0aiA13FJeLABq29BYJuTVgRj3cyC8q+tz19/dQ==", 140 | "cpu": [ 141 | "x64" 142 | ], 143 | "dev": true, 144 | "optional": true, 145 | "os": [ 146 | "linux" 147 | ] 148 | }, 149 | "node_modules/esbuild-linux-arm": { 150 | "version": "0.13.3", 151 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.13.3.tgz", 152 | "integrity": "sha512-9BJNRtLwBh3OP22cln9g3AJdbAQUcjRHqA4BScx9k4RZpGqPokFr548zpeplxWhcwrIjT8qPebwH9CrRVy8Bsw==", 153 | "cpu": [ 154 | "arm" 155 | ], 156 | "dev": true, 157 | "optional": true, 158 | "os": [ 159 | "linux" 160 | ] 161 | }, 162 | "node_modules/esbuild-linux-arm64": { 163 | "version": "0.13.3", 164 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.3.tgz", 165 | "integrity": "sha512-Cauhr45KSo+wRUojs+1qfycQqQCAXTOvsWvkZ6xmEMAXLAm+f8RQGDQeP8CAf8Yeelnegcn6UNdvzdzLHhWDFg==", 166 | "cpu": [ 167 | "arm64" 168 | ], 169 | "dev": true, 170 | "optional": true, 171 | "os": [ 172 | "linux" 173 | ] 174 | }, 175 | "node_modules/esbuild-linux-mips64le": { 176 | "version": "0.13.3", 177 | "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.3.tgz", 178 | "integrity": "sha512-YVzJUGCncuuLm2boYyVeuMFsak4ZAhdiBwi0xNDZCC8sy+tS6Boe2mzcrD2uubv5JKAUOrpN186S1DtU4WgBgw==", 179 | "cpu": [ 180 | "mips64el" 181 | ], 182 | "dev": true, 183 | "optional": true, 184 | "os": [ 185 | "linux" 186 | ] 187 | }, 188 | "node_modules/esbuild-linux-ppc64le": { 189 | "version": "0.13.3", 190 | "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.3.tgz", 191 | "integrity": "sha512-GU6CqqKtJEoyxC2QWHiJtmuOz9wc/jMv8ZloK2WwiGY5yMvAmM3PI103Dj7xcjebNTHBqITTUw/aigY1wx5A3w==", 192 | "cpu": [ 193 | "ppc64" 194 | ], 195 | "dev": true, 196 | "optional": true, 197 | "os": [ 198 | "linux" 199 | ] 200 | }, 201 | "node_modules/esbuild-openbsd-64": { 202 | "version": "0.13.3", 203 | "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.3.tgz", 204 | "integrity": "sha512-HVpkgpn4BQt4BPDAjTOpeMub6mzNWw6Y3gaLQJrpbO24pws6ZwYkY24OI3/Uo3LDCbH6856MM81JxECt92OWjA==", 205 | "cpu": [ 206 | "x64" 207 | ], 208 | "dev": true, 209 | "optional": true, 210 | "os": [ 211 | "openbsd" 212 | ] 213 | }, 214 | "node_modules/esbuild-sunos-64": { 215 | "version": "0.13.3", 216 | "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.13.3.tgz", 217 | "integrity": "sha512-XncBVOtnEfUbPV4CaiFBxh38ychnBfwCxuTm9iAqcHzIwkmeNRN5qMzDyfE1jyfJje+Bbt6AvIfz6SdYt8/UEQ==", 218 | "cpu": [ 219 | "x64" 220 | ], 221 | "dev": true, 222 | "optional": true, 223 | "os": [ 224 | "sunos" 225 | ] 226 | }, 227 | "node_modules/esbuild-svelte": { 228 | "version": "0.5.6", 229 | "resolved": "https://registry.npmjs.org/esbuild-svelte/-/esbuild-svelte-0.5.6.tgz", 230 | "integrity": "sha512-Bz8nU45FrT6sP/Tf3M2rQUuBGxnDSNSPZNIoYwSNt5H+wjSyo/t+zm94tgnOZsR6GgpDMbNQgo4jGbK0NLvEfw==", 231 | "dev": true, 232 | "dependencies": { 233 | "svelte": "^3.42.6" 234 | }, 235 | "peerDependencies": { 236 | "esbuild": ">=0.9.6" 237 | } 238 | }, 239 | "node_modules/esbuild-windows-32": { 240 | "version": "0.13.3", 241 | "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.13.3.tgz", 242 | "integrity": "sha512-ZlgDz7d1nk8wQACi+z8IDzNZVUlN9iprAme+1YSTsfFDlkyI8jeaGWPk9EQFNY7rJzsLVYm6eZ2mhPioc7uT5A==", 243 | "cpu": [ 244 | "ia32" 245 | ], 246 | "dev": true, 247 | "optional": true, 248 | "os": [ 249 | "win32" 250 | ] 251 | }, 252 | "node_modules/esbuild-windows-64": { 253 | "version": "0.13.3", 254 | "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.13.3.tgz", 255 | "integrity": "sha512-YX7KvRez3TR+GudlQm9tND/ssj2FsF9vb8ZWzAoZOLxpPzE3y+3SFJNrfDzzQKPzJ0Pnh9KBP4gsaMwJjKHDhw==", 256 | "cpu": [ 257 | "x64" 258 | ], 259 | "dev": true, 260 | "optional": true, 261 | "os": [ 262 | "win32" 263 | ] 264 | }, 265 | "node_modules/esbuild-windows-arm64": { 266 | "version": "0.13.3", 267 | "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.3.tgz", 268 | "integrity": "sha512-nP7H0Y2a6OJd3Qi1Q8sehhyP4x4JoXK4S5y6FzH2vgaJgiyEurzFxjUufGdMaw+RxtxiwD/uRndUgwaZ2JD8lg==", 269 | "cpu": [ 270 | "arm64" 271 | ], 272 | "dev": true, 273 | "optional": true, 274 | "os": [ 275 | "win32" 276 | ] 277 | }, 278 | "node_modules/svelte": { 279 | "version": "3.43.0", 280 | "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.43.0.tgz", 281 | "integrity": "sha512-T2pMPHrxXp+SM8pLLUXLQgkdo+JhTls7aqj9cD7z8wT2ccP+OrCAmtQS7h6pvMjitaZhXFNnCK582NxDpy8HSw==", 282 | "dev": true, 283 | "engines": { 284 | "node": ">= 8" 285 | } 286 | } 287 | }, 288 | "dependencies": { 289 | "derver": { 290 | "version": "0.4.19", 291 | "resolved": "https://registry.npmjs.org/derver/-/derver-0.4.19.tgz", 292 | "integrity": "sha512-qDxXQd+qqOthqx1R1xr6K/C4kB6CT6H5yR4zJqyleo6BNJWqiSOFdsNNL5oFXMK6/5QPihrzTUsaYiDbMSNt1g==", 293 | "dev": true 294 | }, 295 | "esbuild": { 296 | "version": "0.13.3", 297 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.13.3.tgz", 298 | "integrity": "sha512-98xovMLKnyhv3gcReUuAEi5Ig1rK6SIgvsJuBIcfwzqGSEHsV8UJjMlmkhHoHMf9XZybMpE9Zax8AA8f7i2hlQ==", 299 | "dev": true, 300 | "requires": { 301 | "esbuild-android-arm64": "0.13.3", 302 | "esbuild-darwin-64": "0.13.3", 303 | "esbuild-darwin-arm64": "0.13.3", 304 | "esbuild-freebsd-64": "0.13.3", 305 | "esbuild-freebsd-arm64": "0.13.3", 306 | "esbuild-linux-32": "0.13.3", 307 | "esbuild-linux-64": "0.13.3", 308 | "esbuild-linux-arm": "0.13.3", 309 | "esbuild-linux-arm64": "0.13.3", 310 | "esbuild-linux-mips64le": "0.13.3", 311 | "esbuild-linux-ppc64le": "0.13.3", 312 | "esbuild-openbsd-64": "0.13.3", 313 | "esbuild-sunos-64": "0.13.3", 314 | "esbuild-windows-32": "0.13.3", 315 | "esbuild-windows-64": "0.13.3", 316 | "esbuild-windows-arm64": "0.13.3" 317 | } 318 | }, 319 | "esbuild-android-arm64": { 320 | "version": "0.13.3", 321 | "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.13.3.tgz", 322 | "integrity": "sha512-jc9E8vGTHkzb0Vwl74H8liANV9BWsqtzLHaKvcsRgf1M+aVCBSF0gUheduAKfDsbDMT0judeMLhwBP34EUesTA==", 323 | "dev": true, 324 | "optional": true 325 | }, 326 | "esbuild-darwin-64": { 327 | "version": "0.13.3", 328 | "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.13.3.tgz", 329 | "integrity": "sha512-8bG3Zq+ZNuLlIJebOO2+weI7P2LVf33sOzaUfHj8MuJ+1Ixe4KtQxfYp7qhFnP6xP2ToJaYHxGUfLeiUCEz9hw==", 330 | "dev": true, 331 | "optional": true 332 | }, 333 | "esbuild-darwin-arm64": { 334 | "version": "0.13.3", 335 | "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.3.tgz", 336 | "integrity": "sha512-5E81eImYtTgh8pY7Gq4WQHhWkR/LvYadUXmuYeZBiP+3ADZJZcG60UFceZrjqNPaFOWKr/xmh4aNocwagEubcA==", 337 | "dev": true, 338 | "optional": true 339 | }, 340 | "esbuild-freebsd-64": { 341 | "version": "0.13.3", 342 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.3.tgz", 343 | "integrity": "sha512-ou+f91KkTGexi8HvF/BdtsITL6plbciQfZGys7QX6/QEwyE96PmL5KnU6ZQwoU7E99Ts6Sc9bUDq8HXJubKtBA==", 344 | "dev": true, 345 | "optional": true 346 | }, 347 | "esbuild-freebsd-arm64": { 348 | "version": "0.13.3", 349 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.3.tgz", 350 | "integrity": "sha512-F1zV7nySjHswJuvIgjkiG5liZ63MeazDGXGKViTCeegjZ71sAhOChcaGhKcu6vq9+vqZxlfEi1fmXlx6Pc3coQ==", 351 | "dev": true, 352 | "optional": true 353 | }, 354 | "esbuild-linux-32": { 355 | "version": "0.13.3", 356 | "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.13.3.tgz", 357 | "integrity": "sha512-mHHc2v6uLrHH4zaaq5RB/5IWzgimEJ1HGldzf1qtGI513KZWfH0HRRQ8p1di4notJgBn7tDzWQ1f34ZHy69viQ==", 358 | "dev": true, 359 | "optional": true 360 | }, 361 | "esbuild-linux-64": { 362 | "version": "0.13.3", 363 | "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.13.3.tgz", 364 | "integrity": "sha512-FJ1De2O89mrOuqtaEXu41qIYJU6R41F+OA6vheNwcAQcX8fu0aiA13FJeLABq29BYJuTVgRj3cyC8q+tz19/dQ==", 365 | "dev": true, 366 | "optional": true 367 | }, 368 | "esbuild-linux-arm": { 369 | "version": "0.13.3", 370 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.13.3.tgz", 371 | "integrity": "sha512-9BJNRtLwBh3OP22cln9g3AJdbAQUcjRHqA4BScx9k4RZpGqPokFr548zpeplxWhcwrIjT8qPebwH9CrRVy8Bsw==", 372 | "dev": true, 373 | "optional": true 374 | }, 375 | "esbuild-linux-arm64": { 376 | "version": "0.13.3", 377 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.3.tgz", 378 | "integrity": "sha512-Cauhr45KSo+wRUojs+1qfycQqQCAXTOvsWvkZ6xmEMAXLAm+f8RQGDQeP8CAf8Yeelnegcn6UNdvzdzLHhWDFg==", 379 | "dev": true, 380 | "optional": true 381 | }, 382 | "esbuild-linux-mips64le": { 383 | "version": "0.13.3", 384 | "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.3.tgz", 385 | "integrity": "sha512-YVzJUGCncuuLm2boYyVeuMFsak4ZAhdiBwi0xNDZCC8sy+tS6Boe2mzcrD2uubv5JKAUOrpN186S1DtU4WgBgw==", 386 | "dev": true, 387 | "optional": true 388 | }, 389 | "esbuild-linux-ppc64le": { 390 | "version": "0.13.3", 391 | "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.3.tgz", 392 | "integrity": "sha512-GU6CqqKtJEoyxC2QWHiJtmuOz9wc/jMv8ZloK2WwiGY5yMvAmM3PI103Dj7xcjebNTHBqITTUw/aigY1wx5A3w==", 393 | "dev": true, 394 | "optional": true 395 | }, 396 | "esbuild-openbsd-64": { 397 | "version": "0.13.3", 398 | "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.3.tgz", 399 | "integrity": "sha512-HVpkgpn4BQt4BPDAjTOpeMub6mzNWw6Y3gaLQJrpbO24pws6ZwYkY24OI3/Uo3LDCbH6856MM81JxECt92OWjA==", 400 | "dev": true, 401 | "optional": true 402 | }, 403 | "esbuild-sunos-64": { 404 | "version": "0.13.3", 405 | "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.13.3.tgz", 406 | "integrity": "sha512-XncBVOtnEfUbPV4CaiFBxh38ychnBfwCxuTm9iAqcHzIwkmeNRN5qMzDyfE1jyfJje+Bbt6AvIfz6SdYt8/UEQ==", 407 | "dev": true, 408 | "optional": true 409 | }, 410 | "esbuild-svelte": { 411 | "version": "0.5.6", 412 | "resolved": "https://registry.npmjs.org/esbuild-svelte/-/esbuild-svelte-0.5.6.tgz", 413 | "integrity": "sha512-Bz8nU45FrT6sP/Tf3M2rQUuBGxnDSNSPZNIoYwSNt5H+wjSyo/t+zm94tgnOZsR6GgpDMbNQgo4jGbK0NLvEfw==", 414 | "dev": true, 415 | "requires": { 416 | "svelte": "^3.42.6" 417 | } 418 | }, 419 | "esbuild-windows-32": { 420 | "version": "0.13.3", 421 | "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.13.3.tgz", 422 | "integrity": "sha512-ZlgDz7d1nk8wQACi+z8IDzNZVUlN9iprAme+1YSTsfFDlkyI8jeaGWPk9EQFNY7rJzsLVYm6eZ2mhPioc7uT5A==", 423 | "dev": true, 424 | "optional": true 425 | }, 426 | "esbuild-windows-64": { 427 | "version": "0.13.3", 428 | "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.13.3.tgz", 429 | "integrity": "sha512-YX7KvRez3TR+GudlQm9tND/ssj2FsF9vb8ZWzAoZOLxpPzE3y+3SFJNrfDzzQKPzJ0Pnh9KBP4gsaMwJjKHDhw==", 430 | "dev": true, 431 | "optional": true 432 | }, 433 | "esbuild-windows-arm64": { 434 | "version": "0.13.3", 435 | "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.3.tgz", 436 | "integrity": "sha512-nP7H0Y2a6OJd3Qi1Q8sehhyP4x4JoXK4S5y6FzH2vgaJgiyEurzFxjUufGdMaw+RxtxiwD/uRndUgwaZ2JD8lg==", 437 | "dev": true, 438 | "optional": true 439 | }, 440 | "svelte": { 441 | "version": "3.43.0", 442 | "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.43.0.tgz", 443 | "integrity": "sha512-T2pMPHrxXp+SM8pLLUXLQgkdo+JhTls7aqj9cD7z8wT2ccP+OrCAmtQS7h6pvMjitaZhXFNnCK582NxDpy8HSw==", 444 | "dev": true 445 | } 446 | } 447 | } 448 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svate", 3 | "description": "Set of state machines for Svelte applications", 4 | "version": "0.1.6", 5 | "main": "dist/svate.js", 6 | "module": "dist/svate.js", 7 | "svelte": "dist/svate.js", 8 | "cdn": "dist/svate.min.js", 9 | "unpkg": "dist/svate.min.js", 10 | "scripts": { 11 | "build": "node esbuild", 12 | "dev": "node esbuild --dev", 13 | "test": "echo \"Error: no test specified\" && exit 1" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/AlexxNB/svate.git" 18 | }, 19 | "keywords": [ 20 | "svelte", 21 | "state", 22 | "machine", 23 | "state", 24 | "store", 25 | "flags" 26 | ], 27 | "author": "Alexey Schebelev", 28 | "license": "MIT", 29 | "bugs": { 30 | "url": "https://github.com/AlexxNB/svate/issues" 31 | }, 32 | "homepage": "https://github.com/AlexxNB/svate#readme", 33 | "devDependencies": { 34 | "derver": "^0.4.19", 35 | "esbuild": "^0.13.3", 36 | "esbuild-svelte": "^0.5.6", 37 | "svelte": "^3.43.0" 38 | }, 39 | "peerDependencies": { 40 | "svelte": "3.x" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/lib/flags.js: -------------------------------------------------------------------------------- 1 | import {writable} from 'svelte/store'; 2 | import { err } from './utils'; 3 | 4 | export function flag(initial){ 5 | let state = !!initial; 6 | let lock = false; 7 | 8 | const {subscribe,set} = writable(state); 9 | const locked = writable(lock); 10 | 11 | return { 12 | subscribe, 13 | on(){!lock && set(state=true)}, 14 | off(){!lock && set(state=false)}, 15 | toggle(){!lock && set(state=!state)}, 16 | set(value){!lock && set(state=!!value)}, 17 | lock(){locked.set(lock=true)}, 18 | unlock(){locked.set(lock=false)}, 19 | get state(){return state}, 20 | get locked(){return locked} 21 | } 22 | } 23 | 24 | const PRESERVED = ['subscribe','set','$']; 25 | export function flagset(initial){ 26 | if(!typeof initial == 'object') throw err('flagset function must get object with names and states'); 27 | 28 | const list = Object.keys(initial); 29 | 30 | const initial_state = list.reduce((o,name)=>(o[name] = !!initial[name],o),{}); 31 | const copyInitial = ()=>Object.assign({},initial_state) 32 | let state = copyInitial(); 33 | 34 | let lock = false; 35 | 36 | const stateStore = writable(state); 37 | const locked = writable(lock); 38 | 39 | const setState = ()=>stateStore.set(state); 40 | 41 | const set = { 42 | on(){!lock && setState(list.forEach(name => state[name]=true))}, 43 | off(){!lock && setState(list.forEach(name => state[name]=false))}, 44 | toggle(){!lock && setState(list.forEach(name => state[name]=!state[name]))}, 45 | reset(){!lock && setState(state = copyInitial())}, 46 | set(value){!lock && setState(list.forEach(name => state[name]=!!value))}, 47 | lock(){locked.set(lock=true)}, 48 | unlock(){locked.set(lock=false)}, 49 | get locked(){return locked}, 50 | get list(){return list}, 51 | } 52 | 53 | const flags = { 54 | subscribe: stateStore.subscribe, 55 | set:set, 56 | $:set, 57 | } 58 | 59 | list.forEach( name =>{ 60 | if(PRESERVED.includes[name]) throw err(`flag name can't be ${name}, please rename it`); 61 | flags[name]={ 62 | on(){!lock && setState(state[name]=true)}, 63 | off(){!lock && setState(state[name]=false)}, 64 | toggle(){!lock && setState(state[name]=!state[name])}, 65 | set(value){!lock && setState(state[name]=!!value)}, 66 | get state(){return state[name]} 67 | } 68 | }); 69 | 70 | return flags; 71 | } -------------------------------------------------------------------------------- /src/lib/machines.js: -------------------------------------------------------------------------------- 1 | import {writable} from 'svelte/store'; 2 | import {err,indexOrZero} from '@lib/utils' 3 | 4 | export function machine(list,initial){ 5 | return createStateMachine(list,initial,true); 6 | } 7 | 8 | export function endlessMachine(list,initial){ 9 | return createStateMachine(list,initial,false); 10 | } 11 | 12 | function createStateMachine(list,initial,finite){ 13 | if(!Array.isArray(list) || !list.length) throw err('List of states should be a filled array'); 14 | 15 | let current; 16 | let maxstep = list.length-1; 17 | const getState = num => { 18 | if(finite && num < 0) num = 0; 19 | if(finite && num > maxstep) num = maxstep; 20 | if(!finite && num < 0) num = Math.abs(maxstep+num+1); 21 | if(!finite) num = num % (maxstep+1); 22 | return list[current = num]; 23 | } 24 | 25 | const {subscribe,set} = writable( getState(indexOrZero(list,initial)) ); 26 | const first = writable(current===0); 27 | const last = writable(current===maxstep); 28 | 29 | const setState = num => { 30 | set(getState(num)); 31 | first.set(current===0) 32 | last.set(current===maxstep) 33 | } 34 | 35 | return { 36 | subscribe, 37 | next(){setState(current+1)}, 38 | back(){setState(current-1)}, 39 | first(){setState(0)}, 40 | last(){setState(maxstep)}, 41 | index(step){setState(step)}, 42 | set(state){setState(indexOrZero(list,state))}, 43 | get states(){return list}, 44 | get current(){return getState(current)}, 45 | get isFirst(){return first}, 46 | get isLast(){return last}, 47 | } 48 | } -------------------------------------------------------------------------------- /src/lib/utils.js: -------------------------------------------------------------------------------- 1 | export function err(str){ 2 | return new Error('[Svate]',str); 3 | } 4 | 5 | export function indexOrZero(array,value){ 6 | return (array.indexOf(value) < 0) ? 0 : array.indexOf(value) 7 | } -------------------------------------------------------------------------------- /src/svate.js: -------------------------------------------------------------------------------- 1 | export {machine,endlessMachine} from '@lib/machines'; 2 | export {flag,flagset} from '@lib/flags'; -------------------------------------------------------------------------------- /test/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Svate Test App 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /test/src/App.svelte: -------------------------------------------------------------------------------- 1 | 7 | 8 |

1. Machine

9 | 10 | 11 | 12 |
13 | 14 |

2. Endless machine

15 | 16 | 17 | 18 |
19 | 20 |

3. Single flag

21 | 22 | 23 | 24 |
25 | 26 |

4. Flags set

27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /test/src/EndlessMachine.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 | States: 15 | {#each steps.states as state} 16 | {state}  17 | {/each} 18 |
19 |
Current state: {$steps}
20 |
Is first?: {$isFirst ? 'yes' : 'no'}
21 |
Is last?: {$isLast ? 'yes' : 'no'}
22 | 23 |

24 | 25 | 26 | 27 | 28 |   29 | 30 | 31 |

-------------------------------------------------------------------------------- /test/src/Flag.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 |
Current state: {$togler ? 'on' : 'off'}
9 |
Is locked?: {$locked ? 'yes' : 'no'}
10 |

11 | 12 | 13 | 14 |   15 | 16 | 17 |   18 | 19 | 20 |

-------------------------------------------------------------------------------- /test/src/Flagset.svelte: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 |
13 | Current state: 14 | {#each flags.$.list as name} 15 |
16 |   17 | {name}:{$flags[name] ? 'on' : 'off'} 18 | - 19 | 20 | 21 | 22 |
23 | {/each} 24 |
25 |
Is locked?: {$locked ? 'yes' : 'no'}
26 |

27 | 28 | 29 | 30 |   31 | 32 | 33 |

-------------------------------------------------------------------------------- /test/src/Machine.svelte: -------------------------------------------------------------------------------- 1 | 13 | 14 |
15 | States: 16 | {#each steps.states as state} 17 | {state}  18 | {/each} 19 |
20 |
Current state: {$steps}
21 |
Is first?: {$isFirst ? 'yes' : 'no'}
22 |
Is last?: {$isLast ? 'yes' : 'no'}
23 |

24 | 25 | 26 | 27 | 28 |   29 | 30 | 31 |

-------------------------------------------------------------------------------- /test/src/app.js: -------------------------------------------------------------------------------- 1 | import App from './App.svelte'; 2 | 3 | const app = new App({target: document.body}); 4 | 5 | export default app; --------------------------------------------------------------------------------