Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@ryangjchandler/spruce

Package Overview
Dependencies
Maintainers
1
Versions
26
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ryangjchandler/spruce - npm Package Compare versions

Comparing version 1.1.2 to 2.0.0

tests/persistence.spec.js

2

dist/spruce.js

@@ -1,2 +0,2 @@

function t(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function e(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),n.push.apply(n,r)}return n}var n=function(t){return null==t},r=function(t){return Object.getPrototypeOf(t)===Object.prototype},s=function(t,e){return Object.entries(t).forEach(function(i){var o=i[0],c=i[1];n(c)||!r(c)&&!Array.isArray(c)||(t[o]=s(c,e))}),new Proxy(t,{set:function(t,i,o){return!n(o)&&r(o)&&(o=s(o,e)),e.set(t,i,t[i]=o),!0}})},i={events:{watchers:{},events:{},on:function(t,e,n){var r=this;return void 0===n&&(n=!1),this.events[t]||(this.events[t]=[]),this.events[t].push({callback:e,once:n}),function(){return r.off(t,e)}},once:function(t,e){this.on(t,e,!0)},off:function(t,e){this.events[t]=this.events[t].filter(function(t){return t.callback!==e&&!0!==t.once})},emit:function(t,e){var n=this;void 0===e&&(e={}),(this.events[t]||[]).forEach(function(r){r.callback(e),r.once&&n.off(t,r)}),window.dispatchEvent(new CustomEvent("spruce:"+t,{detail:e,bubbles:!0}))},watch:function(t,e){this.watchers[t]||(this.watchers[t]=[]),this.watchers[t].push(e)},runWatchers:function(t,e,n,r){var s=this;if(s.watchers[n])return s.watchers[n].forEach(function(t){return t(r)});Object.keys(s.watchers).filter(function(t){return t.includes(".")}).forEach(function(i){var o=i.split(".");n===o[o.length-1]&&o.reduce(function(t,o){return(t[n]===e[n]||Object.is(e,t))&&s.watchers[i].forEach(function(t){return t(r)}),t[o]},t)})}},stores:{},subscribers:[],start:function(){try{var t=this;return Promise.resolve(new Promise(function(t){"loading"==document.readyState?document.addEventListener("DOMContentLoaded",t):t()})).then(function(){t.emit("init"),t.attach(),t.stores=s(t.stores,{set:function(e,n,r){t.events.runWatchers(t.stores,e,n,r),t.updateSubscribers()}})})}catch(t){return Promise.reject(t)}},attach:function(){if(!window.Alpine)throw new Error("[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.");var t=this;window.Alpine.addMagicProperty("store",function(e){return t.subscribe(e),t.stores})},store:function(t,e){return this.stores[t]||(this.stores[t]=e),this.stores[t]},reset:function(t,e){this.stores[t]=e},subscribe:function(t){return this.subscribers.includes(t)||this.subscribers.push(t),this.stores},updateSubscribers:function(){this.subscribers.filter(function(t){return!!t.__x}).forEach(function(t){t.__x.updateElements(t)})},on:function(t,e){return this.events.on(t,e)},once:function(t,e){return this.events.once(t,e)},off:function(t,e){this.events.off(t,e)},emit:function(n,r){void 0===r&&(r={}),this.events.emit(n,function(n){for(var r=1;r<arguments.length;r++){var s=null!=arguments[r]?arguments[r]:{};r%2?e(Object(s),!0).forEach(function(e){t(n,e,s[e])}):Object.getOwnPropertyDescriptors?Object.defineProperties(n,Object.getOwnPropertyDescriptors(s)):e(Object(s)).forEach(function(t){Object.defineProperty(n,t,Object.getOwnPropertyDescriptor(s,t))})}return n}({},r,{store:this.stores}))},watch:function(t,e){this.events.watch(t,e)}},o=window.deferLoadingAlpine||function(t){t()};window.deferLoadingAlpine=function(t){window.Spruce=i,window.Spruce.start(),o(t)},module.exports=i;
var t=function(t){return null==t},e=function(t){return Object.getPrototypeOf(t)===Object.prototype},r=function(n,s){return Object.entries(n).forEach(function(i){var o=i[0],c=i[1];t(c)||!e(c)&&!Array.isArray(c)||(n[o]=r(c,s))}),new Proxy(n,{set:function(n,i,o){return!t(o)&&e(o)&&(o=r(o,s)),s.set(n,i,n[i]=o),!0}})},n={stores:{},persisted:[],subscribers:[],watchers:{},disableReactivity:!1,start:function(){try{var t=this;return Promise.resolve(new Promise(function(t){"loading"==document.readyState?document.addEventListener("DOMContentLoaded",t):t()})).then(function(){t.attach(),t.stores=r(t.stores,{set:function(e,r,n){if(!t.disableReactivity){t.updateSubscribers(),t.runWatchers(t.stores,e,r,n),t.disableReactivity=!0;try{t.persisted.forEach(t.updateLocalStorage.bind(t))}catch(t){}t.disableReactivity=!1}}})})}catch(t){return Promise.reject(t)}},attach:function(){if(!window.Alpine)throw new Error("[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.");var t=this;window.Alpine.addMagicProperty("store",function(e){return t.subscribe(e),t.stores})},store:function(t,e,r){if(void 0===r&&(r=!1),r)try{this.stores[t]=this.retrieveFromLocalStorage(t,(n={},Object.entries(e).filter(function(t){return"function"==typeof t[1]}).forEach(function(t){return n[t[0]]=t[1]}),n)),this.persisted.includes(t)||this.persisted.push(t)}catch(t){}var n;return this.stores[t]||(this.stores[t]=e),this.stores[t]},reset:function(t,e){this.stores[t]=e},subscribe:function(t){return this.subscribers.includes(t)||this.subscribers.push(t),this.stores},updateSubscribers:function(){this.subscribers.filter(function(t){return!!t.__x}).forEach(function(t){t.__x.updateElements(t)})},retrieveFromLocalStorage:function(t,e){void 0===e&&(e={});var r=JSON.parse(window.localStorage.getItem("__spruce:"+t));return r?Object.assign(e,r):null},updateLocalStorage:function(t){window.localStorage.setItem("__spruce:"+t,JSON.stringify(this.store(t)))},watch:function(t,e){this.watchers[t]||(this.watchers[t]=[]),this.watchers[t].push(e)},runWatchers:function(t,e,r,n){var s=this;if(s.watchers[r])return s.watchers[r].forEach(function(t){return t(n)});Object.keys(s.watchers).filter(function(t){return t.includes(".")}).forEach(function(i){var o=i.split(".");r===o[o.length-1]&&o.reduce(function(t,o){return(t[r]===e[r]||Object.is(e,t))&&s.watchers[i].forEach(function(t){return t(n)}),t[o]},t)})}},s=window.deferLoadingAlpine||function(t){t()};window.deferLoadingAlpine=function(t){window.Spruce=n,window.Spruce.start(),s(t)},module.exports=n;
//# sourceMappingURL=spruce.js.map

