resonantjs 1.0.7 → 1.0.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/README.md CHANGED
@@ -47,7 +47,10 @@ Include resonant.js in your HTML file, and use the following example to understa
47
47
 
48
48
  <script>
49
49
  const resonantJs = new Resonant();
50
- resonantJs.add("counter", 0);
50
+ resonantJs.add("counter", 0, true);
51
+ //counter will instantiate the variable with name "counter"
52
+ //0 is the initial value of the variable
53
+ //true is optional, if true the variable will be stored in local storage
51
54
  </script>
52
55
  </body>
53
56
  </html>
@@ -45,15 +45,12 @@
45
45
 
46
46
  // Add a callback to log actions taken on tasks
47
47
  resonantJs.addCallback("tasks", (tasks, task, action) => {
48
- console.log(`Action taken: ${action} for ${task.name}`);
48
+ console.log(`Action taken: ${action}`);
49
49
  });
50
50
 
51
51
  function remove(task) {
52
- //get by name
53
- const index = tasks.findIndex(t => t.name === task.name);
54
- tasks.splice(index, 1);
55
-
56
- //You could use as well, still trying to figure out if I want to leave this or not
52
+ const index = tasks.indexOf(task);
53
+ tasks.delete(index);
57
54
  }
58
55
 
59
56
  // Add a function to add a new task
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "resonantjs",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "A lightweight JavaScript framework that enables reactive data-binding for building dynamic and responsive web applications. It simplifies creating interactive UIs by automatically updating the DOM when your data changes.",
5
5
  "main": "resonant.js",
