@ryangjchandler/spruce
Advanced tools
Comparing version 2.0.1 to 2.1.0
@@ -0,1 +1,3 @@ | ||
<p align="center"><img src="/art/header.png?1" alt="spruce header"></p> | ||
> ✨ Help support the maintenance of this package by [sponsoring me](https://github.com/sponsors/ryangjchandler). | ||
@@ -11,225 +13,21 @@ | ||
## Installation | ||
## Documentation | ||
### CDN | ||
To learn more about Spruce and how to use it, please refer to the [official documentation](https://docs.ryangjchandler.co.uk/spruce). | ||
Include the following `<script>` tag in the `<head>` of your document: | ||
## Credits | ||
``` html | ||
<script src="https://cdn.jsdelivr.net/npm/@ryangjchandler/spruce@2.x.x/dist/spruce.umd.js"></script> | ||
``` | ||
- [Ryan Chandler](https://github.com/ryangjchandler) | ||
- [All contributors](https://github.com/ryangjchandler/spruce/contributors) | ||
> **Important**: This must be added **before** loading Alpine.js when using CDN links. | ||
Special thanks to [Caneco](https://twitter.com/caneco) for the logo ✨ | ||
### Manual | ||
## Versioning | ||
If you wish to include Spruce with your own bundle: | ||
This project follows the [Semantic Versioning](https://semver.org/) guidelines. | ||
```bash | ||
yarn add @ryangjchandler/spruce | ||
``` | ||
## Security | ||
or: | ||
Please refer to [SECURITY.md](SECURITY.md) for more information. | ||
```bash | ||
npm install @ryangjchandler/spruce --save | ||
``` | ||
Then add the following to your script: | ||
``` javascript | ||
import Spruce from '@ryangjchandler/spruce' | ||
``` | ||
## Quick start | ||
To verify you have correctly installed Spruce, copy & paste the following code snippet into your project. | ||
``` html | ||
<div x-data> | ||
<div x-show="$store.modal.open === 'login'"> | ||
<p> | ||
This "login" modal isn't built with a11y in mind, don't actually use it | ||
</p> | ||
</div> | ||
</div> | ||
<div x-data> | ||
<div x-show="$store.modal.open === 'register'"> | ||
<p> | ||
This "register" modal isn't built with a11y in mind, don't actually use it | ||
</p> | ||
</div> | ||
</div> | ||
<div x-data> | ||
<select x-model="$store.modal.open"> | ||
<option value="login" selected>login</option> | ||
<option value="register">register</option> | ||
</select> | ||
</div> | ||
<script> | ||
Spruce.store('modal', { | ||
open: 'login', | ||
}); | ||
</script> | ||
``` | ||
To see what the code _should_ do, use [this CodePen](https://codepen.io/hugodf/pen/dyYJXEa). Thanks @HugoDF! | ||
## Usage | ||
Spruce exposes less than a handful of possible interaction points. There is an extremely simple "subscriptions" interaction which connects the roots from your Alpine component to the global store, then there is the "stores" interaction which allows you to define scopes of global state for use throughout your components. | ||
### Entry point | ||
If you are using the CDN build, you can interact with Spruce using the `window.Spruce` variable: | ||
```html | ||
<script> | ||
Spruce.store('modals', { | ||
open: 'login', | ||
}) | ||
</script> | ||
``` | ||
If you are importing Spruce into your own bundle, you can interact with it like any other variable: | ||
**store.js** | ||
```js | ||
import Spruce from '@ryangjchandler/spruce' | ||
Spruce.store('modals', { | ||
open: 'login' | ||
}) | ||
export default Spruce | ||
``` | ||
**app.js** | ||
```js | ||
import './store' | ||
import 'alpinejs' | ||
``` | ||
> **Note**: You must `import` your store before Alpine. | ||
### Subscribing your components | ||
Spruce hooks into Alpine using the "magic properties" API, meaning there are no extra steps needed. Start using the `$store` variable in your components right away. | ||
```html | ||
<div x-data="{}"> | ||
<span x-text="$store.application.name"></span> | ||
</div> | ||
``` | ||
### Defining global state | ||
To define a piece of global state, you can use the `Spruce.store()` method: | ||
```js | ||
Spruce.store('application', { | ||
name: 'Amazing Alpine Application' | ||
}) | ||
``` | ||
The first argument defines the top level property of the scope. The second argument defines the state for the scope, it could be a string, integer or object with nested properties. | ||
To access the `name` property, you can do the following inside of your component: | ||
```html | ||
<div x-data="{}"> | ||
<span x-text="$store.application.name"></span> | ||
</div> | ||
``` | ||
The `<span>` will now have "Amazing Alpine Application" set as its `innerText` . | ||
### Modifying state from outside of Alpine | ||
You can modify your global state from external scripts using the `Spruce.store()` method too: | ||
```js | ||
Spruce.store('application', { | ||
name: 'Amazing Alpine Application' | ||
}) | ||
Spruce.store('application').name = 'Amazing Spruce Integration' | ||
``` | ||
This will trigger Alpine to re-evaluate your subscribed components and re-render. | ||
### Resetting global state | ||
A `Spruce.reset()` method is provided so that you can completely overwrite a global store: | ||
```js | ||
Spruce.store('application', { | ||
name: 'Amazing Alpine Application' | ||
}) | ||
Spruce.reset('application', { | ||
name: 'Reset Application' | ||
}) | ||
``` | ||
Calling the `reset` method will make the new state reactive and cause subscribed components to re-render. | ||
### Externally watching for changes | ||
You can register watchers in a similar fashion to Alpine. All you need is the full dot-notation representation of your piece of state and a callback. | ||
```js | ||
Spruce.store('form', { | ||
name: 'Ryan', | ||
email: 'support@ryangjchandler.co.uk' | ||
}) | ||
Spruce.watch('form.email', value => { | ||
// do something with the new value here | ||
}) | ||
``` | ||
In the above snippet, when we change the value of `form.email` either from a component or externally in a separate JavaScript file, our callback will be invoked and will receive the new value. This can be useful for running automatic inline validation when a property changes, or triggering an action elsewhere in another component without the need for dispatching events. | ||
> **Note**: you can get stuck in an watch loop if you're updating other store properties that also have watchers defined. | ||
### Persisting stores | ||
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. | ||
```js | ||
Spruce.store('form', { | ||
name: 'Ryan', | ||
email: 'support@ryangjchandler.co.uk' | ||
}, true) | ||
``` | ||
When the `form` store is updated, any changes will be persisted to `__spruce:form` key in local storage. | ||
> **Note**: some browsers will disable access to local storage when browsing in private mode. | ||
**Persisted stores with methods** | ||
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. | ||
```js | ||
Spruce.store('form', { | ||
name: 'Ryan', | ||
email: 'support@ryangjchandler.co.uk', | ||
logName() { | ||
console.log(this.name) | ||
} | ||
}, true) | ||
Spruce.store('form').logName() // logs `Ryan` to console. | ||
``` | ||
## Versioning | ||
This project follows the [Semantic Versioning](https://semver.org/) guidelines. | ||
## License | ||
@@ -236,0 +34,0 @@ |
@@ -1,2 +0,2 @@ | ||
"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var e=function(e,t){return function(e,t){e.exports=function(){var e=/^v?(?:\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+))?(?:-[\da-z\-]+(?:\.[\da-z\-]+)*)?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;function t(e){var t,r=e.replace(/^v/,"").replace(/\+.*$/,""),n=-1===(t=r).indexOf("-")?t.length:t.indexOf("-"),i=r.substring(0,n).split(".");return i.push(r.substring(n+1)),i}function r(e){return isNaN(Number(e))?e:Number(e)}function n(t){if("string"!=typeof t)throw new TypeError("Invalid argument expected string");if(!e.test(t))throw new Error("Invalid argument not valid semver ('"+t+"' received)")}function i(e,i){[e,i].forEach(n);for(var o=t(e),s=t(i),u=0;u<Math.max(o.length-1,s.length-1);u++){var a=parseInt(o[u]||0,10),c=parseInt(s[u]||0,10);if(a>c)return 1;if(c>a)return-1}var f=o[o.length-1],d=s[s.length-1];if(f&&d){var p=f.split(".").map(r),h=d.split(".").map(r);for(u=0;u<Math.max(p.length,h.length);u++){if(void 0===p[u]||"string"==typeof h[u]&&"number"==typeof p[u])return-1;if(void 0===h[u]||"string"==typeof p[u]&&"number"==typeof h[u])return 1;if(p[u]>h[u])return 1;if(h[u]>p[u])return-1}}else if(f||d)return f?-1:1;return 0}var o=[">",">=","=","<","<="],s={">":[1],">=":[0,1],"=":[0],"<=":[-1,0],"<":[-1]};return i.validate=function(t){return"string"==typeof t&&e.test(t)},i.compare=function(e,t,r){!function(e){if("string"!=typeof e)throw new TypeError("Invalid operator type, expected string but got "+typeof e);if(-1===o.indexOf(e))throw new TypeError("Invalid operator, expected one of "+o.join("|"))}(r);var n=i(e,t);return s[r].indexOf(n)>-1},i}()}(t={exports:{}}),t.exports}(),t=function(e){return null==e},r=function(e){return Object.getPrototypeOf(e)===Object.prototype},n=function(e,i){return Object.entries(e).forEach(function(o){var s=o[0],u=o[1];t(u)||!r(u)&&!Array.isArray(u)||(e[s]=n(u,i))}),new Proxy(e,{set:function(e,o,s){return!t(s)&&r(s)&&(s=n(s,i)),i.set(e,o,e[o]=s),!0}})},i={stores:{},persisted:[],subscribers:[],watchers:{},disableReactivity:!1,start:function(){try{var e=this;return Promise.resolve(new Promise(function(e){"loading"==document.readyState?document.addEventListener("DOMContentLoaded",e):e()})).then(function(){e.attach(),e.stores=n(e.stores,{set:function(t,r,n){if(!e.disableReactivity){e.updateSubscribers(),e.runWatchers(e.stores,t,r,n),e.disableReactivity=!0;try{e.persisted.forEach(e.updateLocalStorage.bind(e))}catch(e){}e.disableReactivity=!1}}})})}catch(e){return Promise.reject(e)}},attach:function(){if(!(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")||window.Alpine&&e.compare(window.Alpine.version,"2.7.0",">=")))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(e,t,r){if(void 0===r&&(r=!1),r)try{this.stores[e]=this.retrieveFromLocalStorage(e,(n={},Object.entries(t).filter(function(e){return"function"==typeof e[1]}).forEach(function(e){return n[e[0]]=e[1]}),n)),this.persisted.includes(e)||this.persisted.push(e)}catch(e){}var n;return this.stores[e]||(this.stores[e]=t),this.stores[e]},reset:function(e,t){this.stores[e]=t},subscribe:function(e){return this.subscribers.includes(e)||this.subscribers.push(e),this.stores},updateSubscribers:function(){this.subscribers.filter(function(e){return!!e.__x}).forEach(function(e){e.__x.updateElements(e)})},retrieveFromLocalStorage:function(e,t){void 0===t&&(t={});var r=JSON.parse(window.localStorage.getItem("__spruce:"+e));return r?Object.assign(t,r):null},updateLocalStorage:function(e){window.localStorage.setItem("__spruce:"+e,JSON.stringify(this.store(e)))},watch:function(e,t){this.watchers[e]||(this.watchers[e]=[]),this.watchers[e].push(t)},runWatchers:function(e,t,r,n){var i=this;if(i.watchers[r])return i.watchers[r].forEach(function(e){return e(n)});Object.keys(i.watchers).filter(function(e){return e.includes(".")}).forEach(function(o){var s=o.split(".");r===s[s.length-1]&&s.reduce(function(e,s){return(e[r]===t[r]||Object.is(t,e))&&i.watchers[o].forEach(function(e){return e(n)}),e[s]},e)})}},o=window.deferLoadingAlpine||function(e){e()};window.deferLoadingAlpine=function(e){window.Spruce=i,window.Spruce.start(),o(e)},module.exports=i; | ||
"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var t=function(t,e){return function(t,e){t.exports=function(){var t=/^v?(?:\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+))?(?:-[\da-z\-]+(?:\.[\da-z\-]+)*)?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;function e(t){var e,r=t.replace(/^v/,"").replace(/\+.*$/,""),n=-1===(e=r).indexOf("-")?e.length:e.indexOf("-"),i=r.substring(0,n).split(".");return i.push(r.substring(n+1)),i}function r(t){return isNaN(Number(t))?t:Number(t)}function n(e){if("string"!=typeof e)throw new TypeError("Invalid argument expected string");if(!t.test(e))throw new Error("Invalid argument not valid semver ('"+e+"' received)")}function i(t,i){[t,i].forEach(n);for(var s=e(t),o=e(i),u=0;u<Math.max(s.length-1,o.length-1);u++){var a=parseInt(s[u]||0,10),c=parseInt(o[u]||0,10);if(a>c)return 1;if(c>a)return-1}var f=s[s.length-1],d=o[o.length-1];if(f&&d){var p=f.split(".").map(r),h=d.split(".").map(r);for(u=0;u<Math.max(p.length,h.length);u++){if(void 0===p[u]||"string"==typeof h[u]&&"number"==typeof p[u])return-1;if(void 0===h[u]||"string"==typeof p[u]&&"number"==typeof h[u])return 1;if(p[u]>h[u])return 1;if(h[u]>p[u])return-1}}else if(f||d)return f?-1:1;return 0}var s=[">",">=","=","<","<="],o={">":[1],">=":[0,1],"=":[0],"<=":[-1,0],"<":[-1]};return i.validate=function(e){return"string"==typeof e&&t.test(e)},i.compare=function(t,e,r){!function(t){if("string"!=typeof t)throw new TypeError("Invalid operator type, expected string but got "+typeof t);if(-1===s.indexOf(t))throw new TypeError("Invalid operator, expected one of "+s.join("|"))}(r);var n=i(t,e);return o[r].indexOf(n)>-1},i}()}(e={exports:{}}),e.exports}(),e=function(t){return null==t},r=function(t){return Object.getPrototypeOf(t)===Object.prototype},n=function(t,i){return Object.entries(t).forEach(function(s){var o=s[0],u=s[1];e(u)||!r(u)&&!Array.isArray(u)||(t[o]=n(u,i))}),new Proxy(t,{set:function(t,s,o){return!e(o)&&r(o)&&(o=n(o,i)),i.set(t,s,t[s]=o),!0}})},i={stores:{},persisted:[],subscribers:[],watchers:{},disableReactivity:!1,start:function(){var t=this;this.attach(),this.stores=n(this.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}}})},attach:function(){if(!(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")||window.Alpine&&t.compare(window.Alpine.version,"2.7.0",">=")))throw new Error("[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.");var e=this;window.Alpine.addMagicProperty("store",function(t){return e.subscribe(t),e.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)})}};window.Spruce=i;var s=window.deferLoadingAlpine||function(t){t()};window.deferLoadingAlpine=function(t){window.Spruce.start(),s(t)},module.exports=i; | ||
//# sourceMappingURL=spruce.js.map |
@@ -1,2 +0,2 @@ | ||
"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var e,t=(function(e,t){e.exports=function(){var e=/^v?(?:\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+))?(?:-[\da-z\-]+(?:\.[\da-z\-]+)*)?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;function t(e){var t,r=e.replace(/^v/,"").replace(/\+.*$/,""),n=-1===(t=r).indexOf("-")?t.length:t.indexOf("-"),i=r.substring(0,n).split(".");return i.push(r.substring(n+1)),i}function r(e){return isNaN(Number(e))?e:Number(e)}function n(t){if("string"!=typeof t)throw new TypeError("Invalid argument expected string");if(!e.test(t))throw new Error("Invalid argument not valid semver ('"+t+"' received)")}function i(e,i){[e,i].forEach(n);for(var o=t(e),s=t(i),u=0;u<Math.max(o.length-1,s.length-1);u++){var a=parseInt(o[u]||0,10),c=parseInt(s[u]||0,10);if(a>c)return 1;if(c>a)return-1}var f=o[o.length-1],d=s[s.length-1];if(f&&d){var p=f.split(".").map(r),h=d.split(".").map(r);for(u=0;u<Math.max(p.length,h.length);u++){if(void 0===p[u]||"string"==typeof h[u]&&"number"==typeof p[u])return-1;if(void 0===h[u]||"string"==typeof p[u]&&"number"==typeof h[u])return 1;if(p[u]>h[u])return 1;if(h[u]>p[u])return-1}}else if(f||d)return f?-1:1;return 0}var o=[">",">=","=","<","<="],s={">":[1],">=":[0,1],"=":[0],"<=":[-1,0],"<":[-1]};return i.validate=function(t){return"string"==typeof t&&e.test(t)},i.compare=function(e,t,r){!function(e){if("string"!=typeof e)throw new TypeError("Invalid operator type, expected string but got "+typeof e);if(-1===o.indexOf(e))throw new TypeError("Invalid operator, expected one of "+o.join("|"))}(r);var n=i(e,t);return s[r].indexOf(n)>-1},i}()}(e={exports:{}}),e.exports),r=function(e){return null==e},n=function(e){return Object.getPrototypeOf(e)===Object.prototype},i=function(e,t){return Object.entries(e).forEach(function(o){var s=o[0],u=o[1];r(u)||!n(u)&&!Array.isArray(u)||(e[s]=i(u,t))}),new Proxy(e,{set:function(e,o,s){return!r(s)&&n(s)&&(s=i(s,t)),t.set(e,o,e[o]=s),!0}})},o={stores:{},persisted:[],subscribers:[],watchers:{},disableReactivity:!1,start:function(){try{var e=this;return Promise.resolve(new Promise(function(e){"loading"==document.readyState?document.addEventListener("DOMContentLoaded",e):e()})).then(function(){e.attach(),e.stores=i(e.stores,{set:function(t,r,n){if(!e.disableReactivity){e.updateSubscribers(),e.runWatchers(e.stores,t,r,n),e.disableReactivity=!0;try{e.persisted.forEach(e.updateLocalStorage.bind(e))}catch(e){}e.disableReactivity=!1}}})})}catch(e){return Promise.reject(e)}},attach:function(){if(!(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")||window.Alpine&&t.compare(window.Alpine.version,"2.7.0",">=")))throw new Error("[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.");var e=this;window.Alpine.addMagicProperty("store",function(t){return e.subscribe(t),e.stores})},store:function(e,t,r){if(void 0===r&&(r=!1),r)try{this.stores[e]=this.retrieveFromLocalStorage(e,(n={},Object.entries(t).filter(function(e){return"function"==typeof e[1]}).forEach(function(e){return n[e[0]]=e[1]}),n)),this.persisted.includes(e)||this.persisted.push(e)}catch(e){}var n;return this.stores[e]||(this.stores[e]=t),this.stores[e]},reset:function(e,t){this.stores[e]=t},subscribe:function(e){return this.subscribers.includes(e)||this.subscribers.push(e),this.stores},updateSubscribers:function(){this.subscribers.filter(function(e){return!!e.__x}).forEach(function(e){e.__x.updateElements(e)})},retrieveFromLocalStorage:function(e,t){void 0===t&&(t={});var r=JSON.parse(window.localStorage.getItem("__spruce:"+e));return r?Object.assign(t,r):null},updateLocalStorage:function(e){window.localStorage.setItem("__spruce:"+e,JSON.stringify(this.store(e)))},watch:function(e,t){this.watchers[e]||(this.watchers[e]=[]),this.watchers[e].push(t)},runWatchers:function(e,t,r,n){var i=this;if(i.watchers[r])return i.watchers[r].forEach(function(e){return e(n)});Object.keys(i.watchers).filter(function(e){return e.includes(".")}).forEach(function(o){var s=o.split(".");r===s[s.length-1]&&s.reduce(function(e,s){return(e[r]===t[r]||Object.is(t,e))&&i.watchers[o].forEach(function(e){return e(n)}),e[s]},e)})}},s=window.deferLoadingAlpine||function(e){e()};window.deferLoadingAlpine=function(e){window.Spruce=o,window.Spruce.start(),s(e)};export default o; | ||
"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var t,e=(function(t,e){t.exports=function(){var t=/^v?(?:\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+))?(?:-[\da-z\-]+(?:\.[\da-z\-]+)*)?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;function e(t){var e,r=t.replace(/^v/,"").replace(/\+.*$/,""),n=-1===(e=r).indexOf("-")?e.length:e.indexOf("-"),i=r.substring(0,n).split(".");return i.push(r.substring(n+1)),i}function r(t){return isNaN(Number(t))?t:Number(t)}function n(e){if("string"!=typeof e)throw new TypeError("Invalid argument expected string");if(!t.test(e))throw new Error("Invalid argument not valid semver ('"+e+"' received)")}function i(t,i){[t,i].forEach(n);for(var s=e(t),o=e(i),u=0;u<Math.max(s.length-1,o.length-1);u++){var a=parseInt(s[u]||0,10),c=parseInt(o[u]||0,10);if(a>c)return 1;if(c>a)return-1}var f=s[s.length-1],d=o[o.length-1];if(f&&d){var p=f.split(".").map(r),h=d.split(".").map(r);for(u=0;u<Math.max(p.length,h.length);u++){if(void 0===p[u]||"string"==typeof h[u]&&"number"==typeof p[u])return-1;if(void 0===h[u]||"string"==typeof p[u]&&"number"==typeof h[u])return 1;if(p[u]>h[u])return 1;if(h[u]>p[u])return-1}}else if(f||d)return f?-1:1;return 0}var s=[">",">=","=","<","<="],o={">":[1],">=":[0,1],"=":[0],"<=":[-1,0],"<":[-1]};return i.validate=function(e){return"string"==typeof e&&t.test(e)},i.compare=function(t,e,r){!function(t){if("string"!=typeof t)throw new TypeError("Invalid operator type, expected string but got "+typeof t);if(-1===s.indexOf(t))throw new TypeError("Invalid operator, expected one of "+s.join("|"))}(r);var n=i(t,e);return o[r].indexOf(n)>-1},i}()}(t={exports:{}}),t.exports),r=function(t){return null==t},n=function(t){return Object.getPrototypeOf(t)===Object.prototype},i=function(t,e){return Object.entries(t).forEach(function(s){var o=s[0],u=s[1];r(u)||!n(u)&&!Array.isArray(u)||(t[o]=i(u,e))}),new Proxy(t,{set:function(t,s,o){return!r(o)&&n(o)&&(o=i(o,e)),e.set(t,s,t[s]=o),!0}})},s={stores:{},persisted:[],subscribers:[],watchers:{},disableReactivity:!1,start:function(){var t=this;this.attach(),this.stores=i(this.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}}})},attach:function(){if(!(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")||window.Alpine&&e.compare(window.Alpine.version,"2.7.0",">=")))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)})}};window.Spruce=s;var o=window.deferLoadingAlpine||function(t){t()};window.deferLoadingAlpine=function(t){window.Spruce.start(),o(t)};export default s; | ||
//# sourceMappingURL=spruce.module.js.map |
@@ -1,2 +0,2 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.spruce=t()}(this,function(){"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var e,t=(function(e,t){e.exports=function(){var e=/^v?(?:\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+))?(?:-[\da-z\-]+(?:\.[\da-z\-]+)*)?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;function t(e){var t,r=e.replace(/^v/,"").replace(/\+.*$/,""),n=-1===(t=r).indexOf("-")?t.length:t.indexOf("-"),i=r.substring(0,n).split(".");return i.push(r.substring(n+1)),i}function r(e){return isNaN(Number(e))?e:Number(e)}function n(t){if("string"!=typeof t)throw new TypeError("Invalid argument expected string");if(!e.test(t))throw new Error("Invalid argument not valid semver ('"+t+"' received)")}function i(e,i){[e,i].forEach(n);for(var o=t(e),s=t(i),u=0;u<Math.max(o.length-1,s.length-1);u++){var c=parseInt(o[u]||0,10),a=parseInt(s[u]||0,10);if(c>a)return 1;if(a>c)return-1}var f=o[o.length-1],d=s[s.length-1];if(f&&d){var p=f.split(".").map(r),h=d.split(".").map(r);for(u=0;u<Math.max(p.length,h.length);u++){if(void 0===p[u]||"string"==typeof h[u]&&"number"==typeof p[u])return-1;if(void 0===h[u]||"string"==typeof p[u]&&"number"==typeof h[u])return 1;if(p[u]>h[u])return 1;if(h[u]>p[u])return-1}}else if(f||d)return f?-1:1;return 0}var o=[">",">=","=","<","<="],s={">":[1],">=":[0,1],"=":[0],"<=":[-1,0],"<":[-1]};return i.validate=function(t){return"string"==typeof t&&e.test(t)},i.compare=function(e,t,r){!function(e){if("string"!=typeof e)throw new TypeError("Invalid operator type, expected string but got "+typeof e);if(-1===o.indexOf(e))throw new TypeError("Invalid operator, expected one of "+o.join("|"))}(r);var n=i(e,t);return s[r].indexOf(n)>-1},i}()}(e={exports:{}}),e.exports),r=function(e){return null==e},n=function(e){return Object.getPrototypeOf(e)===Object.prototype},i=function(e,t){return Object.entries(e).forEach(function(o){var s=o[0],u=o[1];r(u)||!n(u)&&!Array.isArray(u)||(e[s]=i(u,t))}),new Proxy(e,{set:function(e,o,s){return!r(s)&&n(s)&&(s=i(s,t)),t.set(e,o,e[o]=s),!0}})},o={stores:{},persisted:[],subscribers:[],watchers:{},disableReactivity:!1,start:function(){try{var e=this;return Promise.resolve(new Promise(function(e){"loading"==document.readyState?document.addEventListener("DOMContentLoaded",e):e()})).then(function(){e.attach(),e.stores=i(e.stores,{set:function(t,r,n){if(!e.disableReactivity){e.updateSubscribers(),e.runWatchers(e.stores,t,r,n),e.disableReactivity=!0;try{e.persisted.forEach(e.updateLocalStorage.bind(e))}catch(e){}e.disableReactivity=!1}}})})}catch(e){return Promise.reject(e)}},attach:function(){if(!(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")||window.Alpine&&t.compare(window.Alpine.version,"2.7.0",">=")))throw new Error("[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.");var e=this;window.Alpine.addMagicProperty("store",function(t){return e.subscribe(t),e.stores})},store:function(e,t,r){if(void 0===r&&(r=!1),r)try{this.stores[e]=this.retrieveFromLocalStorage(e,(n={},Object.entries(t).filter(function(e){return"function"==typeof e[1]}).forEach(function(e){return n[e[0]]=e[1]}),n)),this.persisted.includes(e)||this.persisted.push(e)}catch(e){}var n;return this.stores[e]||(this.stores[e]=t),this.stores[e]},reset:function(e,t){this.stores[e]=t},subscribe:function(e){return this.subscribers.includes(e)||this.subscribers.push(e),this.stores},updateSubscribers:function(){this.subscribers.filter(function(e){return!!e.__x}).forEach(function(e){e.__x.updateElements(e)})},retrieveFromLocalStorage:function(e,t){void 0===t&&(t={});var r=JSON.parse(window.localStorage.getItem("__spruce:"+e));return r?Object.assign(t,r):null},updateLocalStorage:function(e){window.localStorage.setItem("__spruce:"+e,JSON.stringify(this.store(e)))},watch:function(e,t){this.watchers[e]||(this.watchers[e]=[]),this.watchers[e].push(t)},runWatchers:function(e,t,r,n){var i=this;if(i.watchers[r])return i.watchers[r].forEach(function(e){return e(n)});Object.keys(i.watchers).filter(function(e){return e.includes(".")}).forEach(function(o){var s=o.split(".");r===s[s.length-1]&&s.reduce(function(e,s){return(e[r]===t[r]||Object.is(t,e))&&i.watchers[o].forEach(function(e){return e(n)}),e[s]},e)})}},s=window.deferLoadingAlpine||function(e){e()};return window.deferLoadingAlpine=function(e){window.Spruce=o,window.Spruce.start(),s(e)},o}); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.spruce=t()}(this,function(){"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var e,t=(function(e,t){e.exports=function(){var e=/^v?(?:\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+))?(?:-[\da-z\-]+(?:\.[\da-z\-]+)*)?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;function t(e){var t,r=e.replace(/^v/,"").replace(/\+.*$/,""),n=-1===(t=r).indexOf("-")?t.length:t.indexOf("-"),i=r.substring(0,n).split(".");return i.push(r.substring(n+1)),i}function r(e){return isNaN(Number(e))?e:Number(e)}function n(t){if("string"!=typeof t)throw new TypeError("Invalid argument expected string");if(!e.test(t))throw new Error("Invalid argument not valid semver ('"+t+"' received)")}function i(e,i){[e,i].forEach(n);for(var o=t(e),s=t(i),u=0;u<Math.max(o.length-1,s.length-1);u++){var a=parseInt(o[u]||0,10),c=parseInt(s[u]||0,10);if(a>c)return 1;if(c>a)return-1}var f=o[o.length-1],d=s[s.length-1];if(f&&d){var p=f.split(".").map(r),h=d.split(".").map(r);for(u=0;u<Math.max(p.length,h.length);u++){if(void 0===p[u]||"string"==typeof h[u]&&"number"==typeof p[u])return-1;if(void 0===h[u]||"string"==typeof p[u]&&"number"==typeof h[u])return 1;if(p[u]>h[u])return 1;if(h[u]>p[u])return-1}}else if(f||d)return f?-1:1;return 0}var o=[">",">=","=","<","<="],s={">":[1],">=":[0,1],"=":[0],"<=":[-1,0],"<":[-1]};return i.validate=function(t){return"string"==typeof t&&e.test(t)},i.compare=function(e,t,r){!function(e){if("string"!=typeof e)throw new TypeError("Invalid operator type, expected string but got "+typeof e);if(-1===o.indexOf(e))throw new TypeError("Invalid operator, expected one of "+o.join("|"))}(r);var n=i(e,t);return s[r].indexOf(n)>-1},i}()}(e={exports:{}}),e.exports),r=function(e){return null==e},n=function(e){return Object.getPrototypeOf(e)===Object.prototype},i=function(e,t){return Object.entries(e).forEach(function(o){var s=o[0],u=o[1];r(u)||!n(u)&&!Array.isArray(u)||(e[s]=i(u,t))}),new Proxy(e,{set:function(e,o,s){return!r(s)&&n(s)&&(s=i(s,t)),t.set(e,o,e[o]=s),!0}})},o={stores:{},persisted:[],subscribers:[],watchers:{},disableReactivity:!1,start:function(){var e=this;this.attach(),this.stores=i(this.stores,{set:function(t,r,n){if(!e.disableReactivity){e.updateSubscribers(),e.runWatchers(e.stores,t,r,n),e.disableReactivity=!0;try{e.persisted.forEach(e.updateLocalStorage.bind(e))}catch(e){}e.disableReactivity=!1}}})},attach:function(){if(!(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")||window.Alpine&&t.compare(window.Alpine.version,"2.7.0",">=")))throw new Error("[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.");var e=this;window.Alpine.addMagicProperty("store",function(t){return e.subscribe(t),e.stores})},store:function(e,t,r){if(void 0===r&&(r=!1),r)try{this.stores[e]=this.retrieveFromLocalStorage(e,(n={},Object.entries(t).filter(function(e){return"function"==typeof e[1]}).forEach(function(e){return n[e[0]]=e[1]}),n)),this.persisted.includes(e)||this.persisted.push(e)}catch(e){}var n;return this.stores[e]||(this.stores[e]=t),this.stores[e]},reset:function(e,t){this.stores[e]=t},subscribe:function(e){return this.subscribers.includes(e)||this.subscribers.push(e),this.stores},updateSubscribers:function(){this.subscribers.filter(function(e){return!!e.__x}).forEach(function(e){e.__x.updateElements(e)})},retrieveFromLocalStorage:function(e,t){void 0===t&&(t={});var r=JSON.parse(window.localStorage.getItem("__spruce:"+e));return r?Object.assign(t,r):null},updateLocalStorage:function(e){window.localStorage.setItem("__spruce:"+e,JSON.stringify(this.store(e)))},watch:function(e,t){this.watchers[e]||(this.watchers[e]=[]),this.watchers[e].push(t)},runWatchers:function(e,t,r,n){var i=this;if(i.watchers[r])return i.watchers[r].forEach(function(e){return e(n)});Object.keys(i.watchers).filter(function(e){return e.includes(".")}).forEach(function(o){var s=o.split(".");r===s[s.length-1]&&s.reduce(function(e,s){return(e[r]===t[r]||Object.is(t,e))&&i.watchers[o].forEach(function(e){return e(n)}),e[s]},e)})}};window.Spruce=o;var s=window.deferLoadingAlpine||function(e){e()};return window.deferLoadingAlpine=function(e){window.Spruce.start(),s(e)},o}); | ||
//# sourceMappingURL=spruce.umd.js.map |
{ | ||
"name": "@ryangjchandler/spruce", | ||
"description": "A lightweight state management layer for Alpine.js", | ||
"version": "2.0.1", | ||
"version": "2.1.0", | ||
"repository": { | ||
@@ -6,0 +6,0 @@ "type": "git", |
@@ -1,2 +0,2 @@ | ||
import { domReady, getMethods, checkForAlpine } from './utils' | ||
import { getMethods, checkForAlpine } from './utils' | ||
import { createObservable } from './observable' | ||
@@ -15,5 +15,3 @@ | ||
async start() { | ||
await domReady() | ||
start() { | ||
this.attach() | ||
@@ -139,6 +137,7 @@ | ||
window.Spruce = Spruce | ||
const deferrer = window.deferLoadingAlpine || function (callback) { callback() } | ||
window.deferLoadingAlpine = function (callback) { | ||
window.Spruce = Spruce | ||
window.Spruce.start() | ||
@@ -145,0 +144,0 @@ |
import compareVersions from 'compare-versions' | ||
export const domReady = () => { | ||
return new Promise(resolve => { | ||
if (document.readyState == "loading") { | ||
document.addEventListener("DOMContentLoaded", resolve) | ||
} else { | ||
resolve() | ||
} | ||
}) | ||
} | ||
export const isNullOrUndefined = value => { | ||
@@ -26,3 +16,3 @@ return value === null || value === undefined | ||
Object.entries(obj).filter(([key, value]) => typeof value === 'function').forEach(([key, value]) => methods[key] = value) | ||
Object.entries(obj).filter(([_, value]) => typeof value === 'function').forEach(([key, value]) => methods[key] = value) | ||
@@ -29,0 +19,0 @@ 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
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
219914
44
555
37