@@ -1,2 +0,2 @@

function t(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function e(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),n.push.apply(n,r)}return n}var n=function(t){return null==t},r=function(t){return Object.getPrototypeOf(t)===Object.prototype},s=function(t,e){return Object.entries(t).forEach(function(i){var o=i[0],c=i[1];n(c)||!r(c)&&!Array.isArray(c)||(t[o]=s(c,e))}),new Proxy(t,{set:function(t,i,o){return!n(o)&&r(o)&&(o=s(o,e)),e.set(t,i,t[i]=o),!0}})},i={events:{watchers:{},events:{},on:function(t,e,n){var r=this;return void 0===n&&(n=!1),this.events[t]||(this.events[t]=[]),this.events[t].push({callback:e,once:n}),function(){return r.off(t,e)}},once:function(t,e){this.on(t,e,!0)},off:function(t,e){this.events[t]=this.events[t].filter(function(t){return t.callback!==e&&!0!==t.once})},emit:function(t,e){var n=this;void 0===e&&(e={}),(this.events[t]||[]).forEach(function(r){r.callback(e),r.once&&n.off(t,r)}),window.dispatchEvent(new CustomEvent("spruce:"+t,{detail:e,bubbles:!0}))},watch:function(t,e){this.watchers[t]||(this.watchers[t]=[]),this.watchers[t].push(e)},runWatchers:function(t,e,n,r){var s=this;if(s.watchers[n])return s.watchers[n].forEach(function(t){return t(r)});Object.keys(s.watchers).filter(function(t){return t.includes(".")}).forEach(function(i){var o=i.split(".");n===o[o.length-1]&&o.reduce(function(t,o){return(t[n]===e[n]||Object.is(e,t))&&s.watchers[i].forEach(function(t){return t(r)}),t[o]},t)})}},stores:{},subscribers:[],start:function(){try{var t=this;return Promise.resolve(new Promise(function(t){"loading"==document.readyState?document.addEventListener("DOMContentLoaded",t):t()})).then(function(){t.emit("init"),t.attach(),t.stores=s(t.stores,{set:function(e,n,r){t.events.runWatchers(t.stores,e,n,r),t.updateSubscribers()}})})}catch(t){return Promise.reject(t)}},attach:function(){if(!window.Alpine)throw new Error("[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.");var t=this;window.Alpine.addMagicProperty("store",function(e){return t.subscribe(e),t.stores})},store:function(t,e){return this.stores[t]||(this.stores[t]=e),this.stores[t]},reset:function(t,e){this.stores[t]=e},subscribe:function(t){return this.subscribers.includes(t)||this.subscribers.push(t),this.stores},updateSubscribers:function(){this.subscribers.filter(function(t){return!!t.__x}).forEach(function(t){t.__x.updateElements(t)})},on:function(t,e){return this.events.on(t,e)},once:function(t,e){return this.events.once(t,e)},off:function(t,e){this.events.off(t,e)},emit:function(n,r){void 0===r&&(r={}),this.events.emit(n,function(n){for(var r=1;r<arguments.length;r++){var s=null!=arguments[r]?arguments[r]:{};r%2?e(Object(s),!0).forEach(function(e){t(n,e,s[e])}):Object.getOwnPropertyDescriptors?Object.defineProperties(n,Object.getOwnPropertyDescriptors(s)):e(Object(s)).forEach(function(t){Object.defineProperty(n,t,Object.getOwnPropertyDescriptor(s,t))})}return n}({},r,{store:this.stores}))},watch:function(t,e){this.events.watch(t,e)}},o=window.deferLoadingAlpine||function(t){t()};window.deferLoadingAlpine=function(t){window.Spruce=i,window.Spruce.start(),o(t)};export default i;
var t=function(t){return null==t},e=function(t){return Object.getPrototypeOf(t)===Object.prototype},r=function(n,s){return Object.entries(n).forEach(function(i){var o=i[0],c=i[1];t(c)||!e(c)&&!Array.isArray(c)||(n[o]=r(c,s))}),new Proxy(n,{set:function(n,i,o){return!t(o)&&e(o)&&(o=r(o,s)),s.set(n,i,n[i]=o),!0}})},n={stores:{},persisted:[],subscribers:[],watchers:{},disableReactivity:!1,start:function(){try{var t=this;return Promise.resolve(new Promise(function(t){"loading"==document.readyState?document.addEventListener("DOMContentLoaded",t):t()})).then(function(){t.attach(),t.stores=r(t.stores,{set:function(e,r,n){if(!t.disableReactivity){t.updateSubscribers(),t.runWatchers(t.stores,e,r,n),t.disableReactivity=!0;try{t.persisted.forEach(t.updateLocalStorage.bind(t))}catch(t){}t.disableReactivity=!1}}})})}catch(t){return Promise.reject(t)}},attach:function(){if(!window.Alpine)throw new Error("[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.");var t=this;window.Alpine.addMagicProperty("store",function(e){return t.subscribe(e),t.stores})},store:function(t,e,r){if(void 0===r&&(r=!1),r)try{this.stores[t]=this.retrieveFromLocalStorage(t,(n={},Object.entries(e).filter(function(t){return"function"==typeof t[1]}).forEach(function(t){return n[t[0]]=t[1]}),n)),this.persisted.includes(t)||this.persisted.push(t)}catch(t){}var n;return this.stores[t]||(this.stores[t]=e),this.stores[t]},reset:function(t,e){this.stores[t]=e},subscribe:function(t){return this.subscribers.includes(t)||this.subscribers.push(t),this.stores},updateSubscribers:function(){this.subscribers.filter(function(t){return!!t.__x}).forEach(function(t){t.__x.updateElements(t)})},retrieveFromLocalStorage:function(t,e){void 0===e&&(e={});var r=JSON.parse(window.localStorage.getItem("__spruce:"+t));return r?Object.assign(e,r):null},updateLocalStorage:function(t){window.localStorage.setItem("__spruce:"+t,JSON.stringify(this.store(t)))},watch:function(t,e){this.watchers[t]||(this.watchers[t]=[]),this.watchers[t].push(e)},runWatchers:function(t,e,r,n){var s=this;if(s.watchers[r])return s.watchers[r].forEach(function(t){return t(n)});Object.keys(s.watchers).filter(function(t){return t.includes(".")}).forEach(function(i){var o=i.split(".");r===o[o.length-1]&&o.reduce(function(t,o){return(t[r]===e[r]||Object.is(e,t))&&s.watchers[i].forEach(function(t){return t(n)}),t[o]},t)})}},s=window.deferLoadingAlpine||function(t){t()};window.deferLoadingAlpine=function(t){window.Spruce=n,window.Spruce.start(),s(t)};export default n;
//# sourceMappingURL=spruce.module.js.map

