@peter.naydenov/morph 1.1.3 → 1.2.1

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,18 @@
2
2
 
3
3
 
4
4
 
5
+ ### 1.2.1 (2025-03-16)
6
+ - [x]Enhanced Error Handling in setupActions.js: Improved the error message to provide more context about the missing level markers, making it easier to debug;
7
+ - [x] Added TypeScript Type Definitions: Created a types directory with an index.d.ts file containing TypeScript definitions for the library, and added the "types" field to package.json for better TypeScript support;
8
+
9
+
10
+
11
+ ### 1.2.0 (2025-03-14)
12
+ - [x] Bug fix: Deeply nested data;
13
+ - [x] Improve: Error message if actions do not have deepness of the data (very difficult to debug);
14
+
15
+
16
+
5
17
  ### 1.1.3 (2025-01-23)
6
18
  - [x] Improve: Error messages when using method "add" with template -> null;
7
19
 
package/dist/morph.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("@peter.naydenov/walk"),t=require("@peter.naydenov/stack");function r(e){return function t(r){const{TG_PRX:a,TG_SFX:o,TG_SIZE_P:s,TG_SIZE_S:i}=e;let c,l,u,f=[];if("string"!=typeof r)return n("notAString");if(0==r.length)return[];if(c=r.indexOf(a),0<c&&f.push(r.slice(0,c)),-1==c)return f.push(r),f;{if(u=r.indexOf(a,c+s),l=r.indexOf(o),-1==l)return n("missingClosing");if(l<c)return n("closedBeforeOpened");if(l+=i,-1!=u&&u<l)return n("newBeforeClosed");f.push(r.slice(c,l));let e=t(r.slice(l));return f.concat(e)}}}function n(e){switch(e){case"notAString":return"Error: Template is not a string.";case"missingClosing":return"Error: Placeholder with missing closing tag.";case"closedBeforeOpened":return"Error: Placeholder closing tag without starting one.";case"newBeforeClosed":return"Error: Nested placeholders. Close placeholder before open new one.";default:return"Error: Unknown template error."}}function a(t,r){const n={};let a=0;if(t instanceof Function)return{dataDeepLevel:0,nestedData:[t()]};if(null==t)return{dataDeepLevel:0,nestedData:[null]};if("string"==typeof t)return{dataDeepLevel:0,nestedData:[t]};if(!r.includes("#"))return{dataDeepLevel:0,nestedData:[t]};return e({data:t,objectCallback:function({key:e,value:t,breadcrumbs:r}){let o=!1;return a=r.split("/").length-1,isNaN(e)||(o=!0),n[a]||(n[a]=o?[]:{}),"root"===e?n[a]=t:o?n[a].push(t):n[a][r]=t,t}}),{dataDeepLevel:a,nestedData:n}}var o={TG_PRX:"{{",TG_SFX:"}}",TG_SIZE_P:2,TG_SIZE_S:2};function s(e){return null==e?"null":"string"==typeof e||"number"==typeof e||"boolean"==typeof e?"primitive":"function"==typeof e?"function":e instanceof Array?"array":e instanceof Object?"object":void 0}function i(e,t,n,...a){e instanceof Object&&Object.entries(e).forEach((([t,r])=>{r instanceof Object&&(e[t]=r.text)}));const s="function"==typeof n[t];return e=function(e={}){return"string"==typeof e?{text:e}:e}(e),s?n[t](e,...a):function(e,t){if(null==t)return null;const n=r(o)(e),a=o;return n.forEach(((e,r)=>{if(e.includes(a.TG_PRX)){const o=e.replace(a.TG_PRX,"").replace(a.TG_SFX,"").trim();t[o]&&(n[r]=t[o])}})),n.join("")}(n[t],e)}function c(n,c=!1,l={}){const{hasError:u,placeholders:f,chop:d,helpers:p,handshake:h}=function(e){const{template:t,helpers:n={},handshake:a}=e,{TG_PRX:s,TG_SFX:i,TG_SIZE_P:c,TG_SIZE_S:l}=o,u=[],f="string"==typeof t?t.replace(/<!--[\s\S]*?-->/g,"").replace(/\s{2,}/g," "):t;let d=null;const p=r(o)(f);return"string"==typeof p?d=p:p.forEach(((e,t)=>{const r=RegExp(s+"\\s*(.*?)\\s*(?::\\s*(.*?)\\s*)?"+i,"g");if(e.includes(s)){const a=r.exec(e);u.push({index:t,data:(n=a[1],n||null),action:a[2]?a[2].split(",").map((e=>e.trim())):null})}var n})),u.forEach((e=>{e.action&&e.action.every((e=>"#"===e||(e.startsWith("?")&&(e=e.replace("?","")),e.startsWith("+")&&(e=e.replace("+","")),e.startsWith("[]")&&(e=e.replace("[]","")),e.startsWith(">")&&(e=e.replace(">","")),""===e||!!n[e]||(d=`Error: Missing helper: ${e}`,!1))))})),{hasError:d,placeholders:u,chop:p,helpers:n,handshake:a}}(n);if(u){function b(){return u}return c?[!1,b]:b}{let m=structuredClone(d);function y(r={},n={},...o){const c=s(r),u=[];if(r=e({data:r}),"null"===c)return m.join("");if("string"==typeof r)switch(r){case"raw":return m.join("");case"demo":if(!h)return"Error: No handshake data.";r=h;break;case"handshake":return h?structuredClone(h):"Error: No handshake data.";case"placeholders":return f.map((e=>m[e.index])).join(", ");default:return`Error: Wrong command "${r}". Available commands: raw, demo, handshake, placeholders.`}return"array"!==c&&(r=[r]),r.forEach((r=>{f.forEach((o=>{const{index:c,data:u,action:f}=o;if(!f&&u){const d=r[u];switch(s(d)){case"function":return void(m[c]=d());case"primitive":return void(m[c]=d);case"array":return void("primitive"===s(d[0])&&(m[c]=d[0]));case"object":return void(d.text&&(m[c]=d.text))}}else{const{dataDeepLevel:h,nestedData:b}=a("@all"===u||null===u||"@root"===u?r:r[u],f),y=function*(e,r){let n=t({type:"LIFO"});for(let t=0;t<=r;t++)n.push(e[t]);for(;n&&!n.isEmpty();){let e=yield n.pull();e&&n.push(e)}}(function(e,t=10){let r={},n=0,a=[...e],o=0;do{r[o]=[],o++}while(o<=t);return a.every((e=>"#"===e?(n++,!(n>t)):e.startsWith("?")?(r[n].push({type:"route",name:e.replace("?",""),level:n}),!0):e.startsWith("+")?(r[n].push({type:"extendedRender",name:e.replace("+",""),level:n}),!0):e.startsWith("[]")?(r[n].push({type:"mix",name:e.replace("[]",""),level:n}),!0):e.startsWith(">")?(r[n].push({type:"data",name:e.replace(">",""),level:n}),!0):(""===e||r[n].push({type:"render",name:e,level:n}),!0))),r}(f,h),h);for(let v of y){let{type:j,name:k,level:x}=v,T=b[x],_=s(T);switch(j){case"route":switch(_){case"array":T.forEach(((e,t)=>{if(null==e)return;const r=s(e),a=p[k](e);null!=a&&("object"===r?T[t].text=i(e,a,p,{...l,...n}):T[t]=i(e,a,p,{...l,...n}))}));break;case"object":T.text=i(T,k,p,{...l,...n});break;case"primitive":b[x]=i(T,k,p,{...l,...n})}break;case"data":switch(_){case"array":T.forEach(((e,t)=>T[t]=e instanceof Function?p[k](e()):p[k](e)));break;case"object":case"primitive":b[x]=p[k](T);break;case"function":b[x]=p[k](T())}break;case"render":const w="function"==typeof p[k];switch(_){case"array":w?T.forEach(((e,t)=>{if(null==e)return;const r=s(e),a=p[k](e,{...l,...n});null==a&&(T[t]=null),"object"===r?e.text=a:T[t]=a})):T.forEach(((e,t)=>{if(null==e)return;const r=s(e),a=i(e,k,p,{...l,...n});null==a&&(T[t]=null),"object"===r?e.text=a:T[t]=a}));break;case"function":b[x]=p[k](T(),{...l,...n});break;case"primitive":b[x]=i(T,k,p,{...l,...n});break;case"object":if(w)b[x].text=p[k](T,{...l,...n});else{Object.keys(T).find((e=>e.includes("/")))?Object.entries(T).forEach((([e,t])=>t.text=i(t,k,p,{...l,...n}))):T.text=i(T,k,p,{...l,...n})}}break;case"extendedRender":"function"==typeof p[k]&&(b[x]=p[k](b[0]));break;case"mix":if(""===k)switch(_){case"object":Object.keys(T).find((e=>e.includes("/")))?Object.entries(T).forEach((([e,t])=>b[x][e]=t.text)):b[x]=T.text;for(let O=x-1;O>=0;O--)b[O]=e({data:b[O],objectCallback:S});function S({value:e,breadcrumbs:t}){return b[x][t]?b[x][t]:e}break;case"array":b[x]=T.map((e=>"object"===s(e)?e.text:e)).filter((e=>null!=e)).join("")}else b[x]=p[k](T)}}let g=s(b[0]),E=b[0];switch(g){case"primitive":if(null==E)return;m[c]=E;break;case"object":if(null==E.text)return;m[c]=E.text;break;case"array":const G=s(E[0]);m[c]="object"===G?E.map((e=>e.text)).join(""):E.join("")}}})),u.push(m.join(""))})),"array"===c?u:o?o.reduce(((e,t)=>"function"!=typeof t?e:t(e,{...l,...n})),u.join("")):u.join("")}return c?[!0,y]:y}}const l={default:{}};const u={build:c,get:function(e){if(!(e instanceof Array))return function(){return'Error: Argument "location" is a string. Should be an array. E.g. ["templateName", "storageName"].'};const[t,r="default"]=e;return l[r]?l[r][t]?l[r][t]:function(){return`Error: Template "${t}" does not exist in storage "${r}".`}:function(){return`Error: Storage "${r}" does not exist.`}},add:function(e,t,...r){const[n,a="default"]=e;if(null==t)return void console.warn(`Warning: Template ${a}/${n} is not added to storage. The template is null.`);let o=t,s=!0;if(l[a]||(l[a]={}),"function"!=typeof t){let e=c(t,!0,...r);s=e[0],o=e[1]}s?l[a][n]=o:console.error(`Error: Template "${n}" looks broken and is not added to storage.`)},list:function(e=["default"]){return e.map((e=>l[e]?Object.keys(l[e]):[])).flat()},clear:function(){Object.keys(l).forEach((e=>{"default"!=e?delete l[e]:l.default={}}))},remove:function(e){const[t,r="default"]=e;return l[r]?l[r][t]?void delete l[r][t]:`Error: Template "${t}" does not exist in storage "${r}".`:`Error: Storage "${r}" does not exist.`}};module.exports=u;
1
+ "use strict";var e=require("@peter.naydenov/walk"),t=require("@peter.naydenov/stack");function r(e){return function t(r){const{TG_PRX:a,TG_SFX:o,TG_SIZE_P:s,TG_SIZE_S:c}=e;let i,l,u,f=[];if("string"!=typeof r)return n("notAString");if(0==r.length)return[];if(i=r.indexOf(a),0<i&&f.push(r.slice(0,i)),-1==i)return f.push(r),f;{if(u=r.indexOf(a,i+s),l=r.indexOf(o),-1==l)return n("missingClosing");if(l<i)return n("closedBeforeOpened");if(l+=c,-1!=u&&u<l)return n("newBeforeClosed");f.push(r.slice(i,l));let e=t(r.slice(l));return f.concat(e)}}}function n(e){switch(e){case"notAString":return"Error: Template is not a string.";case"missingClosing":return"Error: Placeholder with missing closing tag.";case"closedBeforeOpened":return"Error: Placeholder closing tag without starting one.";case"newBeforeClosed":return"Error: Nested placeholders. Close placeholder before open new one.";default:return"Error: Unknown template error."}}function a(t,r){const n=[];let a=0;if(t instanceof Function)return{dataDeepLevel:0,nestedData:[[t()]]};if(null==t)return{dataDeepLevel:0,nestedData:[null]};if("string"==typeof t)return{dataDeepLevel:0,nestedData:[[t]]};if(!r.includes("#"))return n.push([t]),{dataDeepLevel:0,nestedData:n};return e({data:t,objectCallback:function({key:e,value:t,breadcrumbs:r}){return a=r.split("/").length-1,n[a]||(n[a]=[]),t instanceof Array?n[a].push(t):n[a].push([t]),t}}),{dataDeepLevel:a,nestedData:n}}var o={TG_PRX:"{{",TG_SFX:"}}",TG_SIZE_P:2,TG_SIZE_S:2};function s(e){return null==e?"null":"string"==typeof e||"number"==typeof e||"boolean"==typeof e?"primitive":"function"==typeof e?"function":e instanceof Array?"array":e instanceof Object?"object":void 0}function c(e,t,n,...a){e instanceof Object&&Object.entries(e).forEach((([t,r])=>{r instanceof Object&&(e[t]=r.text),r instanceof Array&&(e[t]=r[0])}));const s="function"==typeof n[t];return e=function(e={}){return"string"==typeof e?{text:e}:e}(e),s?n[t](e,...a):function(e,t){if(null==t)return null;const n=r(o)(e),a=o;return n.forEach(((e,r)=>{if(e.includes(a.TG_PRX)){const o=e.replace(a.TG_PRX,"").replace(a.TG_SFX,"").trim();t[o]&&(n[r]=t[o])}})),n.join("")}(n[t],e)}function i(n,i=!1,l={}){const{hasError:u,placeholders:f,chop:d,helpers:p,handshake:h}=function(e){const{template:t,helpers:n={},handshake:a}=e,{TG_PRX:s,TG_SFX:c}=o,i=[],l="string"==typeof t?t.replace(/<!--[\s\S]*?-->/g,"").replace(/\s{2,}/g," "):t;let u=null;const f=r(o)(l);return"string"==typeof f?u=f:f.forEach(((e,t)=>{const r=RegExp(s+"\\s*(.*?)\\s*(?::\\s*(.*?)\\s*)?"+c,"g");if(e.includes(s)){const a=r.exec(e);i.push({index:t,data:(n=a[1],n||null),action:a[2]?a[2].split(",").map((e=>e.trim())):null})}var n})),i.forEach((e=>{e.action&&e.action.every((e=>"#"===e||(e.startsWith("?")&&(e=e.replace("?","")),e.startsWith("+")&&(e=e.replace("+","")),e.startsWith("[]")&&(e=e.replace("[]","")),e.startsWith(">")&&(e=e.replace(">","")),""===e||!!n[e]||(u=`Error: Missing helper: ${e}`,!1))))})),{hasError:u,placeholders:i,chop:f,helpers:n,handshake:a}}(n);if(u){function b(){return u}return i?[!1,b]:b}{let y=structuredClone(d);function m(r={},n={},...o){const i=[];let u=s(r);if(r=e({data:r}),"null"===u)return y.join("");if("string"==typeof r)switch(r){case"raw":return y.join("");case"demo":if(!h)return"Error: No handshake data.";u=s(r=h);break;case"handshake":return h?structuredClone(h):"Error: No handshake data.";case"placeholders":return f.map((e=>y[e.index])).join(", ");default:return`Error: Wrong command "${r}". Available commands: raw, demo, handshake, placeholders.`}return"array"!==u&&(r=[r]),r.forEach((r=>{f.forEach((o=>{const{index:i,data:u,action:f}=o;if(!f&&u){const e=r[u];switch(s(e)){case"function":return void(y[i]=e());case"primitive":return void(y[i]=e);case"array":return void("primitive"===s(e[0])&&(y[i]=e[0]));case"object":return void(e.text&&(y[i]=e.text))}}else{let{dataDeepLevel:o,nestedData:d}=a("@all"===u||null===u||"@root"===u?r:r[u],f),h=function*(e,r){let n=t({type:"LIFO"});for(let t=0;t<=r;t++)n.push(e[t]);for(;n&&!n.isEmpty();){let e=yield n.pull();e&&n.push(e)}}(function(e,t=10){let r={},n=[...e],a=0,o=0,s=0;n.forEach((e=>{"#"===e&&s++})),s<t&&console.error(`Error: Actions doesn't describe all levels of data. Actions: ${e}`);do{r[o]=[],o++}while(o<=t);return n.every((e=>"#"===e?(a++,!(a>t)):e.startsWith("?")?(r[a].push({type:"route",name:e.replace("?",""),level:a}),!0):e.startsWith("+")?(r[a].push({type:"extendedRender",name:e.replace("+",""),level:a}),!0):e.startsWith("[]")?(r[a].push({type:"mix",name:e.replace("[]",""),level:a}),!0):e.startsWith(">")?(r[a].push({type:"data",name:e.replace(">",""),level:a}),!0):(""===e||r[a].push({type:"render",name:e,level:a}),!0))),r}(f,o),o);for(let t of h){let{type:r,name:a,level:o}=t;d[o].forEach((t=>{let i=s(t);switch(r){case"route":switch(i){case"array":t.forEach(((e,r)=>{if(null==e)return;const o=s(e),i=p[a](e);null!=i&&("object"===o?t[r].text=c(e,i,p,{...l,...n}):t[r]=c(e,i,p,{...l,...n}))}));break;case"object":t.text=c(t,a,p,{...l,...n});break;case"primitive":d[o]=c(t,a,p,{...l,...n})}break;case"data":switch(i){case"array":t.forEach(((e,r)=>t[r]=e instanceof Function?p[a](e()):p[a](e)));break;case"object":d[o]=[p[a](t)];break;case"function":d[o]=[p[a](t())];break;case"primitive":d[o]=p[a](t)}break;case"render":const u="function"==typeof p[a];switch(i){case"array":u?t.forEach(((e,r)=>{if(null==e)return;const o=s(e),c=p[a](e,{...l,...n});null==c&&(t[r]=null),"object"===o?e.text=c:t[r]=c})):t.forEach(((e,r)=>{if(null==e)return;const o=s(e),i=c(e,a,p,{...l,...n});null==i?t[r]=null:"object"===o?e.text=i:t[r]=i}));break;case"function":d[o]=p[a](t(),{...l,...n});break;case"primitive":d[o]=c(t,a,p,{...l,...n});break;case"object":if(u)d[o][0].text=p[a](t,{...l,...n});else{Object.keys(t).find((e=>e.includes("/")))?Object.entries(t).forEach((([e,t])=>t.text=c(t,a,p,{...l,...n}))):t.text=c(t,a,p,{...l,...n})}}break;case"extendedRender":"function"==typeof p[a]&&(d[o]=p[a](d[0][0]));break;case"mix":if(""===a)switch(i){case"object":Object.keys(t).find((e=>e.includes("/")))?Object.entries(t).forEach((([e,t])=>d[o][e]=t.text)):d[o]=t.text;for(let h=o-1;h>=0;h--)d[h]=e({data:d[h],objectCallback:f});function f({value:e,breadcrumbs:t}){return d[o][t]?d[o][t]:e}break;case"array":t.forEach(((e,r)=>{if(r>0){let n=s(e);if(null==e)return;t[0]+="object"===n?`${e.text}`:`${e}`,t.toSpliced(r,1)}else{let r=s(e);if(t[0]="",null===r)return;t[0]="object"===r?`${e.text}`:`${e}`}})),t.length=1}else{let b=p[a](t),y=s(b);switch(t.forEach(((e,r)=>t.splice(r,1))),t.length=0,y){case"primitive":t[0]=b;break;case"array":t.push(...b)}}}}))}if(d instanceof Array&&1===d.length&&d[0]instanceof Array&&(d=d[0]),null==d[0])return;let b=s(d[0]),m=d[0];switch(b){case"primitive":if(null==m)return;y[i]=m;break;case"object":if(null==m.text)return;y[i]=m.text;break;case"array":const e=s(m[0]);y[i]="object"===e?m.map((e=>e.text)).join(""):m.join("")}}})),i.push(y.join(""))})),"array"===u?i:o?o.reduce(((e,t)=>"function"!=typeof t?e:t(e,{...l,...n})),i.join("")):i.join("")}return i?[!0,m]:m}}const l={default:{}};const u={build:i,get:function(e){if(!(e instanceof Array))return function(){return'Error: Argument "location" is a string. Should be an array. E.g. ["templateName", "storageName"].'};const[t,r="default"]=e;return l[r]?l[r][t]?l[r][t]:function(){return`Error: Template "${t}" does not exist in storage "${r}".`}:function(){return`Error: Storage "${r}" does not exist.`}},add:function(e,t,...r){const[n,a="default"]=e;if(null==t)return void console.warn(`Warning: Template ${a}/${n} is not added to storage. The template is null.`);let o=t,s=!0;if(l[a]||(l[a]={}),"function"!=typeof t){let e=i(t,!0,...r);s=e[0],o=e[1]}s?l[a][n]=o:console.error(`Error: Template "${n}" looks broken and is not added to storage.`)},list:function(e=["default"]){return e.map((e=>l[e]?Object.keys(l[e]):[])).flat()},clear:function(){Object.keys(l).forEach((e=>{"default"!=e?delete l[e]:l.default={}}))},remove:function(e){const[t,r="default"]=e;return l[r]?l[r][t]?void delete l[r][t]:`Error: Template "${t}" does not exist in storage "${r}".`:`Error: Storage "${r}" does not exist.`}};module.exports=u;
@@ -1 +1 @@
1
- import e from"@peter.naydenov/walk";import t from"@peter.naydenov/stack";function r(e){return function t(r){const{TG_PRX:a,TG_SFX:o,TG_SIZE_P:s,TG_SIZE_S:i}=e;let c,l,u,f=[];if("string"!=typeof r)return n("notAString");if(0==r.length)return[];if(c=r.indexOf(a),0<c&&f.push(r.slice(0,c)),-1==c)return f.push(r),f;{if(u=r.indexOf(a,c+s),l=r.indexOf(o),-1==l)return n("missingClosing");if(l<c)return n("closedBeforeOpened");if(l+=i,-1!=u&&u<l)return n("newBeforeClosed");f.push(r.slice(c,l));let e=t(r.slice(l));return f.concat(e)}}}function n(e){switch(e){case"notAString":return"Error: Template is not a string.";case"missingClosing":return"Error: Placeholder with missing closing tag.";case"closedBeforeOpened":return"Error: Placeholder closing tag without starting one.";case"newBeforeClosed":return"Error: Nested placeholders. Close placeholder before open new one.";default:return"Error: Unknown template error."}}function a(t,r){const n={};let a=0;if(t instanceof Function)return{dataDeepLevel:0,nestedData:[t()]};if(null==t)return{dataDeepLevel:0,nestedData:[null]};if("string"==typeof t)return{dataDeepLevel:0,nestedData:[t]};if(!r.includes("#"))return{dataDeepLevel:0,nestedData:[t]};return e({data:t,objectCallback:function({key:e,value:t,breadcrumbs:r}){let o=!1;return a=r.split("/").length-1,isNaN(e)||(o=!0),n[a]||(n[a]=o?[]:{}),"root"===e?n[a]=t:o?n[a].push(t):n[a][r]=t,t}}),{dataDeepLevel:a,nestedData:n}}var o={TG_PRX:"{{",TG_SFX:"}}",TG_SIZE_P:2,TG_SIZE_S:2};function s(e){return null==e?"null":"string"==typeof e||"number"==typeof e||"boolean"==typeof e?"primitive":"function"==typeof e?"function":e instanceof Array?"array":e instanceof Object?"object":void 0}function i(e,t,n,...a){e instanceof Object&&Object.entries(e).forEach((([t,r])=>{r instanceof Object&&(e[t]=r.text)}));const s="function"==typeof n[t];return e=function(e={}){return"string"==typeof e?{text:e}:e}(e),s?n[t](e,...a):function(e,t){if(null==t)return null;const n=r(o)(e),a=o;return n.forEach(((e,r)=>{if(e.includes(a.TG_PRX)){const o=e.replace(a.TG_PRX,"").replace(a.TG_SFX,"").trim();t[o]&&(n[r]=t[o])}})),n.join("")}(n[t],e)}function c(n,c=!1,l={}){const{hasError:u,placeholders:f,chop:d,helpers:p,handshake:h}=function(e){const{template:t,helpers:n={},handshake:a}=e,{TG_PRX:s,TG_SFX:i,TG_SIZE_P:c,TG_SIZE_S:l}=o,u=[],f="string"==typeof t?t.replace(/<!--[\s\S]*?-->/g,"").replace(/\s{2,}/g," "):t;let d=null;const p=r(o)(f);return"string"==typeof p?d=p:p.forEach(((e,t)=>{const r=RegExp(s+"\\s*(.*?)\\s*(?::\\s*(.*?)\\s*)?"+i,"g");if(e.includes(s)){const a=r.exec(e);u.push({index:t,data:(n=a[1],n||null),action:a[2]?a[2].split(",").map((e=>e.trim())):null})}var n})),u.forEach((e=>{e.action&&e.action.every((e=>"#"===e||(e.startsWith("?")&&(e=e.replace("?","")),e.startsWith("+")&&(e=e.replace("+","")),e.startsWith("[]")&&(e=e.replace("[]","")),e.startsWith(">")&&(e=e.replace(">","")),""===e||!!n[e]||(d=`Error: Missing helper: ${e}`,!1))))})),{hasError:d,placeholders:u,chop:p,helpers:n,handshake:a}}(n);if(u){function b(){return u}return c?[!1,b]:b}{let m=structuredClone(d);function y(r={},n={},...o){const c=s(r),u=[];if(r=e({data:r}),"null"===c)return m.join("");if("string"==typeof r)switch(r){case"raw":return m.join("");case"demo":if(!h)return"Error: No handshake data.";r=h;break;case"handshake":return h?structuredClone(h):"Error: No handshake data.";case"placeholders":return f.map((e=>m[e.index])).join(", ");default:return`Error: Wrong command "${r}". Available commands: raw, demo, handshake, placeholders.`}return"array"!==c&&(r=[r]),r.forEach((r=>{f.forEach((o=>{const{index:c,data:u,action:f}=o;if(!f&&u){const d=r[u];switch(s(d)){case"function":return void(m[c]=d());case"primitive":return void(m[c]=d);case"array":return void("primitive"===s(d[0])&&(m[c]=d[0]));case"object":return void(d.text&&(m[c]=d.text))}}else{const{dataDeepLevel:h,nestedData:b}=a("@all"===u||null===u||"@root"===u?r:r[u],f),y=function*(e,r){let n=t({type:"LIFO"});for(let t=0;t<=r;t++)n.push(e[t]);for(;n&&!n.isEmpty();){let e=yield n.pull();e&&n.push(e)}}(function(e,t=10){let r={},n=0,a=[...e],o=0;do{r[o]=[],o++}while(o<=t);return a.every((e=>"#"===e?(n++,!(n>t)):e.startsWith("?")?(r[n].push({type:"route",name:e.replace("?",""),level:n}),!0):e.startsWith("+")?(r[n].push({type:"extendedRender",name:e.replace("+",""),level:n}),!0):e.startsWith("[]")?(r[n].push({type:"mix",name:e.replace("[]",""),level:n}),!0):e.startsWith(">")?(r[n].push({type:"data",name:e.replace(">",""),level:n}),!0):(""===e||r[n].push({type:"render",name:e,level:n}),!0))),r}(f,h),h);for(let v of y){let{type:j,name:k,level:x}=v,T=b[x],_=s(T);switch(j){case"route":switch(_){case"array":T.forEach(((e,t)=>{if(null==e)return;const r=s(e),a=p[k](e);null!=a&&("object"===r?T[t].text=i(e,a,p,{...l,...n}):T[t]=i(e,a,p,{...l,...n}))}));break;case"object":T.text=i(T,k,p,{...l,...n});break;case"primitive":b[x]=i(T,k,p,{...l,...n})}break;case"data":switch(_){case"array":T.forEach(((e,t)=>T[t]=e instanceof Function?p[k](e()):p[k](e)));break;case"object":case"primitive":b[x]=p[k](T);break;case"function":b[x]=p[k](T())}break;case"render":const w="function"==typeof p[k];switch(_){case"array":w?T.forEach(((e,t)=>{if(null==e)return;const r=s(e),a=p[k](e,{...l,...n});null==a&&(T[t]=null),"object"===r?e.text=a:T[t]=a})):T.forEach(((e,t)=>{if(null==e)return;const r=s(e),a=i(e,k,p,{...l,...n});null==a&&(T[t]=null),"object"===r?e.text=a:T[t]=a}));break;case"function":b[x]=p[k](T(),{...l,...n});break;case"primitive":b[x]=i(T,k,p,{...l,...n});break;case"object":if(w)b[x].text=p[k](T,{...l,...n});else{Object.keys(T).find((e=>e.includes("/")))?Object.entries(T).forEach((([e,t])=>t.text=i(t,k,p,{...l,...n}))):T.text=i(T,k,p,{...l,...n})}}break;case"extendedRender":"function"==typeof p[k]&&(b[x]=p[k](b[0]));break;case"mix":if(""===k)switch(_){case"object":Object.keys(T).find((e=>e.includes("/")))?Object.entries(T).forEach((([e,t])=>b[x][e]=t.text)):b[x]=T.text;for(let O=x-1;O>=0;O--)b[O]=e({data:b[O],objectCallback:S});function S({value:e,breadcrumbs:t}){return b[x][t]?b[x][t]:e}break;case"array":b[x]=T.map((e=>"object"===s(e)?e.text:e)).filter((e=>null!=e)).join("")}else b[x]=p[k](T)}}let g=s(b[0]),E=b[0];switch(g){case"primitive":if(null==E)return;m[c]=E;break;case"object":if(null==E.text)return;m[c]=E.text;break;case"array":const G=s(E[0]);m[c]="object"===G?E.map((e=>e.text)).join(""):E.join("")}}})),u.push(m.join(""))})),"array"===c?u:o?o.reduce(((e,t)=>"function"!=typeof t?e:t(e,{...l,...n})),u.join("")):u.join("")}return c?[!0,y]:y}}const l={default:{}};const u={build:c,get:function(e){if(!(e instanceof Array))return function(){return'Error: Argument "location" is a string. Should be an array. E.g. ["templateName", "storageName"].'};const[t,r="default"]=e;return l[r]?l[r][t]?l[r][t]:function(){return`Error: Template "${t}" does not exist in storage "${r}".`}:function(){return`Error: Storage "${r}" does not exist.`}},add:function(e,t,...r){const[n,a="default"]=e;if(null==t)return void console.warn(`Warning: Template ${a}/${n} is not added to storage. The template is null.`);let o=t,s=!0;if(l[a]||(l[a]={}),"function"!=typeof t){let e=c(t,!0,...r);s=e[0],o=e[1]}s?l[a][n]=o:console.error(`Error: Template "${n}" looks broken and is not added to storage.`)},list:function(e=["default"]){return e.map((e=>l[e]?Object.keys(l[e]):[])).flat()},clear:function(){Object.keys(l).forEach((e=>{"default"!=e?delete l[e]:l.default={}}))},remove:function(e){const[t,r="default"]=e;return l[r]?l[r][t]?void delete l[r][t]:`Error: Template "${t}" does not exist in storage "${r}".`:`Error: Storage "${r}" does not exist.`}};export{u as default};
1
+ import e from"@peter.naydenov/walk";import t from"@peter.naydenov/stack";function r(e){return function t(r){const{TG_PRX:a,TG_SFX:o,TG_SIZE_P:s,TG_SIZE_S:c}=e;let i,l,u,f=[];if("string"!=typeof r)return n("notAString");if(0==r.length)return[];if(i=r.indexOf(a),0<i&&f.push(r.slice(0,i)),-1==i)return f.push(r),f;{if(u=r.indexOf(a,i+s),l=r.indexOf(o),-1==l)return n("missingClosing");if(l<i)return n("closedBeforeOpened");if(l+=c,-1!=u&&u<l)return n("newBeforeClosed");f.push(r.slice(i,l));let e=t(r.slice(l));return f.concat(e)}}}function n(e){switch(e){case"notAString":return"Error: Template is not a string.";case"missingClosing":return"Error: Placeholder with missing closing tag.";case"closedBeforeOpened":return"Error: Placeholder closing tag without starting one.";case"newBeforeClosed":return"Error: Nested placeholders. Close placeholder before open new one.";default:return"Error: Unknown template error."}}function a(t,r){const n=[];let a=0;if(t instanceof Function)return{dataDeepLevel:0,nestedData:[[t()]]};if(null==t)return{dataDeepLevel:0,nestedData:[null]};if("string"==typeof t)return{dataDeepLevel:0,nestedData:[[t]]};if(!r.includes("#"))return n.push([t]),{dataDeepLevel:0,nestedData:n};return e({data:t,objectCallback:function({key:e,value:t,breadcrumbs:r}){return a=r.split("/").length-1,n[a]||(n[a]=[]),t instanceof Array?n[a].push(t):n[a].push([t]),t}}),{dataDeepLevel:a,nestedData:n}}var o={TG_PRX:"{{",TG_SFX:"}}",TG_SIZE_P:2,TG_SIZE_S:2};function s(e){return null==e?"null":"string"==typeof e||"number"==typeof e||"boolean"==typeof e?"primitive":"function"==typeof e?"function":e instanceof Array?"array":e instanceof Object?"object":void 0}function c(e,t,n,...a){e instanceof Object&&Object.entries(e).forEach((([t,r])=>{r instanceof Object&&(e[t]=r.text),r instanceof Array&&(e[t]=r[0])}));const s="function"==typeof n[t];return e=function(e={}){return"string"==typeof e?{text:e}:e}(e),s?n[t](e,...a):function(e,t){if(null==t)return null;const n=r(o)(e),a=o;return n.forEach(((e,r)=>{if(e.includes(a.TG_PRX)){const o=e.replace(a.TG_PRX,"").replace(a.TG_SFX,"").trim();t[o]&&(n[r]=t[o])}})),n.join("")}(n[t],e)}function i(n,i=!1,l={}){const{hasError:u,placeholders:f,chop:d,helpers:p,handshake:h}=function(e){const{template:t,helpers:n={},handshake:a}=e,{TG_PRX:s,TG_SFX:c}=o,i=[],l="string"==typeof t?t.replace(/<!--[\s\S]*?-->/g,"").replace(/\s{2,}/g," "):t;let u=null;const f=r(o)(l);return"string"==typeof f?u=f:f.forEach(((e,t)=>{const r=RegExp(s+"\\s*(.*?)\\s*(?::\\s*(.*?)\\s*)?"+c,"g");if(e.includes(s)){const a=r.exec(e);i.push({index:t,data:(n=a[1],n||null),action:a[2]?a[2].split(",").map((e=>e.trim())):null})}var n})),i.forEach((e=>{e.action&&e.action.every((e=>"#"===e||(e.startsWith("?")&&(e=e.replace("?","")),e.startsWith("+")&&(e=e.replace("+","")),e.startsWith("[]")&&(e=e.replace("[]","")),e.startsWith(">")&&(e=e.replace(">","")),""===e||!!n[e]||(u=`Error: Missing helper: ${e}`,!1))))})),{hasError:u,placeholders:i,chop:f,helpers:n,handshake:a}}(n);if(u){function b(){return u}return i?[!1,b]:b}{let m=structuredClone(d);function y(r={},n={},...o){const i=[];let u=s(r);if(r=e({data:r}),"null"===u)return m.join("");if("string"==typeof r)switch(r){case"raw":return m.join("");case"demo":if(!h)return"Error: No handshake data.";u=s(r=h);break;case"handshake":return h?structuredClone(h):"Error: No handshake data.";case"placeholders":return f.map((e=>m[e.index])).join(", ");default:return`Error: Wrong command "${r}". Available commands: raw, demo, handshake, placeholders.`}return"array"!==u&&(r=[r]),r.forEach((r=>{f.forEach((o=>{const{index:i,data:u,action:f}=o;if(!f&&u){const e=r[u];switch(s(e)){case"function":return void(m[i]=e());case"primitive":return void(m[i]=e);case"array":return void("primitive"===s(e[0])&&(m[i]=e[0]));case"object":return void(e.text&&(m[i]=e.text))}}else{let{dataDeepLevel:o,nestedData:d}=a("@all"===u||null===u||"@root"===u?r:r[u],f),h=function*(e,r){let n=t({type:"LIFO"});for(let t=0;t<=r;t++)n.push(e[t]);for(;n&&!n.isEmpty();){let e=yield n.pull();e&&n.push(e)}}(function(e,t=10){let r={},n=[...e],a=0,o=0,s=0;n.forEach((e=>{"#"===e&&s++})),s<t&&console.error(`Error: Actions doesn't describe all levels of data. Actions: ${e}`);do{r[o]=[],o++}while(o<=t);return n.every((e=>"#"===e?(a++,!(a>t)):e.startsWith("?")?(r[a].push({type:"route",name:e.replace("?",""),level:a}),!0):e.startsWith("+")?(r[a].push({type:"extendedRender",name:e.replace("+",""),level:a}),!0):e.startsWith("[]")?(r[a].push({type:"mix",name:e.replace("[]",""),level:a}),!0):e.startsWith(">")?(r[a].push({type:"data",name:e.replace(">",""),level:a}),!0):(""===e||r[a].push({type:"render",name:e,level:a}),!0))),r}(f,o),o);for(let t of h){let{type:r,name:a,level:o}=t;d[o].forEach((t=>{let i=s(t);switch(r){case"route":switch(i){case"array":t.forEach(((e,r)=>{if(null==e)return;const o=s(e),i=p[a](e);null!=i&&("object"===o?t[r].text=c(e,i,p,{...l,...n}):t[r]=c(e,i,p,{...l,...n}))}));break;case"object":t.text=c(t,a,p,{...l,...n});break;case"primitive":d[o]=c(t,a,p,{...l,...n})}break;case"data":switch(i){case"array":t.forEach(((e,r)=>t[r]=e instanceof Function?p[a](e()):p[a](e)));break;case"object":d[o]=[p[a](t)];break;case"function":d[o]=[p[a](t())];break;case"primitive":d[o]=p[a](t)}break;case"render":const u="function"==typeof p[a];switch(i){case"array":u?t.forEach(((e,r)=>{if(null==e)return;const o=s(e),c=p[a](e,{...l,...n});null==c&&(t[r]=null),"object"===o?e.text=c:t[r]=c})):t.forEach(((e,r)=>{if(null==e)return;const o=s(e),i=c(e,a,p,{...l,...n});null==i?t[r]=null:"object"===o?e.text=i:t[r]=i}));break;case"function":d[o]=p[a](t(),{...l,...n});break;case"primitive":d[o]=c(t,a,p,{...l,...n});break;case"object":if(u)d[o][0].text=p[a](t,{...l,...n});else{Object.keys(t).find((e=>e.includes("/")))?Object.entries(t).forEach((([e,t])=>t.text=c(t,a,p,{...l,...n}))):t.text=c(t,a,p,{...l,...n})}}break;case"extendedRender":"function"==typeof p[a]&&(d[o]=p[a](d[0][0]));break;case"mix":if(""===a)switch(i){case"object":Object.keys(t).find((e=>e.includes("/")))?Object.entries(t).forEach((([e,t])=>d[o][e]=t.text)):d[o]=t.text;for(let h=o-1;h>=0;h--)d[h]=e({data:d[h],objectCallback:f});function f({value:e,breadcrumbs:t}){return d[o][t]?d[o][t]:e}break;case"array":t.forEach(((e,r)=>{if(r>0){let n=s(e);if(null==e)return;t[0]+="object"===n?`${e.text}`:`${e}`,t.toSpliced(r,1)}else{let r=s(e);if(t[0]="",null===r)return;t[0]="object"===r?`${e.text}`:`${e}`}})),t.length=1}else{let b=p[a](t),m=s(b);switch(t.forEach(((e,r)=>t.splice(r,1))),t.length=0,m){case"primitive":t[0]=b;break;case"array":t.push(...b)}}}}))}if(d instanceof Array&&1===d.length&&d[0]instanceof Array&&(d=d[0]),null==d[0])return;let b=s(d[0]),y=d[0];switch(b){case"primitive":if(null==y)return;m[i]=y;break;case"object":if(null==y.text)return;m[i]=y.text;break;case"array":const e=s(y[0]);m[i]="object"===e?y.map((e=>e.text)).join(""):y.join("")}}})),i.push(m.join(""))})),"array"===u?i:o?o.reduce(((e,t)=>"function"!=typeof t?e:t(e,{...l,...n})),i.join("")):i.join("")}return i?[!0,y]:y}}const l={default:{}};const u={build:i,get:function(e){if(!(e instanceof Array))return function(){return'Error: Argument "location" is a string. Should be an array. E.g. ["templateName", "storageName"].'};const[t,r="default"]=e;return l[r]?l[r][t]?l[r][t]:function(){return`Error: Template "${t}" does not exist in storage "${r}".`}:function(){return`Error: Storage "${r}" does not exist.`}},add:function(e,t,...r){const[n,a="default"]=e;if(null==t)return void console.warn(`Warning: Template ${a}/${n} is not added to storage. The template is null.`);let o=t,s=!0;if(l[a]||(l[a]={}),"function"!=typeof t){let e=i(t,!0,...r);s=e[0],o=e[1]}s?l[a][n]=o:console.error(`Error: Template "${n}" looks broken and is not added to storage.`)},list:function(e=["default"]){return e.map((e=>l[e]?Object.keys(l[e]):[])).flat()},clear:function(){Object.keys(l).forEach((e=>{"default"!=e?delete l[e]:l.default={}}))},remove:function(e){const[t,r="default"]=e;return l[r]?l[r][t]?void delete l[r][t]:`Error: Template "${t}" does not exist in storage "${r}".`:`Error: Storage "${r}" does not exist.`}};export{u as default};
package/dist/morph.umd.js CHANGED
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@peter.naydenov/walk")):"function"==typeof define&&define.amd?define(["@peter.naydenov/walk"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).morph=t(e.walk)}(this,(function(e){"use strict";function t(e){return function t(r){const{TG_PRX:o,TG_SFX:a,TG_SIZE_P:i,TG_SIZE_S:s}=e;let l,c,u,f=[];if("string"!=typeof r)return n("notAString");if(0==r.length)return[];if(l=r.indexOf(o),0<l&&f.push(r.slice(0,l)),-1==l)return f.push(r),f;{if(u=r.indexOf(o,l+i),c=r.indexOf(a),-1==c)return n("missingClosing");if(c<l)return n("closedBeforeOpened");if(c+=s,-1!=u&&u<c)return n("newBeforeClosed");f.push(r.slice(l,c));let e=t(r.slice(c));return f.concat(e)}}}function n(e){switch(e){case"notAString":return"Error: Template is not a string.";case"missingClosing":return"Error: Placeholder with missing closing tag.";case"closedBeforeOpened":return"Error: Placeholder closing tag without starting one.";case"newBeforeClosed":return"Error: Nested placeholders. Close placeholder before open new one.";default:return"Error: Unknown template error."}}function r(t,n){const r={};let o=0;if(t instanceof Function)return{dataDeepLevel:0,nestedData:[t()]};if(null==t)return{dataDeepLevel:0,nestedData:[null]};if("string"==typeof t)return{dataDeepLevel:0,nestedData:[t]};if(!n.includes("#"))return{dataDeepLevel:0,nestedData:[t]};return e({data:t,objectCallback:function({key:e,value:t,breadcrumbs:n}){let a=!1;return o=n.split("/").length-1,isNaN(e)||(a=!0),r[o]||(r[o]=a?[]:{}),"root"===e?r[o]=t:a?r[o].push(t):r[o][n]=t,t}}),{dataDeepLevel:o,nestedData:r}}function*o(e,t){let n=function(e={}){let t=[],{type:n,limit:r,onLimit:o}=Object.assign({},{type:"FIFO",limit:!1,onLimit:"update"},e),a="LIFO"===n.toUpperCase(),i=!1;function s(e=1,n=0){let r=[];return n>0&&Array.from({length:n}).map((()=>t.pop())),1==e?t.pop():(Array.from({length:e}).map((()=>{let e=t.pop();null!=e&&r.push(e)})),r)}function l(e=1,n=0){let r=[],o=t.length-n;return e>1&&Array.from({length:e}).map((()=>{null!=t[o-1]&&r.push(t[o-1]),o--})),1==e?t[t.length-1]:r}function c(){}return c.prototype={pull:s,pullReverse:function(e=1,t=0){let n=s(e,t);return n instanceof Array?n.reverse():n},peek:l,peekReverse:function(e=1,t=0){const n=l(e,t);return n instanceof Array?n.reverse():n},getSize:()=>t.length,isEmpty:()=>0==t.length,reset:()=>(t=[],!0),debug:()=>[...t]},c.prototype.push=a?function(e){const n=e instanceof Array,a=n?e.length:1;let l=!1;if("full"!==o||!i){if(r&&n&&a>r&&(e=e.slice(0,-a+r)),r){const a=(n?e.length:1)+t.length;a>=r&&"full"===o&&(e=e.slice(0,-(a-r))),a>=r&&"update"===o&&(l=s(a-r))}return t=e instanceof Array?t.concat(e):t.concat([e]),i=!!r&&t.length===r,l||void 0}}:function(e){const n=e instanceof Array,a=n?e.length:1;let l=!1;if("full"!==o||!i){if(r&&n&&a>r&&(e=e.slice(a-r)),r){const a=(n?e.length:1)+t.length;a>=r&&"full"===o&&(e=e.slice(0,-(a-r))),a>=r&&"update"===o&&(l=s(a-r))}return t=n?e.reduce(((e,t)=>[t,...e]),t):[e].reduce(((e,t)=>[t,...e]),t),i=!!r&&t.length===r,l||void 0}},new c}({type:"LIFO"});for(let r=0;r<=t;r++)n.push(e[r]);for(;n&&!n.isEmpty();){let e=yield n.pull();e&&n.push(e)}}var a={TG_PRX:"{{",TG_SFX:"}}",TG_SIZE_P:2,TG_SIZE_S:2};function i(e){return null==e?"null":"string"==typeof e||"number"==typeof e||"boolean"==typeof e?"primitive":"function"==typeof e?"function":e instanceof Array?"array":e instanceof Object?"object":void 0}function s(e,n,r,...o){e instanceof Object&&Object.entries(e).forEach((([t,n])=>{n instanceof Object&&(e[t]=n.text)}));const i="function"==typeof r[n];return e=function(e={}){return"string"==typeof e?{text:e}:e}(e),i?r[n](e,...o):function(e,n){if(null==n)return null;const r=t(a)(e),o=a;return r.forEach(((e,t)=>{if(e.includes(o.TG_PRX)){const a=e.replace(o.TG_PRX,"").replace(o.TG_SFX,"").trim();n[a]&&(r[t]=n[a])}})),r.join("")}(r[n],e)}function l(n,l=!1,c={}){const{hasError:u,placeholders:f,chop:p,helpers:d,handshake:h}=function(e){const{template:n,helpers:r={},handshake:o}=e,{TG_PRX:i,TG_SFX:s,TG_SIZE_P:l,TG_SIZE_S:c}=a,u=[],f="string"==typeof n?n.replace(/<!--[\s\S]*?-->/g,"").replace(/\s{2,}/g," "):n;let p=null;const d=t(a)(f);return"string"==typeof d?p=d:d.forEach(((e,t)=>{const n=RegExp(i+"\\s*(.*?)\\s*(?::\\s*(.*?)\\s*)?"+s,"g");if(e.includes(i)){const o=n.exec(e);u.push({index:t,data:(r=o[1],r||null),action:o[2]?o[2].split(",").map((e=>e.trim())):null})}var r})),u.forEach((e=>{e.action&&e.action.every((e=>"#"===e||(e.startsWith("?")&&(e=e.replace("?","")),e.startsWith("+")&&(e=e.replace("+","")),e.startsWith("[]")&&(e=e.replace("[]","")),e.startsWith(">")&&(e=e.replace(">","")),""===e||!!r[e]||(p=`Error: Missing helper: ${e}`,!1))))})),{hasError:p,placeholders:u,chop:d,helpers:r,handshake:o}}(n);if(u){function m(){return u}return l?[!1,m]:m}{let y=structuredClone(p);function g(t={},n={},...a){const l=i(t),u=[];if(t=e({data:t}),"null"===l)return y.join("");if("string"==typeof t)switch(t){case"raw":return y.join("");case"demo":if(!h)return"Error: No handshake data.";t=h;break;case"handshake":return h?structuredClone(h):"Error: No handshake data.";case"placeholders":return f.map((e=>y[e.index])).join(", ");default:return`Error: Wrong command "${t}". Available commands: raw, demo, handshake, placeholders.`}return"array"!==l&&(t=[t]),t.forEach((t=>{f.forEach((a=>{const{index:l,data:u,action:f}=a;if(!f&&u){const p=t[u];switch(i(p)){case"function":return void(y[l]=p());case"primitive":return void(y[l]=p);case"array":return void("primitive"===i(p[0])&&(y[l]=p[0]));case"object":return void(p.text&&(y[l]=p.text))}}else{const{dataDeepLevel:h,nestedData:m}=r("@all"===u||null===u||"@root"===u?t:t[u],f),g=o(function(e,t=10){let n={},r=0,o=[...e],a=0;do{n[a]=[],a++}while(a<=t);return o.every((e=>"#"===e?(r++,!(r>t)):e.startsWith("?")?(n[r].push({type:"route",name:e.replace("?",""),level:r}),!0):e.startsWith("+")?(n[r].push({type:"extendedRender",name:e.replace("+",""),level:r}),!0):e.startsWith("[]")?(n[r].push({type:"mix",name:e.replace("[]",""),level:r}),!0):e.startsWith(">")?(n[r].push({type:"data",name:e.replace(">",""),level:r}),!0):(""===e||n[r].push({type:"render",name:e,level:r}),!0))),n}(f,h),h);for(let E of g){let{type:k,name:j,level:x}=E,w=m[x],T=i(w);switch(k){case"route":switch(T){case"array":w.forEach(((e,t)=>{if(null==e)return;const r=i(e),o=d[j](e);null!=o&&("object"===r?w[t].text=s(e,o,d,{...c,...n}):w[t]=s(e,o,d,{...c,...n}))}));break;case"object":w.text=s(w,j,d,{...c,...n});break;case"primitive":m[x]=s(w,j,d,{...c,...n})}break;case"data":switch(T){case"array":w.forEach(((e,t)=>w[t]=e instanceof Function?d[j](e()):d[j](e)));break;case"object":case"primitive":m[x]=d[j](w);break;case"function":m[x]=d[j](w())}break;case"render":const _="function"==typeof d[j];switch(T){case"array":_?w.forEach(((e,t)=>{if(null==e)return;const r=i(e),o=d[j](e,{...c,...n});null==o&&(w[t]=null),"object"===r?e.text=o:w[t]=o})):w.forEach(((e,t)=>{if(null==e)return;const r=i(e),o=s(e,j,d,{...c,...n});null==o&&(w[t]=null),"object"===r?e.text=o:w[t]=o}));break;case"function":m[x]=d[j](w(),{...c,...n});break;case"primitive":m[x]=s(w,j,d,{...c,...n});break;case"object":if(_)m[x].text=d[j](w,{...c,...n});else{Object.keys(w).find((e=>e.includes("/")))?Object.entries(w).forEach((([e,t])=>t.text=s(t,j,d,{...c,...n}))):w.text=s(w,j,d,{...c,...n})}}break;case"extendedRender":"function"==typeof d[j]&&(m[x]=d[j](m[0]));break;case"mix":if(""===j)switch(T){case"object":Object.keys(w).find((e=>e.includes("/")))?Object.entries(w).forEach((([e,t])=>m[x][e]=t.text)):m[x]=w.text;for(let O=x-1;O>=0;O--)m[O]=e({data:m[O],objectCallback:S});function S({value:e,breadcrumbs:t}){return m[x][t]?m[x][t]:e}break;case"array":m[x]=w.map((e=>"object"===i(e)?e.text:e)).filter((e=>null!=e)).join("")}else m[x]=d[j](w)}}let b=i(m[0]),v=m[0];switch(b){case"primitive":if(null==v)return;y[l]=v;break;case"object":if(null==v.text)return;y[l]=v.text;break;case"array":const G=i(v[0]);y[l]="object"===G?v.map((e=>e.text)).join(""):v.join("")}}})),u.push(y.join(""))})),"array"===l?u:a?a.reduce(((e,t)=>"function"!=typeof t?e:t(e,{...c,...n})),u.join("")):u.join("")}return l?[!0,g]:g}}const c={default:{}};return{build:l,get:function(e){if(!(e instanceof Array))return function(){return'Error: Argument "location" is a string. Should be an array. E.g. ["templateName", "storageName"].'};const[t,n="default"]=e;return c[n]?c[n][t]?c[n][t]:function(){return`Error: Template "${t}" does not exist in storage "${n}".`}:function(){return`Error: Storage "${n}" does not exist.`}},add:function(e,t,...n){const[r,o="default"]=e;if(null==t)return void console.warn(`Warning: Template ${o}/${r} is not added to storage. The template is null.`);let a=t,i=!0;if(c[o]||(c[o]={}),"function"!=typeof t){let e=l(t,!0,...n);i=e[0],a=e[1]}i?c[o][r]=a:console.error(`Error: Template "${r}" looks broken and is not added to storage.`)},list:function(e=["default"]){return e.map((e=>c[e]?Object.keys(c[e]):[])).flat()},clear:function(){Object.keys(c).forEach((e=>{"default"!=e?delete c[e]:c.default={}}))},remove:function(e){const[t,n="default"]=e;return c[n]?c[n][t]?void delete c[n][t]:`Error: Template "${t}" does not exist in storage "${n}".`:`Error: Storage "${n}" does not exist.`}}}));
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@peter.naydenov/walk")):"function"==typeof define&&define.amd?define(["@peter.naydenov/walk"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).morph=t(e.walk)}(this,(function(e){"use strict";function t(e){return function t(n){const{TG_PRX:a,TG_SFX:o,TG_SIZE_P:i,TG_SIZE_S:l}=e;let s,c,u,f=[];if("string"!=typeof n)return r("notAString");if(0==n.length)return[];if(s=n.indexOf(a),0<s&&f.push(n.slice(0,s)),-1==s)return f.push(n),f;{if(u=n.indexOf(a,s+i),c=n.indexOf(o),-1==c)return r("missingClosing");if(c<s)return r("closedBeforeOpened");if(c+=l,-1!=u&&u<c)return r("newBeforeClosed");f.push(n.slice(s,c));let e=t(n.slice(c));return f.concat(e)}}}function r(e){switch(e){case"notAString":return"Error: Template is not a string.";case"missingClosing":return"Error: Placeholder with missing closing tag.";case"closedBeforeOpened":return"Error: Placeholder closing tag without starting one.";case"newBeforeClosed":return"Error: Nested placeholders. Close placeholder before open new one.";default:return"Error: Unknown template error."}}function n(t,r){const n=[];let a=0;if(t instanceof Function)return{dataDeepLevel:0,nestedData:[[t()]]};if(null==t)return{dataDeepLevel:0,nestedData:[null]};if("string"==typeof t)return{dataDeepLevel:0,nestedData:[[t]]};if(!r.includes("#"))return n.push([t]),{dataDeepLevel:0,nestedData:n};return e({data:t,objectCallback:function({key:e,value:t,breadcrumbs:r}){return a=r.split("/").length-1,n[a]||(n[a]=[]),t instanceof Array?n[a].push(t):n[a].push([t]),t}}),{dataDeepLevel:a,nestedData:n}}function*a(e,t){let r=function(e={}){let t=[],{type:r,limit:n,onLimit:a}=Object.assign({},{type:"FIFO",limit:!1,onLimit:"update"},e),o="LIFO"===r.toUpperCase(),i=!1;function l(e=1,r=0){let n=[];return r>0&&Array.from({length:r}).map((()=>t.pop())),1==e?t.pop():(Array.from({length:e}).map((()=>{let e=t.pop();null!=e&&n.push(e)})),n)}function s(e=1,r=0){let n=[],a=t.length-r;return e>1&&Array.from({length:e}).map((()=>{null!=t[a-1]&&n.push(t[a-1]),a--})),1==e?t[t.length-1]:n}function c(){}return c.prototype={pull:l,pullReverse:function(e=1,t=0){let r=l(e,t);return r instanceof Array?r.reverse():r},peek:s,peekReverse:function(e=1,t=0){const r=s(e,t);return r instanceof Array?r.reverse():r},getSize:()=>t.length,isEmpty:()=>0==t.length,reset:()=>(t=[],!0),debug:()=>[...t]},c.prototype.push=o?function(e){const r=e instanceof Array,o=r?e.length:1;let s=!1;if("full"!==a||!i){if(n&&r&&o>n&&(e=e.slice(0,-o+n)),n){const o=(r?e.length:1)+t.length;o>=n&&"full"===a&&(e=e.slice(0,-(o-n))),o>=n&&"update"===a&&(s=l(o-n))}return t=e instanceof Array?t.concat(e):t.concat([e]),i=!!n&&t.length===n,s||void 0}}:function(e){const r=e instanceof Array,o=r?e.length:1;let s=!1;if("full"!==a||!i){if(n&&r&&o>n&&(e=e.slice(o-n)),n){const o=(r?e.length:1)+t.length;o>=n&&"full"===a&&(e=e.slice(0,-(o-n))),o>=n&&"update"===a&&(s=l(o-n))}return t=r?e.reduce(((e,t)=>[t,...e]),t):[e].reduce(((e,t)=>[t,...e]),t),i=!!n&&t.length===n,s||void 0}},new c}({type:"LIFO"});for(let n=0;n<=t;n++)r.push(e[n]);for(;r&&!r.isEmpty();){let e=yield r.pull();e&&r.push(e)}}var o={TG_PRX:"{{",TG_SFX:"}}",TG_SIZE_P:2,TG_SIZE_S:2};function i(e){return null==e?"null":"string"==typeof e||"number"==typeof e||"boolean"==typeof e?"primitive":"function"==typeof e?"function":e instanceof Array?"array":e instanceof Object?"object":void 0}function l(e,r,n,...a){e instanceof Object&&Object.entries(e).forEach((([t,r])=>{r instanceof Object&&(e[t]=r.text),r instanceof Array&&(e[t]=r[0])}));const i="function"==typeof n[r];return e=function(e={}){return"string"==typeof e?{text:e}:e}(e),i?n[r](e,...a):function(e,r){if(null==r)return null;const n=t(o)(e),a=o;return n.forEach(((e,t)=>{if(e.includes(a.TG_PRX)){const o=e.replace(a.TG_PRX,"").replace(a.TG_SFX,"").trim();r[o]&&(n[t]=r[o])}})),n.join("")}(n[r],e)}function s(r,s=!1,c={}){const{hasError:u,placeholders:f,chop:p,helpers:d,handshake:h}=function(e){const{template:r,helpers:n={},handshake:a}=e,{TG_PRX:i,TG_SFX:l}=o,s=[],c="string"==typeof r?r.replace(/<!--[\s\S]*?-->/g,"").replace(/\s{2,}/g," "):r;let u=null;const f=t(o)(c);return"string"==typeof f?u=f:f.forEach(((e,t)=>{const r=RegExp(i+"\\s*(.*?)\\s*(?::\\s*(.*?)\\s*)?"+l,"g");if(e.includes(i)){const a=r.exec(e);s.push({index:t,data:(n=a[1],n||null),action:a[2]?a[2].split(",").map((e=>e.trim())):null})}var n})),s.forEach((e=>{e.action&&e.action.every((e=>"#"===e||(e.startsWith("?")&&(e=e.replace("?","")),e.startsWith("+")&&(e=e.replace("+","")),e.startsWith("[]")&&(e=e.replace("[]","")),e.startsWith(">")&&(e=e.replace(">","")),""===e||!!n[e]||(u=`Error: Missing helper: ${e}`,!1))))})),{hasError:u,placeholders:s,chop:f,helpers:n,handshake:a}}(r);if(u){function y(){return u}return s?[!1,y]:y}{let g=structuredClone(p);function m(t={},r={},...o){const s=[];let u=i(t);if(t=e({data:t}),"null"===u)return g.join("");if("string"==typeof t)switch(t){case"raw":return g.join("");case"demo":if(!h)return"Error: No handshake data.";u=i(t=h);break;case"handshake":return h?structuredClone(h):"Error: No handshake data.";case"placeholders":return f.map((e=>g[e.index])).join(", ");default:return`Error: Wrong command "${t}". Available commands: raw, demo, handshake, placeholders.`}return"array"!==u&&(t=[t]),t.forEach((t=>{f.forEach((o=>{const{index:s,data:u,action:f}=o;if(!f&&u){const e=t[u];switch(i(e)){case"function":return void(g[s]=e());case"primitive":return void(g[s]=e);case"array":return void("primitive"===i(e[0])&&(g[s]=e[0]));case"object":return void(e.text&&(g[s]=e.text))}}else{let{dataDeepLevel:o,nestedData:p}=n("@all"===u||null===u||"@root"===u?t:t[u],f),h=a(function(e,t=10){let r={},n=[...e],a=0,o=0,i=0;n.forEach((e=>{"#"===e&&i++})),i<t&&console.error(`Error: Actions doesn't describe all levels of data. Actions: ${e}`);do{r[o]=[],o++}while(o<=t);return n.every((e=>"#"===e?(a++,!(a>t)):e.startsWith("?")?(r[a].push({type:"route",name:e.replace("?",""),level:a}),!0):e.startsWith("+")?(r[a].push({type:"extendedRender",name:e.replace("+",""),level:a}),!0):e.startsWith("[]")?(r[a].push({type:"mix",name:e.replace("[]",""),level:a}),!0):e.startsWith(">")?(r[a].push({type:"data",name:e.replace(">",""),level:a}),!0):(""===e||r[a].push({type:"render",name:e,level:a}),!0))),r}(f,o),o);for(let t of h){let{type:n,name:a,level:o}=t;p[o].forEach((t=>{let s=i(t);switch(n){case"route":switch(s){case"array":t.forEach(((e,n)=>{if(null==e)return;const o=i(e),s=d[a](e);null!=s&&("object"===o?t[n].text=l(e,s,d,{...c,...r}):t[n]=l(e,s,d,{...c,...r}))}));break;case"object":t.text=l(t,a,d,{...c,...r});break;case"primitive":p[o]=l(t,a,d,{...c,...r})}break;case"data":switch(s){case"array":t.forEach(((e,r)=>t[r]=e instanceof Function?d[a](e()):d[a](e)));break;case"object":p[o]=[d[a](t)];break;case"function":p[o]=[d[a](t())];break;case"primitive":p[o]=d[a](t)}break;case"render":const u="function"==typeof d[a];switch(s){case"array":u?t.forEach(((e,n)=>{if(null==e)return;const o=i(e),l=d[a](e,{...c,...r});null==l&&(t[n]=null),"object"===o?e.text=l:t[n]=l})):t.forEach(((e,n)=>{if(null==e)return;const o=i(e),s=l(e,a,d,{...c,...r});null==s?t[n]=null:"object"===o?e.text=s:t[n]=s}));break;case"function":p[o]=d[a](t(),{...c,...r});break;case"primitive":p[o]=l(t,a,d,{...c,...r});break;case"object":if(u)p[o][0].text=d[a](t,{...c,...r});else{Object.keys(t).find((e=>e.includes("/")))?Object.entries(t).forEach((([e,t])=>t.text=l(t,a,d,{...c,...r}))):t.text=l(t,a,d,{...c,...r})}}break;case"extendedRender":"function"==typeof d[a]&&(p[o]=d[a](p[0][0]));break;case"mix":if(""===a)switch(s){case"object":Object.keys(t).find((e=>e.includes("/")))?Object.entries(t).forEach((([e,t])=>p[o][e]=t.text)):p[o]=t.text;for(let h=o-1;h>=0;h--)p[h]=e({data:p[h],objectCallback:f});function f({value:e,breadcrumbs:t}){return p[o][t]?p[o][t]:e}break;case"array":t.forEach(((e,r)=>{if(r>0){let n=i(e);if(null==e)return;t[0]+="object"===n?`${e.text}`:`${e}`,t.toSpliced(r,1)}else{let r=i(e);if(t[0]="",null===r)return;t[0]="object"===r?`${e.text}`:`${e}`}})),t.length=1}else{let y=d[a](t),g=i(y);switch(t.forEach(((e,r)=>t.splice(r,1))),t.length=0,g){case"primitive":t[0]=y;break;case"array":t.push(...y)}}}}))}if(p instanceof Array&&1===p.length&&p[0]instanceof Array&&(p=p[0]),null==p[0])return;let y=i(p[0]),m=p[0];switch(y){case"primitive":if(null==m)return;g[s]=m;break;case"object":if(null==m.text)return;g[s]=m.text;break;case"array":const e=i(m[0]);g[s]="object"===e?m.map((e=>e.text)).join(""):m.join("")}}})),s.push(g.join(""))})),"array"===u?s:o?o.reduce(((e,t)=>"function"!=typeof t?e:t(e,{...c,...r})),s.join("")):s.join("")}return s?[!0,m]:m}}const c={default:{}};return{build:s,get:function(e){if(!(e instanceof Array))return function(){return'Error: Argument "location" is a string. Should be an array. E.g. ["templateName", "storageName"].'};const[t,r="default"]=e;return c[r]?c[r][t]?c[r][t]:function(){return`Error: Template "${t}" does not exist in storage "${r}".`}:function(){return`Error: Storage "${r}" does not exist.`}},add:function(e,t,...r){const[n,a="default"]=e;if(null==t)return void console.warn(`Warning: Template ${a}/${n} is not added to storage. The template is null.`);let o=t,i=!0;if(c[a]||(c[a]={}),"function"!=typeof t){let e=s(t,!0,...r);i=e[0],o=e[1]}i?c[a][n]=o:console.error(`Error: Template "${n}" looks broken and is not added to storage.`)},list:function(e=["default"]){return e.map((e=>c[e]?Object.keys(c[e]):[])).flat()},clear:function(){Object.keys(c).forEach((e=>{"default"!=e?delete c[e]:c.default={}}))},remove:function(e){const[t,r="default"]=e;return c[r]?c[r][t]?void delete c[r][t]:`Error: Template "${t}" does not exist in storage "${r}".`:`Error: Storage "${r}" does not exist.`}}}));
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@peter.naydenov/morph",
3
3
  "description": "Template engine",
