vaderjs 1.2.6 → 1.2.8

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/vader.js CHANGED
@@ -6,7 +6,8 @@ let states = {};
6
6
  * @description Allows you to convert markdown to html
7
7
  */
8
8
  function markdown(content) {
9
- const lines = content.split('\n');
9
+ const lines = content.split('\n').filter((line) => line !== '').map((line) => line.trim());
10
+
10
11
  let result = '';
11
12
 
12
13
  lines.forEach((line) => {
@@ -16,7 +17,8 @@ function markdown(content) {
16
17
 
17
18
  let link = line.match(/\[(.*?)\]\((.*?)\)/g);
18
19
  let ul = line.match(/^\-\s/);
19
- let ol = line.match(/^\d\.\s/);
20
+ let ol = line.match(/^\d\.\s/);
21
+
20
22
  let li = line.match(/^\s/);
21
23
  let hr = line.match(/^\-\-\-\s/);
22
24
  let blockquote = line.match(/^\>\s/);
@@ -25,6 +27,8 @@ function markdown(content) {
25
27
 
26
28
  let codeBlock = line.match(/\`\`\`/g);
27
29
  let codeBlockEnd = line.match(/\`\`\`/g);
30
+ let code = line.match(/\`(.*?)\`/g);
31
+
28
32
 
29
33
 
30
34
  if (heading) {
@@ -35,12 +39,16 @@ function markdown(content) {
35
39
  }
36
40
  if (bold) {
37
41
  bold.forEach((b) => {
38
- line = line.replace(b, `<strong>${b.replace(/\*\*/g, "")}</strong>`);
42
+ line = line.replace(b, `<strong
43
+ className="$vader_markdown_bold"
44
+ >${b.replace(/\*\*/g, "")}</strong>`);
39
45
  });
40
46
  }
41
47
  if (italic) {
42
48
  italic.forEach((i) => {
43
- line = line.replace(i, `<em>${i.replace(/\*/g, "")}</em>`);
49
+ line = line.replace(i, `<em
50
+ className="$vader_markdown_italic"
51
+ >${i.replace(/\*/g, "")}</em>`);
44
52
  });
45
53
  }
46
54
 
@@ -51,26 +59,30 @@ function markdown(content) {
51
59
  let text = l.match(/\[(.*?)\]/g)[0].replace(/\[|\]/g, "");
52
60
  // @ts-ignore
53
61
  let href = l.match(/\((.*?)\)/g)[0].replace(/\(|\)/g, "");
54
- line = line.replace(l, `<a href="${href}">${text}</a>`);
62
+ line = line.replace(l, `<a
63
+ className="$vader_markdown_link"
64
+ href="${href}">${text}</a>`);
55
65
  });
56
66
  }
57
67
  if (ul) {
58
68
  line = line.replace(ul[0], `<li
59
- style="list-style-type: disc;"
60
- >`);
69
+ className="$vader_markdown_ul"
70
+ style="list-style-type: disc;">`);
61
71
  line += `</li>`;
62
72
  }
63
73
  if (ol) {
64
- line = line.replace(ol[0], `<li
65
- style="list-style-type: decimal;"
66
- >`);
74
+ line = line.replace(ol[0], `<li
75
+ className="$vader_markdown_ol"
76
+ style="list-style-type: decimal;">`);
67
77
  line += `</li>`;
68
78
  }
69
79
  if (hr) {
70
80
  line = line.replace(hr[0], `<hr/>`);
71
81
  }
72
82
  if (blockquote) {
73
- line = line.replace(blockquote[0], `<blockquote>`);
83
+ line = line.replace(blockquote[0], `<blockquote
84
+ className="$vader_markdown_blockquote"
85
+ >`);
74
86
  line += `</blockquote>`;
75
87
  }
76
88
  if (image) {
@@ -80,18 +92,32 @@ function markdown(content) {
80
92
  // @ts-ignore
81
93
  let src = i.match(/\((.*?)\)/g)[0].replace(/\(|\)/g, "");
82
94
  i.replace(i, `<img src="${src}" alt="${alt}"/>`);
83
- line = line.replace(i, `<img src="${src}" alt="${alt}"/>`).replace('!','')
95
+ line = line.replace(i, `<img
96
+ className="$vader_markdown_image"
97
+ src="${src}" alt="${alt}"/>`).replace('!','')
84
98
  });
85
99
  }
86
- if(codeBlock){
87
- line = line.replace(codeBlock[0], `<code>`);
88
-
100
+ if (li) {
101
+ line = line.replace(li[0], `<li>`);
102
+ line += `</li>`;
103
+ }
104
+ if (codeBlock) {
105
+ line = line.replace(codeBlock[0], `<pre className="$vader_markdown_code_block" ><code>`);
89
106
  }
90
- if(codeBlockEnd){
91
- line = line.replace(codeBlockEnd[0], `</code>`);
92
- // remove spaces
93
- line = line.replace(/^\s+/g, '');
107
+ if (codeBlockEnd) {
108
+ line = line.replace(codeBlockEnd[0], `</code></pre>`);
94
109
  }
110
+
111
+ if (code) {
112
+ code.forEach((c) => {
113
+ line = line.replace(c, `<code
114
+ className="$vader_markdown_code"
115
+ style="background-color: #f5f5f5; padding: 5px; border-radius: 5px;
116
+ "
117
+ >${c.replace(/\`/g, "")}</code>`);
118
+ });
119
+ }
120
+
95
121
 
96
122
 
97
123
 
@@ -182,6 +208,19 @@ export class Component {
182
208
  });
183
209
  this.snapshots = [];
184
210
 
211
+ /**
212
+ * @property {Boolean} cfr
213
+ * @description Allows you to compile html code on the fly - client fly rendering
214
+ *
215
+ */
216
+ this.cfr = false
217
+ /**
218
+ * @property {Boolean} worker
219
+ * @description Allows you to use a web worker to compile html code on the fly - client fly rendering
220
+
221
+ */
222
+ // @ts-ignore
223
+ this.worker = new Worker(new URL('./worker.js', import.meta.url));
185
224
  }
186
225
 
187
226
  /**
@@ -195,6 +234,7 @@ export class Component {
195
234
  }
196
235
  init() {
197
236
  this.registerComponent();
237
+
198
238
  }
199
239
 
200
240
  registerComponent() {
@@ -763,88 +803,11 @@ export class Component {
763
803
  return /^[a-zA-Z0-9-_]+$/.test(className);
764
804
  }
765
805
 
766
- /**
767
- * The `html` method generates and processes HTML content for a component, performing various validations and tasks.
768
- *
769
- * @param {String} strings - The HTML content to be processed.
770
- * @param {...any} args - Dynamic values to be inserted into the template.
771
- * @returns {string} - The processed HTML content as a string.
772
- *
773
- * @throws {SyntaxError} - Throws a `SyntaxError` if image-related attributes are missing or invalid.
774
- * @throws {Error} - Throws an `Error` if there are issues with class names or relative paths.
775
- *
776
- * @example
777
- * // Example usage within a component:
778
- * const myComponent = new Component();
779
- * const htmlContent = myComponent.html`
780
- * <div>
781
- * <img src="/images/example.jpg" alt="Example Image" />
782
- * </div>
783
- * `;
784
- * document.body.innerHTML = htmlContent;
785
- *
786
- * @remarks
787
- * The `html` method is a core function used in component rendering. It allows you to define and generate HTML content within your component while enforcing best practices and accessibility standards. The method performs several essential tasks:
788
- *
789
- * 1. **Image Validation**: It checks images for the presence of 'alt' attributes and their validity.
790
- * - Throws a `SyntaxError` if an image is missing the 'alt' attribute.
791
- * - Throws a `SyntaxError` if the 'alt' attribute is empty.
792
- * - Checks for an 'aria-hidden' attribute for image elements.
793
- *
794
- * 2. **Class Attribute Handling**: It enforces class attribute usage and allows optional configuration via comments.
795
- * - Throws an `Error` if 'class' attributes are used without permission.
796
- * - Supports 'className' attributes for class definitions.
797
- * - Allows or disallows class-related comments based on your configuration.
798
- *
799
- * 3. **Relative Path Handling**: It processes relative paths in 'href' and 'src' attributes, ensuring proper routing.
800
- * - Converts relative 'href' attributes to anchor links with appropriate routing.
801
- * - Converts relative 'src' attributes to absolute paths with 'public' directories.
802
- *
803
- * 4. **Custom Component Attributes**: It supports adding a 'data-component' attribute to the root element.
804
- * - Ensures that the 'data-component' attribute is present for component identification.
805
- *
806
- * 5. **Lifecycle Method Invocation**: It invokes the `componentDidMount` method if called from a 'render' context.
807
- * - Executes `componentDidMount` to handle component initialization once the DOM is ready.
808
- *
809
- * @see {@link Component}
810
- * @see {@link Component#componentDidMount}
811
- */
812
-
813
- html(strings, ...args) {
814
- // @ts-ignore
815
- if (
816
- // @ts-ignore
817
- new Error().stack &&
818
- // @ts-ignore
819
- new Error().stack.split("\n").length > 0 &&
820
- // @ts-ignore
821
- new Error().stack.split("\n")[2] &&
822
- // @ts-ignore
823
- new Error().stack.split("\n")[2].includes("render") &&
824
- !this.componentMounted
825
- ) {
826
- this.componentMounted = true;
827
- this.componentDidMount();
828
- console.log("component mounted");
829
- }
830
-
831
- let result = "";
832
- for (let i = 0; i < strings.length; i++) {
833
- result += strings[i];
834
- if (i < args.length) {
835
- result += args[i];
836
- }
837
- }
838
-
839
- result = new Function("useRef", `return \`${result}\``)(useRef)
840
806
 
841
- if (!result.trim().startsWith("<body>")) {
842
- console.warn(
843
- "You should wrap your html in a body tag, vader may not grab all html!"
844
- );
845
- }
846
-
807
+ parseHTML(result) {
808
+
847
809
  const dom = new DOMParser().parseFromString(result, "text/html");
810
+ console.log(dom)
848
811
  const elements = dom.documentElement.querySelectorAll("*");
849
812
 
850
813
  elements.forEach((element) => {
@@ -883,6 +846,7 @@ export class Component {
883
846
  element.setAttribute("hidden", "true");
884
847
  // if window.lcoation.pathname includes a html file remove it and only use the path
885
848
  let url = window.location.origin + window.location.pathname.replace(/\/[^\/]*$/, '') + '/public/' + element.getAttribute("src");
849
+ // @ts-ignore
886
850
  let image = new Image();
887
851
  image.src = url;
888
852
  image.onerror = () => {
@@ -925,27 +889,6 @@ export class Component {
925
889
  );
926
890
  }
927
891
  } else if (element.hasAttribute("className")) {
928
- const isLocalhost = window.location.href.includes("localhost");
929
- const is127001 = window.location.href.includes("127.0.0.1");
930
- const ignoreClassComments = document.documentElement.outerHTML
931
- .trim()
932
- .includes("<!-- #vader-class-ignore -->");
933
- const allowClassComments = document.documentElement.outerHTML
934
- .trim()
935
- .includes("<!-- #vader-allow_class -->");
936
-
937
- if (
938
- // @ts-ignore
939
- (!this.validateClassName(element.getAttribute("className")) &&
940
- isLocalhost) ||
941
- (is127001 && !ignoreClassComments && !allowClassComments)
942
- ) {
943
- throw new Error(
944
- `Invalid className ${element.getAttribute(
945
- "className"
946
- )}, please use camelCase instead - example: myClass`
947
- );
948
- }
949
892
  // @ts-ignore
950
893
  element.setAttribute("class", element.getAttribute("className"));
951
894
  element.removeAttribute("className");
@@ -982,6 +925,7 @@ export class Component {
982
925
  }
983
926
  break;
984
927
  }
928
+
985
929
  });
986
930
 
987
931
  result = dom.body.innerHTML;
@@ -989,12 +933,128 @@ export class Component {
989
933
  this.Componentcontent = result;
990
934
 
991
935
  if (!result.includes("<div data-component")) {
992
- result = `<div
993
-
994
- data-component="${this.name}">${result}</div>`;
936
+ result = `<div data-component="${this.name}">${result}</div>`;
937
+ }
938
+ return markdown(result.replace(/\\n/g, '\n').trim())
939
+
940
+ }
941
+
942
+ /**
943
+ * The `html` method generates and processes HTML content for a component, performing various validations and tasks.
944
+ *
945
+ * @param {String} strings - The HTML content to be processed.
946
+ * @param {...any} args - Dynamic values to be inserted into the template.
947
+ * @returns {string} - The processed HTML content as a string.
948
+ *
949
+ * @throws {SyntaxError} - Throws a `SyntaxError` if image-related attributes are missing or invalid.
950
+ * @throws {Error} - Throws an `Error` if there are issues with class names or relative paths.
951
+ *
952
+ * @example
953
+ * // Example usage within a component:
954
+ * const myComponent = new Component();
955
+ * const htmlContent = myComponent.html`
956
+ * <div>
957
+ * <img src="/images/example.jpg" alt="Example Image" />
958
+ * </div>
959
+ * `;
960
+ * document.body.innerHTML = htmlContent;
961
+ *
962
+ * @remarks
963
+ * The `html` method is a core function used in component rendering. It allows you to define and generate HTML content within your component while enforcing best practices and accessibility standards. The method performs several essential tasks:
964
+ *
965
+ * 1. **Image Validation**: It checks images for the presence of 'alt' attributes and their validity.
966
+ * - Throws a `SyntaxError` if an image is missing the 'alt' attribute.
967
+ * - Throws a `SyntaxError` if the 'alt' attribute is empty.
968
+ * - Checks for an 'aria-hidden' attribute for image elements.
969
+ *
970
+ * 2. **Class Attribute Handling**: It enforces class attribute usage and allows optional configuration via comments.
971
+ * - Throws an `Error` if 'class' attributes are used without permission.
972
+ * - Supports 'className' attributes for class definitions.
973
+ * - Allows or disallows class-related comments based on your configuration.
974
+ *
975
+ * 3. **Relative Path Handling**: It processes relative paths in 'href' and 'src' attributes, ensuring proper routing.
976
+ * - Converts relative 'href' attributes to anchor links with appropriate routing.
977
+ * - Converts relative 'src' attributes to absolute paths with 'public' directories.
978
+ *
979
+ * 4. **Custom Component Attributes**: It supports adding a 'data-component' attribute to the root element.
980
+ * - Ensures that the 'data-component' attribute is present for component identification.
981
+ *
982
+ * 5. **Lifecycle Method Invocation**: It invokes the `componentDidMount` method if called from a 'render' context.
983
+ * - Executes `componentDidMount` to handle component initialization once the DOM is ready.
984
+ *
985
+ * @see {@link Component}
986
+ * @see {@link Component#componentDidMount}
987
+ */
988
+
989
+
990
+
991
+ html(strings, ...args) {
992
+ // @ts-ignore
993
+ if (
994
+ // @ts-ignore
995
+ new Error().stack &&
996
+ // @ts-ignore
997
+ new Error().stack.split("\n").length > 0 &&
998
+ // @ts-ignore
999
+ new Error().stack.split("\n")[2] &&
1000
+ // @ts-ignore
1001
+ new Error().stack.split("\n")[2].includes("render") &&
1002
+ !this.componentMounted
1003
+ ) {
1004
+ this.componentMounted = true;
1005
+ this.componentDidMount();
995
1006
  }
996
1007
 
997
- return result;
1008
+
1009
+ if(this.cfr){
1010
+
1011
+ this.worker.postMessage({strings, args, location: window.location.href, name: this.name})
1012
+ let promise = new Promise((resolve, reject)=>{
1013
+ this.worker.onmessage = (e)=>{
1014
+ if(e.data.error){
1015
+ throw new Error(e.data.error)
1016
+ }
1017
+
1018
+ let d = ""
1019
+ if(new Function("useRef", `return \`${e.data}\``)(useRef).includes('#')){
1020
+ d = markdown(new Function("useRef", `return \`${e.data}\``)(useRef))
1021
+ }else{
1022
+ d = new Function("useRef", `return \`${e.data}\``)(useRef)
1023
+ }
1024
+
1025
+ resolve(d)
1026
+
1027
+
1028
+
1029
+ }
1030
+ this.worker.onerror = (e)=>{
1031
+ reject(e)
1032
+ }
1033
+ })
1034
+ // @ts-ignore
1035
+ return promise;
1036
+ }else{
1037
+ let result = "";
1038
+ for (let i = 0; i < strings.length; i++) {
1039
+ result += strings[i];
1040
+ if (i < args.length) {
1041
+ result += args[i];
1042
+ }
1043
+ }
1044
+ result = new Function("useRef", `return \`${result}\``)(useRef)
1045
+
1046
+ if (!result.trim().startsWith("<body>")) {
1047
+ console.warn(
1048
+ "You should wrap your html in a body tag, vader may not grab all html!"
1049
+ );
1050
+ }
1051
+
1052
+
1053
+
1054
+ return this.parseHTML(result);
1055
+ }
1056
+
1057
+
998
1058
  }
999
1059
  // write types to ensure it returns a string
1000
1060
  /**
@@ -1101,39 +1161,80 @@ export const include = async (path) => {
1101
1161
  return res.text();
1102
1162
  })
1103
1163
  .then(async (data) => {
1104
- // Handle includes
1105
- let includes = data.match(/<include src="(.*)"\/>/g);
1106
- if (includes) {
1107
-
1108
- const includePromises = includes.map((e) => {
1164
+ data = new Function(`return \`${data}\`;`)();
1165
+
1166
+ let dom = new DOMParser().parseFromString(data, "text/html");
1167
+ let elements = dom.documentElement.querySelectorAll("*");
1168
+ let conccurentIncludes = [];
1169
+ if(cache[path]){
1170
+ return new Function(`return \`${cache[path]}\`;`)();
1171
+ }
1172
+ if (elements.length > 0) {
1173
+ for (var i = 0; i < elements.length; i++) {
1109
1174
 
1110
- // @ts-ignore
1111
- let includePath = e.match(/<include src="(.*)"\/>/)[1];
1175
+ if (elements[i].nodeName === "INCLUDE") {
1176
+ if(!elements[i].getAttribute("src") || elements[i].getAttribute("src") === ""){
1177
+ throw new Error("Include tag must have src attribute")
1178
+ }
1179
+
1180
+ let componentName = elements[i].getAttribute("src")?.split("/").pop()?.split(".")[0]
1181
+ // @ts-ignore
1182
+ let filedata = await include(elements[i].getAttribute("src"));
1183
+ filedata = new Function(`return \`${filedata}\`;`)();
1184
+ let newdom = new DOMParser().parseFromString(filedata, "text/html");
1112
1185
 
1113
- if (
1114
- includePath.startsWith("/") &&
1115
- !document.documentElement.outerHTML
1116
- .trim()
1117
- .includes("<!-- #vader-disable_relative-paths -->")
1118
- ) {
1119
- includePath = "/src" + includePath;
1120
- }
1121
- return include(includePath).then((includeData) => {
1122
- data = data.replace(e, includeData);
1123
- console.log("included", includePath);
1124
- });
1125
- });
1186
+ newdom.querySelectorAll("include").forEach((el)=>{
1187
+ el.remove()
1188
+ })
1189
+ // @ts-ignore
1190
+
1191
+ let els = dom.querySelectorAll(componentName)
1192
+
1193
+ els.forEach((el)=>{
1194
+
1195
+ console.log(el)
1196
+ if(el.attributes.length > 0){
1197
+ for(var i = 0; i < el.attributes.length; i++){
1198
+ newdom.body.outerHTML = newdom.body.outerHTML.replace(`{{${el.attributes[i].name}}}`, el.attributes[i].value)
1199
+ }
1200
+
1201
+ }
1202
+ if(el.children.length > 0 && newdom.body.querySelector('slot')){
1203
+ for(var i = 0; i < el.children.length; i++){
1204
+ let slots = newdom.body.querySelectorAll("slot")
1205
+ slots.forEach((slot)=>{
1206
+ let id = slot.getAttribute("id")
1207
+ if(id === el.nodeName.toLowerCase()){
1208
+ slot.outerHTML = `<div>${el.innerHTML}</div>`
1209
+ }
1210
+ })
1211
+
1212
+
1213
+ }
1214
+
1215
+ }
1126
1216
 
1127
- // Wait for all includes to be fetched and replaced
1128
- return Promise.all(includePromises).then(() => {
1129
- cache[path] = data;
1217
+ dom.body.querySelectorAll('include').forEach((el)=>{
1218
+ el.remove()
1219
+ })
1220
+
1221
+ dom.body.outerHTML = dom.body.outerHTML.replace(el.outerHTML, newdom.body.innerHTML)
1222
+
1223
+
1224
+ })
1225
+
1130
1226
 
1131
- return data
1132
- });
1133
- } else {
1134
- cache[path] = data;
1135
- return data;
1227
+
1228
+
1229
+ }
1230
+ }
1231
+
1232
+
1136
1233
  }
1234
+
1235
+ data = dom.body.outerHTML
1236
+
1237
+ return data;
1137
1238
  });
1138
1239
  };
1139
1240
 
package/worker.js ADDED
@@ -0,0 +1,106 @@
1
+ onmessage = (e)=>{
2
+ let time_started = Date.now()
3
+ let strings = e.data.strings
4
+ let args = e.data.args
5
+ let l = e.data.location.split('/#/')[0]
6
+ let result = "";
7
+ for (let i = 0; i < strings.length; i++) {
8
+ result += strings[i];
9
+ if (i < args.length) {
10
+ result += args[i];
11
+ }
12
+ }
13
+
14
+ let comments = result.match(/--([^>]*)--/gs)
15
+ if(comments){
16
+ while(comments.length){
17
+ let comment = comments.pop()
18
+ console.log(comment)
19
+ // @ts-ignore
20
+ result = result.replace(comment,'')
21
+ }
22
+ }
23
+
24
+ let code = result.match(/<code([^>]*)>/g)
25
+ if(code){
26
+ while(code.length){
27
+ let c = code.pop()
28
+ // @ts-ignore
29
+ c = c.replace('<code','').replace('>','')
30
+ result = result.replace(`<code${c}>`,`<code${c} style="background:#000;color:#fff;padding:5px;border-radius:5px;font-size:12px;font-weight:bold">`)
31
+ }
32
+ }
33
+
34
+
35
+ if(!result.includes('<body>')){
36
+ throw new Error(`Vader Error: You must enclose your html in a body tag for all components. \n\n${result}`)
37
+ }
38
+ /**
39
+ * @type {string[]}
40
+ * @description - grabbing all className attributes and replace them with class
41
+ */
42
+ // @ts-ignore
43
+ result = result.replace(/classname/g,'class')
44
+ /**
45
+ * @type {string[]}
46
+ * @description - grabbing all image tags and replace the src attribute with the absolute path
47
+ */
48
+ // @ts-ignore
49
+ let images = result.match(/<img([^>]*)>/g)
50
+ for(let i = 0; i < images.length; i++){
51
+ let image = images[i]
52
+ let src = image.match(/src="([^"]*)"/)
53
+ let alt = image.match(/alt="([^"]*)"/)
54
+ if(src){
55
+ if(!src[1].includes('http') || !result.includes('<!-- #vader-disable_relative-paths -->')){
56
+ result = result.replace(src[0],`src="${l}/public/${src[1]}"`)
57
+ }else{
58
+ throw new Error(`Vader Error: You cannot use relative paths in the src attribute of ${src[0]}. Use absolute paths instead. \n\n${src[0]}`)
59
+ }
60
+ }
61
+ if(!alt && !result.includes('<!-- #vader-disable_accessibility -->')){
62
+ throw new Error(`Vader Error: You must include an alt attribute in the image tag \n\n${image} of class ${e.data.name}. `)
63
+ }
64
+
65
+ // @ts-ignore
66
+ if(!caches.match(`${l}/public/${src[1]}`)){
67
+ caches.open('vader').then((cache)=>{
68
+ // @ts-ignore
69
+ cache.add(`${l}/public/${src[1]}`)
70
+ // @ts-ignore
71
+ console.log('cached', `${l}/public/${src[1]}`)
72
+ }).catch((err)=>{
73
+ console.log(err)
74
+ })
75
+ }else{
76
+ // @ts-ignore
77
+ console.log('already cached', caches.match(`${l}/public/${src[1]}`))
78
+ }
79
+ }
80
+
81
+ let href = result.match(/href="([^"]*)"/g)
82
+ if(href){
83
+ while(href.length){
84
+ let h = href.pop()
85
+ // @ts-ignore
86
+ h = h.replace('href="','').replace('"','')
87
+ if(!h.includes('http') || !result.includes('<!-- #vader-disable_relative-paths -->')){
88
+ result = result.replace(`href="${h}"`,`href="#${h}"`)
89
+ }else{
90
+ throw new Error(`Vader Error: You cannot use relative paths in ${e.data.file}. Use absolute paths instead. \n\n${h}`)
91
+ }
92
+ }
93
+ }
94
+
95
+ let time_ended = Date.now()
96
+ let time_taken = time_ended - time_started
97
+ let hasran = false
98
+ if(l.includes('localhost') || l.includes('127.0.0.1') && !hasran){
99
+ hasran = true
100
+ result+= `\$\{console.log('%c${e.data.name} component rendered in ${time_taken}ms','color:#fff;background:#000;padding:5px;border-radius:5px;font-size:12px;font-weight:bold'),""\}`
101
+ }
102
+
103
+
104
+ postMessage(`<div data-component=${e.data.name}>${result}</div>`)
105
+
106
+ }