@@ -1,2 +0,2 @@

!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.spruce=e()}(this,function(){function t(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function e(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),n.push.apply(n,r)}return n}var n=function(t){return null==t},r=function(t){return Object.getPrototypeOf(t)===Object.prototype},i=function(t,e){return Object.entries(t).forEach(function(s){var o=s[0],c=s[1];n(c)||!r(c)&&!Array.isArray(c)||(t[o]=i(c,e))}),new Proxy(t,{set:function(t,s,o){return!n(o)&&r(o)&&(o=i(o,e)),e.set(t,s,t[s]=o),!0}})},s={events:{watchers:{},events:{},on:function(t,e,n){var r=this;return void 0===n&&(n=!1),this.events[t]||(this.events[t]=[]),this.events[t].push({callback:e,once:n}),function(){return r.off(t,e)}},once:function(t,e){this.on(t,e,!0)},off:function(t,e){this.events[t]=this.events[t].filter(function(t){return t.callback!==e&&!0!==t.once})},emit:function(t,e){var n=this;void 0===e&&(e={}),(this.events[t]||[]).forEach(function(r){r.callback(e),r.once&&n.off(t,r)}),window.dispatchEvent(new CustomEvent("spruce:"+t,{detail:e,bubbles:!0}))},watch:function(t,e){this.watchers[t]||(this.watchers[t]=[]),this.watchers[t].push(e)},runWatchers:function(t,e,n,r){var i=this;if(i.watchers[n])return i.watchers[n].forEach(function(t){return t(r)});Object.keys(i.watchers).filter(function(t){return t.includes(".")}).forEach(function(s){var o=s.split(".");n===o[o.length-1]&&o.reduce(function(t,o){return(t[n]===e[n]||Object.is(e,t))&&i.watchers[s].forEach(function(t){return t(r)}),t[o]},t)})}},stores:{},subscribers:[],start:function(){try{var t=this;return Promise.resolve(new Promise(function(t){"loading"==document.readyState?document.addEventListener("DOMContentLoaded",t):t()})).then(function(){t.emit("init"),t.attach(),t.stores=i(t.stores,{set:function(e,n,r){t.events.runWatchers(t.stores,e,n,r),t.updateSubscribers()}})})}catch(t){return Promise.reject(t)}},attach:function(){if(!window.Alpine)throw new Error("[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.");var t=this;window.Alpine.addMagicProperty("store",function(e){return t.subscribe(e),t.stores})},store:function(t,e){return this.stores[t]||(this.stores[t]=e),this.stores[t]},reset:function(t,e){this.stores[t]=e},subscribe:function(t){return this.subscribers.includes(t)||this.subscribers.push(t),this.stores},updateSubscribers:function(){this.subscribers.filter(function(t){return!!t.__x}).forEach(function(t){t.__x.updateElements(t)})},on:function(t,e){return this.events.on(t,e)},once:function(t,e){return this.events.once(t,e)},off:function(t,e){this.events.off(t,e)},emit:function(n,r){void 0===r&&(r={}),this.events.emit(n,function(n){for(var r=1;r<arguments.length;r++){var i=null!=arguments[r]?arguments[r]:{};r%2?e(Object(i),!0).forEach(function(e){t(n,e,i[e])}):Object.getOwnPropertyDescriptors?Object.defineProperties(n,Object.getOwnPropertyDescriptors(i)):e(Object(i)).forEach(function(t){Object.defineProperty(n,t,Object.getOwnPropertyDescriptor(i,t))})}return n}({},r,{store:this.stores}))},watch:function(t,e){this.events.watch(t,e)}},o=window.deferLoadingAlpine||function(t){t()};return window.deferLoadingAlpine=function(t){window.Spruce=s,window.Spruce.start(),o(t)},s});
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.spruce=e()}(this,function(){var t=function(t){return null==t},e=function(t){return Object.getPrototypeOf(t)===Object.prototype},r=function(n,i){return Object.entries(n).forEach(function(s){var o=s[0],c=s[1];t(c)||!e(c)&&!Array.isArray(c)||(n[o]=r(c,i))}),new Proxy(n,{set:function(n,s,o){return!t(o)&&e(o)&&(o=r(o,i)),i.set(n,s,n[s]=o),!0}})},n={stores:{},persisted:[],subscribers:[],watchers:{},disableReactivity:!1,start:function(){try{var t=this;return Promise.resolve(new Promise(function(t){"loading"==document.readyState?document.addEventListener("DOMContentLoaded",t):t()})).then(function(){t.attach(),t.stores=r(t.stores,{set:function(e,r,n){if(!t.disableReactivity){t.updateSubscribers(),t.runWatchers(t.stores,e,r,n),t.disableReactivity=!0;try{t.persisted.forEach(t.updateLocalStorage.bind(t))}catch(t){}t.disableReactivity=!1}}})})}catch(t){return Promise.reject(t)}},attach:function(){if(!window.Alpine)throw new Error("[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.");var t=this;window.Alpine.addMagicProperty("store",function(e){return t.subscribe(e),t.stores})},store:function(t,e,r){if(void 0===r&&(r=!1),r)try{this.stores[t]=this.retrieveFromLocalStorage(t,(n={},Object.entries(e).filter(function(t){return"function"==typeof t[1]}).forEach(function(t){return n[t[0]]=t[1]}),n)),this.persisted.includes(t)||this.persisted.push(t)}catch(t){}var n;return this.stores[t]||(this.stores[t]=e),this.stores[t]},reset:function(t,e){this.stores[t]=e},subscribe:function(t){return this.subscribers.includes(t)||this.subscribers.push(t),this.stores},updateSubscribers:function(){this.subscribers.filter(function(t){return!!t.__x}).forEach(function(t){t.__x.updateElements(t)})},retrieveFromLocalStorage:function(t,e){void 0===e&&(e={});var r=JSON.parse(window.localStorage.getItem("__spruce:"+t));return r?Object.assign(e,r):null},updateLocalStorage:function(t){window.localStorage.setItem("__spruce:"+t,JSON.stringify(this.store(t)))},watch:function(t,e){this.watchers[t]||(this.watchers[t]=[]),this.watchers[t].push(e)},runWatchers:function(t,e,r,n){var i=this;if(i.watchers[r])return i.watchers[r].forEach(function(t){return t(n)});Object.keys(i.watchers).filter(function(t){return t.includes(".")}).forEach(function(s){var o=s.split(".");r===o[o.length-1]&&o.reduce(function(t,o){return(t[r]===e[r]||Object.is(e,t))&&i.watchers[s].forEach(function(t){return t(n)}),t[o]},t)})}},i=window.deferLoadingAlpine||function(t){t()};return window.deferLoadingAlpine=function(t){window.Spruce=n,window.Spruce.start(),i(t)},n});
//# sourceMappingURL=spruce.umd.js.map
{
"name": "@ryangjchandler/spruce",
"description": "A lightweight state management layer for Alpine.js",
"version": "1.1.2",
"version": "2.0.0",
"repository": {

@@ -6,0 +6,0 @@ "type": "git",

@@ -200,59 +200,37 @@ > ✨ Help support the maintenance of this package by [sponsoring me](https://github.com/sponsors/ryangjchandler).

### Event bus
### Persisting stores
Spruce ships with a basic event bus. It exposes two methods:
You can persist the state of a global store between page loads using [local storage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) by passing a third boolean argument to the `Spruce.store()` method.
* `Spruce.on(eventName, callback)` - this can be used to register an event listener. This will react to any internal events, such as `init` . Your callback will receive a single `detail` property which contains any data sent from the event, as well as the global store.
```js
Spruce.on('init', ({ store }) => {
// do something with the store here...
})
Spruce.store('form', {
name: 'Ryan',
email: 'support@ryangjchandler.co.uk'
}, true)
```
* `Spruce.once(eventName, callback)` - this can be used to register an event listener that is only run **a single time**. This is useful for one time events, such as fetching HTML from the server when hovering over a button or similar.
When the `form` store is updated, any changes will be persisted to `__spruce:form` key in local storage.
``` js
Spruce.once('event', () => {
// do something once...
})
```
> **Note**: some browsers will disable access to local storage when browsing in private mode.
* `Spruce.off(eventName, callback)` - this can be used to unhook or de-register an event listener.
**Persisted stores with methods**
``` js
var callback = () => {}
Stores that contain methods can still be persisted. These methods cannot be JSON-serialized, so will be re-added to the data that was retrieved from local storage.
Spruce.off('init', callback)
```
```js
Spruce.store('form', {
name: 'Ryan',
email: 'support@ryangjchandler.co.uk',
logName() {
console.log(this.name)
}
}, true)
You can also unhook a listener using the function returned by `Spruce.on()` . This is especially useful for anonymous function callbacks.
``` js
var off = Spruce.on('event', () => {})
off()
Spruce.store('form').logName() // logs `Ryan` to console.
```
* `Spruce.emit(eventName, data = {})` - this can be used to emit an event. The first argument should be the name of the event, the second should be an object containing data. This will be merged in with the core data, which consists of a `store` property. When emitting an event, a browser event will also be dispatched with a `spruce:` prefix.
``` js
Spruce.emit('event-name', {
foo: 'bar'
})
```
In the example above, a `spruce:event-name` event will be fired on the `window` level, so you could register an event listener inside of your Alpine component:
``` html
<div x-data @spruce:event-name.window="foo = $event.detail.store.foo">
</div>
```
k
## Versioning
This project follows the [Semantic Versioning](https://semver.org/) guidelines. This means that there *could* be breaking changes on minor version changes, up until v1.x is reached.
This project follows the [Semantic Versioning](https://semver.org/) guidelines.
For example, 0.1 -> 0.2 might introduce a breaking change.
## License

@@ -259,0 +237,0 @@

@@ -1,17 +0,18 @@

import { domReady } from './utils'
import { domReady, getMethods } from './utils'
import { createObservable } from './observable'
import EventBus from './bus'
const Spruce = {
events: EventBus,
stores: {},
persisted: [],
subscribers: [],
watchers: {},
disableReactivity: false,
async start() {
await domReady()
this.emit('init')
this.attach()

@@ -21,5 +22,19 @@

set: (target, key, value) => {
this.events.runWatchers(this.stores, target, key, value)
if (this.disableReactivity) {
return
}
this.updateSubscribers()
this.runWatchers(this.stores, target, key, value)
this.disableReactivity = true
try {
this.persisted.forEach(this.updateLocalStorage.bind(this))
} catch (e) {
// Do nothing here (thanks Safari!)
}
this.disableReactivity = false
}

@@ -30,3 +45,3 @@ })

attach() {
if (! window.Alpine) {
if (!window.Alpine) {
throw new Error('[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.')

@@ -44,4 +59,16 @@ }

store(name, state) {
if (! this.stores[name]) {
store(name, state, persist = false) {
if (persist) {
try {
this.stores[name] = this.retrieveFromLocalStorage(name, getMethods(state))
if (!this.persisted.includes(name)) {
this.persisted.push(name)
}
} catch (e) {
// Do nothing here (thanks Safari!)
}
}
if (!this.stores[name]) {
this.stores[name] = state

@@ -58,3 +85,3 @@ }

subscribe(el) {
if (! this.subscribers.includes(el)) {
if (!this.subscribers.includes(el)) {
this.subscribers.push(el)

@@ -67,3 +94,3 @@ }

updateSubscribers() {
this.subscribers.filter(el => !! el.__x).forEach(el => {
this.subscribers.filter(el => !!el.__x).forEach(el => {
el.__x.updateElements(el)

@@ -73,20 +100,42 @@ })

on(name, callback) {
return this.events.on(name, callback)
},
retrieveFromLocalStorage(name, methods = {}) {
const storage = JSON.parse(window.localStorage.getItem(`__spruce:${name}`))
once(name, callback) {
return this.events.once(name, callback)
return storage ? Object.assign(methods, storage) : null
},
off(name, callback) {
this.events.off(name, callback)
updateLocalStorage(name) {
window.localStorage.setItem(`__spruce:${name}`, JSON.stringify(this.store(name)))
},
emit(name, data = {}) {
this.events.emit(name, { ...data, store: this.stores })
watch(name, callback) {
if (!this.watchers[name]) {
this.watchers[name] = []
}
this.watchers[name].push(callback)
},
watch(dotNotation, callback) {
this.events.watch(dotNotation, callback)
runWatchers(stores, target, key, value) {
const self = this
if (self.watchers[key]) {
return self.watchers[key].forEach(callback => callback(value))
}
Object.keys(self.watchers)
.filter(watcher => watcher.includes('.'))
.forEach(fullDotNotationKey => {
let dotNotationParts = fullDotNotationKey.split('.')
if (key !== dotNotationParts[dotNotationParts.length - 1]) return
dotNotationParts.reduce((comparison, part) => {
if (comparison[key] === target[key] || Object.is(target, comparison)) {
self.watchers[fullDotNotationKey].forEach(callback => callback(value))
}
return comparison[part]
}, stores)
})
}

@@ -93,0 +142,0 @@ }

@@ -11,12 +11,2 @@ export const domReady = () => {

export const buildInitExpression = el => {
let expression = "$store = Spruce.subscribe($el)"
if (el.hasAttribute('x-init')) {
expression = `${expression}; ${el.getAttribute('x-init')}`
}
return expression
}
export const isNullOrUndefined = value => {

@@ -30,2 +20,10 @@ return value === null || value === undefined

export const isArray = _ => Array.isArray(_)
export const isArray = _ => Array.isArray(_)
export const getMethods = obj => {
let methods = {}
Object.entries(obj).filter(([key, value]) => typeof value === 'function').forEach(([key, value]) => methods[key] = value)
return methods
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc