vaderjs 1.3.0 → 1.3.2

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
@@ -1,134 +1,96 @@
1
- let dom = /**@type {Obect} **/ {};
1
+ let dom = [];
2
2
  let states = {};
3
- let worker = new Worker(new URL('./worker.js', import.meta.url));
3
+ let worker = new Worker(new URL("./worker.js", import.meta.url));
4
4
  /**
5
5
  * @function markdown
6
6
  * @param {String} content
7
- * @description Allows you to convert markdown to html
7
+ * @description Allows you to convert markdown to html
8
8
  */
9
9
  function markdown(content) {
10
- const lines = content.split('\n').filter((line) => line !== '').map((line) => line.trim());
11
-
12
- let result = '';
13
-
14
- lines.forEach((line) => {
15
- let heading = line.match(/^#{1,6}\s/);
16
- let bold = line.match(/\*\*(.*?)\*\*/g);
17
- let italic = line.match(/\*(.*?)\*/g);
18
-
19
- let link = line.match(/\[(.*?)\]\((.*?)\)/g);
20
- let ul = line.match(/^\-\s/);
21
- let ol = line.match(/^\d\.\s/);
22
-
23
- let li = line.match(/^\s/);
24
- let hr = line.match(/^\-\-\-\s/);
25
- let blockquote = line.match(/^\>\s/);
26
- let image = line.match(/\!\[(.*?)\]\((.*?)\)/g);
27
-
28
-
29
- let codeBlock = line.match(/\`\`\`/g);
30
- let codeBlockEnd = line.match(/\`\`\`/g);
31
- let code = line.match(/\`(.*?)\`/g);
32
-
33
-
34
-
35
- if (heading) {
36
- // @ts-ignore
37
- let headingLevel = heading[0].match(/#/g).length;
38
- line = line.replace(heading[0], `<h${headingLevel}>`);
39
- line += `</h${headingLevel}>`;
40
- }
41
- if (bold) {
42
- bold.forEach((b) => {
43
- line = line.replace(b, `<strong
44
- className="$vader_markdown_bold"
45
- >${b.replace(/\*\*/g, "")}</strong>`);
46
- });
47
- }
48
- if (italic) {
49
- italic.forEach((i) => {
50
- line = line.replace(i, `<em
51
- className="$vader_markdown_italic"
52
- >${i.replace(/\*/g, "")}</em>`);
53
- });
54
- }
55
-
56
-
57
- if(link){
58
- link.forEach((l) => {
59
- // @ts-ignore
60
- let text = l.match(/\[(.*?)\]/g)[0].replace(/\[|\]/g, "");
61
- // @ts-ignore
62
- let href = l.match(/\((.*?)\)/g)[0].replace(/\(|\)/g, "");
63
- line = line.replace(l, `<a
64
- className="$vader_markdown_link"
65
- href="${href}">${text}</a>`);
66
- });
67
- }
68
- if (ul) {
69
- line = line.replace(ul[0], `<li
70
- className="$vader_markdown_ul"
71
- style="list-style-type: disc;">`);
72
- line += `</li>`;
73
- }
74
- if (ol) {
75
- line = line.replace(ol[0], `<li
76
- className="$vader_markdown_ol"
77
- style="list-style-type: decimal;">`);
78
- line += `</li>`;
79
- }
80
- if (hr) {
81
- line = line.replace(hr[0], `<hr/>`);
82
- }
83
- if (blockquote) {
84
- line = line.replace(blockquote[0], `<blockquote
85
- className="$vader_markdown_blockquote"
86
- >`);
87
- line += `</blockquote>`;
88
- }
89
- if (image) {
90
- image.forEach((i) => {
91
- // @ts-ignore
92
- let alt = i.match(/\[(.*?)\]/g)[0].replace(/\[|\]/g, "");
93
- // @ts-ignore
94
- let src = i.match(/\((.*?)\)/g)[0].replace(/\(|\)/g, "");
95
- i.replace(i, `<img src="${src}" alt="${alt}"/>`);
96
- line = line.replace(i, `<img
97
- className="$vader_markdown_image"
98
- src="${src}" alt="${alt}"/>`).replace('!','')
99
- });
100
- }
101
- if (li) {
102
- line = line.replace(li[0], `<li>`);
103
- line += `</li>`;
104
- }
105
- if (codeBlock) {
106
- line = line.replace(codeBlock[0], `<pre className="$vader_markdown_code_block" ><code>`);
107
- }
108
- if (codeBlockEnd) {
109
- line = line.replace(codeBlockEnd[0], `</code></pre>`);
110
- }
111
-
112
- if (code) {
113
- code.forEach((c) => {
114
- line = line.replace(c, `<code
115
- className="$vader_markdown_code"
116
- style="background-color: #f5f5f5; padding: 5px; border-radius: 5px;
117
- "
118
- >${c.replace(/\`/g, "")}</code>`);
119
- });
120
- }
121
-
122
-
123
-
10
+ let headers = content.match(/(#+)(.*)/g);
11
+ if (headers) {
12
+ headers.forEach((header) => {
13
+ if (
14
+ header.includes("/") ||
15
+ header.includes("<") ||
16
+ header.includes(">")
17
+ ) {
18
+ return;
19
+ }
20
+ let level = header.split("#").length;
21
+ content = content.replace(
22
+ header,
23
+ `<h${level} class="markdown_heading">${header.replace(
24
+ /#/g,
25
+ ""
26
+ )}</h${level}>`
27
+ );
28
+ });
29
+ }
124
30
 
125
- result += `${line}\n`;
31
+ content = content.replace(/\*\*(.*?)\*\*/g, (match, text) => {
32
+ return `<b class="markdown_bold">${text}</b>`;
33
+ });
34
+ content = content.replace(/\*(.*?)\*/g, (match, text) => {
35
+ return `<i class="markdown_italic">${text}</i>`;
36
+ });
37
+ content = content.replace(/`(.*?)`/g, (match, text) => {
38
+ return `<code>${text}</code>`;
126
39
  });
40
+ content = content.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (match, text, url) => {
41
+ return `<a class="markdown_link" href="${url}">${text}</a>`;
42
+ });
43
+ content = content.replace(/!\[([^\]]+)\]\(([^)]+)\)/g, (match, alt, src) => {
44
+ return `<img class="markdown_image" src="${src}" alt="${alt}" />`;
45
+ });
46
+ content = content
47
+ .split("\n")
48
+ .map((line, index, arr) => {
49
+ if (line.match(/^\s*-\s+(.*?)$/gm)) {
50
+ if (index === 0 || !arr[index - 1].match(/^\s*-\s+(.*?)$/gm)) {
51
+ return `<ul class="markdown_unordered" style="list-style-type:disc;list-style:inside"><li>${line.replace(
52
+ /^\s*-\s+(.*?)$/gm,
53
+ "$1"
54
+ )}</li>`;
55
+ } else if (
56
+ index === arr.length - 1 ||
57
+ !arr[index + 1].match(/^\s*-\s+(.*?)$/gm)
58
+ ) {
59
+ return `<li>${line.replace(/^\s*-\s+(.*?)$/gm, "$1")}</li></ul>`;
60
+ } else {
61
+ return `<li>${line.replace(/^\s*-\s+(.*?)$/gm, "$1")}</li>`;
62
+ }
63
+ } else {
64
+ return line;
65
+ }
66
+ })
67
+ .join("\n");
127
68
 
128
- return result;
129
- }
69
+ content = content
70
+ .split("\n")
71
+ .map((line, index, arr) => {
72
+ if (line.match(/^\s*\d+\.\s+(.*?)$/gm)) {
73
+ if (index === 0 || !arr[index - 1].match(/^\s*\d+\.\s+(.*?)$/gm)) {
74
+ return `<ol class="markdown_ordered" style="list-style-type:decimal;"><li>${line.replace(
75
+ /^\s*\d+\.\s+(.*?)$/gm,
76
+ "$1"
77
+ )}</li>`;
78
+ } else if (
79
+ index === arr.length - 1 ||
80
+ !arr[index + 1].match(/^\s*\d+\.\s+(.*?)$/gm)
81
+ ) {
82
+ return `<li>${line.replace(/^\s*\d+\.\s+(.*?)$/gm, "$1")}</li></ol>`;
83
+ } else {
84
+ return `<li>${line.replace(/^\s*\d+\.\s+(.*?)$/gm, "$1")}</li>`;
85
+ }
86
+ } else {
87
+ return line;
88
+ }
89
+ })
90
+ .join("\n");
130
91
 
131
-
92
+ return content;
93
+ }
132
94
 