6
6
  "repository": {
package/resonant.js CHANGED
@@ -9,6 +9,17 @@ class ObservableArray extends Array {
9
9
  this.isDeleting = false;
10
10
  }
11
11
 
12
+ //temp fix for issues
13
+ forceUpdate() {
14
+ this.resonantInstance.arrayDataChangeDetection[this.variableName] = this.slice();
15
+ this.resonantInstance._queueUpdate(this.variableName, 'modified', this.slice());
16
+ }
17
+
18
+ update(array) {
19
+ window[this.variableName] = array;
20
+ this.resonantInstance._queueUpdate(this.variableName, 'updated', array);
21
+ }
22
+
12
23
  push(...args) {
13
24
  const result = super.push(...args);
14
25
  this.resonantInstance.arrayDataChangeDetection[this.variableName] = this.slice();
@@ -73,8 +84,8 @@ class ObservableArray extends Array {
73
84
  return true;
74
85
  }
75
86
 
76
- filter(filter) {
77
- if(this.resonantInstance === undefined) {
87
+ filter(filter, actuallyFilter = true) {
88
+ if(this.resonantInstance === undefined || actuallyFilter === false) {
78
89
  return super.filter(filter);
79
90
  }
80
91
 
@@ -121,7 +132,7 @@ class Resonant {
121
132
  }
122
133
  }
123
134
 
124
- updatePersistentData(variableName) {
135
+ updatePersistantData(variableName) {
125
136
  if (localStorage.getItem('res_' + variableName)) {
126
137
  localStorage.setItem('res_' + variableName, JSON.stringify(this.data[variableName]));
127
138
  }
@@ -180,7 +191,7 @@ class Resonant {
180
191
  if (this.pendingUpdates.get(variableName).length === 1) {
181
192
  setTimeout(() => {
182
193
  const updates = this.pendingUpdates.get(variableName);
183
- this.updatePersistentData(variableName);
194
+ this.updatePersistantData(variableName);
184
195
  this.pendingUpdates.delete(variableName);
185
196
  updates.forEach(update => {
186
197
  this._triggerCallbacks(variableName, update);
@@ -190,6 +201,7 @@ class Resonant {
190
201
  this.updateStylesFor(variableName);
191
202
  }, 0);
192
203
  }
204
+
193
205
  }
194
206
 
195
207
  _triggerCallbacks(variableName, callbackData) {
package/resonant.min.js CHANGED
@@ -1 +1 @@
1
- class ObservableArray extends Array{constructor(e,t,...a){if(void 0===t)return super(...a);super(...a),this.variableName=e,this.resonantInstance=t,this.isDeleting=!1}push(...e){let t=super.push(...e);return this.resonantInstance.arrayDataChangeDetection[this.variableName]=this.slice(),e.forEach((e,t)=>{this.resonantInstance._queueUpdate(this.variableName,"added",e,this.length-1-t)}),t}splice(e,t,...a){let s=super.splice(e,t,...a);return this.resonantInstance.arrayDataChangeDetection[this.variableName]=this.slice(),t>0&&s.forEach((t,a)=>{this.resonantInstance._queueUpdate(this.variableName,"removed",t,e+a)}),a.length>0&&a.forEach((t,a)=>{this.resonantInstance._queueUpdate(this.variableName,"added",t,e+a)}),s}set(e,t){if(this[e]!==t){if(this.isDeleting)return!0;let a=this.resonantInstance.arrayDataChangeDetection[this.variableName],s="modified";e>=a.length?s="added":void 0===a[e]&&(s="added"),this.resonantInstance.arrayDataChangeDetection[this.variableName]=this.slice();let i=this[e];this[e]=t,this.resonantInstance._queueUpdate(this.variableName,s,this[e],e,i)}return!0}delete(e){let t=this[e];return this.isDeleting=!0,this.splice(e,1),this.resonantInstance.arrayDataChangeDetection[this.variableName]=this.slice(),this.resonantInstance._queueUpdate(this.variableName,"removed",null,e,t),this.isDeleting=!1,!0}filter(e){if(void 0===this.resonantInstance)return super.filter(e);let t=super.filter(e);return this.resonantInstance.arrayDataChangeDetection[this.variableName]=this.slice(),this.resonantInstance._queueUpdate(this.variableName,"filtered"),t}}class Resonant{constructor(){this.data={},this.callbacks={},this.pendingUpdates=new Map,this.arrayDataChangeDetection={}}add(e,t,a){Array.isArray(t=this.persist(e,t,a))?(this.data[e]=new ObservableArray(e,this,...t),this.arrayDataChangeDetection[e]=this.data[e].slice()):"object"==typeof t?this.data[e]=this._createObject(e,t):this.data[e]=t,this._defineProperty(e),this.updateElement(e)}persist(e,t,a){if(void 0===a||!a)return t;var s=localStorage.getItem("res_"+e);return null!=s?JSON.parse(localStorage.getItem("res_"+e)):(localStorage.setItem("res_"+e,JSON.stringify(t)),t)}updatePersistentData(e){localStorage.getItem("res_"+e)&&localStorage.setItem("res_"+e,JSON.stringify(this.data[e]))}addAll(e){Object.entries(e).forEach(([e,t])=>{this.add(e,t)})}_createObject(e,t){return t[Symbol("isProxy")]=!0,new Proxy(t,{set:(t,a,s)=>{if(t[a]!==s){let i=t[a];t[a]=s,this._queueUpdate(e,"modified",t,a,i)}return!0}})}_defineProperty(e){Object.defineProperty(window,e,{get:()=>this.data[e],set:t=>{Array.isArray(t)?(this.data[e]=new ObservableArray(e,this,...t),this.arrayDataChangeDetection[e]=this.data[e].slice()):"object"==typeof t?this.data[e]=this._createObject(e,t):this.data[e]=t,this.updateElement(e),this.updateDisplayConditionalsFor(e),this.updateStylesFor(e),Array.isArray(t)||"object"==typeof t||this._queueUpdate(e,"modified",this.data[e])}})}_queueUpdate(e,t,a,s,i){this.pendingUpdates.has(e)||this.pendingUpdates.set(e,[]),this.pendingUpdates.get(e).push({action:t,item:a,property:s,oldValue:i}),1===this.pendingUpdates.get(e).length&&setTimeout(()=>{let t=this.pendingUpdates.get(e);this.updatePersistentData(e),this.pendingUpdates.delete(e),t.forEach(t=>{this._triggerCallbacks(e,t)}),this.updateElement(e),this.updateDisplayConditionalsFor(e),this.updateStylesFor(e)},0)}_triggerCallbacks(e,t){this.callbacks[e]&&this.callbacks[e].forEach(a=>{let s=t.item||t.oldValue;a(this.data[e],s,t.action)})}updateElement(e){let t=document.querySelectorAll(`[res="${e}"]`),a=this.data[e];t.forEach(t=>{if(t.value=a,"INPUT"===t.tagName||"TEXTAREA"===t.tagName)t.hasAttribute("data-resonant-bound")||(t.oninput=()=>{this.data[e]=t.value,this._queueUpdate(e,"modified",this.data[e])},t.setAttribute("data-resonant-bound","true"));else if(Array.isArray(a))t.querySelectorAll(`[res="${e}"][res-rendered=true]`).forEach(e=>e.remove()),this._renderArray(e,t);else if("object"==typeof a){let s=t.querySelectorAll("[res-prop]");s.forEach(t=>{let s=t.getAttribute("res-prop");s&&s in a&&(t.hasAttribute("data-resonant-bound")?"INPUT"===t.tagName||"TEXTAREA"===t.tagName?"checkbox"===t.type?t.checked=a[s]:t.value=a[s]:t.innerHTML=a[s]:("INPUT"===t.tagName||"TEXTAREA"===t.tagName?"checkbox"===t.type?(t.checked=a[s],t.onchange=()=>{this.data[e][s]=t.checked}):(t.value=a[s],t.oninput=()=>{this.data[e][s]=t.value}):t.innerHTML=a[s],t.setAttribute("data-resonant-bound","true")))})}else t.innerHTML=a}),this.updateDisplayConditionalsFor(e),this.updateStylesFor(e)}updateDisplayConditionalsFor(variableName){let conditionalElements=document.querySelectorAll(`[res-display*="${variableName}"]`);conditionalElements.forEach(conditionalElement=>{let condition=conditionalElement.getAttribute("res-display");try{eval(condition)?conditionalElement.style.display="":conditionalElement.style.display="none"}catch(e){console.error(`Error evaluating condition for ${variableName}: ${condition}`,e)}})}updateStylesFor(variableName){let styleElements=document.querySelectorAll(`[res-style*="${variableName}"]`);styleElements.forEach(styleElement=>{let styleCondition=styleElement.getAttribute("res-style");try{let parent=styleElement,index=null;for(;parent&&!index;)index=parent.getAttribute("res-index"),parent=parent.parentElement;let resStyles=styleElement.getAttribute("res-styles");if(resStyles&&resStyles.split(" ").forEach(e=>{styleElement.classList.remove(e)}),null!==index){let item=this.data[variableName][index];styleCondition=styleCondition.replace(RegExp(`\\b${variableName}\\b`,"g"),"item");let styleClass=Function("item",`return ${styleCondition}`)(item);if(styleClass)styleElement.classList.add(styleClass);else{var elementHasStyle=styleElement.classList.contains(styleClass);elementHasStyle&&styleElement.classList.remove(styleClass)}}else{let styleClass=eval(styleCondition);if(styleClass)styleElement.classList.add(styleClass),styleElement.setAttribute("res-styles",styleClass);else{var elementHasStyle=styleElement.classList.contains(styleClass);elementHasStyle&&styleElement.classList.remove(styleClass)}}}catch(e){console.error(`Error evaluating style for ${variableName}: ${styleCondition}`,e)}})}_renderArray(e,t){let a=t.cloneNode(!0);t.innerHTML="",window[e+"_template"]?a=window[e+"_template"]:window[e+"_template"]=a,this.data[e].forEach((s,i)=>{let r=a.cloneNode(!0);for(let n in r.setAttribute("res-index",i),s){let l=r.querySelector(`[res-prop="${n}"]`);l&&(l.hasAttribute("data-resonant-bound")?"INPUT"===l.tagName||"TEXTAREA"===l.tagName?"checkbox"===l.type?l.checked=s[n]:l.value=s[n]:l.innerHTML=s[n]:("INPUT"===l.tagName||"TEXTAREA"===l.tagName?"checkbox"===l.type?(l.checked=s[n],l.onchange=()=>{s[n]=l.checked,this._queueUpdate(e,"modified",s,n,s[n])}):(l.value=s[n],l.oninput=()=>{s[n]=l.value,this._queueUpdate(e,"modified",s,n,s[n])}):l.innerHTML=s[n],l.setAttribute("data-resonant-bound","true")))}let h=r.querySelectorAll("[res-onclick], [res-onclick-remove]");h.forEach(t=>{let a=t.getAttribute("res-onclick"),i=t.getAttribute("res-onclick-remove");a&&(t.onclick=()=>{let e=Function("item",`return ${a}(item)`);e(s)}),i&&(t.onclick=()=>{let t=this.data[e].findIndex(e=>e[i]===s[i]);-1!==t&&this.data[e].splice(t,1)})}),r.setAttribute("res-rendered",!0),t.appendChild(r)})}addCallback(e,t){this.callbacks[e]||(this.callbacks[e]=[]),this.callbacks[e].push(t)}}
1
+ class ObservableArray extends Array{constructor(e,t,...a){if(void 0===t)return super(...a);super(...a),this.variableName=e,this.resonantInstance=t,this.isDeleting=!1}forceUpdate(){this.resonantInstance.arrayDataChangeDetection[this.variableName]=this.slice(),this.resonantInstance._queueUpdate(this.variableName,"modified",this.slice())}update(e){window[this.variableName]=e,this.resonantInstance._queueUpdate(this.variableName,"updated",e)}push(...e){var t=super.push(...e);return this.resonantInstance.arrayDataChangeDetection[this.variableName]=this.slice(),e.forEach((e,t)=>{this.resonantInstance._queueUpdate(this.variableName,"added",e,this.length-1-t)}),t}splice(a,e,...t){var s=super.splice(a,e,...t);return this.resonantInstance.arrayDataChangeDetection[this.variableName]=this.slice(),0<e&&s.forEach((e,t)=>{this.resonantInstance._queueUpdate(this.variableName,"removed",e,a+t)}),0<t.length&&t.forEach((e,t)=>{this.resonantInstance._queueUpdate(this.variableName,"added",e,a+t)}),s}set(t,a){if(this[t]!==a){if(this.isDeleting)return!0;var s=this.resonantInstance.arrayDataChangeDetection[this.variableName];let e="modified";(t>=s.length||void 0===s[t])&&(e="added"),this.resonantInstance.arrayDataChangeDetection[this.variableName]=this.slice();s=this[t];this[t]=a,this.resonantInstance._queueUpdate(this.variableName,e,this[t],t,s)}return!0}delete(e){var t=this[e];return this.isDeleting=!0,this.splice(e,1),this.resonantInstance.arrayDataChangeDetection[this.variableName]=this.slice(),this.resonantInstance._queueUpdate(this.variableName,"removed",null,e,t),!(this.isDeleting=!1)}filter(e,t=!0){return void 0===this.resonantInstance||!1===t?super.filter(e):(t=super.filter(e),this.resonantInstance.arrayDataChangeDetection[this.variableName]=this.slice(),this.resonantInstance._queueUpdate(this.variableName,"filtered"),t)}}class Resonant{constructor(){this.data={},this.callbacks={},this.pendingUpdates=new Map,this.arrayDataChangeDetection={}}add(e,t,a){t=this.persist(e,t,a),Array.isArray(t)?(this.data[e]=new ObservableArray(e,this,...t),this.arrayDataChangeDetection[e]=this.data[e].slice()):this.data[e]="object"==typeof t?this._createObject(e,t):t,this._defineProperty(e),this.updateElement(e)}persist(e,t,a){return void 0!==a&&a?null!=localStorage.getItem("res_"+e)?JSON.parse(localStorage.getItem("res_"+e)):(localStorage.setItem("res_"+e,JSON.stringify(t)),t):t}updatePersistantData(e){localStorage.getItem("res_"+e)&&localStorage.setItem("res_"+e,JSON.stringify(this.data[e]))}addAll(e){Object.entries(e).forEach(([e,t])=>{this.add(e,t)})}_createObject(i,e){return e[Symbol("isProxy")]=!0,new Proxy(e,{set:(e,t,a)=>{var s;return e[t]!==a&&(s=e[t],e[t]=a,this._queueUpdate(i,"modified",e,t,s)),!0}})}_defineProperty(t){Object.defineProperty(window,t,{get:()=>this.data[t],set:e=>{Array.isArray(e)?(this.data[t]=new ObservableArray(t,this,...e),this.arrayDataChangeDetection[t]=this.data[t].slice()):this.data[t]="object"==typeof e?this._createObject(t,e):e,this.updateElement(t),this.updateDisplayConditionalsFor(t),this.updateStylesFor(t),Array.isArray(e)||"object"==typeof e||this._queueUpdate(t,"modified",this.data[t])}})}_queueUpdate(t,e,a,s,i){this.pendingUpdates.has(t)||this.pendingUpdates.set(t,[]),this.pendingUpdates.get(t).push({action:e,item:a,property:s,oldValue:i}),1===this.pendingUpdates.get(t).length&&setTimeout(()=>{var e=this.pendingUpdates.get(t);this.updatePersistantData(t),this.pendingUpdates.delete(t),e.forEach(e=>{this._triggerCallbacks(t,e)}),this.updateElement(t),this.updateDisplayConditionalsFor(t),this.updateStylesFor(t)},0)}_triggerCallbacks(a,s){this.callbacks[a]&&this.callbacks[a].forEach(e=>{var t=s.item||s.oldValue;e(this.data[a],t,s.action)})}updateElement(a){var e=document.querySelectorAll(`[res="${a}"]`);const s=this.data[a];e.forEach(e=>{e.value=s,"INPUT"===e.tagName||"TEXTAREA"===e.tagName?e.hasAttribute("data-resonant-bound")||(e.oninput=()=>{this.data[a]=e.value,this._queueUpdate(a,"modified",this.data[a])},e.setAttribute("data-resonant-bound","true")):Array.isArray(s)?(e.querySelectorAll(`[res="${a}"][res-rendered=true]`).forEach(e=>e.remove()),this._renderArray(a,e)):"object"==typeof s?e.querySelectorAll("[res-prop]").forEach(e=>{const t=e.getAttribute("res-prop");t&&t in s&&(e.hasAttribute("data-resonant-bound")?"INPUT"===e.tagName||"TEXTAREA"===e.tagName?"checkbox"===e.type?e.checked=s[t]:e.value=s[t]:e.innerHTML=s[t]:("INPUT"===e.tagName||"TEXTAREA"===e.tagName?"checkbox"===e.type?(e.checked=s[t],e.onchange=()=>{this.data[a][t]=e.checked}):(e.value=s[t],e.oninput=()=>{this.data[a][t]=e.value}):e.innerHTML=s[t],e.setAttribute("data-resonant-bound","true")))}):e.innerHTML=s}),this.updateDisplayConditionalsFor(a),this.updateStylesFor(a)}updateDisplayConditionalsFor(variableName){const conditionalElements=document.querySelectorAll(`[res-display*="${variableName}"]`);conditionalElements.forEach(conditionalElement=>{const condition=conditionalElement.getAttribute("res-display");try{eval(condition)?conditionalElement.style.display="":conditionalElement.style.display="none"}catch(e){}})}updateStylesFor(variableName){const styleElements=document.querySelectorAll(`[res-style*="${variableName}"]`);styleElements.forEach(styleElement=>{let styleCondition=styleElement.getAttribute("res-style");try{let parent=styleElement,index=null;for(;parent&&!index;)index=parent.getAttribute("res-index"),parent=parent.parentElement;let resStyles=styleElement.getAttribute("res-styles");if(resStyles){let resStylesArray=resStyles.split(" ");resStylesArray.forEach(e=>{styleElement.classList.remove(e)})}if(null!==index){const item=this.data[variableName][index],styleClass=(styleCondition=styleCondition.replace(new RegExp(`\\b${variableName}\\b`,"g"),"item"),new Function("item","return "+styleCondition)(item));var elementHasStyle;styleClass?styleElement.classList.add(styleClass):(elementHasStyle=styleElement.classList.contains(styleClass),elementHasStyle&&styleElement.classList.remove(styleClass))}else{const styleClass=eval(styleCondition);var elementHasStyle;styleClass?(styleElement.classList.add(styleClass),styleElement.setAttribute("res-styles",styleClass)):(elementHasStyle=styleElement.classList.contains(styleClass),elementHasStyle&&styleElement.classList.remove(styleClass))}}catch(e){}})}_renderArray(i,n){let r=n.cloneNode(!0);n.innerHTML="",window[i+"_template"]?r=window[i+"_template"]:window[i+"_template"]=r,this.data[i].forEach((s,e)=>{var t=r.cloneNode(!0);t.setAttribute("res-index",e);for(let e in s){const a=t.querySelector(`[res-prop="${e}"]`);a&&(a.hasAttribute("data-resonant-bound")?"INPUT"===a.tagName||"TEXTAREA"===a.tagName?"checkbox"===a.type?a.checked=s[e]:a.value=s[e]:a.innerHTML=s[e]:("INPUT"===a.tagName||"TEXTAREA"===a.tagName?"checkbox"===a.type?(a.checked=s[e],a.onchange=()=>{s[e]=a.checked,this._queueUpdate(i,"modified",s,e,s[e])}):(a.value=s[e],a.oninput=()=>{s[e]=a.value,this._queueUpdate(i,"modified",s,e,s[e])}):a.innerHTML=s[e],a.setAttribute("data-resonant-bound","true")))}t.querySelectorAll("[res-onclick], [res-onclick-remove]").forEach(e=>{const t=e.getAttribute("res-onclick"),a=e.getAttribute("res-onclick-remove");t&&(e.onclick=()=>{new Function("item",`return ${t}(item)`)(s)}),a&&(e.onclick=()=>{var e=this.data[i].findIndex(e=>e[a]===s[a]);-1!==e&&this.data[i].splice(e,1)})}),t.setAttribute("res-rendered",!0),n.appendChild(t)})}addCallback(e,t){this.callbacks[e]||(this.callbacks[e]=[]),this.callbacks[e].push(t)}}