@peter.naydenov/cuts 1.5.0 → 1.6.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 +52 -7
- package/dist/cuts.cjs +1 -1
- package/dist/cuts.esm.mjs +1 -1
- package/dist/cuts.umd.js +1 -1
- package/package.json +1 -1
- package/src/findInstructions.js +0 -6
- package/src/main.js +7 -2
- package/src/methods/setScenes.js +27 -11
- package/src/methods/show.js +26 -27
- package/test-vitest/02-cuts.test.js +364 -8
- package/types/findInstructions.d.ts.map +1 -1
- package/types/main.d.ts.map +1 -1
- package/types/methods/setScenes.d.ts +20 -4
- package/types/methods/setScenes.d.ts.map +1 -1
- package/types/methods/show.d.ts.map +1 -1
package/Changelog.md
CHANGED
|
@@ -1,88 +1,126 @@
|
|
|
1
1
|
# Release History
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
## 1.
|
|
4
|
+
## 1.6.0 ( 2025-10-?? )
|
|
5
|
+
- [x] All 'cuts' errors goes to '@app-error' event;
|
|
6
|
+
- [x] Configuration 'logLevel' default value is 1. If you want to dissable errors logging, set 'logLevel' to 0;
|
|
7
|
+
- [x] Code cleaning. Removing unused code;
|
|
8
|
+
- [x] Test code coverage on 85%;
|
|
9
|
+
- [x] Fix: SSR option for first scene loading;
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## 1.5.0 ( 2025-10-23 )
|
|
5
15
|
- [x] Dependency update. @peter.naydenov/shortcuts - v.3.5.1
|
|
6
16
|
- [x] Dev dependency update. Vitest - v.4.0.1
|
|
7
17
|
- [x] Cuts has event '@app-error'. Shortcut errors will trigger this event;
|
|
8
18
|
- [x] Type improvements;
|
|
9
19
|
- [x] New method `getState` returns an object with the current state;
|
|
10
20
|
- [x] Fix: Closing a long list of scenes breaks the state;
|
|
11
|
-
|
|
21
|
+
- [ ] Bug: SSR option for first scene loading;
|
|
12
22
|
|
|
13
23
|
|
|
14
24
|
|
|
15
25
|
## 1.4.4 ( 2025-10-10)
|
|
16
26
|
- [x] Dependency update. @peter.naydenov/shortcuts - v.3.3.1 ( fixing problem with 'key:specialCharacters' events);
|
|
27
|
+
- [ ] Bug: Closing a long list of scenes breaks the state;
|
|
28
|
+
- [ ] Bug: SSR option for first scene loading;
|
|
17
29
|
|
|
18
30
|
|
|
19
31
|
|
|
20
32
|
## 1.4.3 ( 2025-09-30)
|
|
21
33
|
- [x] Dependency update. ask-for-promise@3.0.2;
|
|
34
|
+
- [ ] Bug: Closing a long list of scenes breaks the state;
|
|
35
|
+
- [ ] Bug: SSR option for first scene loading;
|
|
22
36
|
|
|
23
37
|
|
|
24
38
|
|
|
25
39
|
## 1.4.2 ( 2025-09-29)
|
|
26
40
|
- [x] Dependency update. @peter.naydenov/shortcuts@3.3.0;
|
|
41
|
+
- [ ] Bug: Closing a long list of scenes breaks the state;
|
|
42
|
+
- [ ] Bug: SSR option for first scene loading;
|
|
43
|
+
|
|
44
|
+
|
|
27
45
|
|
|
28
46
|
## 1.4.1. ( 2025-09-24)
|
|
29
47
|
- [x] Fix: Cleaning a duplicated line of code in main.js;
|
|
30
|
-
|
|
48
|
+
- [ ] Bug: Closing a long list of scenes breaks the state;
|
|
49
|
+
- [ ] Bug: SSR option for first scene loading;
|
|
31
50
|
|
|
32
51
|
|
|
33
52
|
## 1.4.0 ( 2025-09-06)
|
|
34
53
|
- [x] New methods: jump, jumpBack, jumpsReset;
|
|
35
54
|
- [ ] Bug: Duplicated line of code in main.js;
|
|
55
|
+
- [ ] Bug: Closing a long list of scenes breaks the state;
|
|
56
|
+
- [ ] Bug: SSR option for first scene loading;
|
|
36
57
|
|
|
37
58
|
|
|
38
59
|
## 1.3.1 ( 2025-08-15)
|
|
39
60
|
- [ ] Fix: Missing typedef for plugin 'form'
|
|
61
|
+
- [ ] Bug: Closing a long list of scenes breaks the state;
|
|
62
|
+
- [ ] Bug: SSR option for first scene loading;
|
|
40
63
|
|
|
41
64
|
|
|
42
65
|
## 1.3.0 ( 2025-08-15)
|
|
43
66
|
- [x] Dependency update. @peter.naydenov/shortcuts@3.1.5. Plugin 'form' is available;
|
|
44
67
|
- [ ] Miss: Missing typedef for plugin 'form'
|
|
45
|
-
|
|
68
|
+
- [ ] Bug: Closing a long list of scenes breaks the state;
|
|
69
|
+
- [ ] Bug: SSR option for first scene loading;
|
|
46
70
|
|
|
47
71
|
|
|
48
72
|
## 1.2.8 ( 2025-05-03)
|
|
49
73
|
- [x] Dependency update. @peter.naydenov/shortcuts@3.1.4;
|
|
74
|
+
- [ ] Bug: Closing a long list of scenes breaks the state;
|
|
75
|
+
- [ ] Bug: SSR option for first scene loading;
|
|
76
|
+
|
|
50
77
|
|
|
51
78
|
|
|
52
79
|
### 1.2.7 ( 2025-02-04)
|
|
53
80
|
- [x] Dependency update. @peter.naydenov/log@1.1.1;
|
|
81
|
+
- [ ] Bug: Closing a long list of scenes breaks the state;
|
|
82
|
+
- [ ] Bug: SSR option for first scene loading;
|
|
54
83
|
|
|
55
84
|
|
|
56
85
|
|
|
57
86
|
### 1.2.6 ( 2025-01-23)
|
|
58
87
|
- [x] Improve: Warn that the scene is not defined if scene is set to null;
|
|
88
|
+
- [ ] Bug: Closing a long list of scenes breaks the state;
|
|
89
|
+
- [ ] Bug: SSR option for first scene loading;
|
|
59
90
|
|
|
60
91
|
|
|
61
92
|
|
|
62
93
|
### 1.2.4 ( 2025-01-15)
|
|
63
94
|
- [x] Dependency update. @peter.naydenov/shortcuts@3.1.3;
|
|
95
|
+
- [ ] Bug: Closing a long list of scenes breaks the state;
|
|
96
|
+
- [ ] Bug: SSR option for first scene loading;
|
|
64
97
|
|
|
65
98
|
|
|
66
99
|
|
|
67
100
|
### 1.2.3 ( 2024-12-23)
|
|
68
101
|
- [x] Dependency update. @peter.naydenov/shortcuts@3.1.2;
|
|
69
|
-
|
|
102
|
+
- [ ] Bug: Closing a long list of scenes breaks the state;
|
|
103
|
+
- [ ] Bug: SSR option for first scene loading;
|
|
70
104
|
|
|
71
105
|
|
|
72
106
|
### 1.2.2 ( 2024-12-22 )
|
|
73
107
|
- [x] Fix: Wrong argument 'dependencies' for 'beforeHide' and 'afterShow' methods;
|
|
74
|
-
|
|
75
|
-
|
|
108
|
+
- [ ] Bug: Closing a long list of scenes breaks the state;
|
|
109
|
+
- [ ] Bug: SSR option for first scene loading;
|
|
76
110
|
|
|
77
111
|
### 1.2.1 ( 2024-12-21 )
|
|
78
112
|
- [x] Fix: Wrong settings if missing 'beforeHide' method;
|
|
79
113
|
- [ ] Bug: Wrong argument 'dependencies' for 'beforeHide' and 'afterShow' methods;
|
|
114
|
+
- [ ] Bug: Closing a long list of scenes breaks the state;
|
|
115
|
+
- [ ] Bug: SSR option for first scene loading;
|
|
80
116
|
|
|
81
117
|
|
|
82
118
|
### 1.2.0 (2024-12-21)
|
|
83
119
|
- [x] Extend 'scene' with optional 'afterShow' and 'beforeHide' methods;
|
|
84
120
|
- [ ] Bug: Wrong settings if missing 'beforeHide' method;
|
|
85
121
|
- [ ] Bug: Wrong argument 'dependencies' for 'beforeHide' and 'afterShow' methods;
|
|
122
|
+
- [ ] Bug: Closing a long list of scenes breaks the state;
|
|
123
|
+
- [ ] Bug: SSR option for first scene loading;
|
|
86
124
|
|
|
87
125
|
|
|
88
126
|
|
|
@@ -90,16 +128,23 @@
|
|
|
90
128
|
- [x] Type improvements;
|
|
91
129
|
- [x] Refactoring related to types;
|
|
92
130
|
- [x] New method `loadPlugins` to load shortcut plugins: `Key`, `Click` or both;
|
|
131
|
+
- [x] Method 'setScene' errors goes to '@app-error'
|
|
132
|
+
- [ ] Bug: Closing a long list of scenes breaks the state;
|
|
133
|
+
- [ ] Bug: SSR option for first scene loading;
|
|
93
134
|
|
|
94
135
|
|
|
95
136
|
|
|
96
137
|
### 1.0.2 (2024-12-12)
|
|
97
138
|
- [x] Create d.ts files in folder 'types';
|
|
139
|
+
- [ ] Bug: Closing a long list of scenes breaks the state;
|
|
140
|
+
- [ ] Bug: SSR option for first scene loading;
|
|
98
141
|
|
|
99
142
|
|
|
100
143
|
|
|
101
144
|
### 1.0.1 (2024-05-10)
|
|
102
145
|
- [x] Fix: Repository address in package.json;
|
|
146
|
+
- [ ] Bug: Closing a long list of scenes breaks the state;
|
|
147
|
+
- [ ] Bug: SSR option for first scene loading;
|
|
103
148
|
|
|
104
149
|
|
|
105
150
|
|
package/dist/cuts.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("@peter.naydenov/shortcuts"),n=require("ask-for-promise"),r=require("@peter.naydenov/log");function*t(e,n,r,t){let s=null,o=!0;if(null===e)return yield*t.map(e=>[e,"show"]),void(yield[r,"show"]);if(0!==t.length){if(t.includes(e)){for(let n=t.indexOf(e)+1;n<t.length;n++)yield[t[n],"show"];return void(yield[r,"show"])}if(!n)return yield[e,"hide"],void(yield*t.map(e=>[e,"show"]));if(t.every((e,r)=>n[r]===t[r]&&(s=r,!0)),null==s)return yield[e,"hide"],n.reverse(),yield*n.map(e=>[e,"hide"]),yield*t.map(e=>[e,"show"]),void(yield[r,"show"]);yield[e,"hide"];for(let e=n.length;e>s+1;e--)yield[n[e-1],"hide"];for(let e=s+1;e<t.length;e++)yield[t[e],"show"];yield[r,"show"]}else{if(
|
|
1
|
+
"use strict";var e=require("@peter.naydenov/shortcuts"),n=require("ask-for-promise"),r=require("@peter.naydenov/log");function*t(e,n,r,t){let s=null,o=!0;if(null===e)return yield*t.map(e=>[e,"show"]),void(yield[r,"show"]);if(0!==t.length){if(t.includes(e)){for(let n=t.indexOf(e)+1;n<t.length;n++)yield[t[n],"show"];return void(yield[r,"show"])}if(!n)return yield[e,"hide"],void(yield*t.map(e=>[e,"show"]));if(t.every((e,r)=>n[r]===t[r]&&(s=r,!0)),null==s)return yield[e,"hide"],n.reverse(),yield*n.map(e=>[e,"hide"]),yield*t.map(e=>[e,"show"]),void(yield[r,"show"]);yield[e,"hide"];for(let e=n.length;e>s+1;e--)yield[n[e-1],"hide"];for(let e=s+1;e<t.length;e++)yield[t[e],"show"];yield[r,"show"]}else{if(yield[e,"hide"],n.includes(r)){let e=n.indexOf(r),t=n.filter((n,r)=>r>e);t.reverse(),yield*t.map(e=>[e,"hide"]),o=!1}else{let e=[...n];e.reverse(),yield*e.map(e=>[e,"hide"])}o&&(yield[r,"show"])}}function s(e){return function(n,...r){const{askForPromise:t,deps:s}=e;return function(){const e=t();return n({task:e,dependencies:s()},...r),e.promise}}}module.exports=function(o={logLevel:0}){const c=e.shortcuts({errorEventName:"@app-error"}),i=o.logLevel||1,u=r({level:i},e=>{const{type:n}=e;"error"===n&&c.emit("@app-error",e)}),l={currentScene:null,currentParents:null,sceneNames:new Set,scenes:{},opened:!1,jumpStack:[]},d={},a={shortcutMngr:c,findInstructions:t,askForPromise:n,setInstruction:s({askForPromise:n,deps:c.getDependencies}),log:u};return d.hide=function(e,n){return function(r=1){const{askForPromise:t,shortcutMngr:s,setInstruction:o}=e,{currentScene:c,currentParents:i,scenes:u}=n,l=t(),d=[],a=i.length>0;let p;return s.pause(),d.push(o(u[c].hide)),a||(n.currentScene=null),a&&"*"===r&&[...i].reverse().forEach(e=>{p=n.currentParents.at(-1),n.currentScene=p,d.push(o(u[e].hide))}),a&&!["*",1].includes(r)&&i.slice("-"+(r-1)).reverse().map(e=>{p=n.currentParents.at(-1),n.currentScene=p,d.push(o(u[e].hide))}),(r=t.sequence(d)).onComplete(()=>{s.changeContext(n.currentScene),l.done()}),l.promise}}(a,l),d.listShortcuts=function(e,n){return function(e){const{scenes:r,sceneNames:t}=n;if(!t.has(e))return null;const{show:s,hide:o,parents:c,beforeUnload:i,afterLoad:u,...l}=r[e];return Object.keys(l)}}(0,l),d.setScenes=function(e,n){return function(r){const{shortcutMngr:t,log:s}=e;r.forEach(e=>{if(null==e)return;const{name:r,scene:o}=e;if(!r)return void s({message:"Scene name is not defined",level:1,type:"error"});if(null==o)return void s({message:`Scene ${r} is not defined`,level:1,type:"error"});o.parents||(o.parents=[]),n.scenes[r]=o,n.sceneNames.add(r);const{show:c,hide:i,parents:u,...l}=o,d={};d[r]=l,t.load(d)})}}(a,l),d.show=function(e,n){return function({scene:r,options:t={ssr:!1}},...s){const{shortcutMngr:o,askForPromise:c,log:i,findInstructions:u,setInstruction:l}=e,d=c(),a=c(),{opened:p,scenes:h,sceneNames:f,currentScene:m}=n;return m&&"function"==typeof h[m].beforeHide?(0,h[m].beforeHide)({done:a.done,dependencies:o.getDependencies()}):a.done(!0),a.onComplete(e=>{if(!e)return d.done(),d.promise;if(!f.has(r))return i({message:`Scene "${r}" is not available.`,level:1,type:"error"}),d.done(),d.promise;if(!p&&t.ssr)return n.opened=!0,n.currentScene=r,o.changeContext(r),d.done(),d.promise;const{show:a,parents:m=[]}=h[r];if("*"===m[0])return l(a,...s)().then(()=>d.done()),n.currentParents.push(n.currentScene),n.currentScene=r,d.promise;if(0!==m.length&&!m.every(e=>f.has(e)))return i({message:`Some of '${r}' parent scenes are not set.`,level:1,type:"error"}),d.done(),d.promise;function g([e,r]){if("show"===r)n.currentScene&&(n.currentParents=[...h[n.currentScene].parents]),n.currentScene=e;else{let r=h[e].parents.at(-1);n.currentScene=r}return h[e][r]}n.currentParents||(n.currentParents=[]);const S=u(n.currentScene,n.currentParents,r,m),y=[];for(let e of S){const n=g(e);y.push(l(n,...s))}c.sequence(y).onComplete(()=>{n.opened=!0,n.currentScene=r,n.currentParents=h[r].parents||null,o.changeContext(r),"function"==typeof h[r].afterShow&&h[r].afterShow({dependencies:o.getDependencies(),done:()=>{}}),d.done()})}),d.promise}}(a,l),d.jump=function(e,n){return function({scene:r},...t){return e.jumpStack.push(e.currentScene),n({scene:r},...t)}}(l,d.show),d.jumpBack=function(e,n){return function({hops:r}={hops:1},...t){for(let n=0;n<r-1;n++)e.jumpStack.pop();if(0===e.jumpStack.length)return;const s=e.jumpStack.pop();return n({scene:s},...t)}}(l,d.show),d.jumpsReset=function(e){return function(){e.jumpStack=[]}}(l),d.loadPlugins=async function(e){const n=e.map(e=>`plugin${e}`),r=await import("@peter.naydenov/shortcuts");return n.map(e=>r[e])},d.setDependencies=e=>c.setDependencies(e),d.getDependencies=()=>c.getDependencies(),d.setNote=n=>e.shortcuts.setNote(n),d.listScenes=()=>[...l.sceneNames],d.enablePlugin=(e,n)=>c.enablePlugin(e,n),d.disablePlugin=e=>c.disablePlugin(e),d.getState=()=>({scene:l.currentScene,parents:l.currentParents,opened:l.opened}),d.emit=(e,...n)=>c.emit(e,...n),d};
|
package/dist/cuts.esm.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{shortcuts as e}from"@peter.naydenov/shortcuts";import n from"ask-for-promise";import r from"@peter.naydenov/log";function*t(e,n,r,t){let s=null,o=!0;if(null===e)return yield*t.map(e=>[e,"show"]),void(yield[r,"show"]);if(0!==t.length){if(t.includes(e)){for(let n=t.indexOf(e)+1;n<t.length;n++)yield[t[n],"show"];return void(yield[r,"show"])}if(!n)return yield[e,"hide"],void(yield*t.map(e=>[e,"show"]));if(t.every((e,r)=>n[r]===t[r]&&(s=r,!0)),null==s)return yield[e,"hide"],n.reverse(),yield*n.map(e=>[e,"hide"]),yield*t.map(e=>[e,"show"]),void(yield[r,"show"]);yield[e,"hide"];for(let e=n.length;e>s+1;e--)yield[n[e-1],"hide"];for(let e=s+1;e<t.length;e++)yield[t[e],"show"];yield[r,"show"]}else{if(
|
|
1
|
+
import{shortcuts as e}from"@peter.naydenov/shortcuts";import n from"ask-for-promise";import r from"@peter.naydenov/log";function*t(e,n,r,t){let s=null,o=!0;if(null===e)return yield*t.map(e=>[e,"show"]),void(yield[r,"show"]);if(0!==t.length){if(t.includes(e)){for(let n=t.indexOf(e)+1;n<t.length;n++)yield[t[n],"show"];return void(yield[r,"show"])}if(!n)return yield[e,"hide"],void(yield*t.map(e=>[e,"show"]));if(t.every((e,r)=>n[r]===t[r]&&(s=r,!0)),null==s)return yield[e,"hide"],n.reverse(),yield*n.map(e=>[e,"hide"]),yield*t.map(e=>[e,"show"]),void(yield[r,"show"]);yield[e,"hide"];for(let e=n.length;e>s+1;e--)yield[n[e-1],"hide"];for(let e=s+1;e<t.length;e++)yield[t[e],"show"];yield[r,"show"]}else{if(yield[e,"hide"],n.includes(r)){let e=n.indexOf(r),t=n.filter((n,r)=>r>e);t.reverse(),yield*t.map(e=>[e,"hide"]),o=!1}else{let e=[...n];e.reverse(),yield*e.map(e=>[e,"hide"])}o&&(yield[r,"show"])}}function s(e){return function(n,...r){const{askForPromise:t,deps:s}=e;return function(){const e=t();return n({task:e,dependencies:s()},...r),e.promise}}}function o(o={logLevel:0}){const c=e({errorEventName:"@app-error"}),i=o.logLevel||1,u=r({level:i},e=>{const{type:n}=e;"error"===n&&c.emit("@app-error",e)}),l={currentScene:null,currentParents:null,sceneNames:new Set,scenes:{},opened:!1,jumpStack:[]},a={},d={shortcutMngr:c,findInstructions:t,askForPromise:n,setInstruction:s({askForPromise:n,deps:c.getDependencies}),log:u};return a.hide=function(e,n){return function(r=1){const{askForPromise:t,shortcutMngr:s,setInstruction:o}=e,{currentScene:c,currentParents:i,scenes:u}=n,l=t(),a=[],d=i.length>0;let p;return s.pause(),a.push(o(u[c].hide)),d||(n.currentScene=null),d&&"*"===r&&[...i].reverse().forEach(e=>{p=n.currentParents.at(-1),n.currentScene=p,a.push(o(u[e].hide))}),d&&!["*",1].includes(r)&&i.slice("-"+(r-1)).reverse().map(e=>{p=n.currentParents.at(-1),n.currentScene=p,a.push(o(u[e].hide))}),(r=t.sequence(a)).onComplete(()=>{s.changeContext(n.currentScene),l.done()}),l.promise}}(d,l),a.listShortcuts=function(e,n){return function(e){const{scenes:r,sceneNames:t}=n;if(!t.has(e))return null;const{show:s,hide:o,parents:c,beforeUnload:i,afterLoad:u,...l}=r[e];return Object.keys(l)}}(0,l),a.setScenes=function(e,n){return function(r){const{shortcutMngr:t,log:s}=e;r.forEach(e=>{if(null==e)return;const{name:r,scene:o}=e;if(!r)return void s({message:"Scene name is not defined",level:1,type:"error"});if(null==o)return void s({message:`Scene ${r} is not defined`,level:1,type:"error"});o.parents||(o.parents=[]),n.scenes[r]=o,n.sceneNames.add(r);const{show:c,hide:i,parents:u,...l}=o,a={};a[r]=l,t.load(a)})}}(d,l),a.show=function(e,n){return function({scene:r,options:t={ssr:!1}},...s){const{shortcutMngr:o,askForPromise:c,log:i,findInstructions:u,setInstruction:l}=e,a=c(),d=c(),{opened:p,scenes:f,sceneNames:h,currentScene:m}=n;return m&&"function"==typeof f[m].beforeHide?(0,f[m].beforeHide)({done:d.done,dependencies:o.getDependencies()}):d.done(!0),d.onComplete(e=>{if(!e)return a.done(),a.promise;if(!h.has(r))return i({message:`Scene "${r}" is not available.`,level:1,type:"error"}),a.done(),a.promise;if(!p&&t.ssr)return n.opened=!0,n.currentScene=r,o.changeContext(r),a.done(),a.promise;const{show:d,parents:m=[]}=f[r];if("*"===m[0])return l(d,...s)().then(()=>a.done()),n.currentParents.push(n.currentScene),n.currentScene=r,a.promise;if(0!==m.length&&!m.every(e=>h.has(e)))return i({message:`Some of '${r}' parent scenes are not set.`,level:1,type:"error"}),a.done(),a.promise;function g([e,r]){if("show"===r)n.currentScene&&(n.currentParents=[...f[n.currentScene].parents]),n.currentScene=e;else{let r=f[e].parents.at(-1);n.currentScene=r}return f[e][r]}n.currentParents||(n.currentParents=[]);const S=u(n.currentScene,n.currentParents,r,m),y=[];for(let e of S){const n=g(e);y.push(l(n,...s))}c.sequence(y).onComplete(()=>{n.opened=!0,n.currentScene=r,n.currentParents=f[r].parents||null,o.changeContext(r),"function"==typeof f[r].afterShow&&f[r].afterShow({dependencies:o.getDependencies(),done:()=>{}}),a.done()})}),a.promise}}(d,l),a.jump=function(e,n){return function({scene:r},...t){return e.jumpStack.push(e.currentScene),n({scene:r},...t)}}(l,a.show),a.jumpBack=function(e,n){return function({hops:r}={hops:1},...t){for(let n=0;n<r-1;n++)e.jumpStack.pop();if(0===e.jumpStack.length)return;const s=e.jumpStack.pop();return n({scene:s},...t)}}(l,a.show),a.jumpsReset=function(e){return function(){e.jumpStack=[]}}(l),a.loadPlugins=async function(e){const n=e.map(e=>`plugin${e}`),r=await import("@peter.naydenov/shortcuts");return n.map(e=>r[e])},a.setDependencies=e=>c.setDependencies(e),a.getDependencies=()=>c.getDependencies(),a.setNote=n=>e.setNote(n),a.listScenes=()=>[...l.sceneNames],a.enablePlugin=(e,n)=>c.enablePlugin(e,n),a.disablePlugin=e=>c.disablePlugin(e),a.getState=()=>({scene:l.currentScene,parents:l.currentParents,opened:l.opened}),a.emit=(e,...n)=>c.emit(e,...n),a}export{o as default};
|
package/dist/cuts.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).cuts=t()}(this,function(){"use strict";var e={_normalizeWithPlugins:function(e,t){return function(e){const n=t.shortcuts;Object.keys(n).forEach(t=>{Object.entries(n[t]).forEach(([r,o])=>{const s=e(r);s!==r&&(delete n[t][r],n[t][s]=o)})})}},_readShortcutWithPlugins:function(e,t){return function(n){const{inAPI:r}=e,o=n.split(":")[0].toLowerCase().trim(),s=r._systemAction(o,"none");let i=n;return-1!==s&&(i=t.plugins[s].shortcutName(n)),i}},_systemAction:function(e,t){return function(e,n,r=null){return t.plugins.findIndex(t=>t.getPrefix()===e&&(t[n]&&t[n](r),!0))}},changeContext:function(e,t){const{shortcuts:n,currentContext:r,ERROR_EVENT_NAME:o}=t,{ev:s}=e;return function(e=!1){const i=r.name;if(!e)return s.reset(),void(r.name=null);i!==e&&(n[e]?(n[i]&&s.reset(),r.name=e,t.plugins.forEach(t=>t.contextChange(e)),Object.entries(n[e]).forEach(([e,t])=>{t.forEach(t=>s.on(e,t))}),s.on("*",(...e)=>{t.exposeShortcut&&t.exposeShortcut(...e)})):s.emit(o,`Context '${e}' does not exist`))}},listShortcuts:function(e,t){const n=t.shortcuts;return function(e=null){if(null!=e){let t=n[e];return null==t?null:Object.entries(t).map(([e,t])=>e)}return Object.keys(n).map(e=>{let t={};return t.context=e,t.shortcuts=Object.entries(n[e]).map(([e,t])=>e),t})}},load:function(e,t){const{shortcuts:n,plugins:r}=t,{API:{changeContext:o,getContext:s}}=e;return function(e){const t=s(),i=r.map(e=>e.getPrefix().toUpperCase());let c=!1;Object.entries(e).forEach(([e,o])=>{e===t&&(c=!0),n[e]={},Object.entries(o).forEach(([t,o])=>{let s=t,c=t.toUpperCase().trim(),u=i.map((e,t)=>c.startsWith(e)?t:null).filter(e=>null!==e);if(u.length){let e=u[0];s=r[e].shortcutName(t)}o instanceof Function&&(o=[o]),n[e][s]=o})}),c&&(o(),o(t))}},unload:function(e,t){const{currentContext:n,shortcuts:r,ERROR_EVENT_NAME:o}=t,{ev:s}=e;return function(e){n.name!==e?r[e]?delete r[e]:s.emit(o,`Context '${e}' does not exist`):s.emit(o,`Context '${e}' can't be removed during is current active context. Change the context first`)}}};function t(e){const t=e.toUpperCase(),n=/KEY\s*\:/i.test(t),r=t.indexOf(":");return n?`KEY:${t.slice(r+1).split(",").map(e=>e.trim()).map(e=>e.split("+").map(e=>e.trim()).sort().join("+")).join(",")}`:e}function n(e,t){let{shiftKey:n,altKey:r,ctrlKey:o}=e,s=t(),i=e.code.replace("Key","").replace("Digit",""),c=[];return o&&c.push("CTRL"),n&&c.push("SHIFT"),r&&c.push("ALT"),s.hasOwnProperty(i)?c.push(s[i].toUpperCase()):["ControlLeft","ControlRight","ShiftLeft","ShiftRight","AltLeft","AltRight","Meta"].includes(i)||c.push(i.toUpperCase()),c.sort()}function r(e,t){let n=0;const{regex:r}=e,{listenOptions:o,currentContext:{name:s},shortcuts:i}=t;return null==s?0:(Object.entries(i[s]).forEach(([e,t])=>{if(!r.test(e))return;n++;let s=e.slice(4).split(",").length;o.maxSequence<s&&(o.maxSequence=s)}),n)}function o(){return{ArrowLeft:"LEFT",ArrowUp:"UP",ArrowRight:"RIGHT",ArrowDown:"DOWN",Enter:"ENTER",NumpadEnter:"ENTER",Escape:"ESC",Backspace:"BACKSPACE",Space:"SPACE",Tab:"TAB",Backquote:"`",BracketLeft:"[",BracketRight:"]",Equal:"=",Slash:"/",Backslash:"\\",IntlBackslash:"`",F1:"F1",F2:"F2",F3:"F3",F4:"F4",F5:"F5",F6:"F6",F7:"F7",F8:"F8",F9:"F9",F10:"F10",F11:"F11",F12:"F12"}}function s(e,t,n){const{listenOptions:{clickTarget:r}}=t;let o=n;return o===document||o===document.body?null:o.dataset[r]||"A"===o.nodeName?o:s(e,t,o.parentNode)}function i(e){const t=e.toUpperCase(),n=/CLICK\s*\:/i.test(t),r=["LEFT","MIDDLE","RIGHT"],o=["ALT","SHIFT","CTRL"];let s=null,i=[],c=0,u=t.indexOf(":");return n?(t.slice(u+1).trim().split("-").map(e=>e.trim()).forEach(e=>{r.includes(e)?s=e:o.includes(e)?i.push(e):isNaN(e)||(c=e)}),`CLICK:${s}-${c}${i.length>0?"-":""}${i.sort().join("-")}`):e}function c(e,t){let{shiftKey:n,altKey:r,ctrlKey:o,key:s,button:i}=e,c=`CLICK:${["LEFT","MIDDLE","RIGHT"][i]}-${t}`,u=[];return o&&u.push("CTRL"),n&&u.push("SHIFT"),r&&u.push("ALT"),u.length>0?`${c}${u.length>0?"-":""}${u.sort().join("-")}`:`${c}`}function u(e,t){let n=0;const{regex:r}=e,{listenOptions:o,currentContext:{name:s},shortcuts:i}=t;return null==s?0:(Object.entries(i[s]).forEach(([e,t])=>{if(!r.test(e))return;n++;let[,s]=e.slice(6).split("-");o.maxClicks<s&&(o.maxClicks=s)}),n)}function l(e){const t=e.toUpperCase(),n=/FORM\s*\:/i.test(t),r=t.indexOf(":");return n?`FORM:${t.slice(r+1).trim()}`:e}function a(e,t){const{regex:n,_defaults:r,ev:o}=e,{currentContext:{name:s},shortcuts:i,callbacks:c}=t;let u=[],l=[],a=[];if(null==s)return!1;if(Object.entries(i[s]).forEach(([e,t])=>{n.test(e)&&("FORM:WATCH"===e&&(u=t),"FORM:DEFINE"===e&&(l=t),"FORM:ACTION"===e&&(a=t))}),0===a.length)return!1;let f=new Set;0===l.length&&(l=[r.define]),0===u.length&&(u=[r.watch]);let p=u.map(e=>e()).reduce((e,t)=>(e.push(t),e),[]);return t.watchList=document.querySelectorAll(p),t.watchList.forEach(e=>f.add(l[0](e))),t.typeFn=l[0]?l[0]:r.define,a.forEach(n=>{if(!(n instanceof Function))return console.warn("Warning: The 'form:action' should be a function."),!1;let r=n({dependencies:e.mainDependencies.extra});if(!(r instanceof Array))return console.warn("Warning: The 'form:action' function should RETURN an array."),!1;r.forEach(({fn:e,type:n,timing:r,wait:s=0})=>{if(f.has(n)&&e instanceof Function){let t=`${n}/${r}`;const s=c.hasOwnProperty(t);s?c[t].push(e):c[t]=[e],s||o.on(t,(e,t)=>{t.forEach(t=>{t instanceof Function&&t(e)})})}"instant"===r&&(t.wait[`${n}`]=s)})}),Object.keys(t.callbacks).length>0}const f={watch:()=>"input, select, textarea, button, a",define:e=>"checkbox"===e.type||"radio"===e.type?"checkbox":"button"==e.type||"submit"==e.type?"button":"input"};function p(t={}){let n={},r={};const o=function(){let e={"*":[]},t={},n=new Set,r=!1,o="";return{on:function(t,n){e[t]||(e[t]=[]),e[t].push(n)},once:function(e,n){"*"!==e&&(t[e]||(t[e]=[]),t[e].push(n))},off:function(n,r){if(r)return e[n]&&(e[n]=e[n].filter(e=>e!==r)),t[n]&&(t[n]=t[n].filter(e=>e!==r)),e[n]&&0===e[n].length&&delete e[n],void(t[n]&&0===t[n].length&&delete e[n]);t[n]&&delete t[n],e[n]&&delete e[n]},reset:function(){e={"*":[]},t={},n=new Set},emit:function(){const[s,...i]=arguments;function c(t){let r=!1;"*"!==t&&(n.has(t)||(e[t].every(e=>{const t=e(...i);return"string"!=typeof t||"STOP"!==t.toUpperCase()||(r=!0,!1)}),r||e["*"].forEach(e=>e(s,...i))))}if(r&&(console.log(`${o} Event "${s}" was triggered.`),i.length>0&&(console.log("Arguments:"),console.log(...i),console.log("^----"))),"*"!==s){if(t[s]){if(n.has(s))return;t[s].forEach(e=>e(...i)),delete t[s]}e[s]&&c(s)}else Object.keys(e).forEach(e=>c(e))},stop:function(r){if("*"===r){const r=Object.keys(e),o=Object.keys(t);return void(n=new Set([...o,...r]))}n.add(r)},start:function(e){"*"!==e?n.delete(e):n.clear()},debug:function(e,t){r=!!e,t&&"string"==typeof t&&(o=t)}}}(),s={currentContext:{name:null,note:null},shortcuts:{},plugins:[],exposeShortcut:!(!t.onShortcut||"function"!=typeof t.onShortcut)&&t.onShortcut,ERROR_EVENT_NAME:t.errorEventName?t.errorEventName:"@shortcuts-error"};let i={ev:o,inAPI:n,API:r,extra:{}};return r.enablePlugin=(e,t={})=>{if("function"!=typeof e)return;let r=e(i,s,t);const o=r.getPrefix();-1===n._systemAction(o,"none")?s.plugins.push(r):r.destroy()},r.disablePlugin=e=>{const t=n._systemAction(e,"destroy");-1!==t&&(s.plugins=s.plugins.filter((e,n)=>n!==t))},r.mutePlugin=e=>n._systemAction(e,"mute"),r.unmutePlugin=e=>n._systemAction(e,"unmute"),r.listPlugins=()=>s.plugins.map(e=>e.getPrefix()),r.getContext=()=>s.currentContext.name,r.getNote=()=>s.currentContext.note,r.setNote=(e=null)=>{"string"!=typeof e&&null!=e||(s.currentContext.note=e)},r.pause=(e="*")=>{let t=n._readShortcutWithPlugins(e);o.stop(t)},r.resume=(e="*")=>{const t=n._readShortcutWithPlugins(e);o.start(t)},r.emit=(e,...t)=>o.emit(n._readShortcutWithPlugins(e),...t),r.listContexts=()=>Object.keys(s.shortcuts),r.setDependencies=e=>i.extra={...i.extra,...e},r.getDependencies=()=>i.extra,r.reset=function(){o.reset(),r.changeContext(),s.plugins.forEach(e=>e.destroy()),r.listContexts().map(e=>r.unload(e)),i.extra={},s.exposeShortcut=null},Object.entries(e).forEach(([e,t])=>{e.startsWith("_")?n[e]=t(i,s):r[e]=t(i,s)}),r}var d=Object.freeze({__proto__:null,pluginClick:function(e,t,n){let{currentContext:r,shortcuts:o}=t,{inAPI:l}=e,a={ev:e.ev,_findTarget:s,_readClickEvent:c,mainDependencies:e,regex:/CLICK\s*\:/i},f={currentContext:r,active:!1,shortcuts:o,listenOptions:{mouseWait:n.mouseWait?n.mouseWait:320,maxClicks:1,clickTarget:n.clickTarget?n.clickTarget:"click"}};l._normalizeWithPlugins(i);let p=function(e,t){const{ev:n,_findTarget:r,_readClickEvent:o,mainDependencies:s}=e,{listenOptions:i,currentContext:c}=t,{mouseWait:u}=i;let l=null,a=null,f=null,p=null,d=0;function m(){const e=o(a,d),t={target:l,targetProps:l?l.getBoundingClientRect():null,x:a.clientX,y:a.clientY,context:c.name,note:c.note,event:a,dependencies:s.extra,type:"click"};n.emit(e,t),f=null,p=null,l=null,a=null,d=0}function h(n){let o=i.maxClicks;return clearTimeout(f),p?(clearTimeout(p),void(p=setTimeout(()=>p=null,u))):(l=r(e,t,n.target),l&&l.dataset.hasOwnProperty("quickClick")&&(o=1),l&&"A"===l.tagName&&(o=1),a=n,d++,d>=o?(m(),void(o>1&&(p=setTimeout(()=>p=null,u)))):void(f=setTimeout(m,u)))}function g(n){let o=i.maxClicks;return clearTimeout(f),p?(clearTimeout(p),void(p=setTimeout(()=>p=null,u))):(l=r(e,t,n.target),l&&l.dataset.hasOwnProperty("quickClick")&&(o=1),l&&"A"===l.tagName&&(o=1),a=n,d++,d>=o?(m(),void(o>1&&(p=setTimeout(()=>p=null,u)))):void(f=setTimeout(m,u)))}return{start:function(){t.active||(window.addEventListener("contextmenu",g),document.addEventListener("click",h),t.active=!0)},stop:function(){t.active&&(window.removeEventListener("contextmenu",g),document.removeEventListener("click",h),t.active=!1,f&&(clearTimeout(f),f=null),p&&(clearTimeout(p),p=null),d=0)}}}(a,f),d=u(a,f);d>0&&p.start();let m={getPrefix:()=>"click",shortcutName:e=>i(e),contextChange:()=>{d=u(a,f),d<1&&p.stop(),d>0&&p.start()},mute:()=>{p.stop()},unmute:()=>p.start(),destroy:()=>p.stop()};return Object.freeze(m),m},pluginForm:function(e,t,n){let{currentContext:r,shortcuts:o}=t,{inAPI:s}=e,i={ev:e.ev,mainDependencies:e,regex:/FORM\s*\:/i,_defaults:f},c={currentContext:r,shortcuts:o,callbacks:{},typeFn:"",watchList:[],wait:{}};s._normalizeWithPlugins(l);let u=function(e,t){const{ev:n}=e;let r=null;function o(e,t,n,r){return{target:n.target,context:t.currentContext.name,note:t.currentContext.note,event:n,dependencies:e.mainDependencies.extra,type:r}}function s(r){const{callbacks:s,typeFn:i}=t,c=i(r.target),u=o(e,t,r,c),l=`${c}/in`;null!=s[l]&&n.emit(l,u,s[l])}function i(r){const{callbacks:s,typeFn:i}=t,c=o(e,t,r,"form-out"),u=`${i(r.target)}/out`;null!=s[u]&&n.emit(u,c,s[u])}function c(s){const{callbacks:i,typeFn:c}=t,u=o(e,t,s,"form-instant"),l=c(s.target),a=t.wait[`${l}`],f=`${l}/instant`;null!=i[f]&&(0!==a?(clearTimeout(r),r=setTimeout(()=>n.emit(f,u,i[f]),a)):n.emit(f,u,i[f]))}return{start:function(){t.active||(document.addEventListener("focusin",s),document.addEventListener("focusout",i),document.addEventListener("input",c),t.active=!0)},stop:function(){t.active&&(document.removeEventListener("focusin",s),document.removeEventListener("focusout",i),document.removeEventListener("input",c),t.active=!1)}}}(i,c);r.name&&a(i,c)&&u.start();let p={getPrefix:()=>"form",shortcutName:e=>l(e),contextChange:()=>{c.callbacks={},c.typeFn="",c.watchList=[],c.wait={},a(i,c)?u.start():u.stop()},mute:()=>u.stop(),unmute:()=>u.start(),destroy:()=>{u.stop()}};return Object.freeze(p),p},pluginKey:function(e,s,i={}){let{currentContext:c,shortcuts:u,exposeShortcut:l}=s,{inAPI:a}=e,f={ev:e.ev,_specialChars:o,_readKeyEvent:n,mainDependencies:e,regex:/KEY\s*\:/i},p={currentContext:c,shortcuts:u,active:!1,listenOptions:{keyWait:i.keyWait?i.keyWait:480,maxSequence:1,keyIgnore:null},streamKeys:!(!i.streamKeys||"function"!=typeof i.streamKeys)&&i.streamKeys};a._normalizeWithPlugins(t);let d=function(e,t){const{ev:n,_specialChars:r,_readKeyEvent:o,mainDependencies:s}=e,{currentContext:i,streamKeys:c,listenOptions:u}=t,{keyWait:l}=u;let a=[],f=null,p=!0,d=!1;const m=()=>p=!1,h=()=>p=!0,g=()=>d=!0,y=()=>!1===p;function v(){let e=a.map(e=>[e.join("+")]);const t={wait:m,end:h,ignore:g,isWaiting:y,note:i.note,context:i.name,dependencies:s.extra,type:"key"};if(!p){let r=e.at(-1);n.emit(r,t),d&&(e=e.slice(0,-1),d=!1)}if(p){const r=`KEY:${e.join(",")}`;n.emit(r,t),a=[],f=null}}function x(t){if(clearTimeout(f),r().hasOwnProperty(t.code))return a.push(o(t,r)),c&&c({key:t.key,context:i.name,note:i.note,dependencies:e.extra}),u.keyIgnore?(clearTimeout(u.keyIgnore),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,l))):p&&a.length===u.maxSequence?(v(),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,l))):void(p?f=setTimeout(v,l):v())}function k(t){if(!r().hasOwnProperty(t.code)){if(clearTimeout(f),c&&c({key:t.key,context:i.name,note:i.note,dependencies:e.extra}),u.keyIgnore)return clearTimeout(u.keyIgnore),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,l));if(a.push(o(t,r)),p&&a.length===u.maxSequence)return v(),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,l));p?f=setTimeout(v,l):v()}}return{start:function(){t.active||(document.addEventListener("keydown",x),document.addEventListener("keypress",k),t.active=!0)},stop:function(){t.active&&(document.removeEventListener("keydown",x),document.removeEventListener("keypress",k),t.active=!1,f&&(clearTimeout(f),f=null),u.keyIgnore&&(clearTimeout(u.keyIgnore),u.keyIgnore=null),a=[],p=!0,d=!1)}}}(f,p),m=r(f,p);m>0&&d.start();let h={getPrefix:()=>"key",shortcutName:e=>t(e),contextChange:e=>{m=r(f,p),m<1&&d.stop(),m>0&&d.start()},mute:()=>d.stop(),unmute:()=>d.start(),destroy:()=>d.stop()};return Object.freeze(h),h},shortcuts:p});function m(e){return e?function(e){let t=e.map(e=>h()),n=t.map(e=>e.promise);t.promises=t;let r=g(Promise.all(n));function o(e){let t="pending";return e.then(()=>t="fulfilled").catch(()=>t="rejected"),t}function s(n,...r){t.forEach((t,s)=>n({value:e[s],done:t.done,cancel:t.cancel,timeout:t.timeout,state:o(t.promise)},...r))}const i={promise:Promise.all(n),promises:t,done:e=>{t.forEach(t=>t.done(e))},cancel:e=>{t.forEach(t=>t.cancel(e))},each:s,onComplete:r,timeout:()=>{}};return i.timeout=y(!0,i),i}(e):h()}function h(){let e,t;const n=new Promise((n,r)=>{e=n,t=r}),r={promise:n,promises:null,done:e,cancel:t,each:()=>{},onComplete:g(n),timeout:()=>{}};return r.timeout=y(!1,r),r.each=(n,...o)=>{n({value:null,done:e,cancel:t,timeout:r.timeout},...o)},r}function g(e){return function(t,n=null){null===n?e.then(e=>t(e)):e.then(e=>t(e),e=>n(e))}}function y(e,t){let n;return n=e?Promise.all(t.promises.map(e=>e.promise)):t.promise,function(e,r){let o,s=new Promise((t,s)=>{o=setTimeout(()=>{t(r),Promise.resolve(n)},e)});return n.then(()=>clearTimeout(o)),t.onComplete=g(Promise.race([n,s])),t}}function v({message:e,level:t,type:n,logLevel:r}){if(0===r)return null;if(r<t)return null;const o=`[Debug]: ${e}`;switch(n){case"warn":console.warn(o);break;case"error":console.error(o);break;default:console.log(o)}return o}function x(e={},t=v){return function({message:n,type:r,level:o,...s}){const{level:i,type:c,defaultMessageLevel:u}=Object.assign({},{level:1e3,type:"log",defaultMessageLevel:1},e);return r||(r=c),o||(o=u),t({message:n,type:r,level:o,logLevel:i,...s})}}function*k(e,t,n,r){let o=null,s=!0;if(null===e)return yield*r.map(e=>[e,"show"]),void(yield[n,"show"]);if(0!==r.length){if(r.includes(e)){for(let t=r.indexOf(e)+1;t<r.length;t++)yield[r[t],"show"];return void(yield[n,"show"])}if(!t)return yield[e,"hide"],void(yield*r.map(e=>[e,"show"]));if(r.every((e,n)=>t[n]===r[n]&&(o=n,!0)),null==o)return yield[e,"hide"],t.reverse(),yield*t.map(e=>[e,"hide"]),yield*r.map(e=>[e,"show"]),void(yield[n,"show"]);yield[e,"hide"];for(let e=t.length;e>o+1;e--)yield[t[e-1],"hide"];for(let e=o+1;e<r.length;e++)yield[r[e],"show"];yield[n,"show"]}else{if(!t)return yield[e,"hide"],void(yield[n,"show"]);if(yield[e,"hide"],t.includes(n)){let e=t.indexOf(n),r=t.filter((t,n)=>n>e);r.reverse(),yield*r.map(e=>[e,"hide"]),s=!1}else{let e=[...t];e.reverse(),yield*e.map(e=>[e,"hide"])}s&&(yield[n,"show"])}}function C(e){return function(t,...n){const{askForPromise:r,deps:o}=e;return function(){const e=r();return t({task:e,dependencies:o()},...n),e.promise}}}return m.sequence=function(e,...t){const n=m(),r=[];const o=function*(e){for(const t of e)yield t}(e);return function e(t,...s){t.done?n.done(r):t.value(...s).then(t=>{r.push(t),e(o.next(),...s,t)})}(o.next(),...t),n},m.all=function(e,...t){const n=m(),r=[],o=e.map((e,n)=>"function"==typeof e?e(...t).then(e=>r[n]=e):e.then(e=>r[n]=e));return Promise.all(o).then(()=>n.done(r)),n},function(e={logLevel:0}){const t=p({errorEventName:"@app-error"}),n=x({level:e.logLevel||0}),r={currentScene:null,currentParents:null,sceneNames:new Set,scenes:{},opened:!1,jumpStack:[]},o={},s={shortcutMngr:t,findInstructions:k,askForPromise:m,setInstruction:C({askForPromise:m,deps:t.getDependencies}),log:n};return o.hide=function(e,t){return function(n=1){const{askForPromise:r,shortcutMngr:o,setInstruction:s}=e,{currentScene:i,currentParents:c,scenes:u}=t,l=r(),a=[],f=c.length>0;let p;return o.pause(),a.push(s(u[i].hide)),f||(t.currentScene=null),f&&"*"===n&&[...c].reverse().forEach(e=>{p=t.currentParents.at(-1),t.currentScene=p,a.push(s(u[e].hide))}),f&&!["*",1].includes(n)&&c.slice("-"+(n-1)).reverse().map(e=>{p=t.currentParents.at(-1),t.currentScene=p,a.push(s(u[e].hide))}),(n=r.sequence(a)).onComplete(()=>{o.changeContext(t.currentScene),l.done()}),l.promise}}(s,r),o.listShortcuts=function(e,t){return function(e){const{scenes:n,sceneNames:r}=t;if(!r.has(e))return null;const{show:o,hide:s,parents:i,beforeUnload:c,afterLoad:u,...l}=n[e];return Object.keys(l)}}(0,r),o.setScenes=function(e,t){return function(n){const{shortcutMngr:r}=e;n.forEach(e=>{if(null==e)return;const{name:n,scene:o}=e;if(null==o)return void console.warn(`Scene ${n} is not defined`);o.parents||(o.parents=[]),t.scenes[n]=o,t.sceneNames.add(n);const{show:s,hide:i,parents:c,...u}=o,l={};l[n]=u,r.load(l)})}}(s,r),o.show=function(e,t){return function({scene:n,options:r={ssr:!1}},...o){const{shortcutMngr:s,askForPromise:i,log:c,findInstructions:u,setInstruction:l}=e,a=i(),f=i(),{opened:p,scenes:d,sceneNames:m,currentScene:h}=t;return h&&"function"==typeof d[h].beforeHide?(0,d[h].beforeHide)({done:f.done,dependencies:s.getDependencies()}):f.done(!0),f.onComplete(e=>{if(!e)return a.done(),a.promise;if(!m.has(n)&&c)return c({message:`Scene ${n} is not available.`,level:1,type:"error"}),a.done(),a.promise;if(!p&&r.ssr)return t.opened=!0,t.currentPage=n,s.changeContext(n),a.done(),a.promise;const{show:f,parents:h=[]}=d[n];if("*"===h[0])return f().then(()=>a.done()),t.currentParents.push(t.currentPage),t.currentPage=n,a.promise;function g([e,n]){if("show"===n)t.currentScene&&(t.currentParents=[...d[t.currentScene].parents]),t.currentScene=e;else{let n=d[e].parents.at(-1);t.currentScene=n}return d[e][n]}h.forEach(e=>m.has(e)),t.currentParents||(t.currentParents=[]);const y=u(t.currentScene,t.currentParents,n,h),v=[];for(let e of y){const t=g(e);v.push(l(t,...o))}i.sequence(v).onComplete(()=>{t.opened=!0,t.currentPage=n,t.currentParents=d[n].parents||null,s.changeContext(n),"function"==typeof d[n].afterShow&&d[n].afterShow({dependencies:s.getDependencies(),done:()=>{}}),a.done()})}),a.promise}}(s,r),o.jump=function(e,t){return function({scene:n},...r){return e.jumpStack.push(e.currentScene),t({scene:n},...r)}}(r,o.show),o.jumpBack=function(e,t){return function({hops:n}={hops:1},...r){for(let t=0;t<n-1;t++)e.jumpStack.pop();if(0===e.jumpStack.length)return;const o=e.jumpStack.pop();return t({scene:o},...r)}}(r,o.show),o.jumpsReset=function(e){return function(){e.jumpStack=[]}}(r),o.loadPlugins=async function(e){const t=e.map(e=>`plugin${e}`),n=await Promise.resolve().then(function(){return d});return t.map(e=>n[e])},o.setDependencies=e=>t.setDependencies(e),o.getDependencies=()=>t.getDependencies(),o.setNote=e=>p.setNote(e),o.listScenes=()=>[...r.sceneNames],o.enablePlugin=(e,n)=>t.enablePlugin(e,n),o.disablePlugin=e=>t.disablePlugin(e),o.getState=()=>({scene:r.currentScene,parents:r.currentParents,opened:r.opened}),o.emit=(e,...n)=>t.emit(e,...n),o}});
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).cuts=t()}(this,function(){"use strict";var e={_normalizeWithPlugins:function(e,t){return function(e){const n=t.shortcuts;Object.keys(n).forEach(t=>{Object.entries(n[t]).forEach(([r,o])=>{const s=e(r);s!==r&&(delete n[t][r],n[t][s]=o)})})}},_readShortcutWithPlugins:function(e,t){return function(n){const{inAPI:r}=e,o=n.split(":")[0].toLowerCase().trim(),s=r._systemAction(o,"none");let i=n;return-1!==s&&(i=t.plugins[s].shortcutName(n)),i}},_systemAction:function(e,t){return function(e,n,r=null){return t.plugins.findIndex(t=>t.getPrefix()===e&&(t[n]&&t[n](r),!0))}},changeContext:function(e,t){const{shortcuts:n,currentContext:r,ERROR_EVENT_NAME:o}=t,{ev:s}=e;return function(e=!1){const i=r.name;if(!e)return s.reset(),void(r.name=null);i!==e&&(n[e]?(n[i]&&s.reset(),r.name=e,t.plugins.forEach(t=>t.contextChange(e)),Object.entries(n[e]).forEach(([e,t])=>{t.forEach(t=>s.on(e,t))}),s.on("*",(...e)=>{t.exposeShortcut&&t.exposeShortcut(...e)})):s.emit(o,`Context '${e}' does not exist`))}},listShortcuts:function(e,t){const n=t.shortcuts;return function(e=null){if(null!=e){let t=n[e];return null==t?null:Object.entries(t).map(([e,t])=>e)}return Object.keys(n).map(e=>{let t={};return t.context=e,t.shortcuts=Object.entries(n[e]).map(([e,t])=>e),t})}},load:function(e,t){const{shortcuts:n,plugins:r}=t,{API:{changeContext:o,getContext:s}}=e;return function(e){const t=s(),i=r.map(e=>e.getPrefix().toUpperCase());let c=!1;Object.entries(e).forEach(([e,o])=>{e===t&&(c=!0),n[e]={},Object.entries(o).forEach(([t,o])=>{let s=t,c=t.toUpperCase().trim(),u=i.map((e,t)=>c.startsWith(e)?t:null).filter(e=>null!==e);if(u.length){let e=u[0];s=r[e].shortcutName(t)}o instanceof Function&&(o=[o]),n[e][s]=o})}),c&&(o(),o(t))}},unload:function(e,t){const{currentContext:n,shortcuts:r,ERROR_EVENT_NAME:o}=t,{ev:s}=e;return function(e){n.name!==e?r[e]?delete r[e]:s.emit(o,`Context '${e}' does not exist`):s.emit(o,`Context '${e}' can't be removed during is current active context. Change the context first`)}}};function t(e){const t=e.toUpperCase(),n=/KEY\s*\:/i.test(t),r=t.indexOf(":");return n?`KEY:${t.slice(r+1).split(",").map(e=>e.trim()).map(e=>e.split("+").map(e=>e.trim()).sort().join("+")).join(",")}`:e}function n(e,t){let{shiftKey:n,altKey:r,ctrlKey:o}=e,s=t(),i=e.code.replace("Key","").replace("Digit",""),c=[];return o&&c.push("CTRL"),n&&c.push("SHIFT"),r&&c.push("ALT"),s.hasOwnProperty(i)?c.push(s[i].toUpperCase()):["ControlLeft","ControlRight","ShiftLeft","ShiftRight","AltLeft","AltRight","Meta"].includes(i)||c.push(i.toUpperCase()),c.sort()}function r(e,t){let n=0;const{regex:r}=e,{listenOptions:o,currentContext:{name:s},shortcuts:i}=t;return null==s?0:(Object.entries(i[s]).forEach(([e,t])=>{if(!r.test(e))return;n++;let s=e.slice(4).split(",").length;o.maxSequence<s&&(o.maxSequence=s)}),n)}function o(){return{ArrowLeft:"LEFT",ArrowUp:"UP",ArrowRight:"RIGHT",ArrowDown:"DOWN",Enter:"ENTER",NumpadEnter:"ENTER",Escape:"ESC",Backspace:"BACKSPACE",Space:"SPACE",Tab:"TAB",Backquote:"`",BracketLeft:"[",BracketRight:"]",Equal:"=",Slash:"/",Backslash:"\\",IntlBackslash:"`",F1:"F1",F2:"F2",F3:"F3",F4:"F4",F5:"F5",F6:"F6",F7:"F7",F8:"F8",F9:"F9",F10:"F10",F11:"F11",F12:"F12"}}function s(e,t,n){const{listenOptions:{clickTarget:r}}=t;let o=n;return o===document||o===document.body?null:o.dataset[r]||"A"===o.nodeName?o:s(e,t,o.parentNode)}function i(e){const t=e.toUpperCase(),n=/CLICK\s*\:/i.test(t),r=["LEFT","MIDDLE","RIGHT"],o=["ALT","SHIFT","CTRL"];let s=null,i=[],c=0,u=t.indexOf(":");return n?(t.slice(u+1).trim().split("-").map(e=>e.trim()).forEach(e=>{r.includes(e)?s=e:o.includes(e)?i.push(e):isNaN(e)||(c=e)}),`CLICK:${s}-${c}${i.length>0?"-":""}${i.sort().join("-")}`):e}function c(e,t){let{shiftKey:n,altKey:r,ctrlKey:o,key:s,button:i}=e,c=`CLICK:${["LEFT","MIDDLE","RIGHT"][i]}-${t}`,u=[];return o&&u.push("CTRL"),n&&u.push("SHIFT"),r&&u.push("ALT"),u.length>0?`${c}${u.length>0?"-":""}${u.sort().join("-")}`:`${c}`}function u(e,t){let n=0;const{regex:r}=e,{listenOptions:o,currentContext:{name:s},shortcuts:i}=t;return null==s?0:(Object.entries(i[s]).forEach(([e,t])=>{if(!r.test(e))return;n++;let[,s]=e.slice(6).split("-");o.maxClicks<s&&(o.maxClicks=s)}),n)}function l(e){const t=e.toUpperCase(),n=/FORM\s*\:/i.test(t),r=t.indexOf(":");return n?`FORM:${t.slice(r+1).trim()}`:e}function a(e,t){const{regex:n,_defaults:r,ev:o}=e,{currentContext:{name:s},shortcuts:i,callbacks:c}=t;let u=[],l=[],a=[];if(null==s)return!1;if(Object.entries(i[s]).forEach(([e,t])=>{n.test(e)&&("FORM:WATCH"===e&&(u=t),"FORM:DEFINE"===e&&(l=t),"FORM:ACTION"===e&&(a=t))}),0===a.length)return!1;let f=new Set;0===l.length&&(l=[r.define]),0===u.length&&(u=[r.watch]);let p=u.map(e=>e()).reduce((e,t)=>(e.push(t),e),[]);return t.watchList=document.querySelectorAll(p),t.watchList.forEach(e=>f.add(l[0](e))),t.typeFn=l[0]?l[0]:r.define,a.forEach(n=>{if(!(n instanceof Function))return console.warn("Warning: The 'form:action' should be a function."),!1;let r=n({dependencies:e.mainDependencies.extra});if(!(r instanceof Array))return console.warn("Warning: The 'form:action' function should RETURN an array."),!1;r.forEach(({fn:e,type:n,timing:r,wait:s=0})=>{if(f.has(n)&&e instanceof Function){let t=`${n}/${r}`;const s=c.hasOwnProperty(t);s?c[t].push(e):c[t]=[e],s||o.on(t,(e,t)=>{t.forEach(t=>{t instanceof Function&&t(e)})})}"instant"===r&&(t.wait[`${n}`]=s)})}),Object.keys(t.callbacks).length>0}const f={watch:()=>"input, select, textarea, button, a",define:e=>"checkbox"===e.type||"radio"===e.type?"checkbox":"button"==e.type||"submit"==e.type?"button":"input"};function p(t={}){let n={},r={};const o=function(){let e={"*":[]},t={},n=new Set,r=!1,o="";return{on:function(t,n){e[t]||(e[t]=[]),e[t].push(n)},once:function(e,n){"*"!==e&&(t[e]||(t[e]=[]),t[e].push(n))},off:function(n,r){if(r)return e[n]&&(e[n]=e[n].filter(e=>e!==r)),t[n]&&(t[n]=t[n].filter(e=>e!==r)),e[n]&&0===e[n].length&&delete e[n],void(t[n]&&0===t[n].length&&delete e[n]);t[n]&&delete t[n],e[n]&&delete e[n]},reset:function(){e={"*":[]},t={},n=new Set},emit:function(){const[s,...i]=arguments;function c(t){let r=!1;"*"!==t&&(n.has(t)||(e[t].every(e=>{const t=e(...i);return"string"!=typeof t||"STOP"!==t.toUpperCase()||(r=!0,!1)}),r||e["*"].forEach(e=>e(s,...i))))}if(r&&(console.log(`${o} Event "${s}" was triggered.`),i.length>0&&(console.log("Arguments:"),console.log(...i),console.log("^----"))),"*"!==s){if(t[s]){if(n.has(s))return;t[s].forEach(e=>e(...i)),delete t[s]}e[s]&&c(s)}else Object.keys(e).forEach(e=>c(e))},stop:function(r){if("*"===r){const r=Object.keys(e),o=Object.keys(t);return void(n=new Set([...o,...r]))}n.add(r)},start:function(e){"*"!==e?n.delete(e):n.clear()},debug:function(e,t){r=!!e,t&&"string"==typeof t&&(o=t)}}}(),s={currentContext:{name:null,note:null},shortcuts:{},plugins:[],exposeShortcut:!(!t.onShortcut||"function"!=typeof t.onShortcut)&&t.onShortcut,ERROR_EVENT_NAME:t.errorEventName?t.errorEventName:"@shortcuts-error"};let i={ev:o,inAPI:n,API:r,extra:{}};return r.enablePlugin=(e,t={})=>{if("function"!=typeof e)return;let r=e(i,s,t);const o=r.getPrefix();-1===n._systemAction(o,"none")?s.plugins.push(r):r.destroy()},r.disablePlugin=e=>{const t=n._systemAction(e,"destroy");-1!==t&&(s.plugins=s.plugins.filter((e,n)=>n!==t))},r.mutePlugin=e=>n._systemAction(e,"mute"),r.unmutePlugin=e=>n._systemAction(e,"unmute"),r.listPlugins=()=>s.plugins.map(e=>e.getPrefix()),r.getContext=()=>s.currentContext.name,r.getNote=()=>s.currentContext.note,r.setNote=(e=null)=>{"string"!=typeof e&&null!=e||(s.currentContext.note=e)},r.pause=(e="*")=>{let t=n._readShortcutWithPlugins(e);o.stop(t)},r.resume=(e="*")=>{const t=n._readShortcutWithPlugins(e);o.start(t)},r.emit=(e,...t)=>o.emit(n._readShortcutWithPlugins(e),...t),r.listContexts=()=>Object.keys(s.shortcuts),r.setDependencies=e=>i.extra={...i.extra,...e},r.getDependencies=()=>i.extra,r.reset=function(){o.reset(),r.changeContext(),s.plugins.forEach(e=>e.destroy()),r.listContexts().map(e=>r.unload(e)),i.extra={},s.exposeShortcut=null},Object.entries(e).forEach(([e,t])=>{e.startsWith("_")?n[e]=t(i,s):r[e]=t(i,s)}),r}var m=Object.freeze({__proto__:null,pluginClick:function(e,t,n){let{currentContext:r,shortcuts:o}=t,{inAPI:l}=e,a={ev:e.ev,_findTarget:s,_readClickEvent:c,mainDependencies:e,regex:/CLICK\s*\:/i},f={currentContext:r,active:!1,shortcuts:o,listenOptions:{mouseWait:n.mouseWait?n.mouseWait:320,maxClicks:1,clickTarget:n.clickTarget?n.clickTarget:"click"}};l._normalizeWithPlugins(i);let p=function(e,t){const{ev:n,_findTarget:r,_readClickEvent:o,mainDependencies:s}=e,{listenOptions:i,currentContext:c}=t,{mouseWait:u}=i;let l=null,a=null,f=null,p=null,m=0;function d(){const e=o(a,m),t={target:l,targetProps:l?l.getBoundingClientRect():null,x:a.clientX,y:a.clientY,context:c.name,note:c.note,event:a,dependencies:s.extra,type:"click"};n.emit(e,t),f=null,p=null,l=null,a=null,m=0}function h(n){let o=i.maxClicks;return clearTimeout(f),p?(clearTimeout(p),void(p=setTimeout(()=>p=null,u))):(l=r(e,t,n.target),l&&l.dataset.hasOwnProperty("quickClick")&&(o=1),l&&"A"===l.tagName&&(o=1),a=n,m++,m>=o?(d(),void(o>1&&(p=setTimeout(()=>p=null,u)))):void(f=setTimeout(d,u)))}function g(n){let o=i.maxClicks;return clearTimeout(f),p?(clearTimeout(p),void(p=setTimeout(()=>p=null,u))):(l=r(e,t,n.target),l&&l.dataset.hasOwnProperty("quickClick")&&(o=1),l&&"A"===l.tagName&&(o=1),a=n,m++,m>=o?(d(),void(o>1&&(p=setTimeout(()=>p=null,u)))):void(f=setTimeout(d,u)))}return{start:function(){t.active||(window.addEventListener("contextmenu",g),document.addEventListener("click",h),t.active=!0)},stop:function(){t.active&&(window.removeEventListener("contextmenu",g),document.removeEventListener("click",h),t.active=!1,f&&(clearTimeout(f),f=null),p&&(clearTimeout(p),p=null),m=0)}}}(a,f),m=u(a,f);m>0&&p.start();let d={getPrefix:()=>"click",shortcutName:e=>i(e),contextChange:()=>{m=u(a,f),m<1&&p.stop(),m>0&&p.start()},mute:()=>{p.stop()},unmute:()=>p.start(),destroy:()=>p.stop()};return Object.freeze(d),d},pluginForm:function(e,t,n){let{currentContext:r,shortcuts:o}=t,{inAPI:s}=e,i={ev:e.ev,mainDependencies:e,regex:/FORM\s*\:/i,_defaults:f},c={currentContext:r,shortcuts:o,callbacks:{},typeFn:"",watchList:[],wait:{}};s._normalizeWithPlugins(l);let u=function(e,t){const{ev:n}=e;let r=null;function o(e,t,n,r){return{target:n.target,context:t.currentContext.name,note:t.currentContext.note,event:n,dependencies:e.mainDependencies.extra,type:r}}function s(r){const{callbacks:s,typeFn:i}=t,c=i(r.target),u=o(e,t,r,c),l=`${c}/in`;null!=s[l]&&n.emit(l,u,s[l])}function i(r){const{callbacks:s,typeFn:i}=t,c=o(e,t,r,"form-out"),u=`${i(r.target)}/out`;null!=s[u]&&n.emit(u,c,s[u])}function c(s){const{callbacks:i,typeFn:c}=t,u=o(e,t,s,"form-instant"),l=c(s.target),a=t.wait[`${l}`],f=`${l}/instant`;null!=i[f]&&(0!==a?(clearTimeout(r),r=setTimeout(()=>n.emit(f,u,i[f]),a)):n.emit(f,u,i[f]))}return{start:function(){t.active||(document.addEventListener("focusin",s),document.addEventListener("focusout",i),document.addEventListener("input",c),t.active=!0)},stop:function(){t.active&&(document.removeEventListener("focusin",s),document.removeEventListener("focusout",i),document.removeEventListener("input",c),t.active=!1)}}}(i,c);r.name&&a(i,c)&&u.start();let p={getPrefix:()=>"form",shortcutName:e=>l(e),contextChange:()=>{c.callbacks={},c.typeFn="",c.watchList=[],c.wait={},a(i,c)?u.start():u.stop()},mute:()=>u.stop(),unmute:()=>u.start(),destroy:()=>{u.stop()}};return Object.freeze(p),p},pluginKey:function(e,s,i={}){let{currentContext:c,shortcuts:u,exposeShortcut:l}=s,{inAPI:a}=e,f={ev:e.ev,_specialChars:o,_readKeyEvent:n,mainDependencies:e,regex:/KEY\s*\:/i},p={currentContext:c,shortcuts:u,active:!1,listenOptions:{keyWait:i.keyWait?i.keyWait:480,maxSequence:1,keyIgnore:null},streamKeys:!(!i.streamKeys||"function"!=typeof i.streamKeys)&&i.streamKeys};a._normalizeWithPlugins(t);let m=function(e,t){const{ev:n,_specialChars:r,_readKeyEvent:o,mainDependencies:s}=e,{currentContext:i,streamKeys:c,listenOptions:u}=t,{keyWait:l}=u;let a=[],f=null,p=!0,m=!1;const d=()=>p=!1,h=()=>p=!0,g=()=>m=!0,y=()=>!1===p;function v(){let e=a.map(e=>[e.join("+")]);const t={wait:d,end:h,ignore:g,isWaiting:y,note:i.note,context:i.name,dependencies:s.extra,type:"key"};if(!p){let r=e.at(-1);n.emit(r,t),m&&(e=e.slice(0,-1),m=!1)}if(p){const r=`KEY:${e.join(",")}`;n.emit(r,t),a=[],f=null}}function x(t){if(clearTimeout(f),r().hasOwnProperty(t.code))return a.push(o(t,r)),c&&c({key:t.key,context:i.name,note:i.note,dependencies:e.extra}),u.keyIgnore?(clearTimeout(u.keyIgnore),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,l))):p&&a.length===u.maxSequence?(v(),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,l))):void(p?f=setTimeout(v,l):v())}function k(t){if(!r().hasOwnProperty(t.code)){if(clearTimeout(f),c&&c({key:t.key,context:i.name,note:i.note,dependencies:e.extra}),u.keyIgnore)return clearTimeout(u.keyIgnore),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,l));if(a.push(o(t,r)),p&&a.length===u.maxSequence)return v(),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,l));p?f=setTimeout(v,l):v()}}return{start:function(){t.active||(document.addEventListener("keydown",x),document.addEventListener("keypress",k),t.active=!0)},stop:function(){t.active&&(document.removeEventListener("keydown",x),document.removeEventListener("keypress",k),t.active=!1,f&&(clearTimeout(f),f=null),u.keyIgnore&&(clearTimeout(u.keyIgnore),u.keyIgnore=null),a=[],p=!0,m=!1)}}}(f,p),d=r(f,p);d>0&&m.start();let h={getPrefix:()=>"key",shortcutName:e=>t(e),contextChange:e=>{d=r(f,p),d<1&&m.stop(),d>0&&m.start()},mute:()=>m.stop(),unmute:()=>m.start(),destroy:()=>m.stop()};return Object.freeze(h),h},shortcuts:p});function d(e){return e?function(e){let t=e.map(e=>h()),n=t.map(e=>e.promise);t.promises=t;let r=g(Promise.all(n));function o(e){let t="pending";return e.then(()=>t="fulfilled").catch(()=>t="rejected"),t}function s(n,...r){t.forEach((t,s)=>n({value:e[s],done:t.done,cancel:t.cancel,timeout:t.timeout,state:o(t.promise)},...r))}const i={promise:Promise.all(n),promises:t,done:e=>{t.forEach(t=>t.done(e))},cancel:e=>{t.forEach(t=>t.cancel(e))},each:s,onComplete:r,timeout:()=>{}};return i.timeout=y(!0,i),i}(e):h()}function h(){let e,t;const n=new Promise((n,r)=>{e=n,t=r}),r={promise:n,promises:null,done:e,cancel:t,each:()=>{},onComplete:g(n),timeout:()=>{}};return r.timeout=y(!1,r),r.each=(n,...o)=>{n({value:null,done:e,cancel:t,timeout:r.timeout},...o)},r}function g(e){return function(t,n=null){null===n?e.then(e=>t(e)):e.then(e=>t(e),e=>n(e))}}function y(e,t){let n;return n=e?Promise.all(t.promises.map(e=>e.promise)):t.promise,function(e,r){let o,s=new Promise((t,s)=>{o=setTimeout(()=>{t(r),Promise.resolve(n)},e)});return n.then(()=>clearTimeout(o)),t.onComplete=g(Promise.race([n,s])),t}}function v({message:e,level:t,type:n,logLevel:r}){if(0===r)return null;if(r<t)return null;const o=`[Debug]: ${e}`;switch(n){case"warn":console.warn(o);break;case"error":console.error(o);break;default:console.log(o)}return o}function x(e={},t=v){return function({message:n,type:r,level:o,...s}){const{level:i,type:c,defaultMessageLevel:u}=Object.assign({},{level:1e3,type:"log",defaultMessageLevel:1},e);return r||(r=c),o||(o=u),t({message:n,type:r,level:o,logLevel:i,...s})}}function*k(e,t,n,r){let o=null,s=!0;if(null===e)return yield*r.map(e=>[e,"show"]),void(yield[n,"show"]);if(0!==r.length){if(r.includes(e)){for(let t=r.indexOf(e)+1;t<r.length;t++)yield[r[t],"show"];return void(yield[n,"show"])}if(!t)return yield[e,"hide"],void(yield*r.map(e=>[e,"show"]));if(r.every((e,n)=>t[n]===r[n]&&(o=n,!0)),null==o)return yield[e,"hide"],t.reverse(),yield*t.map(e=>[e,"hide"]),yield*r.map(e=>[e,"show"]),void(yield[n,"show"]);yield[e,"hide"];for(let e=t.length;e>o+1;e--)yield[t[e-1],"hide"];for(let e=o+1;e<r.length;e++)yield[r[e],"show"];yield[n,"show"]}else{if(yield[e,"hide"],t.includes(n)){let e=t.indexOf(n),r=t.filter((t,n)=>n>e);r.reverse(),yield*r.map(e=>[e,"hide"]),s=!1}else{let e=[...t];e.reverse(),yield*e.map(e=>[e,"hide"])}s&&(yield[n,"show"])}}function C(e){return function(t,...n){const{askForPromise:r,deps:o}=e;return function(){const e=r();return t({task:e,dependencies:o()},...n),e.promise}}}return d.sequence=function(e,...t){const n=d(),r=[];const o=function*(e){for(const t of e)yield t}(e);return function e(t,...s){t.done?n.done(r):t.value(...s).then(t=>{r.push(t),e(o.next(),...s,t)})}(o.next(),...t),n},d.all=function(e,...t){const n=d(),r=[],o=e.map((e,n)=>"function"==typeof e?e(...t).then(e=>r[n]=e):e.then(e=>r[n]=e));return Promise.all(o).then(()=>n.done(r)),n},function(e={logLevel:0}){const t=p({errorEventName:"@app-error"}),n=x({level:e.logLevel||1},e=>{const{type:n}=e;"error"===n&&t.emit("@app-error",e)}),r={currentScene:null,currentParents:null,sceneNames:new Set,scenes:{},opened:!1,jumpStack:[]},o={},s={shortcutMngr:t,findInstructions:k,askForPromise:d,setInstruction:C({askForPromise:d,deps:t.getDependencies}),log:n};return o.hide=function(e,t){return function(n=1){const{askForPromise:r,shortcutMngr:o,setInstruction:s}=e,{currentScene:i,currentParents:c,scenes:u}=t,l=r(),a=[],f=c.length>0;let p;return o.pause(),a.push(s(u[i].hide)),f||(t.currentScene=null),f&&"*"===n&&[...c].reverse().forEach(e=>{p=t.currentParents.at(-1),t.currentScene=p,a.push(s(u[e].hide))}),f&&!["*",1].includes(n)&&c.slice("-"+(n-1)).reverse().map(e=>{p=t.currentParents.at(-1),t.currentScene=p,a.push(s(u[e].hide))}),(n=r.sequence(a)).onComplete(()=>{o.changeContext(t.currentScene),l.done()}),l.promise}}(s,r),o.listShortcuts=function(e,t){return function(e){const{scenes:n,sceneNames:r}=t;if(!r.has(e))return null;const{show:o,hide:s,parents:i,beforeUnload:c,afterLoad:u,...l}=n[e];return Object.keys(l)}}(0,r),o.setScenes=function(e,t){return function(n){const{shortcutMngr:r,log:o}=e;n.forEach(e=>{if(null==e)return;const{name:n,scene:s}=e;if(!n)return void o({message:"Scene name is not defined",level:1,type:"error"});if(null==s)return void o({message:`Scene ${n} is not defined`,level:1,type:"error"});s.parents||(s.parents=[]),t.scenes[n]=s,t.sceneNames.add(n);const{show:i,hide:c,parents:u,...l}=s,a={};a[n]=l,r.load(a)})}}(s,r),o.show=function(e,t){return function({scene:n,options:r={ssr:!1}},...o){const{shortcutMngr:s,askForPromise:i,log:c,findInstructions:u,setInstruction:l}=e,a=i(),f=i(),{opened:p,scenes:m,sceneNames:d,currentScene:h}=t;return h&&"function"==typeof m[h].beforeHide?(0,m[h].beforeHide)({done:f.done,dependencies:s.getDependencies()}):f.done(!0),f.onComplete(e=>{if(!e)return a.done(),a.promise;if(!d.has(n))return c({message:`Scene "${n}" is not available.`,level:1,type:"error"}),a.done(),a.promise;if(!p&&r.ssr)return t.opened=!0,t.currentScene=n,s.changeContext(n),a.done(),a.promise;const{show:f,parents:h=[]}=m[n];if("*"===h[0])return l(f,...o)().then(()=>a.done()),t.currentParents.push(t.currentScene),t.currentScene=n,a.promise;if(0!==h.length&&!h.every(e=>d.has(e)))return c({message:`Some of '${n}' parent scenes are not set.`,level:1,type:"error"}),a.done(),a.promise;function g([e,n]){if("show"===n)t.currentScene&&(t.currentParents=[...m[t.currentScene].parents]),t.currentScene=e;else{let n=m[e].parents.at(-1);t.currentScene=n}return m[e][n]}t.currentParents||(t.currentParents=[]);const y=u(t.currentScene,t.currentParents,n,h),v=[];for(let e of y){const t=g(e);v.push(l(t,...o))}i.sequence(v).onComplete(()=>{t.opened=!0,t.currentScene=n,t.currentParents=m[n].parents||null,s.changeContext(n),"function"==typeof m[n].afterShow&&m[n].afterShow({dependencies:s.getDependencies(),done:()=>{}}),a.done()})}),a.promise}}(s,r),o.jump=function(e,t){return function({scene:n},...r){return e.jumpStack.push(e.currentScene),t({scene:n},...r)}}(r,o.show),o.jumpBack=function(e,t){return function({hops:n}={hops:1},...r){for(let t=0;t<n-1;t++)e.jumpStack.pop();if(0===e.jumpStack.length)return;const o=e.jumpStack.pop();return t({scene:o},...r)}}(r,o.show),o.jumpsReset=function(e){return function(){e.jumpStack=[]}}(r),o.loadPlugins=async function(e){const t=e.map(e=>`plugin${e}`),n=await Promise.resolve().then(function(){return m});return t.map(e=>n[e])},o.setDependencies=e=>t.setDependencies(e),o.getDependencies=()=>t.getDependencies(),o.setNote=e=>p.setNote(e),o.listScenes=()=>[...r.sceneNames],o.enablePlugin=(e,n)=>t.enablePlugin(e,n),o.disablePlugin=e=>t.disablePlugin(e),o.getState=()=>({scene:r.currentScene,parents:r.currentParents,opened:r.opened}),o.emit=(e,...n)=>t.emit(e,...n),o}});
|
package/package.json
CHANGED
package/src/findInstructions.js
CHANGED
|
@@ -20,13 +20,7 @@ function* findInstructions ( currentName, currentParents, targetName, targetPare
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
if ( targetParents.length === 0 ) { // Need to close all current parents, then open the target
|
|
23
|
-
if ( !currentParents ) {
|
|
24
|
-
yield [ currentName, 'hide' ]
|
|
25
|
-
yield [ targetName, 'show' ]
|
|
26
|
-
return
|
|
27
|
-
}
|
|
28
23
|
yield [ currentName, 'hide' ]
|
|
29
|
-
|
|
30
24
|
if ( currentParents.includes ( targetName ) ) {
|
|
31
25
|
let index = currentParents.indexOf ( targetName );
|
|
32
26
|
let filtered = currentParents.filter ( (x,i) => i > index )
|
package/src/main.js
CHANGED
|
@@ -37,8 +37,13 @@ import jumpsReset from './methods/jumpsReset.js'
|
|
|
37
37
|
function main ( cfg= {logLevel:0} ) {
|
|
38
38
|
const
|
|
39
39
|
shortcutMngr = shortcuts ({ errorEventName: '@app-error' })
|
|
40
|
-
, logLevel = cfg.logLevel ||
|
|
41
|
-
, log = createLog ({ level:logLevel })
|
|
40
|
+
, logLevel = cfg.logLevel || 1
|
|
41
|
+
, log = createLog ({ level:logLevel }, (arg) => {
|
|
42
|
+
const { type } = arg;
|
|
43
|
+
if ( type === 'error' ) {
|
|
44
|
+
shortcutMngr.emit ( '@app-error', arg )
|
|
45
|
+
}
|
|
46
|
+
})
|
|
42
47
|
, state = {
|
|
43
48
|
currentScene : null // Current scene name;
|
|
44
49
|
, currentParents : null // Current scene parents if any;
|
package/src/methods/setScenes.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {Object} AskObject
|
|
6
|
+
* @property {function} done - Mark the task as done
|
|
7
|
+
*/
|
|
4
8
|
/**
|
|
5
9
|
* @typedef {Object} SceneObject
|
|
6
|
-
* @property {function} show - load interface and prerequisites for the scene;
|
|
10
|
+
* @property {function({task: AskObject, dependencies: *}): void} show - load interface and prerequisites for the scene;
|
|
7
11
|
* @property {function():boolean} [afterShow] - run after scene is loaded. Optional. Returns true to continue loading, false to cancel;
|
|
8
|
-
* @property {function():void} hide - Reverse the settings from 'show';
|
|
12
|
+
* @property {function({task: AskObject, dependencies: *}): void} hide - Reverse the settings from 'show';
|
|
9
13
|
* @property {function():void} [beforeHide] - Run before scene is hidden. Optional;
|
|
10
14
|
* @property {Array.<string>} [parents] - list of parent scene names.
|
|
11
15
|
* @property {*} ... - shortcut descriptions
|
|
@@ -30,15 +34,27 @@ function setScenes ( dependencies, state ) {
|
|
|
30
34
|
* @description Screen Description is an object with fields 'name' and 'scene'
|
|
31
35
|
*/
|
|
32
36
|
return function setScenes ( list ) {
|
|
33
|
-
const { shortcutMngr } = dependencies;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
const { shortcutMngr, log } = dependencies;
|
|
38
|
+
list.forEach ( item => {
|
|
39
|
+
if ( item == null ) return
|
|
40
|
+
const {name, scene } = item;
|
|
41
|
+
if ( !name ) {
|
|
42
|
+
log ({
|
|
43
|
+
message: `Scene name is not defined`
|
|
44
|
+
, level : 1
|
|
45
|
+
, type : 'error'
|
|
46
|
+
})
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
if ( scene == null ) {
|
|
50
|
+
log ({
|
|
51
|
+
message: `Scene ${name} is not defined`
|
|
52
|
+
, level : 1
|
|
53
|
+
, type : 'error'
|
|
54
|
+
})
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
if ( ! scene.parents ) scene.parents = []
|
|
42
58
|
state.scenes[name] = scene
|
|
43
59
|
state.sceneNames.add ( name )
|
|
44
60
|
|
package/src/methods/show.js
CHANGED
|
@@ -24,8 +24,10 @@ function show ( dependencies, state ) {
|
|
|
24
24
|
|
|
25
25
|
if ( hasBeforeHide ) { // Execute 'beforeUnload' function if exists
|
|
26
26
|
const closingFn = scenes[currentScene].beforeHide;
|
|
27
|
+
// TODO: If async elements in beforeUnload, we will
|
|
28
|
+
// need full unloadTask and function should return a promise
|
|
27
29
|
closingFn ({ done:unloadTask.done, dependencies: shortcutMngr.getDependencies() })
|
|
28
|
-
} // if
|
|
30
|
+
} // if currentScene
|
|
29
31
|
else unloadTask.done ( true )
|
|
30
32
|
|
|
31
33
|
|
|
@@ -38,21 +40,19 @@ function show ( dependencies, state ) {
|
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
if ( !sceneNames.has ( requestedScene ) ) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return showTask.promise
|
|
49
|
-
}
|
|
43
|
+
log ({
|
|
44
|
+
message: `Scene "${requestedScene}" is not available.`
|
|
45
|
+
, level : 1
|
|
46
|
+
, type : 'error'
|
|
47
|
+
})
|
|
48
|
+
showTask.done ()
|
|
49
|
+
return showTask.promise
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
if ( !opened && options.ssr ) { // Check for Server side rendering on first scene load only
|
|
53
53
|
// Executes only once when the scene manager is started
|
|
54
54
|
state.opened = true
|
|
55
|
-
state.
|
|
55
|
+
state.currentScene = requestedScene
|
|
56
56
|
shortcutMngr.changeContext ( requestedScene )
|
|
57
57
|
showTask.done ()
|
|
58
58
|
return showTask.promise
|
|
@@ -60,23 +60,22 @@ function show ( dependencies, state ) {
|
|
|
60
60
|
|
|
61
61
|
const { show, parents=[] } = scenes[requestedScene];
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
63
|
+
if ( parents[0] === '*' ) {
|
|
64
|
+
const overlayTask = setInstruction(show, ...args)()
|
|
65
|
+
overlayTask.then ( () => showTask.done () )
|
|
66
|
+
state.currentParents.push ( state.currentScene )
|
|
67
|
+
state.currentScene = requestedScene
|
|
68
|
+
return showTask.promise
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let checkParents = ( parents.length === 0 ) ? true : parents.every ( name => sceneNames.has ( name ) )
|
|
71
72
|
|
|
72
73
|
if ( !checkParents ) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
})
|
|
79
|
-
}
|
|
74
|
+
log ({
|
|
75
|
+
message: `Some of '${requestedScene}' parent scenes are not set.`
|
|
76
|
+
, level : 1
|
|
77
|
+
, type : 'error'
|
|
78
|
+
})
|
|
80
79
|
showTask.done ()
|
|
81
80
|
return showTask.promise
|
|
82
81
|
}
|
|
@@ -109,7 +108,7 @@ function show ( dependencies, state ) {
|
|
|
109
108
|
|
|
110
109
|
goingTask.onComplete ( () => {
|
|
111
110
|
state.opened = true
|
|
112
|
-
state.
|
|
111
|
+
state.currentScene = requestedScene
|
|
113
112
|
state.currentParents = scenes[requestedScene].parents || null
|
|
114
113
|
shortcutMngr.changeContext ( requestedScene )
|
|
115
114
|
if ( typeof scenes[requestedScene].afterShow === 'function' ) scenes[requestedScene].afterShow ({ dependencies: shortcutMngr.getDependencies(), done: () => {} })
|
|
@@ -16,7 +16,7 @@ describe ( 'Cuts integration', () => {
|
|
|
16
16
|
{ name: 'deep', scene: { show: ({task}) => { calls.push('show deep'); task.done() }, hide: ({task}) => { calls.push('hide deep'); task.done() }, parents: ['top', 'mid'] } }
|
|
17
17
|
]
|
|
18
18
|
|
|
19
|
-
const script = cuts()
|
|
19
|
+
const script = cuts();
|
|
20
20
|
script.setScenes ( scenes )
|
|
21
21
|
|
|
22
22
|
await script.show ({ scene: 'top' })
|
|
@@ -31,12 +31,12 @@ describe ( 'Cuts integration', () => {
|
|
|
31
31
|
|
|
32
32
|
await script.show ({ scene: 'top' })
|
|
33
33
|
expect ( calls ).toEqual ([
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
'show top',
|
|
35
|
+
'show mid',
|
|
36
|
+
'show deep',
|
|
37
|
+
'hide deep',
|
|
38
|
+
'hide mid'
|
|
39
|
+
])
|
|
40
40
|
|
|
41
41
|
await script.show ({ scene: 'deep' })
|
|
42
42
|
expect ( calls ).toEqual ([
|
|
@@ -52,5 +52,361 @@ describe ( 'Cuts integration', () => {
|
|
|
52
52
|
|
|
53
53
|
|
|
54
54
|
|
|
55
|
+
it ( 'Load plugins', async () => {
|
|
56
|
+
const script = cuts()
|
|
57
|
+
const plugins = await script.loadPlugins ( ['Key', 'Click'] )
|
|
58
|
+
expect ( plugins ).toHaveLength ( 2 )
|
|
59
|
+
}) // it Load plugins
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
it ( 'beforeHide', async () => {
|
|
68
|
+
const script = cuts ();
|
|
69
|
+
const calls = [];
|
|
70
|
+
const scenes = [
|
|
71
|
+
{
|
|
72
|
+
name: 'top'
|
|
73
|
+
, scene: {
|
|
74
|
+
show: ({task}) => { calls.push('show top'); task.done() },
|
|
75
|
+
hide: ({task}) => { calls.push('hide top'); task.done() } ,
|
|
76
|
+
// Prevent unload event:
|
|
77
|
+
'beforeHide': ({ done }) => done ( false ) ,
|
|
78
|
+
'click: left-1': () => calls.push('click left-1')
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: 'other'
|
|
83
|
+
, scene: {
|
|
84
|
+
show: ({task}) => { calls.push('show other'); task.done() },
|
|
85
|
+
hide: ({task}) => { calls.push('hide other'); task.done() }
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
script.setScenes ( scenes )
|
|
91
|
+
await script.show ({ scene: 'top' })
|
|
92
|
+
expect ( calls ).toEqual (['show top'])
|
|
93
|
+
|
|
94
|
+
await script.show ({ scene: 'other' })
|
|
95
|
+
expect ( calls ).toEqual (['show top'])
|
|
96
|
+
expect ( script.getState().scene ).toEqual ( 'top' )
|
|
97
|
+
}) // it beforeHide
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
it ( 'Call no existing scene', async () => {
|
|
102
|
+
const script = cuts ({ logLevel : 1 });
|
|
103
|
+
const calls = [];
|
|
104
|
+
const scenes = [
|
|
105
|
+
{
|
|
106
|
+
name: 'top'
|
|
107
|
+
, scene: {
|
|
108
|
+
show: ({task}) => { calls.push('show top'); task.done() },
|
|
109
|
+
hide: ({task}) => { calls.push('hide top'); task.done() } ,
|
|
110
|
+
'click: left-1': () => calls.push ( 'click left-1' ),
|
|
111
|
+
'@app-error': ( arg ) => {
|
|
112
|
+
calls.push ( 'app-error' )
|
|
113
|
+
expect ( arg.type ).toBe ( 'error' )
|
|
114
|
+
expect ( arg.message ).toBe ( 'Scene "any" is not available.' )
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: 'other'
|
|
120
|
+
, scene: {
|
|
121
|
+
show: ({task}) => { calls.push('show other'); task.done() },
|
|
122
|
+
hide: ({task}) => { calls.push('hide other'); task.done() }
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
];
|
|
126
|
+
|
|
127
|
+
script.setScenes ( scenes )
|
|
128
|
+
await script.show ({ scene: 'top' })
|
|
129
|
+
expect ( calls ).toEqual (['show top'])
|
|
130
|
+
|
|
131
|
+
await script.show ({ scene: 'any' })
|
|
132
|
+
expect ( calls ).toEqual (['show top', 'app-error'])
|
|
133
|
+
expect ( script.getState().scene ).toEqual ( 'top' )
|
|
134
|
+
}) // it Call no existing scene
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
it ( 'Server side rendering (SSR)', async () => {
|
|
139
|
+
const script = cuts ();
|
|
140
|
+
const calls = [];
|
|
141
|
+
const scenes = [
|
|
142
|
+
{
|
|
143
|
+
name: 'home',
|
|
144
|
+
scene: {
|
|
145
|
+
show: ({task}) => { calls.push('show home'); task.done() },
|
|
146
|
+
hide: ({task}) => { calls.push('hide home'); task.done() }
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
];
|
|
150
|
+
|
|
151
|
+
script.setScenes ( scenes )
|
|
152
|
+
|
|
153
|
+
// SSR mode: show without executing the scene's show function
|
|
154
|
+
await script.show({ scene: 'home', options: { ssr: true } })
|
|
155
|
+
|
|
156
|
+
expect(calls).toEqual([]); // show function should not be called
|
|
157
|
+
expect(script.getState().scene ).toBe ( 'home' )
|
|
158
|
+
expect(script.getState().opened ).toBe ( true )
|
|
159
|
+
|
|
160
|
+
// Subsequent show should execute normally
|
|
161
|
+
await script.show ({ scene: 'home' })
|
|
162
|
+
expect( calls ).toEqual(['hide home', 'show home'])
|
|
163
|
+
}) // it Server side rendering (SSR)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
it ( 'Non existing parents error', async () => {
|
|
168
|
+
const script = cuts ();
|
|
169
|
+
const calls = [];
|
|
170
|
+
const scenes = [
|
|
171
|
+
{
|
|
172
|
+
name: 'child'
|
|
173
|
+
, scene: {
|
|
174
|
+
show: ({task}) => { calls.push('show child'); task.done() },
|
|
175
|
+
hide: ({task}) => { calls.push('hide child'); task.done() },
|
|
176
|
+
parents: [ 'nonexistent' ]
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
];
|
|
180
|
+
script.setScenes ( scenes )
|
|
181
|
+
await script.show ({ scene: 'child' })
|
|
182
|
+
expect ( calls ).toEqual ([])
|
|
183
|
+
expect ( script.getState().scene ).toBe ( null )
|
|
184
|
+
}) // it Non existing parents error
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
it ( 'No name scene', async () => {
|
|
189
|
+
const script = cuts({ logLevel : 0 });
|
|
190
|
+
const scenes = [
|
|
191
|
+
{
|
|
192
|
+
scene: {
|
|
193
|
+
show: ({task}) => task.done(),
|
|
194
|
+
hide: ({task}) => task.done()
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
];
|
|
198
|
+
script.setScenes ( scenes );
|
|
199
|
+
expect ( script.listScenes() ).toEqual ( [] );
|
|
200
|
+
}) // it No name scene
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
it ( 'No scene in definition', async () => {
|
|
205
|
+
const script = cuts({ logLevel : 0 });
|
|
206
|
+
const scenes = [ {name: 'top'} ];
|
|
207
|
+
script.setScenes ( scenes );
|
|
208
|
+
expect ( script.listScenes() ).toEqual ( [] );
|
|
209
|
+
}) // it No scene in definition
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
it ( 'List shortcuts', async () => {
|
|
214
|
+
const script = cuts ()
|
|
215
|
+
const calls = [];
|
|
216
|
+
|
|
217
|
+
const scenes = [
|
|
218
|
+
{
|
|
219
|
+
name: 'top'
|
|
220
|
+
, scene: {
|
|
221
|
+
show: ({task}) => { calls.push('show top'); task.done() },
|
|
222
|
+
hide: ({task}) => { calls.push('hide top'); task.done() } ,
|
|
223
|
+
'click: left-1': () => calls.push('click left-1')
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
];
|
|
227
|
+
|
|
228
|
+
script.setScenes ( scenes )
|
|
229
|
+
expect ( script.listShortcuts( 'top' ) ).toEqual ( ['click: left-1'] )
|
|
230
|
+
}) // it List shortcuts
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
it ( 'List shortcuts', async () => {
|
|
235
|
+
const script = cuts ()
|
|
236
|
+
const calls = [];
|
|
237
|
+
|
|
238
|
+
const scenes = [
|
|
239
|
+
{
|
|
240
|
+
name: 'top'
|
|
241
|
+
, scene: {
|
|
242
|
+
show: ({task}) => { calls.push('show top'); task.done() },
|
|
243
|
+
hide: ({task}) => { calls.push('hide top'); task.done() } ,
|
|
244
|
+
'click: left-1': () => calls.push('click left-1')
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
];
|
|
248
|
+
|
|
249
|
+
script.setScenes ( scenes )
|
|
250
|
+
expect ( script.listShortcuts( 'none' ) ).toEqual ( null )
|
|
251
|
+
}) // it List shortcuts
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
it ( 'Jump functionality', async () => {
|
|
256
|
+
const script = cuts({ logLevel : 0 });
|
|
257
|
+
const calls = [];
|
|
258
|
+
const scenes = [
|
|
259
|
+
{
|
|
260
|
+
name: 'home'
|
|
261
|
+
, scene: {
|
|
262
|
+
show: ({task}) => { calls.push('show home'); task.done() },
|
|
263
|
+
hide: ({task}) => { calls.push('hide home'); task.done() }
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
name: 'settings'
|
|
268
|
+
, scene: {
|
|
269
|
+
show: ({task}) => { calls.push('show settings'); task.done() },
|
|
270
|
+
hide: ({task}) => { calls.push('hide settings'); task.done() }
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
];
|
|
274
|
+
|
|
275
|
+
script.setScenes ( scenes );
|
|
276
|
+
|
|
277
|
+
await script.show ({ scene: 'home' });
|
|
278
|
+
expect ( calls ).toEqual (['show home']);
|
|
279
|
+
expect ( script.getState().scene ).toEqual ( 'home' );
|
|
280
|
+
|
|
281
|
+
await script.jump ({ scene: 'settings' });
|
|
282
|
+
expect ( calls ).toEqual (['show home', 'hide home', 'show settings']);
|
|
283
|
+
expect ( script.getState().scene ).toEqual ( 'settings' );
|
|
284
|
+
|
|
285
|
+
await script.jumpBack ();
|
|
286
|
+
expect ( calls ).toEqual (['show home', 'hide home', 'show settings', 'hide settings', 'show home']);
|
|
287
|
+
expect ( script.getState().scene ).toEqual ( 'home' );
|
|
288
|
+
}) // it Jump functionality
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
it ( 'Jump with hops', async () => {
|
|
293
|
+
const script = cuts();
|
|
294
|
+
const calls = [];
|
|
295
|
+
const scenes = [
|
|
296
|
+
{
|
|
297
|
+
name: 'scene1'
|
|
298
|
+
, scene: {
|
|
299
|
+
show: ({task}) => { calls.push('show scene1'); task.done() },
|
|
300
|
+
hide: ({task}) => { calls.push('hide scene1'); task.done() }
|
|
301
|
+
}
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
name: 'scene2'
|
|
305
|
+
, scene: {
|
|
306
|
+
show: ({task}) => { calls.push('show scene2'); task.done() },
|
|
307
|
+
hide: ({task}) => { calls.push('hide scene2'); task.done() }
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
name: 'scene3'
|
|
312
|
+
, scene: {
|
|
313
|
+
show: ({task}) => { calls.push('show scene3'); task.done() },
|
|
314
|
+
hide: ({task}) => { calls.push('hide scene3'); task.done() }
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
];
|
|
318
|
+
|
|
319
|
+
script.setScenes ( scenes );
|
|
320
|
+
|
|
321
|
+
await script.show ({ scene: 'scene1' });
|
|
322
|
+
expect ( script.getState().scene ).toEqual ( 'scene1' );
|
|
323
|
+
|
|
324
|
+
await script.jump ({ scene: 'scene2' });
|
|
325
|
+
expect ( script.getState().scene ).toEqual ( 'scene2' );
|
|
326
|
+
|
|
327
|
+
await script.jump ({ scene: 'scene3' });
|
|
328
|
+
expect ( script.getState().scene ).toEqual ( 'scene3' );
|
|
329
|
+
|
|
330
|
+
await script.jumpBack ({ hops: 2 });
|
|
331
|
+
expect ( script.getState().scene ).toEqual ( 'scene1' );
|
|
332
|
+
}) // it Jump with hops
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
it ( 'Jumps reset and jump back on empty stack', async () => {
|
|
337
|
+
const script = cuts();
|
|
338
|
+
const scenes = [
|
|
339
|
+
{
|
|
340
|
+
name: 'scene1'
|
|
341
|
+
, scene: {
|
|
342
|
+
show: ({task}) => task.done(),
|
|
343
|
+
hide: ({task}) => task.done()
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
name: 'scene2'
|
|
348
|
+
, scene: {
|
|
349
|
+
show: ({task}) => task.done(),
|
|
350
|
+
hide: ({task}) => task.done()
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
];
|
|
354
|
+
|
|
355
|
+
script.setScenes ( scenes );
|
|
356
|
+
|
|
357
|
+
await script.show ({ scene: 'scene1' });
|
|
358
|
+
await script.jump ({ scene: 'scene2' });
|
|
359
|
+
expect ( script.getState().scene ).toEqual ( 'scene2' );
|
|
360
|
+
|
|
361
|
+
script.jumpsReset();
|
|
362
|
+
|
|
363
|
+
const result = await script.jumpBack();
|
|
364
|
+
expect ( result ).toBeUndefined();
|
|
365
|
+
expect ( script.getState().scene ).toEqual ( 'scene2' ); // scene should not change
|
|
366
|
+
}) // it Jumps reset and jump back on empty stack
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
it ( 'Show scene with wildcard parent', async () => {
|
|
371
|
+
// Test for scenes with parents: ['*']
|
|
372
|
+
// The '*' wildcard allows the scene to be shown as an overlay over any current scene
|
|
373
|
+
// without hiding the underlying scene. The previous scene is preserved in currentParents.
|
|
374
|
+
const script = cuts();
|
|
375
|
+
const calls = [];
|
|
376
|
+
const scenes = [
|
|
377
|
+
{
|
|
378
|
+
name: 'base'
|
|
379
|
+
, scene: {
|
|
380
|
+
show: ({task}) => { calls.push('show base'); task.done() },
|
|
381
|
+
hide: ({task}) => { calls.push('hide base'); task.done() }
|
|
382
|
+
}
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
name: 'overlay' // This scene uses '*' to indicate it can overlay any scene
|
|
386
|
+
, scene: {
|
|
387
|
+
show: ({task}) => {
|
|
388
|
+
calls.push ( 'show overlay' )
|
|
389
|
+
task.done ()
|
|
390
|
+
},
|
|
391
|
+
hide: ({task}) => { calls.push('hide overlay'); task.done() },
|
|
392
|
+
parents: ['*'] // '*' means this scene can be shown over any current scene
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
];
|
|
396
|
+
|
|
397
|
+
script.setScenes ( scenes );
|
|
398
|
+
|
|
399
|
+
await script.show ({ scene: 'base' });
|
|
400
|
+
expect ( calls ).toEqual (['show base']);
|
|
401
|
+
expect ( script.getState().scene ).toEqual ( 'base' );
|
|
402
|
+
expect ( script.getState().parents ).toEqual ( [] );
|
|
403
|
+
|
|
404
|
+
await script.show ({ scene: 'overlay' });
|
|
405
|
+
expect ( calls ).toEqual (['show base', 'show overlay']); // Note: 'hide base' is not called
|
|
406
|
+
expect ( script.getState().scene ).toEqual ( 'overlay' );
|
|
407
|
+
expect ( script.getState().parents ).toEqual ( ['base'] ); // Previous scene is saved
|
|
408
|
+
}) // it Show scene with wildcard parent
|
|
409
|
+
|
|
410
|
+
|
|
55
411
|
|
|
56
|
-
}) // describe
|
|
412
|
+
}) // describe
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"findInstructions.d.ts","sourceRoot":"","sources":["../src/findInstructions.js"],"names":[],"mappings":";AAGA;;;;;;;;GAQG;AACH,+CANW,MAAM,GAAC,IAAI,kBACX,KAAK,CAAE,MAAM,CAAC,cACd,MAAM,iBACN,KAAK,CAAE,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"findInstructions.d.ts","sourceRoot":"","sources":["../src/findInstructions.js"],"names":[],"mappings":";AAGA;;;;;;;;GAQG;AACH,+CANW,MAAM,GAAC,IAAI,kBACX,KAAK,CAAE,MAAM,CAAC,cACd,MAAM,iBACN,KAAK,CAAE,MAAM,CAAC,sCAyExB"}
|
package/types/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.js"],"names":[],"mappings":";AAoCA;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.js"],"names":[],"mappings":";AAoCA;;;;;;;;;;;;;;;;;;;yBA8CmB,KAAK,0BAAc,GACjB,OAAO,CAAE,UAAU,CAAC;0BAgBtB,GAAC;uBAQC,GAAC;kBAMH,MAAM;kBAQJ,KAAK,CAAE,MAAM,CAAC;6CAQhB,GAAC;8BAQD,MAAM;;gBAuBL,MAAM,WACH,GAAC,EAAA;EAKvB"}
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
export default setScenes;
|
|
2
|
+
export type AskObject = {
|
|
3
|
+
/**
|
|
4
|
+
* - Mark the task as done
|
|
5
|
+
*/
|
|
6
|
+
done: Function;
|
|
7
|
+
};
|
|
2
8
|
export type SceneObject = {
|
|
3
9
|
/**
|
|
4
10
|
* - load interface and prerequisites for the scene;
|
|
5
11
|
*/
|
|
6
|
-
show:
|
|
12
|
+
show: (arg0: {
|
|
13
|
+
task: AskObject;
|
|
14
|
+
dependencies: any;
|
|
15
|
+
}) => void;
|
|
7
16
|
/**
|
|
8
17
|
* - run after scene is loaded. Optional. Returns true to continue loading, false to cancel;
|
|
9
18
|
*/
|
|
@@ -11,7 +20,10 @@ export type SceneObject = {
|
|
|
11
20
|
/**
|
|
12
21
|
* - Reverse the settings from 'show';
|
|
13
22
|
*/
|
|
14
|
-
hide: (
|
|
23
|
+
hide: (arg0: {
|
|
24
|
+
task: AskObject;
|
|
25
|
+
dependencies: any;
|
|
26
|
+
}) => void;
|
|
15
27
|
/**
|
|
16
28
|
* - Run before scene is hidden. Optional;
|
|
17
29
|
*/
|
|
@@ -35,11 +47,15 @@ export type sceneDescription = {
|
|
|
35
47
|
*/
|
|
36
48
|
scene: SceneObject;
|
|
37
49
|
};
|
|
50
|
+
/**
|
|
51
|
+
* @typedef {Object} AskObject
|
|
52
|
+
* @property {function} done - Mark the task as done
|
|
53
|
+
*/
|
|
38
54
|
/**
|
|
39
55
|
* @typedef {Object} SceneObject
|
|
40
|
-
* @property {function} show - load interface and prerequisites for the scene;
|
|
56
|
+
* @property {function({task: AskObject, dependencies: *}): void} show - load interface and prerequisites for the scene;
|
|
41
57
|
* @property {function():boolean} [afterShow] - run after scene is loaded. Optional. Returns true to continue loading, false to cancel;
|
|
42
|
-
* @property {function():void} hide - Reverse the settings from 'show';
|
|
58
|
+
* @property {function({task: AskObject, dependencies: *}): void} hide - Reverse the settings from 'show';
|
|
43
59
|
* @property {function():void} [beforeHide] - Run before scene is hidden. Optional;
|
|
44
60
|
* @property {Array.<string>} [parents] - list of parent scene names.
|
|
45
61
|
* @property {*} ... - shortcut descriptions
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setScenes.d.ts","sourceRoot":"","sources":["../../src/methods/setScenes.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setScenes.d.ts","sourceRoot":"","sources":["../../src/methods/setScenes.js"],"names":[],"mappings":";;;;;;;;;;;UASc,CAAS,IAAkC,EAAlC;QAAC,IAAI,EAAE,SAAS,CAAC;QAAC,YAAY,EAAE,GAAC,CAAA;KAAC,KAAG,IAAI;;;;gBAClD,MAAW,OAAO;;;;UAClB,CAAS,IAAkC,EAAlC;QAAC,IAAI,EAAE,SAAS,CAAC;QAAC,YAAY,EAAE,GAAC,CAAA;KAAC,KAAG,IAAI;;;;iBAClD,MAAW,IAAI;;;;cACf,KAAK,CAAE,MAAM,CAAC;;;;QACd,GAAC;;;;;;UAOD,MAAM;;;;WACN,WAAW;;AAnBzB;;;GAGG;AACH;;;;;;;;GAQG;AAIH;;;;GAIG;AAKH,4DAOgC,MAJhB,gBAAgB,EAII,UAkClC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"show.d.ts","sourceRoot":"","sources":["../../src/methods/show.js"],"names":[],"mappings":";AAIA,2FAKG;IAAwB,KAAK,EAArB,MAAM;IACW,OAAO,GAChC;QAAiC,GAAG,EAA5B,OAAO;KACf;CAAA,
|
|
1
|
+
{"version":3,"file":"show.d.ts","sourceRoot":"","sources":["../../src/methods/show.js"],"names":[],"mappings":";AAIA,2FAKG;IAAwB,KAAK,EAArB,MAAM;IACW,OAAO,GAChC;QAAiC,GAAG,EAA5B,OAAO;KACf;CAAA,mCA4GF"}
|