133
95
  /**
134
96
  * @function useRef
@@ -136,7 +98,7 @@ function markdown(content) {
136
98
  * @param {String} ref
137
99
  * @returns {void | Object} {current, update}
138
100
  */
139
-
101
+
140
102
  export const useRef = (ref) => {
141
103
  const element = document.querySelector(`[ref="${ref}"]`);
142
104
  const getElement = () => element;
@@ -157,7 +119,7 @@ export const useRef = (ref) => {
157
119
 
158
120
  return {
159
121
  current: getElement(),
160
- update,
122
+ update
161
123
  };
162
124
  };
163
125
 
@@ -201,40 +163,65 @@ export class Component {
201
163
  this.$_useStore_subscribers = [];
202
164
  this.init();
203
165
  this.Componentcontent = null;
204
- this.$_signal_dispatch_event = new CustomEvent("signalDispatch", {
166
+ this.$_signal_dispatch_event = new CustomEvent("SignalDispatch", {
205
167
  detail: {
206
168
  hasUpdated: false,
207
- state: null,
208
- },
169
+ state: null
170
+ }
209
171
  });
210
- this.snapshots = [];
211
-
172
+ /**
173
+ * @property {Object} $_signal_dispatch_cleanup_event
174
+ * @description Allows you to dispatch a signal cleanup event
175
+ * @private
176
+ */
177
+ this.$_signal_dispatch_cleanup_event = new CustomEvent(
178
+ "Signal_Cleanup_Dispatch",
179
+ {
180
+ detail: {
181
+ state: null,
182
+ lastState: null
183
+ }
184
+ }
185
+ );
186
+ /**
187
+ * @property {Array} snapshots
188
+ * @private
189
+ */
190
+ this.snapshots = [];
191
+ /**
192
+ * @property {Object} dom
193
+ * @description Allows you to get reference to DOM element
194
+ * @returns {void | HTMLElement}
195
+ *
196
+ */
197
+ this.dom = [];
198
+
212
199
  /**
213
200
  * @property {Boolean} cfr
214
- * @description Allows you to compile html code on the fly - client fly rendering
215
- *
201
+ * @description Allows you to compile html code on the fly - client fly rendering
202
+ *
216
203
  */
217
- this.cfr = false
204
+ this.cfr = false;
218
205
  /**
219
206
  * @property {Boolean} worker
220
207
  * @description Allows you to use a web worker to compile html code on the fly - client fly rendering
221
208
 
222
209
  */
223
-
224
210
  }
225
211
 
226
212
  /**
227
213
  * @method adapter
228
214
  * @description Allows you to create an adapter - this is used to create custom logic
229
- *
230
- *
215
+ *
216
+ *
231
217
  */
232
- adapter() {
233
- return
218
+ adapter(options) {
219
+ // allow you to override the compoent logic
220
+
221
+
234
222
  }
235
223
  init() {
236
224
  this.registerComponent();
237
-
238
225
  }
239
226
 
240
227
  registerComponent() {
@@ -356,13 +343,20 @@ export class Component {
356
343
  this.$_signal_subscribe = (fn, runonce) => {
357
344
  this.$_signal_subscribers.push({
358
345
  function: fn,
359
- runonce: runonce,
346
+ runonce: runonce
360
347
  });
348
+ return fn;
361
349
  };
362
350
  this.$_signal_cleanup = (fn) => {
351
+ this.lastState = state;
363
352
  this.$_signal_subscribers = this.$_signal_subscribers.filter(
364
353
  (subscriber) => subscriber.function !== fn
365
354
  );
355
+ // @ts-ignore
356
+ this.$_signal_dispatch_cleanup_event.detail.state = this.states;
357
+ // @ts-ignore
358
+ this.$_signal_dispatch_cleanup_event.detail.lastState = this.lastState;
359
+ window.dispatchEvent(this.$_signal_dispatch_event);
366
360
  };
367
361
  this.$_signal_dispatch = () => {
368
362
  for (var i = 0; i < this.$_signal_subscribers.length; i++) {
@@ -392,6 +386,7 @@ export class Component {
392
386
  * @param {*} detail
393
387
  */
394
388
  this.$_signal_set = (detail) => {
389
+
395
390
  setState(detail);
396
391
  };
397
392
 
@@ -435,7 +430,7 @@ export class Component {
435
430
  * @description Allows you to get the value of a signal
436
431
  * @returns {any}
437
432
  */
438
- get: this.$_signal_get,
433
+ get: this.$_signal_get
439
434
  };
440
435
  };
441
436
  /**
@@ -519,7 +514,7 @@ export class Component {
519
514
  return logicalOperator === "any"
520
515
  ? auth.canAnyOf(actions)
521
516
  : auth.canAllOf(actions);
522
- },
517
+ }
523
518
  };
524
519
  return auth;
525
520
  }
@@ -559,9 +554,10 @@ export class Component {
559
554
  (action) => {
560
555
  this.states[key] = reducer(this.states[key], action);
561
556
  this.updateComponent();
562
- },
557
+ }
563
558
  ];
564
559
  }
560
+
565
561
  runEffects() {
566
562
  Object.keys(this.effects).forEach((component) => {
567
563
  this.effects[component].forEach((effect) => {
@@ -572,6 +568,7 @@ export class Component {
572
568
  });
573
569
  });
574
570
  }
571
+
575
572
  /**
576
573
  * @method useSyncStore
577
574
  * @description Allows you to create a store
@@ -595,8 +592,7 @@ export class Component {
595
592
  subscriber(s);
596
593
  });
597
594
  }) ||
598
- {},
599
-
595
+ {}
600
596
  );
601
597
 
602
598
  const getField = (fieldName) => {
@@ -619,7 +615,7 @@ export class Component {
619
615
  getField,
620
616
  setField,
621
617
  subscribe,
622
- clear,
618
+ clear
623
619
  };
624
620
  }
625
621
  /**
@@ -638,12 +634,10 @@ export class Component {
638
634
  * setCount(count + 1)
639
635
  */
640
636
  useState(key, initialValue, callback = null) {
641
-
642
- if(!this.states[key]){
643
- this.states[key] = initialValue;
644
- }
645
-
646
-
637
+ if (!this.states[key]) {
638
+ this.states[key] = initialValue;
639
+ }
640
+
647
641
  return [
648
642
  this.states[key],
649
643
  /**
@@ -657,11 +651,52 @@ export class Component {
657
651
  this.updateComponent();
658
652
  // @ts-ignore
659
653
  typeof callback === "function" ? callback() : null;
660
- },
654
+ }
661
655
  ];
662
656
  }
657
+ /**
658
+ * @method useRef
659
+ * @memberof Component
660
+ * @param {string} ref
661
+ * @description Allows you to get reference to DOM elements from the dom array
662
+ * @returns {Object} {current, update}
663
+ * @example
664
+ * let ref = this.useRef('ref')
665
+ * ref.current // returns the DOM element
666
+
667
+ */
668
+
669
+ useRef(ref) {
670
+ // get ref from array
671
+ const element = this.dom[ref];
672
+
673
+ const getElement = () => element;
674
+
675
+ const update = (data) => {
676
+ const newDom = new DOMParser().parseFromString(data, "text/html");
677
+ const newElement = newDom.body.firstChild;
678
+
679
+ if (element) {
680
+ // @ts-ignore
681
+ const isDifferent = !newElement.isEqualNode(element);
682
+ if (isDifferent) {
683
+ // @ts-ignore
684
+ element.parentNode.replaceChild(newElement, element);
685
+ }
686
+ }
687
+ };
688
+
689
+ return {
690
+ /**@type {HTMLElement} */
691
+ // @ts-ignore
692
+ current: getElement,
693
+ /**@type {Function} */
694
+ update
695
+ };
696
+ }
663
697
 
664
698
  /**
699
+ *
665
700
  * @function useEffect
666
701
  * @param {*} effectFn
667
702
  * @param {*} dependencies
@@ -693,7 +728,7 @@ export class Component {
693
728
  this.effects[this.name] = this.effects[this.name].filter(
694
729
  (effect) => effect !== effectFn
695
730
  );
696
- },
731
+ }
697
732
  };
698
733
  }
699
734
  /**
@@ -726,11 +761,11 @@ export class Component {
726
761
  const fragment = document.createDocumentFragment();
727
762
  Object.keys(components).forEach(async (component) => {
728
763
  const { name } = components[component];
729
- const componentContainer = document.querySelector(
764
+
765
+ let componentContainer = document.querySelector(
730
766
  `[data-component="${name}"]`
731
767
  );
732
-
733
- let time = new Date().getTime().toLocaleString();
768
+ let time = new Date().getTime();
734
769
  /**
735
770
  * @property {Object} snapshot
736
771
  * @description Allows you to keep track of component snapshots
@@ -743,7 +778,7 @@ export class Component {
743
778
  prev_state: this.states,
744
779
  prev_props: this.storedProps,
745
780
  // @ts-ignore
746
- content: componentContainer.innerHTML,
781
+ content: componentContainer.innerHTML
747
782
  };
748
783
 
749
784
  if (!componentContainer) return;
@@ -803,11 +838,8 @@ export class Component {
803
838
  return /^[a-zA-Z0-9-_]+$/.test(className);
804
839
  }
805
840
 
806
-
807
841
  parseHTML(result) {
808
-
809
842
  const dom = new DOMParser().parseFromString(result, "text/html");
810
- console.log(dom)
811
843
  const elements = dom.documentElement.querySelectorAll("*");
812
844
 
813
845
  elements.forEach((element) => {
@@ -833,19 +865,23 @@ export class Component {
833
865
  throw new SyntaxError(
834
866
  `Image: ${element.outerHTML} alt attribute cannot be empty`
835
867
  );
836
-
837
868
  } else if (
838
- element.hasAttribute("src") &&
839
- !element.getAttribute("src")?.includes("http") || !element.getAttribute("src")?.includes("https") &&
840
- !document.documentElement.outerHTML
841
- .trim()
842
- .includes("<!-- #vader-disable_accessibility -->")
869
+ (element.hasAttribute("src") &&
870
+ !element.getAttribute("src")?.includes("http")) ||
871
+ (!element.getAttribute("src")?.includes("https") &&
872
+ !document.documentElement.outerHTML
873
+ .trim()
874
+ .includes("<!-- #vader-disable_accessibility -->"))
843
875
  ) {
844
876
  let prevurl = element.getAttribute("src");
845
877
  element.setAttribute("aria-hidden", "true");
846
878
  element.setAttribute("hidden", "true");
847
- // if window.lcoation.pathname includes a html file remove it and only use the path
848
- let url = window.location.origin + window.location.pathname.replace(/\/[^\/]*$/, '') + '/public/' + element.getAttribute("src");
879
+ // if window.lcoation.pathname includes a html file remove it and only use the path
880
+ let url =
881
+ window.location.origin +
882
+ window.location.pathname.replace(/\/[^\/]*$/, "") +
883
+ "/public/" +
884
+ element.getAttribute("src");
849
885
  let image = new Image();
850
886
  image.src = url;
851
887
  image.onerror = () => {
@@ -870,15 +906,16 @@ export class Component {
870
906
  // @ts-ignore
871
907
  dom[element.getAttribute("ref")] = element;
872
908
  }
873
- if(element.nodeName === "MARKDOWN"){
874
- element.innerHTML = markdown(element.innerHTML.replace(/\\n/g, '\n').trim())
909
+ if (element.nodeName === "MARKDOWN") {
910
+ element.innerHTML = markdown(
911
+ element.innerHTML.replace(/\\n/g, "\n").trim()
912
+ );
875
913
  }
876
914
 
877
915
  if (element.hasAttribute("class")) {
878
- const allowClassComments =
879
- document.documentElement.outerHTML.includes(
880
- "<!-- #vader-allow_class -->"
881
- );
916
+ const allowClassComments = document.documentElement.outerHTML.includes(
917
+ "<!-- #vader-allow_class -->"
918
+ );
882
919
  if (!allowClassComments) {
883
920
  console.warn(
884
921
  "you can disable class errors using, <!-- #vader-allow_class -->"
@@ -909,12 +946,14 @@ export class Component {
909
946
  }
910
947
 
911
948
  if (
912
- element.hasAttribute("src") &&
913
- // @ts-ignore
914
- !element.getAttribute("src").includes("http") &&
915
- // @ts-ignore
916
- !element.getAttribute("src").includes("https") &&
917
- !document.documentElement.outerHTML.includes(`<!-- #vader-disable_relative-paths -->`)
949
+ element.hasAttribute("src") &&
950
+ // @ts-ignore
951
+ !element.getAttribute("src").includes("http") &&
952
+ // @ts-ignore
953
+ !element.getAttribute("src").includes("https") &&
954
+ !document.documentElement.outerHTML.includes(
955
+ `<!-- #vader-disable_relative-paths -->`
956
+ )
918
957
  ) {
919
958
  element.setAttribute(
920
959
  "src",
@@ -924,7 +963,6 @@ export class Component {
924
963
  }
925
964
  break;
926
965
  }
927
-
928
966
  });
929
967
 
930
968
  result = dom.body.innerHTML;
@@ -932,12 +970,11 @@ export class Component {
932
970
  this.Componentcontent = result;
933
971
 
934
972
  if (!result.includes("<div data-component")) {
935
- result = `<div data-component="${this.name}">${result}</div>`;
973
+ result = `<div data-component="${this.name}">${result}</div>`;
936
974
  }
937
- return markdown(result.replace(/\\n/g, '\n').trim())
938
-
975
+ return markdown(result.replace(/\\n/g, "\n").trim());
939
976
  }
940
-
977
+
941
978
  /**
942
979
  * The `html` method generates and processes HTML content for a component, performing various validations and tasks.
943
980
  *
@@ -984,49 +1021,102 @@ export class Component {
984
1021
  * @see {@link Component}
985
1022
  * @see {@link Component#componentDidMount}
986
1023
  */
987
-
988
-
989
-
1024
+
990
1025
  html(strings, ...args) {
991
1026
  // @ts-ignore
992
- if (
993
- // @ts-ignore
994
- new Error().stack &&
995
- // @ts-ignore
996
- new Error().stack.split("\n").length > 0 &&
997
- // @ts-ignore
998
- new Error().stack.split("\n")[2] &&
999
- // @ts-ignore
1000
- new Error().stack.split("\n")[2].includes("render") &&
1001
- !this.componentMounted
1002
- ) {
1003
- this.componentMounted = true;
1004
- this.componentDidMount();
1005
- }
1027
+ let tiemr = setInterval(() => {
1028
+ if (document.querySelector(`[data-component="${this.name}"]`)) {
1029
+ clearInterval(tiemr);
1030
+ this.componentMounted = true;
1006
1031
 
1007
-
1008
- if(this.cfr){
1009
-
1010
- worker.postMessage({strings, args, location: window.location.origin + window.location.pathname.replace(/\/[^\/]*$/, '') + '/public/', name: this.name})
1011
- let promise = new Promise((resolve, reject)=>{
1012
- worker.onmessage = (e)=>{
1013
- if(e.data.error){
1014
- throw new Error(e.data.error)
1032
+ document
1033
+ .querySelector(`[data-component="${this.name}"]`)
1034
+ ?.querySelectorAll("*")
1035
+ .forEach((element) => {
1036
+ if (element.hasAttribute("ref")) {
1037
+ // @ts-ignore
1038
+ this.dom[element.getAttribute("ref")] = element;
1039
+ }
1040
+ });
1041
+ this.componentDidMount();
1042
+ }
1043
+ }, 100);
1044
+ let script = document.createElement("script");
1045
+ script.setAttribute("type", "text/javascript");
1046
+ script.setAttribute(`data-component-script`, this.name);
1047
+
1048
+ let dom = this.dom;
1049
+
1050
+ if (this.cfr) {
1051
+ worker.postMessage({
1052
+ strings,
1053
+ args,
1054
+ location:
1055
+ window.location.origin +
1056
+ window.location.pathname.replace(/\/[^\/]*$/, "") +
1057
+ "/public/",
1058
+ name: this.name
1059
+ });
1060
+ let promise = new Promise((resolve, reject) => {
1061
+ worker.onmessage = (e) => {
1062
+ if (e.data.error) {
1063
+ throw new Error(e.data.error);
1015
1064
  }
1065
+ const dom = this.dom; // Assuming this.dom is an object
1066
+ let js = e.data.js;
1067
+ let template = e.data.template;
1068
+ // Bind the component's context
1016
1069
 
1017
-
1018
- resolve(new Function("useRef", `return \`${e.data}\``)(useRef))
1019
-
1020
-
1021
-
1022
- }
1023
- worker.onerror = (e)=>{
1024
- reject(e)
1025
- }
1026
- })
1070
+ const useState = this.useState.bind(this); // Bind the component's context
1071
+ const useEffect = this.useEffect.bind(this); // Bind the component's context
1072
+ const useReducer = this.useReducer.bind(this); // Bind the component's context
1073
+ const useAuth = this.useAuth.bind(this); // Bind the component's context
1074
+ const useSyncStore = this.useSyncStore.bind(this); // Bind the component's context
1075
+ const signal = this.signal.bind(this); // Bind the component's context
1076
+ const rf = this.$Function.bind(this); // Bind the component's context
1077
+ let states = this.states;
1078
+ const useRef = this.useRef.bind(this); // Bind the component's context
1079
+ new Function(
1080
+ "useState",
1081
+ "useEffect",
1082
+ "useAuth",
1083
+ "useReducer",
1084
+ "useSyncStore",
1085
+ "signal",
1086
+ "rf",
1087
+ "dom",
1088
+ "render",
1089
+ "states",
1090
+ "useRef",
1091
+ js
1092
+ )(
1093
+ useState,
1094
+ useEffect,
1095
+ useAuth,
1096
+ useReducer,
1097
+ useSyncStore,
1098
+ signal,
1099
+ rf,
1100
+ this.dom,
1101
+ this.render,
1102
+ this.states,
1103
+ useRef
1104
+ );
1105
+
1106
+ resolve(
1107
+ new Function("useRef", "states", "return" + "`" + template + "`")(
1108
+ useRef,
1109
+ states
1110
+ )
1111
+ );
1112
+ };
1113
+ worker.onerror = (e) => {
1114
+ reject(e);
1115
+ };
1116
+ });
1027
1117
  // @ts-ignore
1028
1118
  return promise;
1029
- }else{
1119
+ } else {
1030
1120
  let result = "";
1031
1121
  for (let i = 0; i < strings.length; i++) {
1032
1122
  result += strings[i];
@@ -1034,20 +1124,16 @@ export class Component {
1034
1124
  result += args[i];
1035
1125
  }
1036
1126
  }
1037
- result = new Function("useRef", `return \`${result}\``)(useRef)
1127
+ result = new Function("useRef", `return \`${result}\``)(useRef);
1038
1128
 
1039
1129
  if (!result.trim().startsWith("<body>")) {
1040
1130
  console.warn(
1041
1131
  "You should wrap your html in a body tag, vader may not grab all html!"
1042
1132
  );
1043
1133
  }
1044
-
1045
-
1046
-
1047
- return this.parseHTML(result);
1048
- }
1049
1134
 
1050
-
1135
+ return this.parseHTML(result);
1136
+ }
1051
1137
  }
1052
1138
  // write types to ensure it returns a string
1053
1139
  /**
@@ -1106,10 +1192,15 @@ const Vader = {
1106
1192
  * }
1107
1193
  */
1108
1194
  Component: Component,
1109
- useRef: useRef,
1195
+ useRef: useRef
1110
1196
  };
1111
- export const component = (name) => {
1112
- return new Component();
1197
+ /**
1198
+ * @function component
1199
+ * @description Allows you to create a component
1200
+ * @returns {Component}
1201
+ */
1202
+ export const component = () => {
1203
+ return new Component()
1113
1204
  };
1114
1205
 
1115
1206
  /**
@@ -1124,81 +1215,85 @@ export const rf = (name, fn) => {
1124
1215
  window[name] = fn;
1125
1216
  };
1126
1217
  let cache = {};
1127
- async function handletemplate(data){
1218
+ async function handletemplate(data) {
1128
1219
  let dom = new DOMParser().parseFromString(data, "text/html");
1129
1220
  let elements = dom.documentElement.querySelectorAll("*");
1130
-
1221
+
1131
1222
  if (elements.length > 0) {
1132
1223
  for (var i = 0; i < elements.length; i++) {
1133
-
1134
1224
  if (elements[i].nodeName === "INCLUDE") {
1135
- if(!elements[i].getAttribute("src") || elements[i].getAttribute("src") === ""){
1136
- throw new Error("Include tag must have src attribute")
1225
+ if (
1226
+ !elements[i].getAttribute("src") ||
1227
+ elements[i].getAttribute("src") === ""
1228
+ ) {
1229
+ throw new Error("Include tag must have src attribute");
1137
1230
  }
1138
-
1139
- let componentName = elements[i].getAttribute("src")?.split("/").pop()?.split(".")[0]
1140
- // @ts-ignore
1141
- let filedata = await include(elements[i].getAttribute("src"))
1142
- // replace ` with \`\` to allow for template literals
1143
- filedata = filedata.replace(/`/g, "\\`")
1144
- cache[elements[i].getAttribute("src")] = filedata
1145
- filedata = new Function(`return \`${filedata}\`;`)();
1146
- let newdom = new DOMParser().parseFromString(filedata, "text/html");
1147
-
1148
- newdom.querySelectorAll("include").forEach((el)=>{
1149
- el.remove()
1150
- })
1151
- // @ts-ignore
1152
-
1153
- let els = dom.querySelectorAll(componentName)
1154
-
1155
- els.forEach((el)=>{
1156
-
1157
- if(el.attributes.length > 0){
1158
- for(var i = 0; i < el.attributes.length; i++){
1159
- newdom.body.outerHTML = newdom.body.outerHTML.replace(`{{${el.attributes[i].name}}}`, el.attributes[i].value)
1160
- }
1161
-
1162
- }
1163
- if(el.children.length > 0 && newdom.body.querySelector('slot')){
1164
- for(var i = 0; i < el.children.length; i++){
1165
- let slots = newdom.body.querySelectorAll("slot")
1166
- slots.forEach((slot)=>{
1167
- let id = slot.getAttribute("id")
1168
- if(id === el.nodeName.toLowerCase()){
1169
- slot.outerHTML = `<div>${el.innerHTML}</div>`
1170
- }
1171
- })
1172
-
1173
-
1231
+
1232
+ let componentName = elements[i]
1233
+ .getAttribute("src")
1234
+ ?.split("/")
1235
+ .pop()
1236
+ ?.split(".")[0];
1237
+ // @ts-ignore
1238
+ let filedata = await include(elements[i].getAttribute("src"));
1239
+ // replace ` with \`\` to allow for template literals
1240
+ filedata = filedata.replace(/`/g, "\\`");
1241
+ cache[elements[i].getAttribute("src")] = filedata;
1242
+ filedata = new Function(`return \`${filedata}\`;`)();
1243
+ let newdom = new DOMParser().parseFromString(filedata, "text/html");
1244
+
1245
+
1246
+ newdom.querySelectorAll("include").forEach((el) => {
1247
+ el.remove();
1248
+ });
1249
+ // @ts-ignore
1250
+
1251
+ let els = dom.querySelectorAll(componentName);
1252
+
1253
+ els.forEach((el) => {
1254
+ if (el.attributes.length > 0) {
1255
+ for (var i = 0; i < el.attributes.length; i++) {
1256
+ // @ts-ignore
1257
+ newdom.body.outerHTML = newdom.body.outerHTML.replaceAll(
1258
+ `{{${el.attributes[i].name}}}`,
1259
+ el.attributes[i].value
1260
+ );
1261
+ }
1262
+ }
1263
+ if (el.children.length > 0 && newdom.body.querySelector("slot")) {
1264
+ for (var i = 0; i < el.children.length; i++) {
1265
+ let slots = newdom.body.querySelectorAll("slot");
1266
+ slots.forEach((slot) => {
1267
+
1268
+ let id = slot.getAttribute("id");
1269
+ console.log(id)
1270
+ if(el.hasAttribute('key') && el.getAttribute('key') === id || !el.hasAttribute('key') && el.nodeName === id){
1271
+
1272
+ slot.outerHTML = `<div>${el.innerHTML}</div>`
1174
1273
  }
1175
-
1176
- }
1177
-
1178
- dom.body.querySelectorAll('include').forEach((el)=>{
1179
- el.remove()
1180
- })
1181
- // replace ` with \`\` to allow for template literals
1182
- dom.body.outerHTML = dom.body.outerHTML.replace(/`/g, "\\`")
1183
- dom.body.outerHTML = dom.body.outerHTML.replace(el.outerHTML, new Function(`return \`${newdom.body.outerHTML}\`;`)())
1184
-
1185
-
1186
- })
1187
-
1188
-
1189
-
1274
+ });
1275
+ }
1276
+ }
1190
1277
 
1278
+ dom.body.querySelectorAll("include").forEach((el) => {
1279
+ el.remove();
1280
+ });
1281
+ // replace ` with \`\` to allow for template literals
1282
+ dom.body.outerHTML = dom.body.outerHTML.replace(/`/g, "\\`");
1283
+ dom.body.outerHTML = dom.body.outerHTML.replace(
1284
+ el.outerHTML,
1285
+ new Function(`return \`${newdom.body.outerHTML}\`;`)()
1286
+ );
1287
+ });
1191
1288
  }
1192
1289
  }
1193
-
1194
-
1195
1290
  }
1196
-
1291
+
1197
1292
  // replace ` with \`\` to allow for template literals
1198
- dom.body.outerHTML = dom.body.outerHTML.replace(/`/g, "\\`")
1293
+ dom.body.outerHTML = dom.body.outerHTML.replace(/`/g, "\\`");
1199
1294
  data = new Function(`return \`${dom.body.outerHTML}\`;`)();
1200
-
1201
- return data;
1295
+
1296
+ return data;
1202
1297
  }
1203
1298
  /**
1204
1299
  * @function include
@@ -1207,10 +1302,7 @@ async function handletemplate(data){
1207
1302
  * @param {string} path
1208
1303
  */
1209
1304
 
1210
-
1211
-
1212
1305
  export const include = async (path) => {
1213
-
1214
1306
  if (
1215
1307
  path.startsWith("/") &&
1216
1308
  !path.includes("/src/") &&
@@ -1221,25 +1313,23 @@ export const include = async (path) => {
1221
1313
  path = "/src/" + path;
1222
1314
  }
1223
1315
  if (cache[path]) {
1224
- return await handletemplate(new Function(`return \`${cache[path]}\`;`)())
1225
-
1226
- }else{
1316
+ return await handletemplate(new Function(`return \`${cache[path]}\`;`)());
1317
+ } else {
1227
1318
  return fetch(`./${path}`)
1228
- .then((res) => {
1229
- if (res.status === 404) {
1230
- throw new Error(`No file found at ${path}`);
1231
- }
1232
- return res.text();
1233
- })
1234
- .then(async (data) => {
1235
- cache[path] = data
1236
-
1237
- data = await handletemplate(new Function(`return \`${data}\`;`)())
1238
-
1239
- return data
1240
- });
1319
+ .then((res) => {
1320
+ if (res.status === 404) {
1321
+ throw new Error(`No file found at ${path}`);
1322
+ }
1323
+ return res.text();
1324
+ })
1325
+ .then(async (data) => {
1326
+ cache[path] = data;
1327
+
1328
+ data = await handletemplate(new Function(`return \`${data}\`;`)());
1329
+
1330
+ return data;
1331
+ });
1241
1332
  }
1242
-
1243
1333
  };
1244
1334
 
1245
1335
  export default Vader;