@peter.naydenov/morph 1.1.2 → 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,7 +2,18 @@
2
2
 
3
3
 
4
4
 
5
- ### 1.1.1 ( 2025-01-20 )
5
+ ### 1.2.0 (2025-03-14)
6
+ - [x] Bug fix: Deeply nested data;
7
+ - [x] Improve: Error message if actions do not have deepness of the data (very difficult to debug);
8
+
9
+
10
+
11
+ ### 1.1.3 (2025-01-23)
12
+ - [x] Improve: Error messages when using method "add" with template -> null;
13
+
14
+
15
+
16
+ ### 1.1.2 ( 2025-01-20 )
6
17
  - [x] Improve: Error messages when using method "set" with string;
7
18
 
8
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: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{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 c(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 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,TG_SIZE_P:i,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*)?"+c,"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 i?[!1,b]:b}{let m=structuredClone(d);function y(r={},n={},...o){const i=s(r),u=[];if(r=e({data:r}),"null"===i)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"!==i&&(r=[r]),r.forEach((r=>{f.forEach((o=>{const{index:i,data:u,action:f}=o;if(!f&&u){const d=r[u];switch(s(d)){case"function":return void(m[i]=d());case"primitive":return void(m[i]=d);case"array":return void("primitive"===s(d[0])&&(m[i]=d[0]));case"object":return void(d.text&&(m[i]=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,_=b[x],w=s(_);switch(j){case"route":switch(w){case"array":_.forEach(((e,t)=>{if(null==e)return;const r=s(e),a=p[k](e);null!=a&&("object"===r?_[t].text=c(e,a,p,{...l,...n}):_[t]=c(e,a,p,{...l,...n}))}));break;case"object":_.text=c(_,k,p,{...l,...n});break;case"primitive":b[x]=c(_,k,p,{...l,...n})}break;case"data":switch(w){case"array":_.forEach(((e,t)=>_[t]=e instanceof Function?p[k](e()):p[k](e)));break;case"object":case"primitive":b[x]=p[k](_);break;case"function":b[x]=p[k](_())}break;case"render":const S="function"==typeof p[k];switch(w){case"array":S?_.forEach(((e,t)=>{if(null==e)return;const r=s(e),a=p[k](e,{...l,...n});null==a&&(_[t]=null),"object"===r?e.text=a:_[t]=a})):_.forEach(((e,t)=>{if(null==e)return;const r=s(e),a=c(e,k,p,{...l,...n});null==a&&(_[t]=null),"object"===r?e.text=a:_[t]=a}));break;case"function":b[x]=p[k](_(),{...l,...n});break;case"primitive":b[x]=c(_,k,p,{...l,...n});break;case"object":if(S)b[x].text=p[k](_,{...l,...n});else{Object.keys(_).find((e=>e.includes("/")))?Object.entries(_).forEach((([e,t])=>t.text=c(t,k,p,{...l,...n}))):_.text=c(_,k,p,{...l,...n})}}break;case"extendedRender":"function"==typeof p[k]&&(b[x]=p[k](b[0]));break;case"mix":if(""===k)switch(w){case"object":Object.keys(_).find((e=>e.includes("/")))?Object.entries(_).forEach((([e,t])=>b[x][e]=t.text)):b[x]=_.text;for(let O=x-1;O>=0;O--)b[O]=e({data:b[O],objectCallback:T});function T({value:e,breadcrumbs:t}){return b[x][t]?b[x][t]:e}break;case"array":b[x]=_.map((e=>"object"===s(e)?e.text:e)).filter((e=>null!=e)).join("")}else b[x]=p[k](_)}}let E=s(b[0]),g=b[0];switch(E){case"primitive":if(null==g)return;m[i]=g;break;case"object":if(null==g.text)return;m[i]=g.text;break;case"array":const G=s(g[0]);m[i]="object"===G?g.map((e=>e.text)).join(""):g.join("")}}})),u.push(m.join(""))})),"array"===i?u:o?o.reduce(((e,t)=>"function"!=typeof t?e:t(e,{...l,...n})),u.join("")):u.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;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
+ "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: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{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 c(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 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,TG_SIZE_P:i,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*)?"+c,"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 i?[!1,b]:b}{let m=structuredClone(d);function y(r={},n={},...o){const i=s(r),u=[];if(r=e({data:r}),"null"===i)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"!==i&&(r=[r]),r.forEach((r=>{f.forEach((o=>{const{index:i,data:u,action:f}=o;if(!f&&u){const d=r[u];switch(s(d)){case"function":return void(m[i]=d());case"primitive":return void(m[i]=d);case"array":return void("primitive"===s(d[0])&&(m[i]=d[0]));case"object":return void(d.text&&(m[i]=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,_=b[x],w=s(_);switch(j){case"route":switch(w){case"array":_.forEach(((e,t)=>{if(null==e)return;const r=s(e),a=p[k](e);null!=a&&("object"===r?_[t].text=c(e,a,p,{...l,...n}):_[t]=c(e,a,p,{...l,...n}))}));break;case"object":_.text=c(_,k,p,{...l,...n});break;case"primitive":b[x]=c(_,k,p,{...l,...n})}break;case"data":switch(w){case"array":_.forEach(((e,t)=>_[t]=e instanceof Function?p[k](e()):p[k](e)));break;case"object":case"primitive":b[x]=p[k](_);break;case"function":b[x]=p[k](_())}break;case"render":const S="function"==typeof p[k];switch(w){case"array":S?_.forEach(((e,t)=>{if(null==e)return;const r=s(e),a=p[k](e,{...l,...n});null==a&&(_[t]=null),"object"===r?e.text=a:_[t]=a})):_.forEach(((e,t)=>{if(null==e)return;const r=s(e),a=c(e,k,p,{...l,...n});null==a&&(_[t]=null),"object"===r?e.text=a:_[t]=a}));break;case"function":b[x]=p[k](_(),{...l,...n});break;case"primitive":b[x]=c(_,k,p,{...l,...n});break;case"object":if(S)b[x].text=p[k](_,{...l,...n});else{Object.keys(_).find((e=>e.includes("/")))?Object.entries(_).forEach((([e,t])=>t.text=c(t,k,p,{...l,...n}))):_.text=c(_,k,p,{...l,...n})}}break;case"extendedRender":"function"==typeof p[k]&&(b[x]=p[k](b[0]));break;case"mix":if(""===k)switch(w){case"object":Object.keys(_).find((e=>e.includes("/")))?Object.entries(_).forEach((([e,t])=>b[x][e]=t.text)):b[x]=_.text;for(let O=x-1;O>=0;O--)b[O]=e({data:b[O],objectCallback:T});function T({value:e,breadcrumbs:t}){return b[x][t]?b[x][t]:e}break;case"array":b[x]=_.map((e=>"object"===s(e)?e.text:e)).filter((e=>null!=e)).join("")}else b[x]=p[k](_)}}let E=s(b[0]),g=b[0];switch(E){case"primitive":if(null==g)return;m[i]=g;break;case"object":if(null==g.text)return;m[i]=g.text;break;case"array":const G=s(g[0]);m[i]="object"===G?g.map((e=>e.text)).join(""):g.join("")}}})),u.push(m.join(""))})),"array"===i?u:o?o.reduce(((e,t)=>"function"!=typeof t?e:t(e,{...l,...n})),u.join("")):u.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;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};
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 c,l,u,f=[];if("string"!=typeof r)return n("notAString");if(0==r.length)return[];if(c=r.indexOf(o),0<c&&f.push(r.slice(0,c)),-1==c)return f.push(r),f;{if(u=r.indexOf(o,c+i),l=r.indexOf(a),-1==l)return n("missingClosing");if(l<c)return n("closedBeforeOpened");if(l+=s,-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 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 c(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 l(){}return l.prototype={pull:s,pullReverse:function(e=1,t=0){let n=s(e,t);return n instanceof Array?n.reverse():n},peek:c,peekReverse:function(e=1,t=0){const n=c(e,t);return n instanceof Array?n.reverse():n},getSize:()=>t.length,isEmpty:()=>0==t.length,reset:()=>(t=[],!0),debug:()=>[...t]},l.prototype.push=a?function(e){const n=e instanceof Array,a=n?e.length:1;let c=!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&&(c=s(a-r))}return t=e instanceof Array?t.concat(e):t.concat([e]),i=!!r&&t.length===r,c||void 0}}:function(e){const n=e instanceof Array,a=n?e.length:1;let c=!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&&(c=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,c||void 0}},new l}({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 c(n,c=!1,l={}){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:c,TG_SIZE_S:l}=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 y(){return u}return c?[!1,y]:y}{let m=structuredClone(p);function g(t={},n={},...a){const c=i(t),u=[];if(t=e({data:t}),"null"===c)return m.join("");if("string"==typeof t)switch(t){case"raw":return m.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=>m[e.index])).join(", ");default:return`Error: Wrong command "${t}". Available commands: raw, demo, handshake, placeholders.`}return"array"!==c&&(t=[t]),t.forEach((t=>{f.forEach((a=>{const{index:c,data:u,action:f}=a;if(!f&&u){const p=t[u];switch(i(p)){case"function":return void(m[c]=p());case"primitive":return void(m[c]=p);case"array":return void("primitive"===i(p[0])&&(m[c]=p[0]));case"object":return void(p.text&&(m[c]=p.text))}}else{const{dataDeepLevel:h,nestedData:y}=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=y[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,{...l,...n}):w[t]=s(e,o,d,{...l,...n}))}));break;case"object":w.text=s(w,j,d,{...l,...n});break;case"primitive":y[x]=s(w,j,d,{...l,...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":y[x]=d[j](w);break;case"function":y[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,{...l,...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,{...l,...n});null==o&&(w[t]=null),"object"===r?e.text=o:w[t]=o}));break;case"function":y[x]=d[j](w(),{...l,...n});break;case"primitive":y[x]=s(w,j,d,{...l,...n});break;case"object":if(_)y[x].text=d[j](w,{...l,...n});else{Object.keys(w).find((e=>e.includes("/")))?Object.entries(w).forEach((([e,t])=>t.text=s(t,j,d,{...l,...n}))):w.text=s(w,j,d,{...l,...n})}}break;case"extendedRender":"function"==typeof d[j]&&(y[x]=d[j](y[0]));break;case"mix":if(""===j)switch(T){case"object":Object.keys(w).find((e=>e.includes("/")))?Object.entries(w).forEach((([e,t])=>y[x][e]=t.text)):y[x]=w.text;for(let O=x-1;O>=0;O--)y[O]=e({data:y[O],objectCallback:S});function S({value:e,breadcrumbs:t}){return y[x][t]?y[x][t]:e}break;case"array":y[x]=w.map((e=>"object"===i(e)?e.text:e)).filter((e=>null!=e)).join("")}else y[x]=d[j](w)}}let b=i(y[0]),v=y[0];switch(b){case"primitive":if(null==v)return;m[c]=v;break;case"object":if(null==v.text)return;m[c]=v.text;break;case"array":const G=i(v[0]);m[c]="object"===G?v.map((e=>e.text)).join(""):v.join("")}}})),u.push(m.join(""))})),"array"===c?u:a?a.reduce(((e,t)=>"function"!=typeof t?e:t(e,{...l,...n})),u.join("")):u.join("")}return c?[!0,g]:g}}const l={default:{}};return{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,n="default"]=e;return l[n]?l[n][t]?l[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;let a=t,i=!0;if(l[o]||(l[o]={}),"function"!=typeof t){let e=c(t,!0,...n);i=e[0],a=e[1]}i?l[o][r]=a:console.error(`Error: Template "${r}" 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,n="default"]=e;return l[n]?l[n][t]?void delete l[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,7 +1,7 @@
1
1
  {
2
2
  "name": "@peter.naydenov/morph",
3
3
  "description": "Template engine",
4
- "version": "1.1.2",
4
+ "version": "1.2.0",
5
5
  "license": "MIT",
6
6
  "author": "Peter Naydenov",
7
7
  "main": ".src/main.js",
@@ -26,13 +26,13 @@
26
26
  "@peter.naydenov/walk": "^5.0.1"
27
27
  },
28
28
  "devDependencies": {
29
- "@rollup/plugin-commonjs": "^28.0.2",
30
- "@rollup/plugin-node-resolve": "^16.0.0",
29
+ "@rollup/plugin-commonjs": "^28.0.3",
30
+ "@rollup/plugin-node-resolve": "^16.0.1",
31
31
  "@rollup/plugin-terser": "^0.4.4",
32
32
  "c8": "^10.1.3",
33
- "chai": "5.1.2",
34
- "mocha": "11.0.1",
35
- "rollup": "^4.31.0"
33
+ "chai": "5.2.0",
34
+ "mocha": "11.1.0",
35
+ "rollup": "^4.35.0"
36
36
  },
37
37
  "repository": {
38
38
  "type": "git",
package/src/main.js CHANGED
@@ -72,15 +72,20 @@ function get ( location ) {
72
72
  * @param {string[]} location - The location to add the template to. Array of two elements.
73
73
  * The first element is the name of the template. The second element
74
74
  * is optional and is the name of the storage. Defaults to 'default'.
75
- * @param {object|function} tplfn - The template description or the already built template function.
75
+ * @param {object|function|null} tplfn - The template description or the already built template function.
76
76
  * @param {...any} args - Additional arguments to be passed to the build function.
77
77
  * Only used if the first argument is a template description.
78
78
  */
79
79
  function add ( location, tplfn, ...args ) {
80
80
  const [ name, strName='default'] = location
81
+ if ( tplfn == null ) {
82
+ console.warn ( `Warning: Template ${strName}/${name} is not added to storage. The template is null.` )
83
+ return
84
+ }
81
85
  let fn = tplfn;
82
86
  let successBuild = true;
83
87
  if( !storage[strName] ) storage[strName] = {}
88
+
84
89
  if ( typeof tplfn !== 'function' ) {
85
90
  let r = build ( tplfn, true, ...args )
86
91
  successBuild = r[0]
@@ -1,29 +1,28 @@
1
1
  import walk from '@peter.naydenov/walk'
2
+ // import _defineDataType from './_defineType';'../methods/_defineType.js'
2
3
 
3
4
 
4
5
 
5
6
  function _defineData ( d, action ) {
6
- const nestedData = {};
7
+ const nestedData = [];
7
8
  let dataDeepLevel = 0;
8
9
 
9
- if ( d instanceof Function ) return { dataDeepLevel:0, nestedData:[d()] }
10
+ if ( d instanceof Function ) return { dataDeepLevel:0, nestedData:[[d()]] }
10
11
  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 '#'
12
+ if ( typeof d === 'string' ) return { dataDeepLevel:0, nestedData:[[d]] }
13
+
14
+ // Note: Nest data only if action has '#'
14
15
  if ( !action.includes('#') ) {
15
- return { dataDeepLevel:0, nestedData:[d] }
16
+ nestedData.push ( [d] )
17
+ return { dataDeepLevel:0, nestedData }
16
18
  }
17
19
 
18
20
  function findObjects ({key, value, breadcrumbs}) {
19
- let isArray = false;
20
-
21
21
  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
22
+
23
+ if ( !nestedData[dataDeepLevel] ) nestedData[dataDeepLevel] = [];
24
+ if ( value instanceof Array ) nestedData[dataDeepLevel].push(value)
25
+ else nestedData[dataDeepLevel].push([ value ])
27
26
  return value
28
27
  } // step func.
29
28
 
@@ -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: Actions doesn't describe all levels of data. Actions: ${actions}` )
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,20 @@ 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
+ // TODO: If 'd' is null -> then no data for all the placeholders
90
+
91
91
  d.forEach ( dElement => {
92
92
  placeholders.forEach ( holder => { // Placeholders
93
93
  const
94
94
  { index, data, action } = holder // index - placeholder index, data - key of data, action - list of operations
95
95
  , dataOnly = !action && data
96
- ;
96
+ ;
97
97
 
98
98
  if ( dataOnly ) {
99
99
  const
100
100
  info = dElement[data]
101
101
  , type = _defineDataType ( info )
102
- ;
102
+ ;
103
103
  switch ( type ) {
104
104
  case 'function' :
105
105
  cuts[index] = info ()
@@ -116,17 +116,20 @@ function build ( tpl, extra=false, buildDependencies={} ) {
116
116
  } // switch
117
117
  } // dataOnly
118
118
  else { // Data and Actions or only Actions
119
- const
119
+ let
120
120
  { dataDeepLevel, nestedData } = (data==='@all' || data===null || data==='@root' ) ? _defineData ( dElement, action ) : _defineData ( dElement[data], action )
121
121
  , actSetup = _actionSupply ( _setupActions ( action, dataDeepLevel ), dataDeepLevel )
122
122
  ;
123
123
 
124
124
  for ( let step of actSetup ) {
125
- let { type, name, level } = step;
126
125
  let
127
- theData = nestedData[level]
128
- , dataType = _defineDataType ( theData )
126
+ { type, name, level } = step
127
+ , levelData = nestedData[level]
129
128
  ;
129
+
130
+ levelData.forEach ( theData => {
131
+
132
+ let dataType = _defineDataType ( theData )
130
133
  switch ( type ) { // Action type 'route','data', 'render', or mix -> different operations
131
134
  case 'route':
132
135
  switch ( dataType ) {
@@ -148,16 +151,16 @@ function build ( tpl, extra=false, buildDependencies={} ) {
148
151
  break
149
152
  }
150
153
  break
151
- case 'data':
154
+ case 'data':
152
155
  switch ( dataType ) {
153
156
  case 'array':
154
157
  theData.forEach ( (d,i) => theData[i] = ( d instanceof Function ) ? helpers[name]( d() ) : helpers[name]( d ) )
155
158
  break
156
159
  case 'object':
157
- nestedData[level] = helpers[name]( theData )
160
+ nestedData[level] = [helpers[name]( theData )]
158
161
  break
159
162
  case 'function':
160
- nestedData[level] = helpers[name]( theData() )
163
+ nestedData[level] = [helpers[name]( theData() )]
161
164
  break
162
165
  case 'primitive':
163
166
  nestedData[level] = helpers[name]( theData )
@@ -176,18 +179,18 @@ function build ( tpl, extra=false, buildDependencies={} ) {
176
179
 
177
180
  if ( text == null ) theData[i] = null
178
181
  if ( dType === 'object' ) d['text'] = text
179
- else theData[i] = text
182
+ else theData[i] = text
180
183
  })
181
184
  else theData.forEach ( (d,i) => {
182
185
  if ( d == null ) return
183
186
  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
- })
187
+ dType = _defineDataType ( d )
188
+ , text = render ( d, name, helpers, {...buildDependencies, ...dependencies} )
189
+ ;
190
+ if ( text == null ) theData[i] = null
191
+ else if ( dType === 'object' ) d['text'] = text
192
+ else theData[i] = text
193
+ })
191
194
  break
192
195
  case 'function':
193
196
  nestedData[level] = helpers[name]( theData(), {...buildDependencies, ...dependencies} )
@@ -196,7 +199,7 @@ function build ( tpl, extra=false, buildDependencies={} ) {
196
199
  nestedData[level] = render ( theData, name, helpers, {...buildDependencies, ...dependencies} )
197
200
  break
198
201
  case 'object':
199
- if ( isRenderFunction ) nestedData[level]['text'] = helpers[name]( theData, {...buildDependencies, ...dependencies} )
202
+ if ( isRenderFunction ) nestedData[level][0]['text'] = helpers[name]( theData, {...buildDependencies, ...dependencies} )
200
203
  else {
201
204
  let kTest = Object.keys ( theData ).find ( k => k.includes ( '/' ) ); // Check if keys are breadcrumbs
202
205
  if ( kTest ) Object.entries( theData ).forEach( ([k,v]) => v['text'] = render ( v, name, helpers, {...buildDependencies, ...dependencies} ) )
@@ -209,13 +212,13 @@ function build ( tpl, extra=false, buildDependencies={} ) {
209
212
  // TODO: Test extendedRender
210
213
  const isValid = typeof helpers[name] === 'function'; // Render could be a function and template.
211
214
  if ( isValid ) {
212
- nestedData[level] = helpers[name]( nestedData[0] )
215
+ nestedData[level] = helpers[name]( nestedData[0][0] )
213
216
  }
214
217
  else {
215
218
  // TODO: Error...
216
219
  }
217
220
  break
218
- case 'mix':
221
+ case 'mix':
219
222
  if ( name === '' ) { // when is anonymous mixing helper
220
223
  switch ( dataType ) {
221
224
  case 'object':
@@ -231,26 +234,61 @@ function build ( tpl, extra=false, buildDependencies={} ) {
231
234
  } // check
232
235
  break
233
236
  case 'array':
234
- nestedData[level] = theData.map ( x => {
237
+ theData.forEach ( (x,i) => {
238
+ if ( i > 0 ) {
235
239
  let xType = _defineDataType ( x );
236
- if ( xType === 'object' ) return x.text
237
- return x
238
- })
239
- .filter ( x => x != null )
240
- .join ( '' )
240
+ if ( x == null ) return
241
+ if ( xType === 'object' ) theData[0] += `${x.text}`
242
+ else theData[0] += `${x}`
243
+ theData.toSpliced(i,1)
244
+ }
245
+ else {
246
+ let xxType = _defineDataType ( x );
247
+ theData[0] = ''
248
+ if ( xxType === null ) return
249
+ else if ( xxType === 'object' ) theData[0] = `${x.text}`
250
+ else theData[0] = `${x}`
251
+ }
252
+ })
253
+ theData.length = 1
241
254
  break
242
255
  } // switch dataType
243
256
  } // if name === ''
244
- else nestedData[level] = helpers[name]( theData )
257
+ else {
258
+ let
259
+ val = helpers[name]( theData )
260
+ , valType = _defineDataType ( val )
261
+ ;
262
+
263
+ theData.forEach ( ( x, i ) => theData.splice ( i, 1) )
264
+ theData.length = 0
265
+ switch ( valType ) {
266
+ case 'primitive':
267
+ theData[0] = val
268
+ break
269
+ case 'array':
270
+ theData.push ( ...val )
271
+ break
272
+ } // switch valType
273
+ }
245
274
  break
246
275
  default:
247
276
  break
248
277
  }
278
+ }) // levelData
249
279
  } // for step of actSetup
250
-
251
- let accType = _defineDataType ( nestedData[0] )
252
- let fineData = nestedData[0]
253
-
280
+
281
+ if ( nestedData instanceof Array &&
282
+ nestedData.length === 1 &&
283
+ nestedData[0] instanceof Array
284
+ ) nestedData = nestedData[0]
285
+ if ( nestedData[0] == null ) return
286
+
287
+ let
288
+ accType = _defineDataType ( nestedData[0] )
289
+ , fineData = nestedData[0]
290
+ ;
291
+
254
292
  switch ( accType ) {
255
293
  case 'primitive':
256
294
  if ( fineData == null ) return
@@ -282,7 +320,6 @@ function build ( tpl, extra=false, buildDependencies={} ) {
282
320
  } // success func.
283
321
  return extra ? [ true, success ] : success
284
322
  }
285
-
286
323
  } // build func.
287
324
 
288
325
 
@@ -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={} ) {