@peter.naydenov/cuts 1.1.0 → 1.2.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 CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
 
4
4
 
5
+
6
+
7
+ ### 1.2.0 (2024-12-21)
8
+ - [x] Extend 'scene' with optional 'afterShow' and 'beforeHide' methods;
9
+
10
+
11
+
5
12
  ### 1.1.0 (2024-12-13)
6
13
  - [x] Type improvements;
7
14
  - [x] Refactoring related to types;
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;if(null===e)return yield*t.map((e=>[e,"show"])),void(yield[r,"show"]);if(!t||0===t.length)return n?(yield[e,"hide"],n.reverse(),yield*n.map((e=>[e,"hide"])),void(yield[r,"show"])):(yield[e,"hide"],void(yield[r,"show"]));if(t.includes(e)){for(let n=t.indexOf(e)+1;n<t.length;n++)yield[t[n],"show"];yield[r,"show"]}else{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"]}}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(e,n){return function(e){const{scenes:r,sceneNames:t}=n;if(!t.has(e))return null;const{show:s,hide:o,parents:i,...c}=r[e];return Object.keys(c)}}module.exports=function(i={logLevel:0}){const c=e.shortcuts(),u=i.logLevel||0,l=r({level:u}),d={currentScene:null,currentParents:null,sceneNames:new Set,scenes:{},opened:!1},a={},h={shortcutMngr:c,API:a,inAPI:{},findInstructions:t,askForPromise:n,setInstruction:s({askForPromise:n,deps:c.getDependencies}),log:l};return a.hide=function(e,n){return function(r=1){const{askForPromise:t,shortcutMngr:s,setInstruction:o}=e,{currentScene:i,currentParents:c,scenes:u}=n,l=t(),d=[],a=c.length>0;let h;return s.pause(),d.push(o(u[i].hide)),a||(n.currentScene=null),a&&"*"===r&&[...c].reverse().forEach((e=>{h=n.currentParents.pop(),n.currentScene=h,d.push(o(u[e].hide))})),a&&!["*",1].includes(r)&&c.slice("-"+(r-1)).reverse().map((e=>{h=n.currentParents.pop(),n.currentScene=h,d.push(o(u[e].hide))})),(r=t.sequence(d)).onComplete((()=>{s.changeContext(n.currentScene),l.done()})),l.promise}}(h,d),a.listShortcuts=o(0,d),a.listShortcuts=o(0,d),a.setScenes=function(e,n){return function(r){const{shortcutMngr:t}=e;r.forEach((({name:e,scene:r})=>{r.parents||(r.parents=[]),n.scenes[e]=r,n.sceneNames.add(e);const{show:s,hide:o,parents:i,...c}=r,u={};u[e]=c,t.load(u)}))}}(h,d),a.show=function(e,n){return function({scene:r,options:t={ssr:!1}},...s){const{shortcutMngr:o,askForPromise:i,log:c,findInstructions:u,setInstruction:l}=e,d=i(),{opened:a,scenes:h,sceneNames:p}=n;if(!p.has(r)&&c)return c({message:`Scene ${r} is not available.`,level:1,type:"error"}),d.done(),d.promise;if(!a&&t.ssr)return n.opened=!0,n.currentPage=r,o.changeContext(r),d.done(),d.promise;const{show:f,parents:m}=h[r];if("*"===m[0])return f().then((()=>d.done())),n.currentParents.push(n.currentPage),n.currentPage=r,d.promise;function g([e,r]){if("show"===r)n.currentScene&&n.currentParents.push(n.currentScene),n.currentScene=e;else{let e=n.currentParents.pop();n.currentScene=e}return h[e][r]}m.forEach((e=>p.has(e))),n.currentParents||(n.currentParents=[]);const y=u(n.currentScene,n.currentParents,r,m),P=[];for(let e of y)[e].map(g).map((e=>P.push(l(e),...s)));return i.sequence(P).onComplete((()=>{n.opened=!0,o.changeContext(r),d.done()})),d.promise}}(h,d),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.shortcuts.setNote(n),a.listScenes=()=>[...d.sceneNames],a.enablePlugin=(e,n)=>c.enablePlugin(e,n),a.disablePlugin=e=>c.disablePlugin(e),a.emit=(e,...n)=>c.emit(e,...n),a};
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;if(null===e)return yield*t.map((e=>[e,"show"])),void(yield[r,"show"]);if(!t||0===t.length)return n?(yield[e,"hide"],n.reverse(),yield*n.map((e=>[e,"hide"])),void(yield[r,"show"])):(yield[e,"hide"],void(yield[r,"show"]));if(t.includes(e)){for(let n=t.indexOf(e)+1;n<t.length;n++)yield[t[n],"show"];yield[r,"show"]}else{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"]}}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(e,n){return function(e){const{scenes:r,sceneNames:t}=n;if(!t.has(e))return null;const{show:s,hide:o,parents:i,beforeUnload:c,afterLoad:u,...l}=r[e];return Object.keys(l)}}module.exports=function(i={logLevel:0}){const c=e.shortcuts(),u=i.logLevel||0,l=r({level:u}),d={currentScene:null,currentParents:null,sceneNames:new Set,scenes:{},opened:!1},a={},h={shortcutMngr:c,API:a,inAPI:{},findInstructions:t,askForPromise:n,setInstruction:s({askForPromise:n,deps:c.getDependencies}),log:l};return a.hide=function(e,n){return function(r=1){const{askForPromise:t,shortcutMngr:s,setInstruction:o}=e,{currentScene:i,currentParents:c,scenes:u}=n,l=t(),d=[],a=c.length>0;let h;return s.pause(),d.push(o(u[i].hide)),a||(n.currentScene=null),a&&"*"===r&&[...c].reverse().forEach((e=>{h=n.currentParents.pop(),n.currentScene=h,d.push(o(u[e].hide))})),a&&!["*",1].includes(r)&&c.slice("-"+(r-1)).reverse().map((e=>{h=n.currentParents.pop(),n.currentScene=h,d.push(o(u[e].hide))})),(r=t.sequence(d)).onComplete((()=>{s.changeContext(n.currentScene),l.done()})),l.promise}}(h,d),a.listShortcuts=o(0,d),a.listShortcuts=o(0,d),a.setScenes=function(e,n){return function(r){const{shortcutMngr:t}=e;r.forEach((({name:e,scene:r})=>{r.parents||(r.parents=[]),n.scenes[e]=r,n.sceneNames.add(e);const{show:s,hide:o,parents:i,...c}=r,u={};u[e]=c,t.load(u)}))}}(h,d),a.show=function(e,n){return function({scene:r,options:t={ssr:!1}},...s){const{shortcutMngr:o,askForPromise:i,log:c,findInstructions:u,setInstruction:l}=e,d=i(),a=i(),{opened:h,scenes:p,sceneNames:f,currentPage:m}=n;if(m){const n=p[m].beforeHide;"function"==typeof n&&n({done:a.done,dependencies:e})}else a.done();return a.onComplete((a=>{if(!a)return d.done(),d.promise;if(!f.has(r)&&c)return c({message:`Scene ${r} is not available.`,level:1,type:"error"}),d.done(),d.promise;if(!h&&t.ssr)return n.opened=!0,n.currentPage=r,o.changeContext(r),d.done(),d.promise;const{show:m,parents:g=[]}=p[r];if("*"===g[0])return m().then((()=>d.done())),n.currentParents.push(n.currentPage),n.currentPage=r,d.promise;function y([e,r]){if("show"===r)n.currentScene&&n.currentParents.push(n.currentScene),n.currentScene=e;else{let e=n.currentParents.pop();n.currentScene=e}return p[e][r]}g.forEach((e=>f.has(e))),n.currentParents||(n.currentParents=[]);const P=u(n.currentScene,n.currentParents,r,g),w=[];for(let e of P)[e].map(y).map((e=>w.push(l(e),...s)));i.sequence(w).onComplete((()=>{n.opened=!0,o.changeContext(r),"function"==typeof p[r].afterShow&&p[r].afterShow({dependencies:e,done:()=>{}}),d.done()}))})),d.promise}}(h,d),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.shortcuts.setNote(n),a.listScenes=()=>[...d.sceneNames],a.enablePlugin=(e,n)=>c.enablePlugin(e,n),a.disablePlugin=e=>c.disablePlugin(e),a.emit=(e,...n)=>c.emit(e,...n),a};
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;if(null===e)return yield*t.map((e=>[e,"show"])),void(yield[r,"show"]);if(!t||0===t.length)return n?(yield[e,"hide"],n.reverse(),yield*n.map((e=>[e,"hide"])),void(yield[r,"show"])):(yield[e,"hide"],void(yield[r,"show"]));if(t.includes(e)){for(let n=t.indexOf(e)+1;n<t.length;n++)yield[t[n],"show"];yield[r,"show"]}else{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"]}}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(e,n){return function(e){const{scenes:r,sceneNames:t}=n;if(!t.has(e))return null;const{show:s,hide:o,parents:i,...c}=r[e];return Object.keys(c)}}function i(i={logLevel:0}){const c=e(),u=i.logLevel||0,l=r({level:u}),d={currentScene:null,currentParents:null,sceneNames:new Set,scenes:{},opened:!1},a={},p={shortcutMngr:c,API:a,inAPI:{},findInstructions:t,askForPromise:n,setInstruction:s({askForPromise:n,deps:c.getDependencies}),log:l};return a.hide=function(e,n){return function(r=1){const{askForPromise:t,shortcutMngr:s,setInstruction:o}=e,{currentScene:i,currentParents:c,scenes:u}=n,l=t(),d=[],a=c.length>0;let p;return s.pause(),d.push(o(u[i].hide)),a||(n.currentScene=null),a&&"*"===r&&[...c].reverse().forEach((e=>{p=n.currentParents.pop(),n.currentScene=p,d.push(o(u[e].hide))})),a&&!["*",1].includes(r)&&c.slice("-"+(r-1)).reverse().map((e=>{p=n.currentParents.pop(),n.currentScene=p,d.push(o(u[e].hide))})),(r=t.sequence(d)).onComplete((()=>{s.changeContext(n.currentScene),l.done()})),l.promise}}(p,d),a.listShortcuts=o(0,d),a.listShortcuts=o(0,d),a.setScenes=function(e,n){return function(r){const{shortcutMngr:t}=e;r.forEach((({name:e,scene:r})=>{r.parents||(r.parents=[]),n.scenes[e]=r,n.sceneNames.add(e);const{show:s,hide:o,parents:i,...c}=r,u={};u[e]=c,t.load(u)}))}}(p,d),a.show=function(e,n){return function({scene:r,options:t={ssr:!1}},...s){const{shortcutMngr:o,askForPromise:i,log:c,findInstructions:u,setInstruction:l}=e,d=i(),{opened:a,scenes:p,sceneNames:h}=n;if(!h.has(r)&&c)return c({message:`Scene ${r} is not available.`,level:1,type:"error"}),d.done(),d.promise;if(!a&&t.ssr)return n.opened=!0,n.currentPage=r,o.changeContext(r),d.done(),d.promise;const{show:f,parents:m}=p[r];if("*"===m[0])return f().then((()=>d.done())),n.currentParents.push(n.currentPage),n.currentPage=r,d.promise;function g([e,r]){if("show"===r)n.currentScene&&n.currentParents.push(n.currentScene),n.currentScene=e;else{let e=n.currentParents.pop();n.currentScene=e}return p[e][r]}m.forEach((e=>h.has(e))),n.currentParents||(n.currentParents=[]);const y=u(n.currentScene,n.currentParents,r,m),P=[];for(let e of y)[e].map(g).map((e=>P.push(l(e),...s)));return i.sequence(P).onComplete((()=>{n.opened=!0,o.changeContext(r),d.done()})),d.promise}}(p,d),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=()=>[...d.sceneNames],a.enablePlugin=(e,n)=>c.enablePlugin(e,n),a.disablePlugin=e=>c.disablePlugin(e),a.emit=(e,...n)=>c.emit(e,...n),a}export{i as default};
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;if(null===e)return yield*t.map((e=>[e,"show"])),void(yield[r,"show"]);if(!t||0===t.length)return n?(yield[e,"hide"],n.reverse(),yield*n.map((e=>[e,"hide"])),void(yield[r,"show"])):(yield[e,"hide"],void(yield[r,"show"]));if(t.includes(e)){for(let n=t.indexOf(e)+1;n<t.length;n++)yield[t[n],"show"];yield[r,"show"]}else{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"]}}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(e,n){return function(e){const{scenes:r,sceneNames:t}=n;if(!t.has(e))return null;const{show:s,hide:o,parents:i,beforeUnload:c,afterLoad:u,...l}=r[e];return Object.keys(l)}}function i(i={logLevel:0}){const c=e(),u=i.logLevel||0,l=r({level:u}),d={currentScene:null,currentParents:null,sceneNames:new Set,scenes:{},opened:!1},a={},p={shortcutMngr:c,API:a,inAPI:{},findInstructions:t,askForPromise:n,setInstruction:s({askForPromise:n,deps:c.getDependencies}),log:l};return a.hide=function(e,n){return function(r=1){const{askForPromise:t,shortcutMngr:s,setInstruction:o}=e,{currentScene:i,currentParents:c,scenes:u}=n,l=t(),d=[],a=c.length>0;let p;return s.pause(),d.push(o(u[i].hide)),a||(n.currentScene=null),a&&"*"===r&&[...c].reverse().forEach((e=>{p=n.currentParents.pop(),n.currentScene=p,d.push(o(u[e].hide))})),a&&!["*",1].includes(r)&&c.slice("-"+(r-1)).reverse().map((e=>{p=n.currentParents.pop(),n.currentScene=p,d.push(o(u[e].hide))})),(r=t.sequence(d)).onComplete((()=>{s.changeContext(n.currentScene),l.done()})),l.promise}}(p,d),a.listShortcuts=o(0,d),a.listShortcuts=o(0,d),a.setScenes=function(e,n){return function(r){const{shortcutMngr:t}=e;r.forEach((({name:e,scene:r})=>{r.parents||(r.parents=[]),n.scenes[e]=r,n.sceneNames.add(e);const{show:s,hide:o,parents:i,...c}=r,u={};u[e]=c,t.load(u)}))}}(p,d),a.show=function(e,n){return function({scene:r,options:t={ssr:!1}},...s){const{shortcutMngr:o,askForPromise:i,log:c,findInstructions:u,setInstruction:l}=e,d=i(),a=i(),{opened:p,scenes:h,sceneNames:f,currentPage:m}=n;if(m){const n=h[m].beforeHide;"function"==typeof n&&n({done:a.done,dependencies:e})}else a.done();return a.onComplete((a=>{if(!a)return d.done(),d.promise;if(!f.has(r)&&c)return c({message:`Scene ${r} is not available.`,level:1,type:"error"}),d.done(),d.promise;if(!p&&t.ssr)return n.opened=!0,n.currentPage=r,o.changeContext(r),d.done(),d.promise;const{show:m,parents:g=[]}=h[r];if("*"===g[0])return m().then((()=>d.done())),n.currentParents.push(n.currentPage),n.currentPage=r,d.promise;function y([e,r]){if("show"===r)n.currentScene&&n.currentParents.push(n.currentScene),n.currentScene=e;else{let e=n.currentParents.pop();n.currentScene=e}return h[e][r]}g.forEach((e=>f.has(e))),n.currentParents||(n.currentParents=[]);const P=u(n.currentScene,n.currentParents,r,g),w=[];for(let e of P)[e].map(y).map((e=>w.push(l(e),...s)));i.sequence(w).onComplete((()=>{n.opened=!0,o.changeContext(r),"function"==typeof h[r].afterShow&&h[r].afterShow({dependencies:e,done:()=>{}}),d.done()}))})),d.promise}}(p,d),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=()=>[...d.sceneNames],a.enablePlugin=(e,n)=>c.enablePlugin(e,n),a.disablePlugin=e=>c.disablePlugin(e),a.emit=(e,...n)=>c.emit(e,...n),a}export{i 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],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}=t,{ev:o}=e;return function(e=!1){const s=r.name;if(!e)return o.reset(),void(r.name=null);s!==e&&(n[e]?(n[s]&&o.reset(),r.name=e,t.plugins.forEach((t=>t.contextChange(e))),Object.entries(n[e]).forEach((([e,t])=>{t.forEach((t=>o.on(e,t)))})),o.on("*",((...e)=>{t.exposeShortcut&&t.exposeShortcut(...e)}))):o.emit("@shortcuts-error",`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}=t,{ev:o}=e;return function(e){n.name!==e?r[e]?delete r[e]:o.emit("shortcuts-error",`Context '${e}' does not exist`):o.emit("shortcuts-error",`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=e.code.replace("Key","").replace("Digit",""),i=[];return o&&i.push("CTRL"),n&&i.push("SHIFT"),r&&i.push("ALT"),t.hasOwnProperty(s)?i.push(t[s].toUpperCase()):["ControlLeft","ControlRight","ShiftLeft","ShiftRight","AltLeft","AltRight","Meta"].includes(s)||i.push(s.toUpperCase()),i.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(t={}){const n=new function(){let e={"*":[]},t={},n=[],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=[]},emit:function(){const[s,...i]=arguments;function c(t){let r=!1;"*"!==t&&(n.includes(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.includes(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)n.push(r);else{const r=Object.keys(e),o=Object.keys(t);n=[...o,...r]}},start:function(e){n="*"!==e?n.filter((t=>e!=t)):[]},debug:function(e,t){r=!!e,t&&"string"==typeof t&&(o=t)}}},r={},o={},s={currentContext:{name:null,note:null},shortcuts:{},plugins:[],exposeShortcut:!(!t.onShortcut||"function"!=typeof t.onShortcut)&&t.onShortcut},i={ev:n,inAPI:r,API:o,extra:{}};return o.enablePlugin=(e,t={})=>{const n=e.name;if(-1===r._systemAction(n,"none")){let n;n=e(i,s,t),s.plugins.push(n)}},o.disablePlugin=e=>{const t=r._systemAction(e,"destroy");-1!==t&&(s.plugins=s.plugins.filter(((e,n)=>n!==t)))},o.mutePlugin=e=>r._systemAction(e,"mute"),o.unmutePlugin=e=>r._systemAction(e,"unmute"),o.getContext=()=>s.currentContext.name,o.getNote=()=>s.currentContext.note,o.setNote=(e=null)=>{"string"!=typeof e&&null!=e||(s.currentContext.note=e)},o.pause=(e="*")=>{let t=r._readShortcutWithPlugins(e);n.stop(t)},o.resume=(e="*")=>{const t=r._readShortcutWithPlugins(e);n.start(t)},o.emit=(e,...t)=>n.emit(r._readShortcutWithPlugins(e),...t),o.listContexts=()=>Object.keys(s.shortcuts),o.setDependencies=e=>i.extra={...i.extra,...e},o.getDependencies=()=>i.extra,Object.entries(e).forEach((([e,t])=>{e.startsWith("_")?r[e]=t(i,s):o[e]=t(i,s)})),o}var a=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},p={currentContext:r,shortcuts:o,listenOptions:{mouseWait:n.mouseWait?n.mouseWait:320,maxClicks:1,clickTarget:n.clickTarget?n.clickTarget:"click"}};l._normalizeWithPlugins(i);let f=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,p=null,f=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),p=null,f=null,l=null,a=null,d=0}function h(n){let o=i.maxClicks;return clearTimeout(p),f?(clearTimeout(f),void(f=setTimeout((()=>f=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&&(f=setTimeout((()=>f=null),u)))):void(p=setTimeout(m,u)))}function g(n){let o=i.maxClicks;return clearTimeout(p),f?(clearTimeout(f),void(f=setTimeout((()=>f=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&&(f=setTimeout((()=>f=null),u)))):void(p=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)}}}(a,p),d=u(a,p);d>0&&f.start();let m={getPrefix:()=>"click",shortcutName:e=>i(e),contextChange:()=>{d=u(a,p),d<1&&f.stop(),d>0&&f.start()},mute:()=>f.stop(),unmute:()=>f.start(),destroy:()=>{f.stop(),p=null,m=null}};return Object.freeze(m),m},pluginKey:function(e,s,i={}){let{currentContext:c,shortcuts:u,exposeShortcut:l}=s,{inAPI:a}=e,p={ev:e.ev,_specialChars:o,_readKeyEvent:n,mainDependencies:e,regex:/KEY\s*\:/i},f={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,exposeShortcut:l};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=[],p=null,f=!0,d=!1;const m=()=>f=!1,h=()=>f=!0,g=()=>d=!0,y=()=>!1===f;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(!f){let r=e.at(-1);n.emit(r,t),d&&(e=e.slice(0,-1),d=!1)}if(f){const r=`KEY:${e.join(",")}`;n.emit(r,t),a=[],p=null}}function x(t){if(clearTimeout(p),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))):f&&a.length===u.maxSequence?(v(),void(u.keyIgnore=setTimeout((()=>u.keyIgnore=null),l))):void(f?p=setTimeout(v,l):v())}function C(t){if(!r.hasOwnProperty(t.code)){if(clearTimeout(p),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)),f&&a.length===u.maxSequence)return v(),void(u.keyIgnore=setTimeout((()=>u.keyIgnore=null),l));f?p=setTimeout(v,l):v()}}return{start:function(){t.active||(document.addEventListener("keydown",x),document.addEventListener("keypress",C),t.active=!0)},stop:function(){t.active&&(document.removeEventListener("keydown",x),document.removeEventListener("keypress",C),t.active=!1)}}}(p,f),m=r(p,f);m>0&&d.start();let h={getPrefix:()=>"key",shortcutName:e=>t(e),contextChange:e=>{m=r(p,f),m<1&&d.stop(),m>0&&d.start()},mute:()=>d.stop(),unmute:()=>d.start(),destroy:()=>{d.stop(),f=null,h=null}};return Object.freeze(h),h},shortcuts:l});function p(e){let t,n=!1;return e?(t=function(e){let t=e.map((e=>f())),n=t.map((e=>e.promise));return t.promises=n,t.onComplete=d(Promise.all(n)),t}(e),n=!0):t=f(),t.timeout=function(e,t){let n;n=e?Promise.all(t.promises):t.promise;return 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=d(Promise.race([n,s])),t}}(n,t),t}function f(){let e,t;const n=new Promise(((n,r)=>{e=n,t=r}));return{promise:n,done:e,cancel:t,onComplete:d(n)}}function d(e){return function(t){e.then((e=>t(e)))}}function m({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 h(e={},t=m){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*g(e,t,n,r){let o=null;if(null===e)return yield*r.map((e=>[e,"show"])),void(yield[n,"show"]);if(!r||0===r.length)return t?(yield[e,"hide"],t.reverse(),yield*t.map((e=>[e,"hide"])),void(yield[n,"show"])):(yield[e,"hide"],void(yield[n,"show"]));if(r.includes(e)){for(let t=r.indexOf(e)+1;t<r.length;t++)yield[r[t],"show"];yield[n,"show"]}else{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"]}}function y(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}}}function v(e,t){return function(e){const{scenes:n,sceneNames:r}=t;if(!r.has(e))return null;const{show:o,hide:s,parents:i,...c}=n[e];return Object.keys(c)}}return p.sequence=function(e,...t){const n=p(),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},p.all=function(e,...t){const n=p(),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=l(),n=h({level:e.logLevel||0}),r={currentScene:null,currentParents:null,sceneNames:new Set,scenes:{},opened:!1},o={},s={shortcutMngr:t,API:o,inAPI:{},findInstructions:g,askForPromise:p,setInstruction:y({askForPromise:p,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=[],p=c.length>0;let f;return o.pause(),a.push(s(u[i].hide)),p||(t.currentScene=null),p&&"*"===n&&[...c].reverse().forEach((e=>{f=t.currentParents.pop(),t.currentScene=f,a.push(s(u[e].hide))})),p&&!["*",1].includes(n)&&c.slice("-"+(n-1)).reverse().map((e=>{f=t.currentParents.pop(),t.currentScene=f,a.push(s(u[e].hide))})),(n=r.sequence(a)).onComplete((()=>{o.changeContext(t.currentScene),l.done()})),l.promise}}(s,r),o.listShortcuts=v(0,r),o.listShortcuts=v(0,r),o.setScenes=function(e,t){return function(n){const{shortcutMngr:r}=e;n.forEach((({name:e,scene:n})=>{n.parents||(n.parents=[]),t.scenes[e]=n,t.sceneNames.add(e);const{show:o,hide:s,parents:i,...c}=n,u={};u[e]=c,r.load(u)}))}}(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(),{opened:p,scenes:f,sceneNames:d}=t;if(!d.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:m,parents:h}=f[n];if("*"===h[0])return m().then((()=>a.done())),t.currentParents.push(t.currentPage),t.currentPage=n,a.promise;function g([e,n]){if("show"===n)t.currentScene&&t.currentParents.push(t.currentScene),t.currentScene=e;else{let e=t.currentParents.pop();t.currentScene=e}return f[e][n]}h.forEach((e=>d.has(e))),t.currentParents||(t.currentParents=[]);const y=u(t.currentScene,t.currentParents,n,h),v=[];for(let e of y)[e].map(g).map((e=>v.push(l(e),...o)));return i.sequence(v).onComplete((()=>{t.opened=!0,s.changeContext(n),a.done()})),a.promise}}(s,r),o.loadPlugins=async function(e){const t=e.map((e=>`plugin${e}`)),n=await Promise.resolve().then((function(){return a}));return t.map((e=>n[e]))},o.setDependencies=e=>t.setDependencies(e),o.getDependencies=()=>t.getDependencies(),o.setNote=e=>l.setNote(e),o.listScenes=()=>[...r.sceneNames],o.enablePlugin=(e,n)=>t.enablePlugin(e,n),o.disablePlugin=e=>t.disablePlugin(e),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((([o,r])=>{const s=e(o);s!==o&&(delete n[t][o],n[t][s]=r)}))}))}},_readShortcutWithPlugins:function(e,t){return function(n){const{inAPI:o}=e,r=n.split(":")[0],s=o._systemAction(r,"none");let i=n;return-1!==s&&(i=t.plugins[s].shortcutName(n)),i}},_systemAction:function(e,t){return function(e,n,o=null){return t.plugins.findIndex((t=>t.getPrefix()===e&&(t[n]&&t[n](o),!0)))}},changeContext:function(e,t){const{shortcuts:n,currentContext:o}=t,{ev:r}=e;return function(e=!1){const s=o.name;if(!e)return r.reset(),void(o.name=null);s!==e&&(n[e]?(n[s]&&r.reset(),o.name=e,t.plugins.forEach((t=>t.contextChange(e))),Object.entries(n[e]).forEach((([e,t])=>{t.forEach((t=>r.on(e,t)))})),r.on("*",((...e)=>{t.exposeShortcut&&t.exposeShortcut(...e)}))):r.emit("@shortcuts-error",`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:o}=t,{API:{changeContext:r,getContext:s}}=e;return function(e){const t=s(),i=o.map((e=>e.getPrefix().toUpperCase()));let c=!1;Object.entries(e).forEach((([e,r])=>{e===t&&(c=!0),n[e]={},Object.entries(r).forEach((([t,r])=>{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=o[e].shortcutName(t)}r instanceof Function&&(r=[r]),n[e][s]=r}))})),c&&(r(),r(t))}},unload:function(e,t){const{currentContext:n,shortcuts:o}=t,{ev:r}=e;return function(e){n.name!==e?o[e]?delete o[e]:r.emit("shortcuts-error",`Context '${e}' does not exist`):r.emit("shortcuts-error",`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),o=t.indexOf(":");return n?`KEY:${t.slice(o+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:o,ctrlKey:r}=e,s=e.code.replace("Key","").replace("Digit",""),i=[];return r&&i.push("CTRL"),n&&i.push("SHIFT"),o&&i.push("ALT"),t.hasOwnProperty(s)?i.push(t[s].toUpperCase()):["ControlLeft","ControlRight","ShiftLeft","ShiftRight","AltLeft","AltRight","Meta"].includes(s)||i.push(s.toUpperCase()),i.sort()}function o(e,t){let n=0;const{regex:o}=e,{listenOptions:r,currentContext:{name:s},shortcuts:i}=t;return null==s?0:(Object.entries(i[s]).forEach((([e,t])=>{if(!o.test(e))return;n++;let s=e.slice(4).split(",").length;r.maxSequence<s&&(r.maxSequence=s)})),n)}function r(){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:o}}=t;let r=n;return r===document||r===document.body?null:r.dataset[o]||"A"===r.nodeName?r:s(e,t,r.parentNode)}function i(e){const t=e.toUpperCase(),n=/CLICK\s*\:/i.test(t),o=["LEFT","MIDDLE","RIGHT"],r=["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=>{o.includes(e)?s=e:r.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:o,ctrlKey:r,key:s,button:i}=e,c=`CLICK:${["LEFT","MIDDLE","RIGHT"][i]}-${t}`,u=[];return r&&u.push("CTRL"),n&&u.push("SHIFT"),o&&u.push("ALT"),u.length>0?`${c}${u.length>0?"-":""}${u.sort().join("-")}`:`${c}`}function u(e,t){let n=0;const{regex:o}=e,{listenOptions:r,currentContext:{name:s},shortcuts:i}=t;return null==s?0:(Object.entries(i[s]).forEach((([e,t])=>{if(!o.test(e))return;n++;let[,s]=e.slice(6).split("-");r.maxClicks<s&&(r.maxClicks=s)})),n)}function l(t={}){const n=new function(){let e={"*":[]},t={},n=[],o=!1,r="";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,o){if(o)return e[n]&&(e[n]=e[n].filter((e=>e!==o))),t[n]&&(t[n]=t[n].filter((e=>e!==o))),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=[]},emit:function(){const[s,...i]=arguments;function c(t){let o=!1;"*"!==t&&(n.includes(t)||(e[t].every((e=>{const t=e(...i);return"string"!=typeof t||"STOP"!==t.toUpperCase()||(o=!0,!1)})),o||e["*"].forEach((e=>e(s,...i)))))}if(o&&(console.log(`${r} Event "${s}" was triggered.`),i.length>0&&(console.log("Arguments:"),console.log(...i),console.log("^----"))),"*"!==s){if(t[s]){if(n.includes(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(o){if("*"!==o)n.push(o);else{const o=Object.keys(e),r=Object.keys(t);n=[...r,...o]}},start:function(e){n="*"!==e?n.filter((t=>e!=t)):[]},debug:function(e,t){o=!!e,t&&"string"==typeof t&&(r=t)}}},o={},r={},s={currentContext:{name:null,note:null},shortcuts:{},plugins:[],exposeShortcut:!(!t.onShortcut||"function"!=typeof t.onShortcut)&&t.onShortcut},i={ev:n,inAPI:o,API:r,extra:{}};return r.enablePlugin=(e,t={})=>{const n=e.name;if(-1===o._systemAction(n,"none")){let n;n=e(i,s,t),s.plugins.push(n)}},r.disablePlugin=e=>{const t=o._systemAction(e,"destroy");-1!==t&&(s.plugins=s.plugins.filter(((e,n)=>n!==t)))},r.mutePlugin=e=>o._systemAction(e,"mute"),r.unmutePlugin=e=>o._systemAction(e,"unmute"),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=o._readShortcutWithPlugins(e);n.stop(t)},r.resume=(e="*")=>{const t=o._readShortcutWithPlugins(e);n.start(t)},r.emit=(e,...t)=>n.emit(o._readShortcutWithPlugins(e),...t),r.listContexts=()=>Object.keys(s.shortcuts),r.setDependencies=e=>i.extra={...i.extra,...e},r.getDependencies=()=>i.extra,Object.entries(e).forEach((([e,t])=>{e.startsWith("_")?o[e]=t(i,s):r[e]=t(i,s)})),r}var a=Object.freeze({__proto__:null,pluginClick:function(e,t,n){let{currentContext:o,shortcuts:r}=t,{inAPI:l}=e,a={ev:e.ev,_findTarget:s,_readClickEvent:c,mainDependencies:e,regex:/CLICK\s*\:/i},f={currentContext:o,shortcuts:r,listenOptions:{mouseWait:n.mouseWait?n.mouseWait:320,maxClicks:1,clickTarget:n.clickTarget?n.clickTarget:"click"}};l._normalizeWithPlugins(i);let d=function(e,t){const{ev:n,_findTarget:o,_readClickEvent:r,mainDependencies:s}=e,{listenOptions:i,currentContext:c}=t,{mouseWait:u}=i;let l=null,a=null,f=null,d=null,p=0;function m(){const e=r(a,p),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,d=null,l=null,a=null,p=0}function h(n){let r=i.maxClicks;return clearTimeout(f),d?(clearTimeout(d),void(d=setTimeout((()=>d=null),u))):(l=o(e,t,n.target),l&&l.dataset.hasOwnProperty("quickClick")&&(r=1),l&&"A"===l.tagName&&(r=1),a=n,p++,p>=r?(m(),void(r>1&&(d=setTimeout((()=>d=null),u)))):void(f=setTimeout(m,u)))}function g(n){let r=i.maxClicks;return clearTimeout(f),d?(clearTimeout(d),void(d=setTimeout((()=>d=null),u))):(l=o(e,t,n.target),l&&l.dataset.hasOwnProperty("quickClick")&&(r=1),l&&"A"===l.tagName&&(r=1),a=n,p++,p>=r?(m(),void(r>1&&(d=setTimeout((()=>d=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)}}}(a,f),p=u(a,f);p>0&&d.start();let m={getPrefix:()=>"click",shortcutName:e=>i(e),contextChange:()=>{p=u(a,f),p<1&&d.stop(),p>0&&d.start()},mute:()=>d.stop(),unmute:()=>d.start(),destroy:()=>{d.stop(),f=null,m=null}};return Object.freeze(m),m},pluginKey:function(e,s,i={}){let{currentContext:c,shortcuts:u,exposeShortcut:l}=s,{inAPI:a}=e,f={ev:e.ev,_specialChars:r,_readKeyEvent:n,mainDependencies:e,regex:/KEY\s*\:/i},d={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,exposeShortcut:l};a._normalizeWithPlugins(t);let p=function(e,t){const{ev:n,_specialChars:o,_readKeyEvent:r,mainDependencies:s}=e,{currentContext:i,streamKeys:c,listenOptions:u}=t,{keyWait:l}=u;let a=[],f=null,d=!0,p=!1;const m=()=>d=!1,h=()=>d=!0,g=()=>p=!0,y=()=>!1===d;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(!d){let o=e.at(-1);n.emit(o,t),p&&(e=e.slice(0,-1),p=!1)}if(d){const o=`KEY:${e.join(",")}`;n.emit(o,t),a=[],f=null}}function x(t){if(clearTimeout(f),o.hasOwnProperty(t.code))return a.push(r(t,o)),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))):d&&a.length===u.maxSequence?(v(),void(u.keyIgnore=setTimeout((()=>u.keyIgnore=null),l))):void(d?f=setTimeout(v,l):v())}function C(t){if(!o.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(r(t,o)),d&&a.length===u.maxSequence)return v(),void(u.keyIgnore=setTimeout((()=>u.keyIgnore=null),l));d?f=setTimeout(v,l):v()}}return{start:function(){t.active||(document.addEventListener("keydown",x),document.addEventListener("keypress",C),t.active=!0)},stop:function(){t.active&&(document.removeEventListener("keydown",x),document.removeEventListener("keypress",C),t.active=!1)}}}(f,d),m=o(f,d);m>0&&p.start();let h={getPrefix:()=>"key",shortcutName:e=>t(e),contextChange:e=>{m=o(f,d),m<1&&p.stop(),m>0&&p.start()},mute:()=>p.stop(),unmute:()=>p.start(),destroy:()=>{p.stop(),d=null,h=null}};return Object.freeze(h),h},shortcuts:l});function f(e){return e?function(e){let t=e.map((e=>d())),n=t.map((e=>e.promise));t.promises=t;let o=p(Promise.all(n));function r(e){let t="pending";return e.then((()=>t="fulfilled")).catch((()=>t="rejected")),t}function s(n,...o){t.forEach(((t,s)=>n({value:e[s],done:t.done,cancel:t.cancel,timeout:t.timeout,state:r(t.promise)},...o)))}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:o,timeout:()=>{}};return i.timeout=m(!0,i),i}(e):d()}function d(){let e,t;const n=new Promise(((n,o)=>{e=n,t=o})),o={promise:n,promises:null,done:e,cancel:t,each:()=>{},onComplete:p(n),timeout:()=>{}};return o.timeout=m(!1,o),o.each=(n,...r)=>{n({value:null,done:e,cancel:t,timeout:o.timeout},...r)},o}function p(e){return function(t,n=null){null===n?e.then((e=>t(e))):e.then((e=>t(e)),(e=>n(e)))}}function m(e,t){let n;return n=e?Promise.all(t.promises.map((e=>e.promise))):t.promise,function(e,o){let r,s=new Promise(((t,s)=>{r=setTimeout((()=>{t(o),Promise.resolve(n)}),e)}));return n.then((()=>clearTimeout(r))),t.onComplete=p(Promise.race([n,s])),t}}function h({message:e,level:t,type:n,logLevel:o}){if(0===o)return null;if(o<t)return null;const r=`[Debug]: ${e}`;switch(n){case"warn":console.warn(r);break;case"error":console.error(r);break;default:console.log(r)}return r}function g(e={},t=h){return function({message:n,type:o,level:r,...s}){const{level:i,type:c,defaultMessageLevel:u}=Object.assign({},{level:1e3,type:"log",defaultMessageLevel:1},e);return o||(o=c),r||(r=u),t({message:n,type:o,level:r,logLevel:i,...s})}}function*y(e,t,n,o){let r=null;if(null===e)return yield*o.map((e=>[e,"show"])),void(yield[n,"show"]);if(!o||0===o.length)return t?(yield[e,"hide"],t.reverse(),yield*t.map((e=>[e,"hide"])),void(yield[n,"show"])):(yield[e,"hide"],void(yield[n,"show"]));if(o.includes(e)){for(let t=o.indexOf(e)+1;t<o.length;t++)yield[o[t],"show"];yield[n,"show"]}else{if(!t)return yield[e,"hide"],void(yield*o.map((e=>[e,"show"])));if(o.every(((e,n)=>t[n]===o[n]&&(r=n,!0))),null==r)return yield[e,"hide"],t.reverse(),yield*t.map((e=>[e,"hide"])),yield*o.map((e=>[e,"show"])),void(yield[n,"show"]);yield[e,"hide"];for(let e=t.length;e>r+1;e--)yield[t[e-1],"hide"];for(let e=r+1;e<o.length;e++)yield[o[e],"show"];yield[n,"show"]}}function v(e){return function(t,...n){const{askForPromise:o,deps:r}=e;return function(){const e=o();return t({task:e,dependencies:r()},...n),e.promise}}}function x(e,t){return function(e){const{scenes:n,sceneNames:o}=t;if(!o.has(e))return null;const{show:r,hide:s,parents:i,beforeUnload:c,afterLoad:u,...l}=n[e];return Object.keys(l)}}return f.sequence=function(e,...t){const n=f(),o=[];const r=function*(e){for(const t of e)yield t}(e);return function e(t,...s){t.done?n.done(o):t.value(...s).then((t=>{o.push(t),e(r.next(),...s,t)}))}(r.next(),...t),n},f.all=function(e,...t){const n=f(),o=[],r=e.map(((e,n)=>"function"==typeof e?e(...t).then((e=>o[n]=e)):e.then((e=>o[n]=e))));return Promise.all(r).then((()=>n.done(o))),n},function(e={logLevel:0}){const t=l(),n=g({level:e.logLevel||0}),o={currentScene:null,currentParents:null,sceneNames:new Set,scenes:{},opened:!1},r={},s={shortcutMngr:t,API:r,inAPI:{},findInstructions:y,askForPromise:f,setInstruction:v({askForPromise:f,deps:t.getDependencies}),log:n};return r.hide=function(e,t){return function(n=1){const{askForPromise:o,shortcutMngr:r,setInstruction:s}=e,{currentScene:i,currentParents:c,scenes:u}=t,l=o(),a=[],f=c.length>0;let d;return r.pause(),a.push(s(u[i].hide)),f||(t.currentScene=null),f&&"*"===n&&[...c].reverse().forEach((e=>{d=t.currentParents.pop(),t.currentScene=d,a.push(s(u[e].hide))})),f&&!["*",1].includes(n)&&c.slice("-"+(n-1)).reverse().map((e=>{d=t.currentParents.pop(),t.currentScene=d,a.push(s(u[e].hide))})),(n=o.sequence(a)).onComplete((()=>{r.changeContext(t.currentScene),l.done()})),l.promise}}(s,o),r.listShortcuts=x(0,o),r.listShortcuts=x(0,o),r.setScenes=function(e,t){return function(n){const{shortcutMngr:o}=e;n.forEach((({name:e,scene:n})=>{n.parents||(n.parents=[]),t.scenes[e]=n,t.sceneNames.add(e);const{show:r,hide:s,parents:i,...c}=n,u={};u[e]=c,o.load(u)}))}}(s,o),r.show=function(e,t){return function({scene:n,options:o={ssr:!1}},...r){const{shortcutMngr:s,askForPromise:i,log:c,findInstructions:u,setInstruction:l}=e,a=i(),f=i(),{opened:d,scenes:p,sceneNames:m,currentPage:h}=t;if(h){const t=p[h].beforeHide;"function"==typeof t&&t({done:f.done,dependencies:e})}else f.done();return f.onComplete((f=>{if(!f)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(!d&&o.ssr)return t.opened=!0,t.currentPage=n,s.changeContext(n),a.done(),a.promise;const{show:h,parents:g=[]}=p[n];if("*"===g[0])return h().then((()=>a.done())),t.currentParents.push(t.currentPage),t.currentPage=n,a.promise;function y([e,n]){if("show"===n)t.currentScene&&t.currentParents.push(t.currentScene),t.currentScene=e;else{let e=t.currentParents.pop();t.currentScene=e}return p[e][n]}g.forEach((e=>m.has(e))),t.currentParents||(t.currentParents=[]);const v=u(t.currentScene,t.currentParents,n,g),x=[];for(let e of v)[e].map(y).map((e=>x.push(l(e),...r)));i.sequence(x).onComplete((()=>{t.opened=!0,s.changeContext(n),"function"==typeof p[n].afterShow&&p[n].afterShow({dependencies:e,done:()=>{}}),a.done()}))})),a.promise}}(s,o),r.loadPlugins=async function(e){const t=e.map((e=>`plugin${e}`)),n=await Promise.resolve().then((function(){return a}));return t.map((e=>n[e]))},r.setDependencies=e=>t.setDependencies(e),r.getDependencies=()=>t.getDependencies(),r.setNote=e=>l.setNote(e),r.listScenes=()=>[...o.sceneNames],r.enablePlugin=(e,n)=>t.enablePlugin(e,n),r.disablePlugin=e=>t.disablePlugin(e),r.emit=(e,...n)=>t.emit(e,...n),r}}));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@peter.naydenov/cuts",
3
3
  "description": "SPA scene manager",
4
- "version": "1.1.0",
4
+ "version": "1.2.0",
5
5
  "license": "MIT",
6
6
  "author": "Peter Naydenov",
7
7
  "main": "./src/main.js",
@@ -23,6 +23,7 @@
23
23
  "postbuild": "tsc -p tsconfig.json",
24
24
  "preview": "vite preview",
25
25
  "test": "mocha test-mocha/*.js",
26
+ "cover": "c8 mocha test-mocha/*.js",
26
27
  "cypress": "cypress open --component --browser chrome"
27
28
  },
28
29
  "repository": {
@@ -30,25 +31,38 @@
30
31
  "url": "git+https://github.com/PeterNaydenov/cuts.git"
31
32
  },
32
33
  "devDependencies": {
33
- "@peter.naydenov/visual-controller-for-vue3": "^2.1.3",
34
- "@rollup/plugin-commonjs": "^28.0.1",
35
- "@rollup/plugin-node-resolve": "^15.3.0",
34
+ "@peter.naydenov/visual-controller-for-vue3": "^2.1.4",
35
+ "@rollup/plugin-commonjs": "^28.0.2",
36
+ "@rollup/plugin-node-resolve": "^16.0.0",
36
37
  "@rollup/plugin-terser": "^0.4.4",
37
38
  "@types/node": "^22.10.2",
38
39
  "@vitejs/plugin-vue": "^5.2.1",
39
40
  "c8": "^10.1.3",
40
41
  "chai": "^5.1.2",
41
- "cypress": "^13.16.1",
42
+ "cypress": "^13.17.0",
42
43
  "mocha": "^11.0.1",
43
- "rollup": "^4.28.1",
44
+ "rollup": "^4.29.1",
44
45
  "typescript": "^5.7.2",
45
- "vite": "^6.0.3",
46
+ "vite": "^6.0.5",
46
47
  "vue": "^3.5.13"
47
48
  },
48
49
  "dependencies": {
49
50
  "@peter.naydenov/log": "^1.1.0",
50
51
  "@peter.naydenov/shortcuts": "^3.1.1",
51
- "ask-for-promise": "^2.0.4"
52
+ "ask-for-promise": "^3.0.1"
53
+ },
54
+ "c8": {
55
+ "include": [
56
+ "src/**/*.js"
57
+ ],
58
+ "exclude": [
59
+ "node_modules",
60
+ "test"
61
+ ],
62
+ "reporter": [
63
+ "lcov",
64
+ "text-summary"
65
+ ]
52
66
  },
53
67
  "keywords": [
54
68
  "script",
package/src/main.js CHANGED
@@ -11,8 +11,8 @@
11
11
  * - Rename to @peter.naydenov/cuts
12
12
  * Changes in documentation and some methods were renamed accordingly.
13
13
  * Version 1.0.0.
14
- * Published on May 8th, 2024;
15
- *
14
+ * Published for first time as package '@peter.naydenov/cuts' on May 8th, 2024;
15
+ * Extend 'scene' with optional 'afterShow' and 'beforeHide' methods. December 21st, 2024;
16
16
  */
17
17
 
18
18
 
@@ -10,7 +10,7 @@ function listShortcuts ( dependencies, state ) {
10
10
  return function listShortcuts ( sceneName ) {
11
11
  const { scenes, sceneNames } = state;
12
12
  if ( ! sceneNames.has ( sceneName ) ) return null
13
- const { show, hide, parents, ...shortcuts } = scenes[sceneName];
13
+ const { show, hide, parents, beforeUnload, afterLoad, ...shortcuts } = scenes[sceneName];
14
14
  return Object.keys ( shortcuts )
15
15
  }} // listShortcuts func.
16
16
 
@@ -1,9 +1,22 @@
1
1
  'use strict'
2
2
 
3
+
4
+ /**
5
+ * @typedef {Object} SceneObject
6
+ * @param {function} show - load interface and prerequisites for the scene;
7
+ * @param {function} [afterShow] - run after scene is loaded. Optional;
8
+ * @param {function} hide - Reverse the settings from 'show';
9
+ * @param {function} [beforeHide] - Run before scene is hidden. Optional;
10
+ * @param {Array.<string>} [parents] - list of parent scene names.
11
+ * @param {*} ... - shortcut descriptions
12
+ */
13
+
14
+
15
+
3
16
  /**
4
17
  * @typedef {Object} sceneDescription
5
18
  * @param {string} name - name of the scene
6
- * @param {object} scene - object should contain 'show' and 'hide' + shortcuts and action functions
19
+ * @param {SceneObject} scene - object should contain 'show' and 'hide' + shortcuts and action functions
7
20
  */
8
21
 
9
22
 
@@ -12,7 +25,7 @@
12
25
  function setScenes ( dependencies, state ) {
13
26
  /**
14
27
  * @function setScenes
15
- * @param {ScreenDescription[]} list - list of objects with name and scene. Scene should be a Scene model.
28
+ * @param {SceneDescription[]} list - list of objects with name and scene. Scene should be a Scene model.
16
29
  * @returns void
17
30
  * @description Screen Description is an object with fields 'name' and 'scene'
18
31
  */
@@ -17,84 +17,105 @@ function show ( dependencies, state ) {
17
17
  const
18
18
  { shortcutMngr, askForPromise, log, findInstructions, setInstruction } = dependencies
19
19
  , showTask = askForPromise ()
20
- , { opened, scenes, sceneNames } = state
20
+ , unloadTask = askForPromise ()
21
+ , { opened, scenes, sceneNames, currentPage } = state
21
22
  ;
22
-
23
- if ( !sceneNames.has ( requestedScene ) ) {
24
- if ( log ) {
25
- log ({
26
- message: `Scene ${requestedScene} is not available.`
27
- , level : 1
28
- , type : 'error'
29
- })
30
- showTask.done ()
31
- return showTask.promise
32
- }
33
- }
34
23
 
35
- if ( !opened && options.ssr ) { // Check for Server side rendering on first scene load only
36
- // Executes only once when the scene manager is started
37
- state.opened = true
38
- state.currentPage = requestedScene
39
- shortcutMngr.changeContext ( requestedScene )
40
- showTask.done ()
41
- return showTask.promise
42
- }
43
-
44
- const { show, parents } = scenes[requestedScene];
45
-
46
- if ( parents[0] === '*' ) {
47
- show ().then ( () => showTask.done () )
48
- state.currentParents.push ( state.currentPage )
49
- state.currentPage = requestedScene
50
- return showTask.promise
51
- }
52
-
53
- let checkParents = parents.forEach ( name => sceneNames.has ( name ) ) || true ;
54
- if ( !checkParents ) {
55
- if ( log ) {
56
- log ({
57
- message: `Some of '${requestedScene}' parent scenes are not set.`
58
- , level : 1
59
- , type : 'error'
60
- })
24
+ if ( currentPage ) { // Execute 'beforeUnload' function if exists
25
+ const closingFn = scenes[currentPage].beforeHide;
26
+ if ( typeof closingFn === 'function' ) {
27
+ closingFn ({ done:unloadTask.done, dependencies })
61
28
  }
62
- showTask.done ()
63
- return showTask.promise
64
- }
29
+ } // if currentPage
30
+ else unloadTask.done ()
65
31
 
66
- function getStep ([name, action]) { // Returns a scene function(hide or show) according to instructions
67
- if ( action === 'show' ) {
68
- if ( state.currentScene ) state.currentParents.push ( state.currentScene )
69
- state.currentScene = name
70
- }
71
- else {
72
- let el = state.currentParents.pop ();
73
- state.currentScene = el
74
- }
75
- return scenes[name][action]
76
- } // getStep func.
77
32
 
78
- if ( !state.currentParents ) state.currentParents = []
79
- const
80
- g = findInstructions ( state.currentScene, state.currentParents, requestedScene, parents )
81
- , instructions = []
82
- ;
83
-
84
- for ( let inst of g ) {
85
- [inst]
86
- .map ( getStep )
87
- .map ( step => instructions.push ( setInstruction(step),...args ))
88
- // Note: Methods 'show' and 'hide' are async, but we need to provide them a data,
89
- // so we need to wrap them in a another function that returns a promise
90
- }
91
-
92
- const goingTask = askForPromise.sequence ( instructions ); // Execute open steps(show and hide) in sequence
93
- goingTask.onComplete ( () => {
94
- state.opened = true
95
- shortcutMngr.changeContext ( requestedScene )
96
- showTask.done ()
97
- })
33
+ unloadTask.onComplete ( continueLoading => {
34
+
35
+ if ( !continueLoading ) {
36
+ // if the 'beforeUnload' function returns false
37
+ // Cancel loading the new scene
38
+ showTask.done ()
39
+ return showTask.promise
40
+ }
41
+
42
+ if ( !sceneNames.has ( requestedScene ) ) {
43
+ if ( log ) {
44
+ log ({
45
+ message: `Scene ${requestedScene} is not available.`
46
+ , level : 1
47
+ , type : 'error'
48
+ })
49
+ showTask.done ()
50
+ return showTask.promise
51
+ }
52
+ }
53
+
54
+ if ( !opened && options.ssr ) { // Check for Server side rendering on first scene load only
55
+ // Executes only once when the scene manager is started
56
+ state.opened = true
57
+ state.currentPage = requestedScene
58
+ shortcutMngr.changeContext ( requestedScene )
59
+ showTask.done ()
60
+ return showTask.promise
61
+ }
62
+
63
+ const { show, parents=[] } = scenes[requestedScene];
64
+
65
+ if ( parents[0] === '*' ) {
66
+ show ().then ( () => showTask.done () )
67
+ state.currentParents.push ( state.currentPage )
68
+ state.currentPage = requestedScene
69
+ return showTask.promise
70
+ }
71
+
72
+ let checkParents = parents.forEach ( name => sceneNames.has ( name ) ) || true ;
73
+ if ( !checkParents ) {
74
+ if ( log ) {
75
+ log ({
76
+ message: `Some of '${requestedScene}' parent scenes are not set.`
77
+ , level : 1
78
+ , type : 'error'
79
+ })
80
+ }
81
+ showTask.done ()
82
+ return showTask.promise
83
+ }
84
+
85
+ function getStep ([name, action]) { // Returns a scene function(hide or show) according to instructions
86
+ if ( action === 'show' ) {
87
+ if ( state.currentScene ) state.currentParents.push ( state.currentScene )
88
+ state.currentScene = name
89
+ }
90
+ else {
91
+ let el = state.currentParents.pop ();
92
+ state.currentScene = el
93
+ }
94
+ return scenes[name][action]
95
+ } // getStep func.
96
+
97
+ if ( !state.currentParents ) state.currentParents = []
98
+ const
99
+ g = findInstructions ( state.currentScene, state.currentParents, requestedScene, parents )
100
+ , instructions = []
101
+ ;
102
+
103
+ for ( let inst of g ) {
104
+ [inst]
105
+ .map ( getStep )
106
+ .map ( step => instructions.push ( setInstruction(step),...args ))
107
+ // Note: Methods 'show' and 'hide' are async, but we need to provide them a data,
108
+ // so we need to wrap them in a another function that returns a promise
109
+ }
110
+
111
+ const goingTask = askForPromise.sequence ( instructions ); // Execute open steps(show and hide) in sequence
112
+ goingTask.onComplete ( () => {
113
+ state.opened = true
114
+ shortcutMngr.changeContext ( requestedScene )
115
+ if ( typeof scenes[requestedScene].afterShow === 'function' ) scenes[requestedScene].afterShow ({ dependencies, done: () => {} })
116
+ showTask.done ()
117
+ })
118
+ }) // unloadTask onComplete
98
119
  return showTask.promise
99
120
  } // show func.
100
121
  return show
package/types/main.d.ts CHANGED
@@ -4,7 +4,7 @@ declare function main(cfg?: {
4
4
  }): {
5
5
  hide: (endSteps?: number | string) => Promise<any>;
6
6
  listShortcuts: (sceneName: string) => (Array<string> | null);
7
- setScenes: (list: ScreenDescription[]) => void;
7
+ setScenes: (list: SceneDescription[]) => void;
8
8
  show: ({ scene: requestedScene, options }: {
9
9
  scene: string;
10
10
  options?: {
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.js"],"names":[],"mappings":";AAiCA;;;;;sBAvBe,iBAAiB;;;;;;;yBA6Db,KAAK,iBAAc,GACjB,OAAO,CAAE,UAAU,CAAC;0BAgBtB,GAAC;uBAQC,GAAC;kBAMH,MAAM;kBAQJ,KAAK,CAAE,MAAM,CAAC;6CAQhB,GAAC;8BAQD,MAAM;gBASN,MAAM,WACH,GAAC,EAAA;EAMtB"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.js"],"names":[],"mappings":";AAiCA;;;;;sBAdgB,gBAAgB;;;;;;;yBAoDb,KAAK,iBAAc,GACjB,OAAO,CAAE,UAAU,CAAC;0BAgBtB,GAAC;uBAQC,GAAC;kBAMH,MAAM;kBAQJ,KAAK,CAAE,MAAM,CAAC;6CAQhB,GAAC;8BAQD,MAAM;gBASN,MAAM,WACH,GAAC,EAAA;EAMtB"}
@@ -1,9 +1,19 @@
1
1
  export default setScenes;
2
+ export type SceneObject = any;
2
3
  export type sceneDescription = any;
4
+ /**
5
+ * @typedef {Object} SceneObject
6
+ * @param {function} show - load interface and prerequisites for the scene;
7
+ * @param {function} [afterShow] - run after scene is loaded. Optional;
8
+ * @param {function} hide - Reverse the settings from 'show';
9
+ * @param {function} [beforeHide] - Run before scene is hidden. Optional;
10
+ * @param {Array.<string>} [parents] - list of parent scene names.
11
+ * @param {*} ... - shortcut descriptions
12
+ */
3
13
  /**
4
14
  * @typedef {Object} sceneDescription
5
15
  * @param {string} name - name of the scene
6
- * @param {object} scene - object should contain 'show' and 'hide' + shortcuts and action functions
16
+ * @param {SceneObject} scene - object should contain 'show' and 'hide' + shortcuts and action functions
7
17
  */
8
- declare function setScenes(dependencies: any, state: any): (list: ScreenDescription[]) => void;
18
+ declare function setScenes(dependencies: any, state: any): (list: SceneDescription[]) => void;
9
19
  //# sourceMappingURL=setScenes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"setScenes.d.ts","sourceRoot":"","sources":["../../src/methods/setScenes.js"],"names":[],"mappings":";;AAEA;;;;GAIG;AAKH,kEAGe,iBAAiB,EAAE,UAoBhC"}
1
+ {"version":3,"file":"setScenes.d.ts","sourceRoot":"","sources":["../../src/methods/setScenes.js"],"names":[],"mappings":";;;AAGA;;;;;;;;GAQG;AAIH;;;;GAIG;AAKH,kEAGe,gBAAgB,EAAE,UAoB/B"}
@@ -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,mCAwFF"}
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,mCA6GF"}