4
- "version": "1.1.3",
4
+ "version": "1.2.1",
5
5
  "license": "MIT",
6
6
  "author": "Peter Naydenov",
7
- "main": ".src/main.js",
7
+ "main": "./src/main.js",
8
8
  "type": "module",
9
+ "types": "./types/index.d.ts",
9
10
  "exports": {
10
11
  ".": {
11
12
  "import": "./src/main.js",
@@ -26,13 +27,13 @@
26
27
  "@peter.naydenov/walk": "^5.0.1"
27
28
  },
28
29
  "devDependencies": {
29
- "@rollup/plugin-commonjs": "^28.0.2",
30
- "@rollup/plugin-node-resolve": "^16.0.0",
30
+ "@rollup/plugin-commonjs": "^28.0.3",
31
+ "@rollup/plugin-node-resolve": "^16.0.1",
31
32
  "@rollup/plugin-terser": "^0.4.4",
32
33
  "c8": "^10.1.3",
33
- "chai": "5.1.2",
34
- "mocha": "11.0.1",
35
- "rollup": "^4.31.0"
34
+ "chai": "5.2.0",
35
+ "mocha": "11.1.0",
36
+ "rollup": "^4.35.0"
36
37
  },
37
38
  "repository": {
38
39
  "type": "git",
@@ -3,27 +3,25 @@ import walk from '@peter.naydenov/walk'
3
3
 
4
4
 
5
5
  function _defineData ( d, action ) {
6
- const nestedData = {};
6
+ const nestedData = [];
7
7
  let dataDeepLevel = 0;
8
8
 
9
- if ( d instanceof Function ) return { dataDeepLevel:0, nestedData:[d()] }
9
+ if ( d instanceof Function ) return { dataDeepLevel:0, nestedData:[[d()]] }
10
10
  if ( d == null ) return { dataDeepLevel:0, nestedData:[ null ] }
11
- if ( typeof d === 'string' ) return { dataDeepLevel:0, nestedData:[d] }
12
-
13
- // Note: Nest data only if action includes '#'
11
+ if ( typeof d === 'string' ) return { dataDeepLevel:0, nestedData:[[d]] }
12
+
13
+ // Note: Nest data only if action has '#'
14
14
  if ( !action.includes('#') ) {
15
- return { dataDeepLevel:0, nestedData:[d] }
15
+ nestedData.push ( [d] )
16
+ return { dataDeepLevel:0, nestedData }
16
17
  }
17
18
 
18
19
  function findObjects ({key, value, breadcrumbs}) {
19
- let isArray = false;
20
-
21
20
  dataDeepLevel = breadcrumbs.split('/').length -1;
22
- if ( !isNaN(key) ) isArray = true
23
- if ( !nestedData[dataDeepLevel] ) nestedData[dataDeepLevel] = isArray? [] : {}
24
- if ( key === 'root' ) nestedData[dataDeepLevel] = value
25
- else if ( isArray ) nestedData[dataDeepLevel].push ( value )
26
- else nestedData[dataDeepLevel][breadcrumbs] = value
21
+
22
+ if ( !nestedData[dataDeepLevel] ) nestedData[dataDeepLevel] = [];
23
+ if ( value instanceof Array ) nestedData[dataDeepLevel].push(value)
24
+ else nestedData[dataDeepLevel].push([ value ])
27
25
  return value
28
26
  } // step func.
29
27
 
@@ -5,7 +5,8 @@ import settings from './settings.js'
5
5
 
6
6
  function _renderHolder ( template, data ) {
7
7
  // Data should be an object. No array, no string.
8
- if ( data == null ) return null
8
+ if ( data == null ) return null
9
+
9
10
  const
10
11
  chop = _chopTemplate (settings)( template )
11
12
  , set = settings
@@ -1,16 +1,22 @@
1
1
  function _setupActions ( actions, dataDeepLevel=10 ) {
2
2
  let
3
3
  actSetup = {}
4
- , actLevel = 0
5
4
  , actionList = [...actions]
5
+ , actLevel = 0
6
6
  , i = 0
7
+ , countHashes = 0
7
8
  ;
8
-
9
+
10
+ actionList.forEach ( action => { if ( action === '#' ) countHashes++ })
11
+ if ( countHashes < dataDeepLevel ) console.error ( `Error: Not enough level markers (#) for data with depth level ${dataDeepLevel}. Found ${countHashes} level markers in actions: ${actions.join(', ')}` )
12
+
9
13
  do {
10
14
  actSetup[i] = []
11
15
  i++
12
16
  } while ( i <= dataDeepLevel )
13
17
 
18
+
19
+
14
20
  actionList.every ( act => {
15
21
  if ( act === '#' ) { // it's a change level action
16
22
  actLevel++
@@ -52,6 +58,7 @@ function _setupActions ( actions, dataDeepLevel=10 ) {
52
58
  if ( act === '' ) {
53
59
  return true
54
60
  }
61
+
55
62
  actSetup[actLevel].push ({
56
63
  type: 'render'
57
64
  , name: act
@@ -59,6 +66,7 @@ function _setupActions ( actions, dataDeepLevel=10 ) {
59
66
  })
60
67
  return true
61
68
  }) // actionList every
69
+
62
70
  return actSetup
63
71
  } // _setupActions func.
64
72
 
@@ -59,10 +59,8 @@ function build ( tpl, extra=false, buildDependencies={} ) {
59
59
  * If 'args' are provided, they are applied to the result in order.
60
60
  */
61
61
  function success ( d={}, dependencies={}, ...args ) {
62
- const
63
- topLevelType = _defineDataType ( d )
64
- , endData = []
65
- ;
62
+ const endData = [];
63
+ let topLevelType = _defineDataType ( d );
66
64
  d = walk ({data:d})
67
65
 
68
66
  if ( topLevelType === 'null' ) return cuts.join ( '' )
@@ -70,10 +68,11 @@ function build ( tpl, extra=false, buildDependencies={} ) {
70
68
  if ( typeof d === 'string' ) { // 'd' is a string when we want to debug the template
71
69
  switch ( d ) {
72
70
  case 'raw':
73
- return cuts.join('') // Original template with placeholders
71
+ return cuts.join ( '' ) // Original template with placeholders
74
72
  case 'demo':
75
73
  if ( !handshake ) return `Error: No handshake data.`
76
74
  d = handshake // Render with handshake object
75
+ topLevelType = _defineDataType ( d )
77
76
  break
78
77
  case 'handshake':
79
78
  if ( !handshake ) return `Error: No handshake data.`
@@ -87,19 +86,21 @@ function build ( tpl, extra=false, buildDependencies={} ) {
87
86
 
88
87
  if ( topLevelType !== 'array' ) d = [ d ]
89
88
 
90
- // TODO: If 'd' is null -> then no data for all the placeholders
89
+ // Handle null data case - just return the template without placeholders
90
+ if ( topLevelType === 'null' ) return cuts.join ( '' ).replace(/{{.*?}}/g, '')
91
+
91
92
  d.forEach ( dElement => {
92
93
  placeholders.forEach ( holder => { // Placeholders
93
94
  const
94
95
  { index, data, action } = holder // index - placeholder index, data - key of data, action - list of operations
95
96
  , dataOnly = !action && data
96
- ;
97
+ ;
97
98
 
98
99
  if ( dataOnly ) {
99
100
  const
100
101
  info = dElement[data]
101
102
  , type = _defineDataType ( info )
102
- ;
103
+ ;
103
104
  switch ( type ) {
104
105
  case 'function' :
105
106
  cuts[index] = info ()
@@ -116,17 +117,20 @@ function build ( tpl, extra=false, buildDependencies={} ) {
116
117
  } // switch
117
118
  } // dataOnly
118
119
  else { // Data and Actions or only Actions
119
- const
120
+ let
120
121
  { dataDeepLevel, nestedData } = (data==='@all' || data===null || data==='@root' ) ? _defineData ( dElement, action ) : _defineData ( dElement[data], action )
121
122
  , actSetup = _actionSupply ( _setupActions ( action, dataDeepLevel ), dataDeepLevel )
122
123
  ;
123
124
 
124
125
  for ( let step of actSetup ) {
125
- let { type, name, level } = step;
126
126
  let
127
- theData = nestedData[level]
128
- , dataType = _defineDataType ( theData )
127
+ { type, name, level } = step
128
+ , levelData = nestedData[level]
129
129
  ;
130
+
131
+ levelData.forEach ( theData => {
132
+
133
+ let dataType = _defineDataType ( theData )
130
134
  switch ( type ) { // Action type 'route','data', 'render', or mix -> different operations
131
135
  case 'route':
132
136
  switch ( dataType ) {
@@ -148,16 +152,16 @@ function build ( tpl, extra=false, buildDependencies={} ) {
148
152
  break
149
153
  }
150
154
  break
151
- case 'data':
155
+ case 'data':
152
156
  switch ( dataType ) {
153
157
  case 'array':
154
158
  theData.forEach ( (d,i) => theData[i] = ( d instanceof Function ) ? helpers[name]( d() ) : helpers[name]( d ) )
155
159
  break
156
160
  case 'object':
157
- nestedData[level] = helpers[name]( theData )
161
+ nestedData[level] = [helpers[name]( theData )]
158
162
  break
159
163
  case 'function':
160
- nestedData[level] = helpers[name]( theData() )
164
+ nestedData[level] = [helpers[name]( theData() )]
161
165
  break
162
166
  case 'primitive':
163
167
  nestedData[level] = helpers[name]( theData )
@@ -176,18 +180,18 @@ function build ( tpl, extra=false, buildDependencies={} ) {
176
180
 
177
181
  if ( text == null ) theData[i] = null
178
182
  if ( dType === 'object' ) d['text'] = text
179
- else theData[i] = text
183
+ else theData[i] = text
180
184
  })
181
185
  else theData.forEach ( (d,i) => {
182
186
  if ( d == null ) return
183
187
  const
184
- dType = _defineDataType ( d )
185
- , text = render ( d, name, helpers, {...buildDependencies, ...dependencies} )
186
- ;
187
- if ( text == null ) theData[i] = null
188
- if ( dType === 'object' ) d['text'] = text
189
- else theData[i] = text
190
- })
188
+ dType = _defineDataType ( d )
189
+ , text = render ( d, name, helpers, {...buildDependencies, ...dependencies} )
190
+ ;
191
+ if ( text == null ) theData[i] = null
192
+ else if ( dType === 'object' ) d['text'] = text
193
+ else theData[i] = text
194
+ })
191
195
  break
192
196
  case 'function':
193
197
  nestedData[level] = helpers[name]( theData(), {...buildDependencies, ...dependencies} )
@@ -196,7 +200,7 @@ function build ( tpl, extra=false, buildDependencies={} ) {
196
200
  nestedData[level] = render ( theData, name, helpers, {...buildDependencies, ...dependencies} )
197
201
  break
198
202
  case 'object':
199
- if ( isRenderFunction ) nestedData[level]['text'] = helpers[name]( theData, {...buildDependencies, ...dependencies} )
203
+ if ( isRenderFunction ) nestedData[level][0]['text'] = helpers[name]( theData, {...buildDependencies, ...dependencies} )
200
204
  else {
201
205
  let kTest = Object.keys ( theData ).find ( k => k.includes ( '/' ) ); // Check if keys are breadcrumbs
202
206
  if ( kTest ) Object.entries( theData ).forEach( ([k,v]) => v['text'] = render ( v, name, helpers, {...buildDependencies, ...dependencies} ) )
@@ -209,13 +213,13 @@ function build ( tpl, extra=false, buildDependencies={} ) {
209
213
  // TODO: Test extendedRender
210
214
  const isValid = typeof helpers[name] === 'function'; // Render could be a function and template.
211
215
  if ( isValid ) {
212
- nestedData[level] = helpers[name]( nestedData[0] )
216
+ nestedData[level] = helpers[name]( nestedData[0][0] )
213
217
  }
214
218
  else {
215
219
  // TODO: Error...
216
220
  }
217
221
  break
218
- case 'mix':
222
+ case 'mix':
219
223
  if ( name === '' ) { // when is anonymous mixing helper
220
224
  switch ( dataType ) {
221
225
  case 'object':
@@ -231,26 +235,61 @@ function build ( tpl, extra=false, buildDependencies={} ) {
231
235
  } // check
232
236
  break
233
237
  case 'array':
234
- nestedData[level] = theData.map ( x => {
238
+ theData.forEach ( (x,i) => {
239
+ if ( i > 0 ) {
235
240
  let xType = _defineDataType ( x );
236
- if ( xType === 'object' ) return x.text
237
- return x
238
- })
239
- .filter ( x => x != null )
240
- .join ( '' )
241
+ if ( x == null ) return
242
+ if ( xType === 'object' ) theData[0] += `${x.text}`
243
+ else theData[0] += `${x}`
244
+ theData.toSpliced(i,1)
245
+ }
246
+ else {
247
+ let xxType = _defineDataType ( x );
248
+ theData[0] = ''
249
+ if ( xxType === null ) return
250
+ else if ( xxType === 'object' ) theData[0] = `${x.text}`
251
+ else theData[0] = `${x}`
252
+ }
253
+ })
254
+ theData.length = 1
241
255
  break
242
256
  } // switch dataType
243
257
  } // if name === ''
244
- else nestedData[level] = helpers[name]( theData )
258
+ else {
259
+ let
260
+ val = helpers[name]( theData )
261
+ , valType = _defineDataType ( val )
262
+ ;
263
+
264
+ theData.forEach ( ( x, i ) => theData.splice ( i, 1) )
265
+ theData.length = 0
266
+ switch ( valType ) {
267
+ case 'primitive':
268
+ theData[0] = val
269
+ break
270
+ case 'array':
271
+ theData.push ( ...val )
272
+ break
273
+ } // switch valType
274
+ }
245
275
  break
246
276
  default:
247
277
  break
248
278
  }
279
+ }) // levelData
249
280
  } // for step of actSetup
250
-
251
- let accType = _defineDataType ( nestedData[0] )
252
- let fineData = nestedData[0]
253
-
281
+
282
+ if ( nestedData instanceof Array &&
283
+ nestedData.length === 1 &&
284
+ nestedData[0] instanceof Array
285
+ ) nestedData = nestedData[0]
286
+ if ( nestedData[0] == null ) return
287
+
288
+ let
289
+ accType = _defineDataType ( nestedData[0] )
290
+ , fineData = nestedData[0]
291
+ ;
292
+
254
293
  switch ( accType ) {
255
294
  case 'primitive':
256
295
  if ( fineData == null ) return
@@ -282,7 +321,6 @@ function build ( tpl, extra=false, buildDependencies={} ) {
282
321
  } // success func.
283
322
  return extra ? [ true, success ] : success
284
323
  }
285
-
286
324
  } // build func.
287
325
 
288
326
 
@@ -15,9 +15,11 @@ import _renderHolder from "./_renderHolder.js"
15
15
  */
16
16
  function render ( theData, name, helpers, ...args ) {
17
17
  // *** Executes rendering and return the results
18
+
18
19
  if ( theData instanceof Object ) { // Make sure all properties are not objects
19
20
  Object.entries ( theData ).forEach ( ([key, value]) => {
20
21
  if ( value instanceof Object ) theData[key] = value['text']
22
+ if ( value instanceof Array ) theData[key] = value[0]
21
23
  })
22
24
  }
23
25
  function setRenderData ( d={} ) {
@@ -0,0 +1,60 @@
1
+ declare module '@peter.naydenov/morph' {
2
+ /**
3
+ * Template description object
4
+ */
5
+ interface TemplateDescription {
6
+ /**
7
+ * Template string with placeholders
8
+ */
9
+ template: string;
10
+ /**
11
+ * Optional helper functions or templates
12
+ */
13
+ helpers?: Record<string, any>;
14
+ /**
15
+ * Optional example data for rendering
16
+ */
17
+ handshake?: Record<string, any>;
18
+ }
19
+
20
+ /**
21
+ * Build a component from template description
22
+ */
23
+ function build(tpl: TemplateDescription, extra?: boolean, buildDependencies?: Record<string, any>): Function;
24
+
25
+ /**
26
+ * Get a component from component storage
27
+ */
28
+ function get(location: [string, string?]): Function;
29
+
30
+ /**
31
+ * Add a component to component storage
32
+ */
33
+ function add(location: [string, string?], tplfn: Function | TemplateDescription, ...args: any[]): void;
34
+
35
+ /**
36
+ * List the names of all components in the component storage
37
+ */
38
+ function list(storageNames?: string[]): string[];
39
+
40
+ /**
41
+ * Clear up all the components in the storage
42
+ */
43
+ function clear(): void;
44
+
45
+ /**
46
+ * Remove a template from component storage
47
+ */
48
+ function remove(location: [string, string?]): void | string;
49
+
50
+ const morphAPI: {
51
+ build: typeof build;
52
+ get: typeof get;
53
+ add: typeof add;
54
+ list: typeof list;
55
+ clear: typeof clear;
56
+ remove: typeof remove;
57
+ };
58
+
59
+ export default morphAPI;
60
+ }