@peter.naydenov/morph 0.0.4 → 1.0.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
@@ -1,6 +1,15 @@
1
1
  ## Release History
2
2
 
3
3
 
4
+ ### 1.0.1 (2025-01-08)
5
+ - [x] Fix: Render functions are not receiving dependencies;
6
+
7
+
8
+
9
+ ### 1.0.0 (2024-12-28)
10
+ - [x] Change of addressing templates and stores;
11
+ - [ ] Bug: Render functions are not receiving dependencies;
12
+
4
13
 
5
14
  ### 0.0.4 (2017-12-24)
6
15
  - [x] Dependency update. @peter.naydenov/walk 5.0.1;
@@ -1,3 +1,43 @@
1
1
  # Migration Guides
2
2
 
3
- No migration guide available yet
3
+
4
+ ## 0.x.x -> 1.x.x
5
+ Main change is how you address templates. Before template name and storage were separated arguments. Now they are a single argument where the first element is the template name and the second element is the storage name. Storage name is optional and defaults to 'default'.
6
+
7
+ ```js
8
+ // Add template to default storage
9
+ // Before
10
+ morph.add ( 'myName', myTpl )
11
+ // After
12
+ morph.add ( ['myName'], myTpl )
13
+
14
+ // Add template to named storage
15
+ // Before
16
+ morph.add ( 'myName', myTpl, 'myStorage' )
17
+ // After
18
+ morph.add ( ['myName', 'myStorage'], myTpl )
19
+ ```
20
+
21
+ Calling the render function has changed. The first argument again is the data, but then we have optional injection object and then comes post processing function.
22
+
23
+ ```js
24
+ // My injection is new argument
25
+ // Before
26
+ morph.render ( myData, postProcess1, postProcess2, postProcess3 )
27
+ // After
28
+ morph.render ( myData, myInjection, postProcess1, postProcess2, postProcess3 )
29
+ ```
30
+
31
+ List method is extended. Now you can pass more then one storage to scan for template names.
32
+
33
+ ```js
34
+ // Before
35
+ let storage1Templates = morph.list ( 'storage1' )
36
+ let storage2Templates = morph.list ( 'storage2' )
37
+ let all = storage1Templates.concat ( storage2Templates )
38
+
39
+ // After
40
+ let all = morph.list ( ['storage1', 'storage2'] )
41
+ ```
42
+
43
+ Library is prety well typed now so expect a smooth migration process.
package/README.md CHANGED
@@ -1,5 +1,4 @@
1
1
  # Morph (@peter.naydenov/morph)
2
- **Experimental stage. Not tested well yet.**
3
2
 
