@peter.naydenov/morph 1.2.3 → 2.0.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
@@ -1,6 +1,13 @@
1
1
  ## Release History
2
2
 
3
3
 
4
+ ### 2.0.0 (2025-03-25)
5
+ - [x] Memory action intoduced - memory is available in data functions;
6
+ - [x] Change in arguments format for helper functions;
7
+ - [x] Overwrite action introduced - when change in data should be available for all placeholders;
8
+
9
+
10
+
4
11
 
5
12
  ### 1.2.3 (2025-03-17)
6
13
  - [x] Refactoring: Extended render;
@@ -1,6 +1,41 @@
1
1
  # Migration Guides
2
2
 
3
3
 
4
+ ## 1.x.x -> 2.x.x
5
+ Modification of data is available only for current placeholder. If you need to remember changes in data, use the new memory action - '^something' where '^' is for memory and 'something' is the name. Memory will make a snapshot of the current data and will be available in helper functions. If you need to provide changes to all placeholders, use overwrite action. It's a snapshot that will be remember as a main data and will be available for all placeholders.
6
+
7
+ Arguments for helper functions are chaged. Because we want to have many arguments and we don't want to think about their order, we make an object with named arguments. Available arguments are: data, dependencies, memory.
8
+
9
+ ```js
10
+ // Before
11
+ const template = {
12
+ template : `Hello from {{ @all : name }}. I'm {{ age }} years old {{ job }}`
13
+ , helpers : {
14
+ name: ( data ) => data.name // Change in arguments of helper functions!
15
+ }
16
+ , handshake: {
17
+ name: 'Peter'
18
+ , age: 40
19
+ , job: 'developer'
20
+ }
21
+ }
22
+
23
+ // After
24
+ const template = {
25
+ template : `Hello from {{ @all : name }}. I'm {{ age }} years old {{ job }}`
26
+ , helpers : {
27
+ name: ({ data, memory, dependencies }) => data.name // data is named argument
28
+ }
29
+ , handshake: {
30
+ name: 'Peter'
31
+ , age: 40
32
+ , job: 'developer'
33
+ }
34
+
35
+ ```
36
+
37
+
38
+
4
39
  ## 0.x.x -> 1.x.x
5
40
  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
41
 
package/README.md CHANGED
@@ -8,6 +8,15 @@
8
8
 
9
9
 
10
10
 
11
+ ## What's new in version 2.x.x
12
+ - Data helper functions modifies the data per placeholder;
13
+ - Arguments for helper functions are named arguments;
14
+ - Memory action introduced - memory is available in helper functions as a named argument;
15
+ - Overwrite action introduced - when change in data should be available for all placeholders;
16
+
17
+
18
+
19
+
11
20
  ## General Information
12
21
 
13
22
  `Morph` has a logic-less template syntax. Placeholders are places surrounded by double curly braces `{{ }}` and they represents the pleces where the data will be inserted.
@@ -17,6 +26,7 @@ Some features of Morph:
17
26
  - Simple logic-less template syntax;
18
27
  - Builtin storage;
19
28
  - Powerfull action system for data decoration;
29
+ - Demo request can render the template with the builtin data;
20
30
  - Nesting templates as part of the action system;
21
31
  - Partial rendering (render only available data);
22
32
  - Option to connect templates to external data sources;
@@ -26,6 +36,10 @@ Some features of Morph:
26
36
 
27
37
 
28
38
 
39
+
40
+
41
+
42
+
29
43
  ## Installation
30
44
 
31
45
  ```
@@ -50,13 +64,22 @@ import morph from "@peter.naydenov/morph"
50
64
 
51
65
  const myTemplateDescription = {
52
66
  template: `Hello, {{name}}!` // simple template - a string with a placeholder
67
+ , helers : {
68
+ // helper functions
69
+ }
70
+ , handshake : {
71
+ // ... demo data here
72
+ name : 'Ivan'
73
+ }
53
74
  }
54
75
  const myTemplate = morph.build ( myTemplateDescription ); // myTemplate is a render function
55
76
  const htmlBlock = myTemplate ( { name: 'Peter' } ) // Provide data to the render function and get the result
56
77
  // htmlBlock === 'Hello, Peter!'
78
+ const demo = myTemplate ( 'demo' )
79
+ // demo === 'Hello, Ivan!'
57
80
  ```
58
81
 
59
- Morph contains also a builtin template storage. Instead of creating variable for each template, we can use the storage.
82
+ Morph contains also a builtin template storages. Instead of creating variable for each template, we can use the storages.
60
83
 
61
84
  ```js
62
85
  // add template to the storage. Automatically builds the render function
@@ -64,6 +87,14 @@ Morph contains also a builtin template storage. Instead of creating variable for
64
87
  morph.add ( ['myTemplate'], myTemplateDescription )
65
88
  // get template from the storage and render it
66
89
  const htmlBlock = morph.get ( ['myTemplate'] )({ name: 'Peter' })
90
+ // it's same as text above
91
+ morph.add ( ['myTemplate', 'default'], myTemplateDescription )
92
+ const htmlBlock = morph.get ( ['myTemplate', 'default'] )({ name: 'Peter' })
93
+ // if we use custom storage:
94
+ morph.add ( ['myTemplate', 'hidden'], myTemplateDescription ) // write template in storage 'hidden'
95
+ const htmlBlock = morph.get ( ['myTemplate', 'hidden'] )({ name: 'Peter' }) // render template from 'hidden' storage
96
+ morph.get ( ['myTemplate'] )({ name: 'Peter' }) // call template 'myTemplate' from default storage
97
+ // will return error, because default storage does not have template "myTemplate"
67
98
  ```
68
99
 
69
100
  Let's see a more complex example before we go into details:
@@ -80,6 +111,9 @@ const myTemplateDescription = {
80
111
  , a: `<a href="{{href}}">{{text}}</a>`
81
112
  , getAge: (person) => person.age
82
113
  }
114
+ , handshake: {
115
+ // ... demo data here
116
+ }
83
117
  }
84
118
  const myTemplate = morph.build ( myTemplateDescription );
85
119
  const htmlBlock = myTemplate ( { person: {
@@ -182,6 +216,10 @@ Actions are concise representations of a sequence of function calls. Some functi
182
216
  - `Mixing` functions start with '[]';
183
217
  - `Conditional render` actions start with '?';
184
218
  - `Extended render` start with '+';
219
+ - `Memory` actions start with '^'. Memory action will take a data snapshot and will be available in helper functions as a named argument 'memory'. The name after the prefix is the name of the snapshot. Request saved data from helper functions by calling 'memory[name]';
220
+ - `Overwrite` action is marked with '^^'. Means that the current data will be available for all placeholders, not only for the current placeholder;
221
+
222
+
185
223
 
186
224
  Here are some examples:
187
225
  ```js
package/dist/morph.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("@peter.naydenov/walk"),t=require("@peter.naydenov/stack");function r(e){return function t(r){const{TG_PRX:a,TG_SFX:o,TG_SIZE_P:s,TG_SIZE_S:i}=e;let c,l,u,f=[];if("string"!=typeof r)return n("notAString");if(0==r.length)return[];if(c=r.indexOf(a),0<c&&f.push(r.slice(0,c)),-1==c)return f.push(r),f;{if(u=r.indexOf(a,c+s),l=r.indexOf(o),-1==l)return n("missingClosing");if(l<c)return n("closedBeforeOpened");if(l+=i,-1!=u&&u<l)return n("newBeforeClosed");f.push(r.slice(c,l));let e=t(r.slice(l));return f.concat(e)}}}function n(e){switch(e){case"notAString":return"Error: Template is not a string.";case"missingClosing":return"Error: Placeholder with missing closing tag.";case"closedBeforeOpened":return"Error: Placeholder closing tag without starting one.";case"newBeforeClosed":return"Error: Nested placeholders. Close placeholder before open new one.";default:return"Error: Unknown template error."}}function a(t,r){const n=[];let a=0;if(t instanceof Function)return{dataDeepLevel:0,nestedData:[[t()]]};if(null==t)return{dataDeepLevel:0,nestedData:[null]};if("string"==typeof t)return{dataDeepLevel:0,nestedData:[[t]]};if(!r.includes("#"))return n.push([t]),{dataDeepLevel:0,nestedData:n};return e({data:t,objectCallback:function({key:e,value:t,breadcrumbs:r}){return e===r?(n[0]=[t],t):(a=r.split("/").length-1,n[a]||(n[a]=[]),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 i(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 c(n,c=!1,l={}){const{hasError:u,placeholders:f,chop:d,helpers:p,handshake:h}=function(e){const{template:t,helpers:n={},handshake:a}=e,{TG_PRX:s,TG_SFX:i}=o,c=[],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*)?"+i,"g");if(e.includes(s)){const a=r.exec(e);c.push({index:t,data:(n=a[1],n||null),action:a[2]?a[2].split(",").map((e=>e.trim())):null})}var n})),c.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:c,chop:f,helpers:n,handshake:a}}(n);if(u){function b(){return u}return c?[!1,b]:b}{let m=structuredClone(d);function y(r={},n={},...o){const c=[];let u=s(r),d={...l,...n};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]),"null"===u?m.join(""):(r.forEach((r=>{f.forEach((n=>{const{index:o,data:c,action:l}=n;if(!l&&c){const e=r[c];switch(s(e)){case"function":return void(m[o]=e());case"primitive":return void(m[o]=e);case"array":return void("primitive"===s(e[0])&&(m[o]=e[0]));case"object":return void(e.text&&(m[o]=e.text))}}else{let{dataDeepLevel:n,nestedData:u}=a("@all"===c||null===c||"@root"===c?r:r[c],l),f=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: Not enough level markers (#) for data with depth level ${t}. Found ${s} level markers in actions: ${e.join(", ")}`);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}(l,n),n);for(let t of f){let{type:r,name:n,level:a}=t;(u[a]||[]).forEach((t=>{let o=s(t);switch(r){case"route":switch(o){case"array":t.forEach(((e,r)=>{if(null==e)return;const a=s(e),o=p[n](e);null!=o&&("object"===a?t[r].text=i(e,o,p,d):t[r]=i(e,o,p,d))}));break;case"object":t.text=i(t,n,p,d)}break;case"data":switch(o){case"array":t.forEach(((e,r)=>t[r]=e instanceof Function?p[n](e()):p[n](e)));break;case"object":u[a]=[p[n](t)];break;case"function":u[a]=[p[n](t())];break;case"primitive":u[a]=p[n](t)}break;case"render":const c="function"==typeof p[n];switch(o){case"array":c?t.forEach(((e,r)=>{if(null==e)return;const a=s(e),o=p[n](e,d);null==o&&(t[r]=null),"object"===a?e.text=o:t[r]=o})):t.forEach(((e,r)=>{if(null==e)return;const a=s(e),o=i(e,n,p,d);null==o?t[r]=null:"object"===a?e.text=o:t[r]=o}));break;case"function":u[a]=p[n](t(),d);break;case"primitive":u[a]=i(t,n,p,d);break;case"object":c?u[a][0].text=p[n](t,d):t.text=i(t,n,p,d)}break;case"extendedRender":"function"==typeof p[n]&&u[0].forEach(((e,t)=>u[0][t]=p[n](e)));break;case"mix":if(""===n)switch(o){case"object":Object.keys(t).find((e=>e.includes("/")))?Object.entries(t).forEach((([e,t])=>u[a][e]=t.text)):u[a]=t.text;for(let f=a-1;f>=0;f--)u[f]=e({data:u[f],objectCallback:l});function l({value:e,breadcrumbs:t}){return u[a][t]?u[a][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 h=p[n](t),b=s(h);switch(t.forEach(((e,r)=>t.splice(r,1))),t.length=0,b){case"primitive":t[0]=h;break;case"array":t.push(...h)}}}}))}if(u instanceof Array&&1===u.length&&u[0]instanceof Array&&(u=u[0]),null==u[0])return;let h=s(u[0]),b=u[0];switch(h){case"primitive":if(null==b)return;m[o]=b;break;case"object":if(null==b.text)return;m[o]=b.text;break;case"array":const e=s(b[0]);m[o]="object"===e?b.map((e=>e.text)).join(""):b.join("")}}})),c.push(m.join(""))})),"array"===u?c:o?o.reduce(((e,t)=>"function"!=typeof t?e:t(e,d)),c.join("")):c.join(""))}return c?[!0,y]:y}}const l={default:{}};const u={build:c,get:function(e){if(!(e instanceof Array))return function(){return'Error: Argument "location" is a string. Should be an array. E.g. ["templateName", "storageName"].'};const[t,r="default"]=e;return l[r]?l[r][t]?l[r][t]:function(){return`Error: Template "${t}" does not exist in storage "${r}".`}:function(){return`Error: Storage "${r}" does not exist.`}},add:function(e,t,...r){const[n,a="default"]=e;if(null==t)return void console.warn(`Warning: Template ${a}/${n} is not added to storage. The template is null.`);let o=t,s=!0;if(l[a]||(l[a]={}),"function"!=typeof t){let e=c(t,!0,...r);s=e[0],o=e[1]}s?l[a][n]=o:console.error(`Error: Template "${n}" looks broken and is not added to storage.`)},list:function(e=["default"]){return e.map((e=>l[e]?Object.keys(l[e]):[])).flat()},clear:function(){Object.keys(l).forEach((e=>{"default"!=e?delete l[e]:l.default={}}))},remove:function(e){const[t,r="default"]=e;return l[r]?l[r][t]?void delete l[r][t]:`Error: Template "${t}" does not exist in storage "${r}".`:`Error: Storage "${r}" does not exist.`}};module.exports=u;
1
+ "use strict";var e=require("@peter.naydenov/walk"),t=require("@peter.naydenov/stack");function r(e){return function t(r){const{TG_PRX:a,TG_SFX:o,TG_SIZE_P:s,TG_SIZE_S:c}=e;let i,l,u,f=[];if("string"!=typeof r)return n("notAString");if(0==r.length)return[];if(i=r.indexOf(a),0<i&&f.push(r.slice(0,i)),-1==i)return f.push(r),f;{if(u=r.indexOf(a,i+s),l=r.indexOf(o),-1==l)return n("missingClosing");if(l<i)return n("closedBeforeOpened");if(l+=c,-1!=u&&u<l)return n("newBeforeClosed");f.push(r.slice(i,l));let e=t(r.slice(l));return f.concat(e)}}}function n(e){switch(e){case"notAString":return"Error: Template is not a string.";case"missingClosing":return"Error: Placeholder with missing closing tag.";case"closedBeforeOpened":return"Error: Placeholder closing tag without starting one.";case"newBeforeClosed":return"Error: Nested placeholders. Close placeholder before open new one.";default:return"Error: Unknown template error."}}function a(t,r){const n=[];let a=0;if(t instanceof Function)return{dataDeepLevel:0,nestedData:[[t()]]};if(null==t)return{dataDeepLevel:0,nestedData:[null]};if("string"==typeof t)return{dataDeepLevel:0,nestedData:[[t]]};const o=structuredClone(t);if(!r.includes("#"))return n.push([o]),{dataDeepLevel:0,nestedData:n};return e({data:o,objectCallback:function({key:e,value:t,breadcrumbs:r}){return e===r?(n[0]=[t],t):(a=r.split("/").length-1,n[a]||(n[a]=[]),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||!(!e.startsWith("^")||"^^"===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=[],u={};let d=s(r),b={...l,...n};if(r=e({data:r}),"null"===d)return m.join("");if("string"==typeof r)switch(r){case"raw":return m.join("");case"demo":if(!h)return"Error: No handshake data.";d=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"!==d&&(r=[r]),"null"===d?m.join(""):(r.forEach((r=>{f.forEach((n=>{const{index:o,data:i,action:l}=n,f=!l&&i,d=structuredClone(u),h={dependencies:b,memory:d};if(f){const e=r[i];switch(s(e)){case"function":return void(m[o]=e());case"primitive":return void(m[o]=e);case"array":return void("primitive"===s(e[0])&&(m[o]=e[0]));case"object":return void(e.text&&(m[o]=e.text))}}else{let{dataDeepLevel:n,nestedData:f}=a("@all"===i||null===i||"@root"===i?r:r[i],l),d=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: Not enough level markers (#) for data with depth level ${t}. Found ${s} level markers in actions: ${e.join(", ")}`);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("^")&&"^^"!==e?(r[a].push({type:"save",name:e.replace("^",""),level:a}),!0):"^^"===e?(r[a].push({type:"overwrite",name:"none",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}(l,n),n);for(let t of d){let{type:n,name:a,level:o}=t;(f[o]||[]).forEach((t=>{let i=s(t);switch(n){case"route":switch(i){case"array":t.forEach(((e,r)=>{if(null==e)return;const n=s(e),o=p[a]({data:e,...h});null!=o&&("object"===n?t[r].text=c(e,o,p,b):t[r]=c(e,o,p,b))}));break;case"object":t.text=c(t,a,p,b)}break;case"save":u[a]=structuredClone(t);break;case"overwrite":r=structuredClone(t);break;case"data":switch(i){case"array":t.forEach(((e,r)=>t[r]=e instanceof Function?p[a]({data:e(),...h}):p[a]({data:e,...h})));break;case"object":f[o]=[p[a]({data:t,...h})];break;case"function":f[o]=[p[a]({data:t(),...h})];break;case"primitive":f[o]=p[a]({data:t,...h})}break;case"render":const l="function"==typeof p[a];switch(i){case"array":l?t.forEach(((e,r)=>{if(null==e)return;const n=s(e),o=p[a]({data:e,...h});null==o&&(t[r]=null),"object"===n?e.text=o:t[r]=o})):t.forEach(((e,r)=>{if(null==e)return;const n=s(e),o=c(e,a,p,b);null==o?t[r]=null:"object"===n?e.text=o:t[r]=o}));break;case"function":f[o]=p[a]({data:t(),...h});break;case"primitive":f[o]=c(t,a,p,b);break;case"object":l?f[o][0].text=p[a]({data:t,...h}):t.text=c(t,a,p,b)}break;case"extendedRender":"function"==typeof p[a]&&f[0].forEach(((e,t)=>f[0][t]=p[a]({data:e,...h})));break;case"mix":if(""===a)switch(i){case"object":Object.keys(t).find((e=>e.includes("/")))?Object.entries(t).forEach((([e,t])=>f[o][e]=t.text)):f[o]=t.text;for(let m=o-1;m>=0;m--)f[m]=e({data:f[m],objectCallback:d});function d({value:e,breadcrumbs:t}){return f[o][t]?f[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 y=p[a]({data:t,...h}),v=s(y);switch(t.forEach(((e,r)=>t.splice(r,1))),t.length=0,v){case"primitive":t[0]=y;break;case"array":t.push(...y)}}}}))}if(f instanceof Array&&1===f.length&&f[0]instanceof Array&&(f=f[0]),null==f[0])return;let y=s(f[0]),v=f[0];switch(y){case"primitive":if(null==v)return;m[o]=v;break;case"object":if(null==v.text)return;m[o]=v.text;break;case"array":const e=s(v[0]);m[o]="object"===e?v.map((e=>e.text)).join(""):v.join("")}}})),i.push(m.join(""))})),"array"===d?i:o?o.reduce(((e,t)=>"function"!=typeof t?e:t(e,b)),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.`}};module.exports=u;
@@ -1 +1 @@
1
- import e from"@peter.naydenov/walk";import t from"@peter.naydenov/stack";function r(e){return function t(r){const{TG_PRX:a,TG_SFX:o,TG_SIZE_P:s,TG_SIZE_S:i}=e;let c,l,u,f=[];if("string"!=typeof r)return n("notAString");if(0==r.length)return[];if(c=r.indexOf(a),0<c&&f.push(r.slice(0,c)),-1==c)return f.push(r),f;{if(u=r.indexOf(a,c+s),l=r.indexOf(o),-1==l)return n("missingClosing");if(l<c)return n("closedBeforeOpened");if(l+=i,-1!=u&&u<l)return n("newBeforeClosed");f.push(r.slice(c,l));let e=t(r.slice(l));return f.concat(e)}}}function n(e){switch(e){case"notAString":return"Error: Template is not a string.";case"missingClosing":return"Error: Placeholder with missing closing tag.";case"closedBeforeOpened":return"Error: Placeholder closing tag without starting one.";case"newBeforeClosed":return"Error: Nested placeholders. Close placeholder before open new one.";default:return"Error: Unknown template error."}}function a(t,r){const n=[];let a=0;if(t instanceof Function)return{dataDeepLevel:0,nestedData:[[t()]]};if(null==t)return{dataDeepLevel:0,nestedData:[null]};if("string"==typeof t)return{dataDeepLevel:0,nestedData:[[t]]};if(!r.includes("#"))return n.push([t]),{dataDeepLevel:0,nestedData:n};return e({data:t,objectCallback:function({key:e,value:t,breadcrumbs:r}){return e===r?(n[0]=[t],t):(a=r.split("/").length-1,n[a]||(n[a]=[]),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 i(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 c(n,c=!1,l={}){const{hasError:u,placeholders:f,chop:d,helpers:p,handshake:h}=function(e){const{template:t,helpers:n={},handshake:a}=e,{TG_PRX:s,TG_SFX:i}=o,c=[],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*)?"+i,"g");if(e.includes(s)){const a=r.exec(e);c.push({index:t,data:(n=a[1],n||null),action:a[2]?a[2].split(",").map((e=>e.trim())):null})}var n})),c.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:c,chop:f,helpers:n,handshake:a}}(n);if(u){function m(){return u}return c?[!1,m]:m}{let b=structuredClone(d);function y(r={},n={},...o){const c=[];let u=s(r),d={...l,...n};if(r=e({data:r}),"null"===u)return b.join("");if("string"==typeof r)switch(r){case"raw":return b.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=>b[e.index])).join(", ");default:return`Error: Wrong command "${r}". Available commands: raw, demo, handshake, placeholders.`}return"array"!==u&&(r=[r]),"null"===u?b.join(""):(r.forEach((r=>{f.forEach((n=>{const{index:o,data:c,action:l}=n;if(!l&&c){const e=r[c];switch(s(e)){case"function":return void(b[o]=e());case"primitive":return void(b[o]=e);case"array":return void("primitive"===s(e[0])&&(b[o]=e[0]));case"object":return void(e.text&&(b[o]=e.text))}}else{let{dataDeepLevel:n,nestedData:u}=a("@all"===c||null===c||"@root"===c?r:r[c],l),f=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: Not enough level markers (#) for data with depth level ${t}. Found ${s} level markers in actions: ${e.join(", ")}`);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}(l,n),n);for(let t of f){let{type:r,name:n,level:a}=t;(u[a]||[]).forEach((t=>{let o=s(t);switch(r){case"route":switch(o){case"array":t.forEach(((e,r)=>{if(null==e)return;const a=s(e),o=p[n](e);null!=o&&("object"===a?t[r].text=i(e,o,p,d):t[r]=i(e,o,p,d))}));break;case"object":t.text=i(t,n,p,d)}break;case"data":switch(o){case"array":t.forEach(((e,r)=>t[r]=e instanceof Function?p[n](e()):p[n](e)));break;case"object":u[a]=[p[n](t)];break;case"function":u[a]=[p[n](t())];break;case"primitive":u[a]=p[n](t)}break;case"render":const c="function"==typeof p[n];switch(o){case"array":c?t.forEach(((e,r)=>{if(null==e)return;const a=s(e),o=p[n](e,d);null==o&&(t[r]=null),"object"===a?e.text=o:t[r]=o})):t.forEach(((e,r)=>{if(null==e)return;const a=s(e),o=i(e,n,p,d);null==o?t[r]=null:"object"===a?e.text=o:t[r]=o}));break;case"function":u[a]=p[n](t(),d);break;case"primitive":u[a]=i(t,n,p,d);break;case"object":c?u[a][0].text=p[n](t,d):t.text=i(t,n,p,d)}break;case"extendedRender":"function"==typeof p[n]&&u[0].forEach(((e,t)=>u[0][t]=p[n](e)));break;case"mix":if(""===n)switch(o){case"object":Object.keys(t).find((e=>e.includes("/")))?Object.entries(t).forEach((([e,t])=>u[a][e]=t.text)):u[a]=t.text;for(let f=a-1;f>=0;f--)u[f]=e({data:u[f],objectCallback:l});function l({value:e,breadcrumbs:t}){return u[a][t]?u[a][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 h=p[n](t),m=s(h);switch(t.forEach(((e,r)=>t.splice(r,1))),t.length=0,m){case"primitive":t[0]=h;break;case"array":t.push(...h)}}}}))}if(u instanceof Array&&1===u.length&&u[0]instanceof Array&&(u=u[0]),null==u[0])return;let h=s(u[0]),m=u[0];switch(h){case"primitive":if(null==m)return;b[o]=m;break;case"object":if(null==m.text)return;b[o]=m.text;break;case"array":const e=s(m[0]);b[o]="object"===e?m.map((e=>e.text)).join(""):m.join("")}}})),c.push(b.join(""))})),"array"===u?c:o?o.reduce(((e,t)=>"function"!=typeof t?e:t(e,d)),c.join("")):c.join(""))}return c?[!0,y]:y}}const l={default:{}};const u={build:c,get:function(e){if(!(e instanceof Array))return function(){return'Error: Argument "location" is a string. Should be an array. E.g. ["templateName", "storageName"].'};const[t,r="default"]=e;return l[r]?l[r][t]?l[r][t]:function(){return`Error: Template "${t}" does not exist in storage "${r}".`}:function(){return`Error: Storage "${r}" does not exist.`}},add:function(e,t,...r){const[n,a="default"]=e;if(null==t)return void console.warn(`Warning: Template ${a}/${n} is not added to storage. The template is null.`);let o=t,s=!0;if(l[a]||(l[a]={}),"function"!=typeof t){let e=c(t,!0,...r);s=e[0],o=e[1]}s?l[a][n]=o:console.error(`Error: Template "${n}" looks broken and is not added to storage.`)},list:function(e=["default"]){return e.map((e=>l[e]?Object.keys(l[e]):[])).flat()},clear:function(){Object.keys(l).forEach((e=>{"default"!=e?delete l[e]:l.default={}}))},remove:function(e){const[t,r="default"]=e;return l[r]?l[r][t]?void delete l[r][t]:`Error: Template "${t}" does not exist in storage "${r}".`:`Error: Storage "${r}" does not exist.`}};export{u as default};
1
+ import e from"@peter.naydenov/walk";import t from"@peter.naydenov/stack";function r(e){return function t(r){const{TG_PRX:a,TG_SFX:o,TG_SIZE_P:s,TG_SIZE_S:c}=e;let i,l,u,f=[];if("string"!=typeof r)return n("notAString");if(0==r.length)return[];if(i=r.indexOf(a),0<i&&f.push(r.slice(0,i)),-1==i)return f.push(r),f;{if(u=r.indexOf(a,i+s),l=r.indexOf(o),-1==l)return n("missingClosing");if(l<i)return n("closedBeforeOpened");if(l+=c,-1!=u&&u<l)return n("newBeforeClosed");f.push(r.slice(i,l));let e=t(r.slice(l));return f.concat(e)}}}function n(e){switch(e){case"notAString":return"Error: Template is not a string.";case"missingClosing":return"Error: Placeholder with missing closing tag.";case"closedBeforeOpened":return"Error: Placeholder closing tag without starting one.";case"newBeforeClosed":return"Error: Nested placeholders. Close placeholder before open new one.";default:return"Error: Unknown template error."}}function a(t,r){const n=[];let a=0;if(t instanceof Function)return{dataDeepLevel:0,nestedData:[[t()]]};if(null==t)return{dataDeepLevel:0,nestedData:[null]};if("string"==typeof t)return{dataDeepLevel:0,nestedData:[[t]]};const o=structuredClone(t);if(!r.includes("#"))return n.push([o]),{dataDeepLevel:0,nestedData:n};return e({data:o,objectCallback:function({key:e,value:t,breadcrumbs:r}){return e===r?(n[0]=[t],t):(a=r.split("/").length-1,n[a]||(n[a]=[]),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||!(!e.startsWith("^")||"^^"===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 m(){return u}return i?[!1,m]:m}{let b=structuredClone(d);function y(r={},n={},...o){const i=[],u={};let d=s(r),m={...l,...n};if(r=e({data:r}),"null"===d)return b.join("");if("string"==typeof r)switch(r){case"raw":return b.join("");case"demo":if(!h)return"Error: No handshake data.";d=s(r=h);break;case"handshake":return h?structuredClone(h):"Error: No handshake data.";case"placeholders":return f.map((e=>b[e.index])).join(", ");default:return`Error: Wrong command "${r}". Available commands: raw, demo, handshake, placeholders.`}return"array"!==d&&(r=[r]),"null"===d?b.join(""):(r.forEach((r=>{f.forEach((n=>{const{index:o,data:i,action:l}=n,f=!l&&i,d=structuredClone(u),h={dependencies:m,memory:d};if(f){const e=r[i];switch(s(e)){case"function":return void(b[o]=e());case"primitive":return void(b[o]=e);case"array":return void("primitive"===s(e[0])&&(b[o]=e[0]));case"object":return void(e.text&&(b[o]=e.text))}}else{let{dataDeepLevel:n,nestedData:f}=a("@all"===i||null===i||"@root"===i?r:r[i],l),d=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: Not enough level markers (#) for data with depth level ${t}. Found ${s} level markers in actions: ${e.join(", ")}`);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("^")&&"^^"!==e?(r[a].push({type:"save",name:e.replace("^",""),level:a}),!0):"^^"===e?(r[a].push({type:"overwrite",name:"none",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}(l,n),n);for(let t of d){let{type:n,name:a,level:o}=t;(f[o]||[]).forEach((t=>{let i=s(t);switch(n){case"route":switch(i){case"array":t.forEach(((e,r)=>{if(null==e)return;const n=s(e),o=p[a]({data:e,...h});null!=o&&("object"===n?t[r].text=c(e,o,p,m):t[r]=c(e,o,p,m))}));break;case"object":t.text=c(t,a,p,m)}break;case"save":u[a]=structuredClone(t);break;case"overwrite":r=structuredClone(t);break;case"data":switch(i){case"array":t.forEach(((e,r)=>t[r]=e instanceof Function?p[a]({data:e(),...h}):p[a]({data:e,...h})));break;case"object":f[o]=[p[a]({data:t,...h})];break;case"function":f[o]=[p[a]({data:t(),...h})];break;case"primitive":f[o]=p[a]({data:t,...h})}break;case"render":const l="function"==typeof p[a];switch(i){case"array":l?t.forEach(((e,r)=>{if(null==e)return;const n=s(e),o=p[a]({data:e,...h});null==o&&(t[r]=null),"object"===n?e.text=o:t[r]=o})):t.forEach(((e,r)=>{if(null==e)return;const n=s(e),o=c(e,a,p,m);null==o?t[r]=null:"object"===n?e.text=o:t[r]=o}));break;case"function":f[o]=p[a]({data:t(),...h});break;case"primitive":f[o]=c(t,a,p,m);break;case"object":l?f[o][0].text=p[a]({data:t,...h}):t.text=c(t,a,p,m)}break;case"extendedRender":"function"==typeof p[a]&&f[0].forEach(((e,t)=>f[0][t]=p[a]({data:e,...h})));break;case"mix":if(""===a)switch(i){case"object":Object.keys(t).find((e=>e.includes("/")))?Object.entries(t).forEach((([e,t])=>f[o][e]=t.text)):f[o]=t.text;for(let b=o-1;b>=0;b--)f[b]=e({data:f[b],objectCallback:d});function d({value:e,breadcrumbs:t}){return f[o][t]?f[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 y=p[a]({data:t,...h}),v=s(y);switch(t.forEach(((e,r)=>t.splice(r,1))),t.length=0,v){case"primitive":t[0]=y;break;case"array":t.push(...y)}}}}))}if(f instanceof Array&&1===f.length&&f[0]instanceof Array&&(f=f[0]),null==f[0])return;let y=s(f[0]),v=f[0];switch(y){case"primitive":if(null==v)return;b[o]=v;break;case"object":if(null==v.text)return;b[o]=v.text;break;case"array":const e=s(v[0]);b[o]="object"===e?v.map((e=>e.text)).join(""):v.join("")}}})),i.push(b.join(""))})),"array"===d?i:o?o.reduce(((e,t)=>"function"!=typeof t?e:t(e,m)),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(n){const{TG_PRX:o,TG_SFX:a,TG_SIZE_P:l,TG_SIZE_S:i}=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+l),c=n.indexOf(a),-1==c)return r("missingClosing");if(c<s)return r("closedBeforeOpened");if(c+=i,-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 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(!r.includes("#"))return n.push([t]),{dataDeepLevel:0,nestedData:n};return e({data:t,objectCallback:function({key:e,value:t,breadcrumbs:r}){return e===r?(n[0]=[t],t):(o=r.split("/").length-1,n[o]||(n[o]=[]),n[o].push(t),t)}}),{dataDeepLevel:o,nestedData:n}}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(),l=!1;function i(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:i,pullReverse:function(e=1,t=0){let r=i(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||!l){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=i(a-n))}return t=e instanceof Array?t.concat(e):t.concat([e]),l=!!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||!l){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=i(a-n))}return t=r?e.reduce(((e,t)=>[t,...e]),t):[e].reduce(((e,t)=>[t,...e]),t),l=!!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 l(e){return null==e?"null":"string"==typeof e||"number"==typeof e||"boolean"==typeof e?"primitive":"function"==typeof e?"function":e instanceof Array?"array":e instanceof Object?"object":void 0}function i(e,r,n,...o){e instanceof Object&&Object.entries(e).forEach((([t,r])=>{r instanceof Object&&(e[t]=r.text),r instanceof Array&&(e[t]=r[0])}));const l="function"==typeof n[r];return e=function(e={}){return"string"==typeof e?{text:e}:e}(e),l?n[r](e,...o):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,c={}){const{hasError:u,placeholders:f,chop:p,helpers:d,handshake:h}=function(e){const{template:r,helpers:n={},handshake:o}=e,{TG_PRX:l,TG_SFX:i}=a,s=[],c="string"==typeof r?r.replace(/<!--[\s\S]*?-->/g,"").replace(/\s{2,}/g," "):r;let u=null;const f=t(a)(c);return"string"==typeof f?u=f:f.forEach(((e,t)=>{const r=RegExp(l+"\\s*(.*?)\\s*(?::\\s*(.*?)\\s*)?"+i,"g");if(e.includes(l)){const o=r.exec(e);s.push({index:t,data:(n=o[1],n||null),action:o[2]?o[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:o}}(r);if(u){function y(){return u}return s?[!1,y]:y}{let g=structuredClone(p);function m(t={},r={},...a){const s=[];let u=l(t),p={...c,...r};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=l(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]),"null"===u?g.join(""):(t.forEach((t=>{f.forEach((r=>{const{index:a,data:s,action:c}=r;if(!c&&s){const e=t[s];switch(l(e)){case"function":return void(g[a]=e());case"primitive":return void(g[a]=e);case"array":return void("primitive"===l(e[0])&&(g[a]=e[0]));case"object":return void(e.text&&(g[a]=e.text))}}else{let{dataDeepLevel:r,nestedData:u}=n("@all"===s||null===s||"@root"===s?t:t[s],c),f=o(function(e,t=10){let r={},n=[...e],o=0,a=0,l=0;n.forEach((e=>{"#"===e&&l++})),l<t&&console.error(`Error: Not enough level markers (#) for data with depth level ${t}. Found ${l} level markers in actions: ${e.join(", ")}`);do{r[a]=[],a++}while(a<=t);return n.every((e=>"#"===e?(o++,!(o>t)):e.startsWith("?")?(r[o].push({type:"route",name:e.replace("?",""),level:o}),!0):e.startsWith("+")?(r[o].push({type:"extendedRender",name:e.replace("+",""),level:o}),!0):e.startsWith("[]")?(r[o].push({type:"mix",name:e.replace("[]",""),level:o}),!0):e.startsWith(">")?(r[o].push({type:"data",name:e.replace(">",""),level:o}),!0):(""===e||r[o].push({type:"render",name:e,level:o}),!0))),r}(c,r),r);for(let t of f){let{type:r,name:n,level:o}=t;(u[o]||[]).forEach((t=>{let a=l(t);switch(r){case"route":switch(a){case"array":t.forEach(((e,r)=>{if(null==e)return;const o=l(e),a=d[n](e);null!=a&&("object"===o?t[r].text=i(e,a,d,p):t[r]=i(e,a,d,p))}));break;case"object":t.text=i(t,n,d,p)}break;case"data":switch(a){case"array":t.forEach(((e,r)=>t[r]=e instanceof Function?d[n](e()):d[n](e)));break;case"object":u[o]=[d[n](t)];break;case"function":u[o]=[d[n](t())];break;case"primitive":u[o]=d[n](t)}break;case"render":const s="function"==typeof d[n];switch(a){case"array":s?t.forEach(((e,r)=>{if(null==e)return;const o=l(e),a=d[n](e,p);null==a&&(t[r]=null),"object"===o?e.text=a:t[r]=a})):t.forEach(((e,r)=>{if(null==e)return;const o=l(e),a=i(e,n,d,p);null==a?t[r]=null:"object"===o?e.text=a:t[r]=a}));break;case"function":u[o]=d[n](t(),p);break;case"primitive":u[o]=i(t,n,d,p);break;case"object":s?u[o][0].text=d[n](t,p):t.text=i(t,n,d,p)}break;case"extendedRender":"function"==typeof d[n]&&u[0].forEach(((e,t)=>u[0][t]=d[n](e)));break;case"mix":if(""===n)switch(a){case"object":Object.keys(t).find((e=>e.includes("/")))?Object.entries(t).forEach((([e,t])=>u[o][e]=t.text)):u[o]=t.text;for(let f=o-1;f>=0;f--)u[f]=e({data:u[f],objectCallback:c});function c({value:e,breadcrumbs:t}){return u[o][t]?u[o][t]:e}break;case"array":t.forEach(((e,r)=>{if(r>0){let n=l(e);if(null==e)return;t[0]+="object"===n?`${e.text}`:`${e}`,t.toSpliced(r,1)}else{let r=l(e);if(t[0]="",null===r)return;t[0]="object"===r?`${e.text}`:`${e}`}})),t.length=1}else{let h=d[n](t),y=l(h);switch(t.forEach(((e,r)=>t.splice(r,1))),t.length=0,y){case"primitive":t[0]=h;break;case"array":t.push(...h)}}}}))}if(u instanceof Array&&1===u.length&&u[0]instanceof Array&&(u=u[0]),null==u[0])return;let h=l(u[0]),y=u[0];switch(h){case"primitive":if(null==y)return;g[a]=y;break;case"object":if(null==y.text)return;g[a]=y.text;break;case"array":const e=l(y[0]);g[a]="object"===e?y.map((e=>e.text)).join(""):y.join("")}}})),s.push(g.join(""))})),"array"===u?s:a?a.reduce(((e,t)=>"function"!=typeof t?e:t(e,p)),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,o="default"]=e;if(null==t)return void console.warn(`Warning: Template ${o}/${n} is not added to storage. The template is null.`);let a=t,l=!0;if(c[o]||(c[o]={}),"function"!=typeof t){let e=s(t,!0,...r);l=e[0],a=e[1]}l?c[o][n]=a: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.`}}}));
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:l,TG_SIZE_S:s}=e;let i,c,u,f=[];if("string"!=typeof n)return r("notAString");if(0==n.length)return[];if(i=n.indexOf(a),0<i&&f.push(n.slice(0,i)),-1==i)return f.push(n),f;{if(u=n.indexOf(a,i+l),c=n.indexOf(o),-1==c)return r("missingClosing");if(c<i)return r("closedBeforeOpened");if(c+=s,-1!=u&&u<c)return r("newBeforeClosed");f.push(n.slice(i,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]]};const o=structuredClone(t);if(!r.includes("#"))return n.push([o]),{dataDeepLevel:0,nestedData:n};return e({data:o,objectCallback:function({key:e,value:t,breadcrumbs:r}){return e===r?(n[0]=[t],t):(a=r.split("/").length-1,n[a]||(n[a]=[]),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(),l=!1;function s(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 i(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:s,pullReverse:function(e=1,t=0){let r=s(e,t);return r instanceof Array?r.reverse():r},peek:i,peekReverse:function(e=1,t=0){const r=i(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 i=!1;if("full"!==a||!l){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&&(i=s(o-n))}return t=e instanceof Array?t.concat(e):t.concat([e]),l=!!n&&t.length===n,i||void 0}}:function(e){const r=e instanceof Array,o=r?e.length:1;let i=!1;if("full"!==a||!l){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&&(i=s(o-n))}return t=r?e.reduce(((e,t)=>[t,...e]),t):[e].reduce(((e,t)=>[t,...e]),t),l=!!n&&t.length===n,i||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 l(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,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 l="function"==typeof n[r];return e=function(e={}){return"string"==typeof e?{text:e}:e}(e),l?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 i(r,i=!1,c={}){const{hasError:u,placeholders:f,chop:d,helpers:p,handshake:h}=function(e){const{template:r,helpers:n={},handshake:a}=e,{TG_PRX:l,TG_SFX:s}=o,i=[],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(l+"\\s*(.*?)\\s*(?::\\s*(.*?)\\s*)?"+s,"g");if(e.includes(l)){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||!(!e.startsWith("^")||"^^"===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}}(r);if(u){function m(){return u}return i?[!1,m]:m}{let y=structuredClone(d);function g(t={},r={},...o){const i=[],u={};let d=l(t),m={...c,...r};if(t=e({data:t}),"null"===d)return y.join("");if("string"==typeof t)switch(t){case"raw":return y.join("");case"demo":if(!h)return"Error: No handshake data.";d=l(t=h);break;case"handshake":return h?structuredClone(h):"Error: No handshake data.";case"placeholders":return f.map((e=>y[e.index])).join(", ");default:return`Error: Wrong command "${t}". Available commands: raw, demo, handshake, placeholders.`}return"array"!==d&&(t=[t]),"null"===d?y.join(""):(t.forEach((t=>{f.forEach((r=>{const{index:o,data:i,action:c}=r,f=!c&&i,d=structuredClone(u),h={dependencies:m,memory:d};if(f){const e=t[i];switch(l(e)){case"function":return void(y[o]=e());case"primitive":return void(y[o]=e);case"array":return void("primitive"===l(e[0])&&(y[o]=e[0]));case"object":return void(e.text&&(y[o]=e.text))}}else{let{dataDeepLevel:r,nestedData:f}=n("@all"===i||null===i||"@root"===i?t:t[i],c),d=a(function(e,t=10){let r={},n=[...e],a=0,o=0,l=0;n.forEach((e=>{"#"===e&&l++})),l<t&&console.error(`Error: Not enough level markers (#) for data with depth level ${t}. Found ${l} level markers in actions: ${e.join(", ")}`);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("^")&&"^^"!==e?(r[a].push({type:"save",name:e.replace("^",""),level:a}),!0):"^^"===e?(r[a].push({type:"overwrite",name:"none",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}(c,r),r);for(let r of d){let{type:n,name:a,level:o}=r;(f[o]||[]).forEach((r=>{let i=l(r);switch(n){case"route":switch(i){case"array":r.forEach(((e,t)=>{if(null==e)return;const n=l(e),o=p[a]({data:e,...h});null!=o&&("object"===n?r[t].text=s(e,o,p,m):r[t]=s(e,o,p,m))}));break;case"object":r.text=s(r,a,p,m)}break;case"save":u[a]=structuredClone(r);break;case"overwrite":t=structuredClone(r);break;case"data":switch(i){case"array":r.forEach(((e,t)=>r[t]=e instanceof Function?p[a]({data:e(),...h}):p[a]({data:e,...h})));break;case"object":f[o]=[p[a]({data:r,...h})];break;case"function":f[o]=[p[a]({data:r(),...h})];break;case"primitive":f[o]=p[a]({data:r,...h})}break;case"render":const c="function"==typeof p[a];switch(i){case"array":c?r.forEach(((e,t)=>{if(null==e)return;const n=l(e),o=p[a]({data:e,...h});null==o&&(r[t]=null),"object"===n?e.text=o:r[t]=o})):r.forEach(((e,t)=>{if(null==e)return;const n=l(e),o=s(e,a,p,m);null==o?r[t]=null:"object"===n?e.text=o:r[t]=o}));break;case"function":f[o]=p[a]({data:r(),...h});break;case"primitive":f[o]=s(r,a,p,m);break;case"object":c?f[o][0].text=p[a]({data:r,...h}):r.text=s(r,a,p,m)}break;case"extendedRender":"function"==typeof p[a]&&f[0].forEach(((e,t)=>f[0][t]=p[a]({data:e,...h})));break;case"mix":if(""===a)switch(i){case"object":Object.keys(r).find((e=>e.includes("/")))?Object.entries(r).forEach((([e,t])=>f[o][e]=t.text)):f[o]=r.text;for(let y=o-1;y>=0;y--)f[y]=e({data:f[y],objectCallback:d});function d({value:e,breadcrumbs:t}){return f[o][t]?f[o][t]:e}break;case"array":r.forEach(((e,t)=>{if(t>0){let n=l(e);if(null==e)return;r[0]+="object"===n?`${e.text}`:`${e}`,r.toSpliced(t,1)}else{let t=l(e);if(r[0]="",null===t)return;r[0]="object"===t?`${e.text}`:`${e}`}})),r.length=1}else{let g=p[a]({data:r,...h}),b=l(g);switch(r.forEach(((e,t)=>r.splice(t,1))),r.length=0,b){case"primitive":r[0]=g;break;case"array":r.push(...g)}}}}))}if(f instanceof Array&&1===f.length&&f[0]instanceof Array&&(f=f[0]),null==f[0])return;let g=l(f[0]),b=f[0];switch(g){case"primitive":if(null==b)return;y[o]=b;break;case"object":if(null==b.text)return;y[o]=b.text;break;case"array":const e=l(b[0]);y[o]="object"===e?b.map((e=>e.text)).join(""):b.join("")}}})),i.push(y.join(""))})),"array"===d?i:o?o.reduce(((e,t)=>"function"!=typeof t?e:t(e,m)),i.join("")):i.join(""))}return i?[!0,g]:g}}const c={default:{}};return{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 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,l=!0;if(c[a]||(c[a]={}),"function"!=typeof t){let e=i(t,!0,...r);l=e[0],o=e[1]}l?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.2.3",
4
+ "version": "2.0.0",
5
5
  "license": "MIT",
6
6
  "author": "Peter Naydenov",
7
7
  "main": "./src/main.js",
@@ -33,7 +33,7 @@
33
33
  "c8": "^10.1.3",
34
34
  "chai": "5.2.0",
35
35
  "mocha": "11.1.0",
36
- "rollup": "^4.35.0"
36
+ "rollup": "^4.37.0"
37
37
  },
38
38
  "repository": {
39
39
  "type": "git",
@@ -2,22 +2,22 @@ import walk from '@peter.naydenov/walk'
2
2
 
3
3
 
4
4
 
5
- function _defineData ( d, action ) {
5
+ function _defineData ( dSource, action ) {
6
6
  const nestedData = [];
7
7
  let dataDeepLevel = 0;
8
8
 
9
- if ( d instanceof Function ) return { dataDeepLevel:0, nestedData:[[d()]] }
10
- if ( d == null ) return { dataDeepLevel:0, nestedData:[ null ] }
11
- if ( typeof d === 'string' ) return { dataDeepLevel:0, nestedData:[[d]] }
9
+ if ( dSource instanceof Function ) return { dataDeepLevel:0, nestedData:[[dSource()]] }
10
+ if ( dSource == null ) return { dataDeepLevel:0, nestedData:[ null ] }
11
+ if ( typeof dSource === 'string' ) return { dataDeepLevel:0, nestedData:[[dSource]] }
12
+
13
+ const d = structuredClone ( dSource )
12
14
 
13
15
  // Note: Nest data only if action has '#'
14
16
  if ( !action.includes('#') ) {
15
17
  nestedData.push ( [d] )
16
18
  return { dataDeepLevel:0, nestedData }
17
19
  }
18
-
19
- // nestedData[0] = [d]
20
-
20
+
21
21
  function findObjects ({key, value, breadcrumbs}) {
22
22
  if ( key === breadcrumbs ) {
23
23
  nestedData[0] = [ value ]
@@ -52,13 +52,15 @@ function _readTemplate ( tpl ) {
52
52
  placeholders.forEach ( holder => {
53
53
  if ( !holder.action ) return
54
54
  holder.action.every ( act => {
55
- if ( act === '#' ) return true
55
+ if ( act === '#' ) return true
56
+ if ( act === '^^' ) return true
57
+ if ( act.startsWith('^') && act !== '^^' ) return true
56
58
  if ( act.startsWith ( '?' )) act = act.replace ( '?', '' )
57
59
  if ( act.startsWith ( '+' )) act = act.replace ( '+', '' )
58
60
  if ( act.startsWith ( '[]' )) act = act.replace ( '[]', '' )
59
61
  if ( act.startsWith ( '>' )) act = act.replace ( '>', '' )
60
- if ( act === '' ) return true
61
- if ( helpers[act] ) return true
62
+ if ( act === '' ) return true
63
+ if ( helpers[act] ) return true
62
64
  else {
63
65
  hasError = `Error: Missing helper: ${act}`
64
66
  return false
@@ -31,6 +31,22 @@ function _setupActions ( actions, dataDeepLevel=10 ) {
31
31
  })
32
32
  return true
33
33
  }
34
+ if ( act.startsWith ('^') && act !== '^^' ) {
35
+ actSetup[actLevel].push ({
36
+ type: 'save'
37
+ , name: act.replace ( '^', '' )
38
+ , level: actLevel
39
+ })
40
+ return true
41
+ }
42
+ if ( act === '^^') {
43
+ actSetup[actLevel].push ({
44
+ type: 'overwrite'
45
+ , name : 'none'
46
+ , level: actLevel
47
+ })
48
+ return true
49
+ }
34
50
  if ( act.startsWith ( '+' ) ) { // it's a extended render action
35
51
  actSetup[actLevel].push ({
36
52
  type: 'extendedRender'
@@ -60,9 +60,10 @@ function build ( tpl, extra=false, buildDependencies={} ) {
60
60
  */
61
61
  function success ( d={}, dependencies={}, ...args ) {
62
62
  const endData = [];
63
+ const memory = {};
63
64
  let topLevelType = _defineDataType ( d );
64
65
  let deps = { ...buildDependencies, ...dependencies }
65
- d = walk ({data:d})
66
+ d = walk ({data:d}) // Creates copy of data to avoid mutation of the original
66
67
 
67
68
  if ( topLevelType === 'null' ) return cuts.join ( '' )
68
69
  // Commands : raw, demo, handshake, placeholders
@@ -94,7 +95,9 @@ function build ( tpl, extra=false, buildDependencies={} ) {
94
95
  placeholders.forEach ( holder => { // Placeholders
95
96
  const
96
97
  { index, data, action } = holder // index - placeholder index, data - key of data, action - list of operations
97
- , dataOnly = !action && data
98
+ , dataOnly = !action && data
99
+ , mem = structuredClone ( memory )
100
+ , extendArguments = { dependencies: deps, memory:mem }
98
101
  ;
99
102
 
100
103
  if ( dataOnly ) {
@@ -132,6 +135,7 @@ function build ( tpl, extra=false, buildDependencies={} ) {
132
135
  levelData.forEach ( theData => {
133
136
  let dataType = _defineDataType ( theData )
134
137
 
138
+
135
139
  switch ( type ) { // Action type 'route','data', 'render', or mix -> different operations
136
140
  case 'route':
137
141
  switch ( dataType ) {
@@ -139,7 +143,7 @@ function build ( tpl, extra=false, buildDependencies={} ) {
139
143
  theData.forEach ( (d,i) => {
140
144
  if ( d == null ) return
141
145
  const dType = _defineDataType ( d )
142
- const routeName = helpers[name]( d );
146
+ const routeName = helpers[name]( {data:d, ...extendArguments});
143
147
  if ( routeName == null ) return
144
148
  if ( dType === 'object' ) theData[i]['text'] = render ( d, routeName, helpers, deps )
145
149
  else theData[i] = render ( d, routeName, helpers, deps )
@@ -149,33 +153,38 @@ function build ( tpl, extra=false, buildDependencies={} ) {
149
153
  theData['text'] = render ( theData, name, helpers, deps )
150
154
  break
151
155
  }
152
- break
153
- case 'data':
156
+ break
157
+ case 'save' :
158
+ memory[name] = structuredClone ( theData )
159
+ break
160
+ case 'overwrite':
161
+ dElement = structuredClone ( theData )
162
+ break
163
+ case 'data':
154
164
  switch ( dataType ) {
155
165
  case 'array':
156
- theData.forEach ( (d,i) => theData[i] = ( d instanceof Function ) ? helpers[name]( d() ) : helpers[name]( d ) )
166
+ theData.forEach ( (d,i) => theData[i] = ( d instanceof Function ) ? helpers[name]({ data:d(), ...extendArguments }) : helpers[name]( {data:d, ...extendArguments} ) )
157
167
  break
158
168
  case 'object':
159
- nestedData[level] = [helpers[name]( theData )]
169
+ nestedData[level] = [helpers[name]( {data:theData,...extendArguments} )]
160
170
  break
161
171
  case 'function':
162
- nestedData[level] = [helpers[name]( theData() )]
172
+ nestedData[level] = [helpers[name]( {data:theData(),...extendArguments} )]
163
173
  break
164
174
  case 'primitive':
165
- nestedData[level] = helpers[name]( theData )
175
+ nestedData[level] = helpers[name]( {data:theData,...extendArguments} )
166
176
  break
167
177
  } // switch dataType
168
178
 
169
179
  break
170
180
  case 'render':
171
181
  const isRenderFunction = typeof helpers[name] === 'function'; // Render could be a function and template.
172
-
173
182
  switch ( dataType ) {
174
183
  case 'array':
175
184
  if ( isRenderFunction ) theData.forEach ( (d,i) => {
176
185
  if ( d == null ) return
177
186
  const dType = _defineDataType ( d );
178
- const text = helpers[name]( d, deps );
187
+ const text = helpers[name]( {data:d, ...extendArguments} );
179
188
 
180
189
  if ( text == null ) theData[i] = null
181
190
  if ( dType === 'object' ) d['text'] = text
@@ -183,8 +192,6 @@ function build ( tpl, extra=false, buildDependencies={} ) {
183
192
  })
184
193
  else theData.forEach ( (d,i) => {
185
194
  if ( d == null ) return
186
-
187
-
188
195
  const
189
196
  dType = _defineDataType ( d )
190
197
  , text = render ( d, name, helpers, deps )
@@ -195,13 +202,13 @@ function build ( tpl, extra=false, buildDependencies={} ) {
195
202
  })
196
203
  break
197
204
  case 'function':
198
- nestedData[level] = helpers[name]( theData(), deps )
205
+ nestedData[level] = helpers[name]( {data:theData(), ...extendArguments} )
199
206
  break
200
207
  case 'primitive':
201
208
  nestedData[level] = render ( theData, name, helpers, deps )
202
209
  break
203
210
  case 'object':
204
- if ( isRenderFunction ) nestedData[level][0]['text'] = helpers[name]( theData, deps )
211
+ if ( isRenderFunction ) nestedData[level][0]['text'] = helpers[name]({ data:theData, ...extendArguments} )
205
212
  else {
206
213
  theData [ 'text' ] = render ( theData, name, helpers, deps )
207
214
  }
@@ -212,7 +219,7 @@ function build ( tpl, extra=false, buildDependencies={} ) {
212
219
  // TODO: Test extendedRender
213
220
  const isValid = typeof helpers[name] === 'function'; // Render could be a function and template.
214
221
  if ( isValid ) {
215
- nestedData[0].forEach ( (d,i) => nestedData[0][i] = helpers[name]( d ) )
222
+ nestedData[0].forEach ( (d,i) => nestedData[0][i] = helpers[name]( {data:d, ...extendArguments} ) )
216
223
  }
217
224
  else {
218
225
  // TODO: Error...
@@ -256,7 +263,7 @@ function build ( tpl, extra=false, buildDependencies={} ) {
256
263
  } // if name === ''
257
264
  else {
258
265
  let
259
- val = helpers[name]( theData )
266
+ val = helpers[name]({ data:theData, ...extendArguments })
260
267
  , valType = _defineDataType ( val )
261
268
  ;
262
269