4
3
  ![version](https://img.shields.io/github/package-json/v/peterNaydenov/morph)
5
4
  ![license](https://img.shields.io/github/license/peterNaydenov/morph)
@@ -52,8 +51,8 @@ import morph from "@peter.naydenov/morph"
52
51
  const myTemplateDescription = {
53
52
  template: `Hello, {{name}}!` // simple template - a string with a placeholder
54
53
  }
55
- const myTemplate = morph.build ( myTemplateDescription ); // myTemplate is a render function
56
- const htmlBlock = myTemplate ( { name: 'Peter' } ) // Provide data to the render function and get the result
54
+ const myTemplate = morph.build ( myTemplateDescription ); // myTemplate is a render function
55
+ const htmlBlock = myTemplate ( { name: 'Peter' } ) // Provide data to the render function and get the result
57
56
  // htmlBlock === 'Hello, Peter!'
58
57
  ```
59
58
 
@@ -61,9 +60,10 @@ Morph contains also a builtin template storage. Instead of creating variable for
61
60
 
62
61
  ```js
63
62
  // add template to the storage. Automatically builds the render function
64
- morph.add ( 'myTemplate', myTemplateDescription )
63
+ // Array of two elements. 0 - template name, 1 - optional. Storage name. Defaults to 'default'
64
+ morph.add ( ['myTemplate'], myTemplateDescription )
65
65
  // get template from the storage and render it
66
- const htmlBlock = morph.get ( 'myTemplate' )({ name: 'Peter' })
66
+ const htmlBlock = morph.get ( ['myTemplate'] )({ name: 'Peter' })
67
67
  ```
68
68
 
69
69
  Let's see a more complex example before we go into details:
@@ -201,7 +201,15 @@ When input data is array, the result will be an array. Result for each element w
201
201
 
202
202
  Learn more about how actions work in the section 'helper functions' below.
203
203
 
204
+ ## Helper Functions
204
205
 
206
+ Helpers are templates and functions that are used by actions to decorate the data. Helper functions can be used in templates as actions. Action type explains what to expect from the helper function.
207
+
208
+ - `Render functions` should return a string - the data that will replace the placeholder.
209
+ - `Data functions` are created to manipulate the data. Expectation is to return data, that will continue to be used by other actions.
210
+ - `Mixing functions` should merge data in a single data result that will be used by other actions.
211
+ - `Extended render functions` will return a string like regular render functions, but will receive a deep branch of requested data;
212
+ - `Conditional render functions` could return null, that means: ignore this action. The result could be also a string: the name of other helper function that will render the data.
205
213
 
206
214
 
207
215
 
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){const r={};let n=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]};return e({data:t,objectCallback:function({key:e,value:t,breadcrumbs:a}){let o=!1;return n=a.split("/").length-1,isNaN(e)||(o=!0),r[n]||(r[n]=o?[]:{}),"root"===e?r[n]=t:o?r[n].push(t):r[n][a]=t,t}}),{dataDeepLevel:n,nestedData:r}}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){e instanceof Object&&Object.entries(e).forEach((([t,r])=>{r instanceof Object&&(e[t]=r.text)}));const a="function"==typeof n[t];return e=function(e={}){return"string"==typeof e?{text:e}:e}(e),a?n[t](e):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){const{hasError:l,placeholders:u,chop:f,helpers:d,handshake:p}=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=[];let f=null;const d=r(o)(t);return"string"==typeof d?f=d:d.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]||(f=`Error: Missing helper: ${e}`,!1))))})),{hasError:f,placeholders:u,chop:d,helpers:n,handshake:a}}(n);if(l){function h(){return l}return i?[!1,h]:h}{let b=structuredClone(f);function m(r={},...n){const o=s(r),i=[];if("null"===o)return b.join("");if("string"==typeof r)switch(r){case"raw":return b.join("");case"demo":if(!p)return"Error: No handshake data.";r=p;break;case"handshake":return p?structuredClone(p):"Error: No handshake data.";case"placeholders":return u.map((e=>b[e.index])).join(", ");default:return`Error: Wrong command "${r}". Available commands: raw, demo, handshake, placeholders.`}return"array"!==o&&(r=[r]),r.forEach((r=>{u.forEach((n=>{const{index:o,data:i,action:l}=n;if(!l&&i){const u=r[i];switch(s(u)){case"function":return void(b[o]=u());case"primitive":return void(b[o]=u);case"array":return void("primitive"===s(u[0])&&(b[o]=u[0]));case"object":return void(u.text&&(b[o]=u.text))}}else{const{dataDeepLevel:f,nestedData:p}=a("@all"===i||null===i||"@root"===i?r:r[i]),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=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}(l,f),f);for(let E of h){let{type:v,name:k,level:j}=E,x=p[j],g=s(x);switch(v){case"route":switch(g){case"array":x.forEach(((e,t)=>{if(null==e)return;const r=s(e),n=d[k](e);null!=n&&("object"===r?x[t].text=c(e,n,d):x[t]=c(e,n,d))}));break;case"object":x.text=c(x,routeName,d);break;case"primitive":p[j]=c(x,routeName,d)}break;case"data":switch(g){case"array":x.forEach(((e,t)=>x[t]=e instanceof Function?d[k](e()):d[k](e)));break;case"object":case"primitive":p[j]=d[k](x);break;case"function":p[j]=d[k](x())}break;case"render":const _="function"==typeof d[k];switch(g){case"array":_?x.forEach(((e,t)=>{if(null==e)return;const r=s(e),n=d[k](e);null==n&&(x[t]=null),"object"===r?e.text=n:x[t]=n})):x.forEach(((e,t)=>{if(null==e)return;const r=s(e),n=c(e,k,d);null==n&&(x[t]=null),"object"===r?e.text=n:x[t]=n}));break;case"primitive":p[j]=c(x,k,d);break;case"object":Object.keys(x).find((e=>e.includes("/")))?Object.entries(x).forEach((([e,t])=>t.text=c(t,k,d))):x.text=c(x,k,d)}break;case"extendedRender":"function"==typeof d[k]&&(p[j]=d[k](p[0]));break;case"mix":if(""===k)switch(g){case"object":Object.keys(x).find((e=>e.includes("/")))?Object.entries(x).forEach((([e,t])=>p[j][e]=t.text)):p[j]=x.text;for(let T=j-1;T>=0;T--)p[T]=e({data:p[T],objectCallback:w});function w({value:e,breadcrumbs:t}){return p[j][t]?p[j][t]:e}break;case"array":p[j]=x.map((e=>"object"===s(e)?e.text:e)).filter((e=>null!=e)).join("")}else p[j]=d[k](x)}}let m=s(p[0]),y=p[0];switch(m){case"primitive":if(null==y)return;b[o]=y;break;case"object":if(null==y.text)return;b[o]=y.text;break;case"array":b[o]=y.join("")}}})),i.push(b.join(""))})),"array"===o?i:n?n.reduce(((e,t)=>t(e)),i.join("")):i.join("")}return i?[!0,m]:m}}const l={default:{}};const u={build:i,get:function(e,t="default"){return l[t]?l[t][e]?l[t][e]:function(){return`Error: Template "${e}" does not exist in storage "${t}".`}:function(){return`Error: Storage "${t}" does not exist.`}},add:function(e,t,r="default"){let n=t,a=!0;l[r]||(l[r]={}),"function"!=typeof t&&([a,n]=i(t,!0)),a?l[r][e]=n:console.error(`Error: Template "${e}" looks broken and is not added to storage.`)},list:function(e="default"){return l[e]?Object.keys(l[e]):[]},clear:function(){Object.keys(l).forEach((e=>{"default"!=e?delete l[e]:l.default={}}))},remove:function(e,t="default"){return l[t]?l[t][e]?void delete l[t][e]:`Error: Template "${e}" does not exist in storage "${t}".`:`Error: Storage "${t}" 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){const r={};let n=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]};return e({data:t,objectCallback:function({key:e,value:t,breadcrumbs:a}){let o=!1;return n=a.split("/").length-1,isNaN(e)||(o=!0),r[n]||(r[n]=o?[]:{}),"root"===e?r[n]=t:o?r[n].push(t):r[n][a]=t,t}}),{dataDeepLevel:n,nestedData:r}}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=[];let f=null;const d=r(o)(t);return"string"==typeof d?f=d:d.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]||(f=`Error: Missing helper: ${e}`,!1))))})),{hasError:f,placeholders:u,chop:d,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("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]),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 j of y){let{type:k,name:x,level:g}=j,_=b[g],w=s(_);switch(k){case"route":switch(w){case"array":_.forEach(((e,t)=>{if(null==e)return;const r=s(e),a=p[x](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(_,x,p,{...l,...n});break;case"primitive":b[g]=c(_,x,p,{...l,...n})}break;case"data":switch(w){case"array":_.forEach(((e,t)=>_[t]=e instanceof Function?p[x](e()):p[x](e)));break;case"object":case"primitive":b[g]=p[x](_);break;case"function":b[g]=p[x](_())}break;case"render":const T="function"==typeof p[x];switch(w){case"array":T?_.forEach(((e,t)=>{if(null==e)return;const r=s(e),a=p[x](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,x,p,{...l,...n});null==a&&(_[t]=null),"object"===r?e.text=a:_[t]=a}));break;case"primitive":b[g]=c(_,x,p,{...l,...n});break;case"object":Object.keys(_).find((e=>e.includes("/")))?Object.entries(_).forEach((([e,t])=>t.text=c(t,x,p,{...l,...n}))):_.text=c(_,x,p,{...l,...n})}break;case"extendedRender":"function"==typeof p[x]&&(b[g]=p[x](b[0]));break;case"mix":if(""===x)switch(w){case"object":Object.keys(_).find((e=>e.includes("/")))?Object.entries(_).forEach((([e,t])=>b[g][e]=t.text)):b[g]=_.text;for(let O=g-1;O>=0;O--)b[O]=e({data:b[O],objectCallback:S});function S({value:e,breadcrumbs:t}){return b[g][t]?b[g][t]:e}break;case"array":b[g]=_.map((e=>"object"===s(e)?e.text:e)).filter((e=>null!=e)).join("")}else b[g]=p[x](_)}}let E=s(b[0]),v=b[0];switch(E){case"primitive":if(null==v)return;m[i]=v;break;case"object":if(null==v.text)return;m[i]=v.text;break;case"array":const G=s(v[0]);m[i]="object"===G?v.map((e=>e.text)).join(""):v.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){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 +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){const r={};let n=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]};return e({data:t,objectCallback:function({key:e,value:t,breadcrumbs:a}){let o=!1;return n=a.split("/").length-1,isNaN(e)||(o=!0),r[n]||(r[n]=o?[]:{}),"root"===e?r[n]=t:o?r[n].push(t):r[n][a]=t,t}}),{dataDeepLevel:n,nestedData:r}}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){e instanceof Object&&Object.entries(e).forEach((([t,r])=>{r instanceof Object&&(e[t]=r.text)}));const a="function"==typeof n[t];return e=function(e={}){return"string"==typeof e?{text:e}:e}(e),a?n[t](e):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){const{hasError:l,placeholders:u,chop:f,helpers:d,handshake:p}=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=[];let f=null;const d=r(o)(t);return"string"==typeof d?f=d:d.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]||(f=`Error: Missing helper: ${e}`,!1))))})),{hasError:f,placeholders:u,chop:d,helpers:n,handshake:a}}(n);if(l){function h(){return l}return i?[!1,h]:h}{let b=structuredClone(f);function m(r={},...n){const o=s(r),i=[];if("null"===o)return b.join("");if("string"==typeof r)switch(r){case"raw":return b.join("");case"demo":if(!p)return"Error: No handshake data.";r=p;break;case"handshake":return p?structuredClone(p):"Error: No handshake data.";case"placeholders":return u.map((e=>b[e.index])).join(", ");default:return`Error: Wrong command "${r}". Available commands: raw, demo, handshake, placeholders.`}return"array"!==o&&(r=[r]),r.forEach((r=>{u.forEach((n=>{const{index:o,data:i,action:l}=n;if(!l&&i){const u=r[i];switch(s(u)){case"function":return void(b[o]=u());case"primitive":return void(b[o]=u);case"array":return void("primitive"===s(u[0])&&(b[o]=u[0]));case"object":return void(u.text&&(b[o]=u.text))}}else{const{dataDeepLevel:f,nestedData:p}=a("@all"===i||null===i||"@root"===i?r:r[i]),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=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}(l,f),f);for(let E of h){let{type:v,name:k,level:j}=E,x=p[j],g=s(x);switch(v){case"route":switch(g){case"array":x.forEach(((e,t)=>{if(null==e)return;const r=s(e),n=d[k](e);null!=n&&("object"===r?x[t].text=c(e,n,d):x[t]=c(e,n,d))}));break;case"object":x.text=c(x,routeName,d);break;case"primitive":p[j]=c(x,routeName,d)}break;case"data":switch(g){case"array":x.forEach(((e,t)=>x[t]=e instanceof Function?d[k](e()):d[k](e)));break;case"object":case"primitive":p[j]=d[k](x);break;case"function":p[j]=d[k](x())}break;case"render":const _="function"==typeof d[k];switch(g){case"array":_?x.forEach(((e,t)=>{if(null==e)return;const r=s(e),n=d[k](e);null==n&&(x[t]=null),"object"===r?e.text=n:x[t]=n})):x.forEach(((e,t)=>{if(null==e)return;const r=s(e),n=c(e,k,d);null==n&&(x[t]=null),"object"===r?e.text=n:x[t]=n}));break;case"primitive":p[j]=c(x,k,d);break;case"object":Object.keys(x).find((e=>e.includes("/")))?Object.entries(x).forEach((([e,t])=>t.text=c(t,k,d))):x.text=c(x,k,d)}break;case"extendedRender":"function"==typeof d[k]&&(p[j]=d[k](p[0]));break;case"mix":if(""===k)switch(g){case"object":Object.keys(x).find((e=>e.includes("/")))?Object.entries(x).forEach((([e,t])=>p[j][e]=t.text)):p[j]=x.text;for(let T=j-1;T>=0;T--)p[T]=e({data:p[T],objectCallback:w});function w({value:e,breadcrumbs:t}){return p[j][t]?p[j][t]:e}break;case"array":p[j]=x.map((e=>"object"===s(e)?e.text:e)).filter((e=>null!=e)).join("")}else p[j]=d[k](x)}}let m=s(p[0]),y=p[0];switch(m){case"primitive":if(null==y)return;b[o]=y;break;case"object":if(null==y.text)return;b[o]=y.text;break;case"array":b[o]=y.join("")}}})),i.push(b.join(""))})),"array"===o?i:n?n.reduce(((e,t)=>t(e)),i.join("")):i.join("")}return i?[!0,m]:m}}const l={default:{}};const u={build:i,get:function(e,t="default"){return l[t]?l[t][e]?l[t][e]:function(){return`Error: Template "${e}" does not exist in storage "${t}".`}:function(){return`Error: Storage "${t}" does not exist.`}},add:function(e,t,r="default"){let n=t,a=!0;l[r]||(l[r]={}),"function"!=typeof t&&([a,n]=i(t,!0)),a?l[r][e]=n:console.error(`Error: Template "${e}" looks broken and is not added to storage.`)},list:function(e="default"){return l[e]?Object.keys(l[e]):[]},clear:function(){Object.keys(l).forEach((e=>{"default"!=e?delete l[e]:l.default={}}))},remove:function(e,t="default"){return l[t]?l[t][e]?void delete l[t][e]:`Error: Template "${e}" does not exist in storage "${t}".`:`Error: Storage "${t}" 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){const r={};let n=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]};return e({data:t,objectCallback:function({key:e,value:t,breadcrumbs:a}){let o=!1;return n=a.split("/").length-1,isNaN(e)||(o=!0),r[n]||(r[n]=o?[]:{}),"root"===e?r[n]=t:o?r[n].push(t):r[n][a]=t,t}}),{dataDeepLevel:n,nestedData:r}}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=[];let f=null;const d=r(o)(t);return"string"==typeof d?f=d:d.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]||(f=`Error: Missing helper: ${e}`,!1))))})),{hasError:f,placeholders:u,chop:d,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("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]),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:k,name:x,level:g}=v,_=b[g],w=s(_);switch(k){case"route":switch(w){case"array":_.forEach(((e,t)=>{if(null==e)return;const r=s(e),a=p[x](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(_,x,p,{...l,...n});break;case"primitive":b[g]=c(_,x,p,{...l,...n})}break;case"data":switch(w){case"array":_.forEach(((e,t)=>_[t]=e instanceof Function?p[x](e()):p[x](e)));break;case"object":case"primitive":b[g]=p[x](_);break;case"function":b[g]=p[x](_())}break;case"render":const T="function"==typeof p[x];switch(w){case"array":T?_.forEach(((e,t)=>{if(null==e)return;const r=s(e),a=p[x](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,x,p,{...l,...n});null==a&&(_[t]=null),"object"===r?e.text=a:_[t]=a}));break;case"primitive":b[g]=c(_,x,p,{...l,...n});break;case"object":Object.keys(_).find((e=>e.includes("/")))?Object.entries(_).forEach((([e,t])=>t.text=c(t,x,p,{...l,...n}))):_.text=c(_,x,p,{...l,...n})}break;case"extendedRender":"function"==typeof p[x]&&(b[g]=p[x](b[0]));break;case"mix":if(""===x)switch(w){case"object":Object.keys(_).find((e=>e.includes("/")))?Object.entries(_).forEach((([e,t])=>b[g][e]=t.text)):b[g]=_.text;for(let O=g-1;O>=0;O--)b[O]=e({data:b[O],objectCallback:S});function S({value:e,breadcrumbs:t}){return b[g][t]?b[g][t]:e}break;case"array":b[g]=_.map((e=>"object"===s(e)?e.text:e)).filter((e=>null!=e)).join("")}else b[g]=p[x](_)}}let E=s(b[0]),j=b[0];switch(E){case"primitive":if(null==j)return;m[i]=j;break;case"object":if(null==j.text)return;m[i]=j.text;break;case"array":const G=s(j[0]);m[i]="object"===G?j.map((e=>e.text)).join(""):j.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){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};
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(n){const{TG_PRX:o,TG_SFX:a,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(o),0<s&&f.push(n.slice(0,s)),-1==s)return f.push(n),f;{if(u=n.indexOf(o,s+i),c=n.indexOf(a),-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){const r={};let n=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]};return e({data:t,objectCallback:function({key:e,value:t,breadcrumbs:o}){let a=!1;return n=o.split("/").length-1,isNaN(e)||(a=!0),r[n]||(r[n]=a?[]:{}),"root"===e?r[n]=t:a?r[n].push(t):r[n][o]=t,t}}),{dataDeepLevel:n,nestedData:r}}function*o(e,t){let r=function(e={}){let t=[],{type:r,limit:n,onLimit:o}=Object.assign({},{type:"FIFO",limit:!1,onLimit:"update"},e),a="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=[],o=t.length-r;return e>1&&Array.from({length:e}).map((()=>{null!=t[o-1]&&n.push(t[o-1]),o--})),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=a?function(e){const r=e instanceof Array,a=r?e.length:1;let s=!1;if("full"!==o||!i){if(n&&r&&a>n&&(e=e.slice(0,-a+n)),n){const a=(r?e.length:1)+t.length;a>=n&&"full"===o&&(e=e.slice(0,-(a-n))),a>=n&&"update"===o&&(s=l(a-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,a=r?e.length:1;let s=!1;if("full"!==o||!i){if(n&&r&&a>n&&(e=e.slice(a-n)),n){const a=(r?e.length:1)+t.length;a>=n&&"full"===o&&(e=e.slice(0,-(a-n))),a>=n&&"update"===o&&(s=l(a-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 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 l(e,r,n){e instanceof Object&&Object.entries(e).forEach((([t,r])=>{r instanceof Object&&(e[t]=r.text)}));const o="function"==typeof n[r];return e=function(e={}){return"string"==typeof e?{text:e}:e}(e),o?n[r](e):function(e,r){if(null==r)return null;const n=t(a)(e),o=a;return n.forEach(((e,t)=>{if(e.includes(o.TG_PRX)){const a=e.replace(o.TG_PRX,"").replace(o.TG_SFX,"").trim();r[a]&&(n[t]=r[a])}})),n.join("")}(n[r],e)}function s(r,s=!1){const{hasError:c,placeholders:u,chop:f,helpers:p,handshake:d}=function(e){const{template:r,helpers:n={},handshake:o}=e,{TG_PRX:i,TG_SFX:l,TG_SIZE_P:s,TG_SIZE_S:c}=a,u=[];let f=null;const p=t(a)(r);return"string"==typeof p?f=p:p.forEach(((e,t)=>{const r=RegExp(i+"\\s*(.*?)\\s*(?::\\s*(.*?)\\s*)?"+l,"g");if(e.includes(i)){const o=r.exec(e);u.push({index:t,data:(n=o[1],n||null),action:o[2]?o[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]||(f=`Error: Missing helper: ${e}`,!1))))})),{hasError:f,placeholders:u,chop:p,helpers:n,handshake:o}}(r);if(c){function h(){return c}return s?[!1,h]:h}{let y=structuredClone(f);function m(t={},...r){const a=i(t),s=[];if("null"===a)return y.join("");if("string"==typeof t)switch(t){case"raw":return y.join("");case"demo":if(!d)return"Error: No handshake data.";t=d;break;case"handshake":return d?structuredClone(d):"Error: No handshake data.";case"placeholders":return u.map((e=>y[e.index])).join(", ");default:return`Error: Wrong command "${t}". Available commands: raw, demo, handshake, placeholders.`}return"array"!==a&&(t=[t]),t.forEach((t=>{u.forEach((r=>{const{index:a,data:s,action:c}=r;if(!c&&s){const u=t[s];switch(i(u)){case"function":return void(y[a]=u());case"primitive":return void(y[a]=u);case"array":return void("primitive"===i(u[0])&&(y[a]=u[0]));case"object":return void(u.text&&(y[a]=u.text))}}else{const{dataDeepLevel:f,nestedData:d}=n("@all"===s||null===s||"@root"===s?t:t[s]),h=o(function(e,t=10){let r={},n=0,o=[...e],a=0;do{r[a]=[],a++}while(a<=t);return o.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}(c,f),f);for(let g of h){let{type:v,name:E,level:k}=g,j=d[k],x=i(j);switch(v){case"route":switch(x){case"array":j.forEach(((e,t)=>{if(null==e)return;const r=i(e),n=p[E](e);null!=n&&("object"===r?j[t].text=l(e,n,p):j[t]=l(e,n,p))}));break;case"object":j.text=l(j,routeName,p);break;case"primitive":d[k]=l(j,routeName,p)}break;case"data":switch(x){case"array":j.forEach(((e,t)=>j[t]=e instanceof Function?p[E](e()):p[E](e)));break;case"object":case"primitive":d[k]=p[E](j);break;case"function":d[k]=p[E](j())}break;case"render":const w="function"==typeof p[E];switch(x){case"array":w?j.forEach(((e,t)=>{if(null==e)return;const r=i(e),n=p[E](e);null==n&&(j[t]=null),"object"===r?e.text=n:j[t]=n})):j.forEach(((e,t)=>{if(null==e)return;const r=i(e),n=l(e,E,p);null==n&&(j[t]=null),"object"===r?e.text=n:j[t]=n}));break;case"primitive":d[k]=l(j,E,p);break;case"object":Object.keys(j).find((e=>e.includes("/")))?Object.entries(j).forEach((([e,t])=>t.text=l(t,E,p))):j.text=l(j,E,p)}break;case"extendedRender":"function"==typeof p[E]&&(d[k]=p[E](d[0]));break;case"mix":if(""===E)switch(x){case"object":Object.keys(j).find((e=>e.includes("/")))?Object.entries(j).forEach((([e,t])=>d[k][e]=t.text)):d[k]=j.text;for(let _=k-1;_>=0;_--)d[_]=e({data:d[_],objectCallback:T});function T({value:e,breadcrumbs:t}){return d[k][t]?d[k][t]:e}break;case"array":d[k]=j.map((e=>"object"===i(e)?e.text:e)).filter((e=>null!=e)).join("")}else d[k]=p[E](j)}}let m=i(d[0]),b=d[0];switch(m){case"primitive":if(null==b)return;y[a]=b;break;case"object":if(null==b.text)return;y[a]=b.text;break;case"array":y[a]=b.join("")}}})),s.push(y.join(""))})),"array"===a?s:r?r.reduce(((e,t)=>t(e)),s.join("")):s.join("")}return s?[!0,m]:m}}const c={default:{}};return{build:s,get:function(e,t="default"){return c[t]?c[t][e]?c[t][e]:function(){return`Error: Template "${e}" does not exist in storage "${t}".`}:function(){return`Error: Storage "${t}" does not exist.`}},add:function(e,t,r="default"){let n=t,o=!0;c[r]||(c[r]={}),"function"!=typeof t&&([o,n]=s(t,!0)),o?c[r][e]=n:console.error(`Error: Template "${e}" looks broken and is not added to storage.`)},list:function(e="default"){return c[e]?Object.keys(c[e]):[]},clear:function(){Object.keys(c).forEach((e=>{"default"!=e?delete c[e]:c.default={}}))},remove:function(e,t="default"){return c[t]?c[t][e]?void delete c[t][e]:`Error: Template "${e}" does not exist in storage "${t}".`:`Error: Storage "${t}" 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(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){const n={};let r=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]};return e({data:t,objectCallback:function({key:e,value:t,breadcrumbs:o}){let a=!1;return r=o.split("/").length-1,isNaN(e)||(a=!0),n[r]||(n[r]=a?[]:{}),"root"===e?n[r]=t:a?n[r].push(t):n[r][o]=t,t}}),{dataDeepLevel:r,nestedData:n}}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=[];let f=null;const p=t(a)(n);return"string"==typeof p?f=p:p.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]||(f=`Error: Missing helper: ${e}`,!1))))})),{hasError:f,placeholders:u,chop:p,helpers:r,handshake:o}}(n);if(u){function y(){return u}return c?[!1,y]:y}{let m=structuredClone(p);function b(t={},n={},...a){const c=i(t),u=[];if("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]),b=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 b){let{type:j,name:k,level:x}=E,w=y[x],T=i(w);switch(j){case"route":switch(T){case"array":w.forEach(((e,t)=>{if(null==e)return;const r=i(e),o=d[k](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,k,d,{...l,...n});break;case"primitive":y[x]=s(w,k,d,{...l,...n})}break;case"data":switch(T){case"array":w.forEach(((e,t)=>w[t]=e instanceof Function?d[k](e()):d[k](e)));break;case"object":case"primitive":y[x]=d[k](w);break;case"function":y[x]=d[k](w())}break;case"render":const _="function"==typeof d[k];switch(T){case"array":_?w.forEach(((e,t)=>{if(null==e)return;const r=i(e),o=d[k](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,k,d,{...l,...n});null==o&&(w[t]=null),"object"===r?e.text=o:w[t]=o}));break;case"primitive":y[x]=s(w,k,d,{...l,...n});break;case"object":Object.keys(w).find((e=>e.includes("/")))?Object.entries(w).forEach((([e,t])=>t.text=s(t,k,d,{...l,...n}))):w.text=s(w,k,d,{...l,...n})}break;case"extendedRender":"function"==typeof d[k]&&(y[x]=d[k](y[0]));break;case"mix":if(""===k)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 S=x-1;S>=0;S--)y[S]=e({data:y[S],objectCallback:O});function O({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[k](w)}}let g=i(y[0]),v=y[0];switch(g){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,b]:b}}const l={default:{}};return{build:c,get:function(e){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.`}}}));
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@peter.naydenov/morph",
3
3
  "description": "Template engine",
4
- "version": "0.0.4",
4
+ "version": "1.0.1",
5
5
  "license": "MIT",
6
6
  "author": "Peter Naydenov",
7
- "main": "./dist/morph.umd.js",
7
+ "main": ".src/main.js",
8
8
  "type": "module",
9
9
  "exports": {
10
10
  ".": {
11
- "import": "./dist/morph.esm.mjs",
11
+ "import": "./src/main.js",
12
12
  "require": "./dist/morph.cjs",
13
- "default": "./dist/morph.umd.js"
13
+ "default": "./src/main.js"
14
14
  },
15
15
  "./package.json": "./package.json",
16
16
  "./dist/*": "./dist/*",
package/src/main.js CHANGED
@@ -7,6 +7,7 @@
7
7
  * History notes:
8
8
  * - Idea was born on October 28th, 2024.
9
9
  * - Published on GitHub for first time: November 30th, 2024
10
+ * - Version 1.0.0: December 28st, 2024
10
11
  *
11
12
  */
12
13
 
@@ -15,11 +16,26 @@ import build from "./methods/build.js"
15
16
 
16
17
 
17
18
 
18
- const storage = { default: {}};
19
+ const storage = ( () => ({default: {}}) ) ();
19
20
 
20
21
 
21
22
 
22
- function get ( prop, strName='default' ) {
23
+
24
+
25
+
26
+ /**
27
+ * Get a template from a storage.
28
+ *
29
+ * @param {string[]} location - The location of the template. Array of two elements.
30
+ * The first element is the name of the template. The second element
31
+ * is optional and is the name of the storage. Defaults to 'default'.
32
+ *
33
+ * @returns {function } The template (a render function) if it exists in the storage.
34
+ * An function that returns an error message if
35
+ * either the storage or template does not exist.
36
+ */
37
+ function get ( location ) {
38
+ const [prop, strName='default'] = location;
23
39
  if ( !storage[strName] ) {
24
40
  return function () {
25
41
  return `Error: Storage "${strName}" does not exist.`
@@ -35,25 +51,63 @@ function get ( prop, strName='default' ) {
35
51
 
36
52
 
37
53
 
38
- function add ( name, tplfn, strName='default' ) {
54
+
55
+
56
+
57
+
58
+ /**
59
+ * Add a template to a storage.
60
+ *
61
+ * If the template is already a function, it is added to the storage.
62
+ * If the template is a template description (an object), it is built and
63
+ * added to the storage.
64
+ * If the template is broken, an error message is printed in the console
65
+ * and the template is not added to the storage.
66
+ *
67
+ * @param {string[]} location - The location to add the template to. Array of two elements.
68
+ * The first element is the name of the template. The second element
69
+ * is optional and is the name of the storage. Defaults to 'default'.
70
+ * @param {object|function} tplfn - The template description or the already built template function.
71
+ * @param {...any} args - Additional arguments to be passed to the build function.
72
+ * Only used if the first argument is a template description.
73
+ */
74
+ function add ( location, tplfn, ...args ) {
75
+ const [ name, strName='default'] = location
39
76
  let fn = tplfn;
40
77
  let successBuild = true;
41
78
  if( !storage[strName] ) storage[strName] = {}
42
- if ( typeof tplfn !== 'function' ) [ successBuild, fn ] = build ( tplfn, true )
43
-
79
+ if ( typeof tplfn !== 'function' ) {
80
+ let r = build ( tplfn, true, ...args )
81
+ successBuild = r[0]
82
+ fn = r[1]
83
+ }
44
84
  if ( successBuild ) storage[strName][name] = fn
45
85
  else console.error ( `Error: Template "${name}" looks broken and is not added to storage.` )
46
86
  } // add func.
47
87
 
48
88
 
49
89
 
50
- function list ( strName='default' ) {
51
- if ( !storage[strName] ) return []
52
- return Object.keys ( storage[strName] )
90
+ /**
91
+ * Returns an array of all the names of the templates in the given storages.
92
+ * No arguments - will return the list of templates in the 'default' storage.
93
+ *
94
+ * @param {string[]} [storageNames=['default']] - The names of the storages to retrieve template names from;
95
+ * @returns {string[]} An array of all the template names in the given storages;
96
+ */
97
+ function list ( storageNames=['default'] ) {
98
+ let r = storageNames.map ( strName => {
99
+ if ( !storage[strName] ) return []
100
+ else return Object.keys ( storage[strName])
101
+ })
102
+ return r.flat ()
53
103
  } // list func.
54
104
 
55
105
 
56
106
 
107
+ /**
108
+ * Clears all templates from the storages.
109
+ * This function deletes all storages. Storage 'default' will be reset to an empty object.
110
+ */
57
111
  function clear ( ) {
58
112
  const keys = Object.keys ( storage )
59
113
  keys.forEach ( key => {
@@ -64,28 +118,26 @@ function clear ( ) {
64
118
 
65
119
 
66
120
 
67
- function remove ( name, strName='default' ) {
121
+
122
+ /**
123
+ * Removes a template from the storage.
124
+ *
125
+ * @param {string[]} location - The location to remove the template from. Array of two elements.
126
+ * The first element is the name of the template. The second element
127
+ * is optional and is the name of the storage. Defaults to 'default'.
128
+ *
129
+ * @returns {void|string} An error message if the storage or template does not exist.
130
+ */
131
+ function remove ( location ) {
132
+ const [name, strName='default'] = location;
68
133
  if ( !storage[strName] ) return `Error: Storage "${strName}" does not exist.`
69
134
  if ( !storage[strName][name] ) return `Error: Template "${name}" does not exist in storage "${strName}".`
70
135
  delete storage[strName][name]
71
136
  } // remove func.
72
137
 
73
138
 
74
-
139
+ // Engine API
75
140
  const morphAPI = {
76
- // Engine API
77
- /**
78
- *
79
- * build -
80
- * add - register a component to component storage
81
- * get - get a component from component storage
82
- * list - list all components in component storage
83
- * clear - clear all templates in component storage
84
- * remove - remove a template from component storage
85
- *
86
- * shine - extra step to remove all non used placeholders and <rs> tags
87
- *
88
- */
89
141
  build // build a component from template description
90
142
  , get // get a component from component storage
91
143
  , add // add a component to component storage
@@ -94,8 +146,7 @@ const morphAPI = {
94
146
  , remove // remove a template from component storage
95
147
  } // morphAPI
96
148
 
97
- // TODO: How to change render templates on condition?
98
- // - Use compiled versions of simile templates
149
+
99
150
 
100
151
  export default morphAPI
101
152
 
@@ -10,9 +10,29 @@ import render from './render.js'
10
10
 
11
11
  import walk from '@peter.naydenov/walk'
12
12
 
13
+ /**
14
+ * @typedef {Object} Template
15
+ * @property {string} template - Data to be rendered;
16
+ * @property {object} [helpers] - Optional. Object with helper functions or simple templates for this template;
17
+ * @property {object} [handshake] - Optional. Example for data to be rendered with;
18
+ */
13
19
 
20
+ /**
21
+ * @typedef {Array} tupleResult
22
+ * @property {boolean} 0 - Indicates success (true) or failure (false).
23
+ * @property {function} 1 - The rendering function or an error function.
24
+ */
14
25
 
15
- function build ( tpl, extra=false ) {
26
+
27
+
28
+ /**
29
+ *
30
+ * @param {Template} tpl - template definition;
31
+ * @param {boolean} [extra] - Optional. How to receive the answer - faslse:as a string(answer) or tuple[success, answer];
32
+ * @param {object} [buildDependencies] - Optional. External dependencies injected;
33
+ * @returns {function|tupleResult} - rendering function
34
+ */
35
+ function build ( tpl, extra=false, buildDependencies={} ) {
16
36
  const { hasError, placeholders, chop, helpers, handshake } = _readTemplate ( tpl );
17
37
  if ( hasError ) {
18
38
  function fail () { return hasError }
@@ -22,7 +42,23 @@ import walk from '@peter.naydenov/walk'
22
42
  let cuts = structuredClone ( chop );
23
43
  // *** Template recognition complete. Start building the rendering function -->
24
44
 
25
- function success ( d={}, ...args ) {
45
+ /**
46
+ * Function to render a template with data.
47
+ * @param {Object} [d={}] - The data to render with. If string, it's a command.
48
+ * @param {Object} [dependencies={}] - The dependencies to use for the rendering.
49
+ * @param {...any} args - The postprocessing functions to apply to the result.
50
+ * @returns {string|string[]} The rendered template.
51
+ * @description
52
+ * If 'd' is a string, it's a command. The available commands are:
53
+ * - 'raw' - returns the original template with placeholders
54
+ * - 'demo' - renders the template with the handshake data
55
+ * - 'handshake' - returns a copy of the handshake data
56
+ * - 'placeholders' - returns the placeholders as a comma separated string
57
+ * If 'd' is an object, it's the data to render with. If it's an array, it's an array of objects to render with.
58
+ * The function returns the rendered template.
59
+ * If 'args' are provided, they are applied to the result in order.
60
+ */
61
+ function success ( d={}, dependencies={}, ...args ) {
26
62
  const
27
63
  topLevelType = _defineDataType ( d )
28
64
  , endData = []
@@ -98,15 +134,15 @@ import walk from '@peter.naydenov/walk'
98
134
  const dType = _defineDataType ( d )
99
135
  const routeName = helpers[name]( d );
100
136
  if ( routeName == null ) return
101
- if ( dType === 'object' ) theData[i]['text'] = render ( d, routeName, helpers )
102
- else theData[i] = render ( d, routeName, helpers )
137
+ if ( dType === 'object' ) theData[i]['text'] = render ( d, routeName, helpers, {...buildDependencies, ...dependencies} )
138
+ else theData[i] = render ( d, routeName, helpers, {...buildDependencies, ...dependencies} )
103
139
  })
104
140
  break
105
141
  case 'object':
106
- theData['text'] = render ( theData, routeName, helpers )
142
+ theData['text'] = render ( theData, name, helpers, {...buildDependencies, ...dependencies} )
107
143
  break
108
144
  case 'primitive':
109
- nestedData[level] = render ( theData, routeName, helpers )
145
+ nestedData[level] = render ( theData, name, helpers, {...buildDependencies, ...dependencies} )
110
146
  break
111
147
  }
112
148
  break
@@ -134,7 +170,7 @@ import walk from '@peter.naydenov/walk'
134
170
  if ( isRenderFunction ) theData.forEach ( (d,i) => {
135
171
  if ( d == null ) return
136
172
  const dType = _defineDataType ( d );
137
- const text = helpers[name]( d );
173
+ const text = helpers[name]( d, {...buildDependencies, ...dependencies} );
138
174
  if ( text == null ) theData[i] = null
139
175
  if ( dType === 'object' ) d['text'] = text
140
176
  else theData[i] = text
@@ -143,7 +179,7 @@ import walk from '@peter.naydenov/walk'
143
179
  if ( d == null ) return
144
180
  const
145
181
  dType = _defineDataType ( d )
146
- , text = render ( d, name, helpers )
182
+ , text = render ( d, name, helpers, {...buildDependencies, ...dependencies} )
147
183
  ;
148
184
  if ( text == null ) theData[i] = null
149
185
  if ( dType === 'object' ) d['text'] = text
@@ -151,12 +187,12 @@ import walk from '@peter.naydenov/walk'
151
187
  })
152
188
  break
153
189
  case 'primitive':
154
- nestedData[level] = render ( theData, name, helpers )
190
+ nestedData[level] = render ( theData, name, helpers, {...buildDependencies, ...dependencies} )
155
191
  break
156
192
  case 'object':
157
193
  let kTest = Object.keys ( theData ).find ( k => k.includes ( '/' ) ); // Check if keys are breadcrumbs
158
- if ( kTest ) Object.entries( theData ).forEach( ([k,v]) => v['text'] = render ( v, name, helpers ) )
159
- else theData['text'] = render ( theData, name, helpers )
194
+ if ( kTest ) Object.entries( theData ).forEach( ([k,v]) => v['text'] = render ( v, name, helpers, {...buildDependencies, ...dependencies} ) )
195
+ else theData['text'] = render ( theData, name, helpers, {...buildDependencies, ...dependencies} )
160
196
  break
161
197
  } // switch renderDataType
162
198
  break;
@@ -202,6 +238,7 @@ import walk from '@peter.naydenov/walk'
202
238
  break
203
239
  }
204
240
  } // for step of actSetup
241
+
205
242
  let accType = _defineDataType ( nestedData[0] )
206
243
  let fineData = nestedData[0]
207
244
 
@@ -215,16 +252,22 @@ import walk from '@peter.naydenov/walk'
215
252
  cuts[index] = fineData['text']
216
253
  break
217
254
  case 'array':
218
- cuts[index] = fineData.join ( '' )
255
+ const aType = _defineDataType ( fineData[0] )
256
+ if ( aType === 'object' ) cuts[index] = fineData.map ( x => x.text ).join ( '')
257
+ else cuts[index] = fineData.join ( '' )
219
258
  break
220
259
  } // switch accType
221
260
  } // else other
222
- }) // forEach placeholders
261
+ }) // forEach placeholders
223
262
  endData.push ( cuts.join ( '' ))
224
263
  }) // forEach d
225
264
 
226
265
  if ( topLevelType === 'array' ) return endData
227
- if (args) return args.reduce ( (acc, fn) => fn ( acc ), endData.join ( '' ) )
266
+ // Execute postprocess functions
267
+ if (args) return args.reduce ( (acc, fn) => {
268
+ if ( typeof fn !== 'function' ) return acc
269
+ return fn ( acc, {...buildDependencies,...dependencies} )
270
+ }, endData.join ( '' ) )
228
271
  else return endData.join ( '' )
229
272
 
230
273
  } // success func.
@@ -2,7 +2,18 @@ import _renderHolder from "./_renderHolder.js"
2
2
 
3
3
 
4
4
 
5
- function render ( theData, name, helpers ) {
5
+ /**
6
+ *
7
+ * Execute rendering and return the results
8
+ *
9
+ * @param {object|string} theData - Data to be rendered. If it's a string, it's the value of 'text' property.
10
+ * @param {string} name - Name of the render to be executed.
11
+ * @param {object} helpers - Object with helper functions or templates.
12
+ * @param {...any} args - Extra arguments to be passed to the render function.
13
+ *
14
+ * @returns {string} - Rendered string.
15
+ */
16
+ function render ( theData, name, helpers, ...args ) {
6
17
  // *** Executes rendering and return the results
7
18
  if ( theData instanceof Object ) { // Make sure all properties are not objects
8
19
  Object.entries ( theData ).forEach ( ([key, value]) => {
@@ -15,7 +26,7 @@ function render ( theData, name, helpers ) {
15
26
  } // setRenderData func.
16
27
  const isRenderFunction = typeof helpers[name] === 'function'; // Render could be a function or template.
17
28
  theData = setRenderData ( theData )
18
- if ( isRenderFunction ) return helpers[name]( theData )
29
+ if ( isRenderFunction ) return helpers[name]( theData, ...args )
19
30
  else return _renderHolder ( helpers[name], theData )
20
31
  } // render func.
21
32