From e179358f9e686e7c75d13fc0b70a44ee4f9c1e3d Mon Sep 17 00:00:00 2001 From: Josh Hanley Date: Mon, 11 Jan 2021 19:54:22 +1100 Subject: [PATCH 1/5] Add test to ensure watchers still run after change --- tests/cypress/fixtures/watchers/init.html | 2 ++ tests/cypress/integration/watchers.spec.js | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/tests/cypress/fixtures/watchers/init.html b/tests/cypress/fixtures/watchers/init.html index 3bfc9e1..cbd3b37 100644 --- a/tests/cypress/fixtures/watchers/init.html +++ b/tests/cypress/fixtures/watchers/init.html @@ -14,6 +14,8 @@ + + diff --git a/tests/cypress/integration/watchers.spec.js b/tests/cypress/integration/watchers.spec.js index 1be1462..6b42d65 100644 --- a/tests/cypress/integration/watchers.spec.js +++ b/tests/cypress/integration/watchers.spec.js @@ -20,6 +20,14 @@ describe('watchers', () => { cy.get('[data-todo-item]').should('have.length', 1) cy.get('[data-todo-label]').should('have.text', 'Yay!') + cy.get('[data-reset-todo-label]').click() + cy.get('[data-todo-label]').should('have.text', 'Yes!') + + cy.get('[data-reset-todos]').click() + + cy.get('[data-todo-item]').should('have.length', 0) + cy.get('[data-todo-label]').should('have.text', 'Yay!') + cy.get('[data-change-name]').click() cy.get('[data-todo-label]').should('have.text', 'Changed!') From ab261d05b244f1c84819d89d8847203d25d2c7cd Mon Sep 17 00:00:00 2001 From: Josh Hanley Date: Mon, 11 Jan 2021 19:14:05 +1100 Subject: [PATCH 2/5] Add fix to ensure changes to arrays can be observed --- src/observable.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/observable.js b/src/observable.js index 9a4a89d..3470bdd 100644 --- a/src/observable.js +++ b/src/observable.js @@ -12,11 +12,20 @@ export const createObservable = (target, callbacks) => { return callbacks.get(target, key, receiver) }, set(target, key, value, receiver) { - if (! isNullOrUndefined(value) && isObject(value)) { + if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) { value = createObservable(value, callbacks) } - callbacks.set(target, key, target[key] = value, receiver) + let originalValue = target[key] + + target[key] = value + + // Copy watchers from the original value if they exist + if (!isNullOrUndefined(originalValue) && !isNullOrUndefined(originalValue.__watchers)) { + target[key].__watchers = originalValue.__watchers + } + + callbacks.set(target, key, target[key], receiver) return true } From 14fa96d594b4ba885353a1b786aa99f8a174adb8 Mon Sep 17 00:00:00 2001 From: Josh Hanley Date: Sun, 24 Jan 2021 07:35:50 +1100 Subject: [PATCH 3/5] Build assets --- dist/spruce.js | 2 +- dist/spruce.js.map | 2 +- dist/spruce.module.js | 2 +- dist/spruce.module.js.map | 2 +- dist/spruce.umd.js | 2 +- dist/spruce.umd.js.map | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dist/spruce.js b/dist/spruce.js index 8c48432..c5f2fba 100644 --- a/dist/spruce.js +++ b/dist/spruce.js @@ -1,2 +1,2 @@ -function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var r=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 s=t(e),o=t(i),c=0;cu)return 1;if(u>a)return-1}var f=s[s.length-1],h=o[o.length-1];if(f&&h){var l=f.split(".").map(r),p=h.split(".").map(r);for(c=0;cp[c])return 1;if(p[c]>l[c])return-1}}else if(f||h)return f?-1:1;return 0}var s=[">",">=","=","<","<="],o={">":[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===s.indexOf(e))throw new TypeError("Invalid operator, expected one of "+s.join("|"))}(r);var n=i(e,t);return o[r].indexOf(n)>-1},i}()}(t={exports:{}}),t.exports}(),n=function(e){return null==e},i=function(e){return Object.getPrototypeOf(e)===Object.prototype},s=function(e){return Array.isArray(e)},o=function(e,t){return Object.entries(e).forEach(function(r){var c=r[0],a=r[1];n(a)||!i(a)&&!s(a)||(e[c]=o(a,t))}),new Proxy(e,{get:function(e,r,n){return t.get(e,r,n)},set:function(e,r,s,c){return!n(s)&&i(s)&&(s=o(s,t)),t.set(e,r,e[r]=s,c),!0}})},c={stores:{},persistenceDriver:window.localStorage,persisted:[],subscribers:[],watchers:{},disableReactivity:!1,startingCallbacks:[],startedCallbacks:[],hasStarted:!1,start:function(){var e=this;this.startingCallbacks.forEach(function(e){return e()}),this.attach(),this.stores=o(this.stores,{get:function(t,r,n){return Object.is(n,e.stores)&&["get","set","toggle","clear"].includes(r)?e[r].bind(e):Reflect.get(t,r,n)},set:function(t,r,n,i){if(!e.disableReactivity){e.updateSubscribers(),e.runWatchers(t,r,n,i),e.disableReactivity=!0;try{e.persisted.forEach(e.updateLocalStorage.bind(e))}catch(e){}e.disableReactivity=!1}}}),this.hasStarted=!0,this.disableReactivity=!0,Object.entries(this.watchers).forEach(function(t){var r=t[0];t[1].forEach(function(t){return e.watch(r,t)})}),this.disableReactivity=!1,this.startedCallbacks.forEach(function(e){return e()})},starting:function(e){this.startingCallbacks.push(e)},started:function(e){this.startedCallbacks.push(e)},attach:function(){if(!(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")||window.Alpine&&r.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),"function"==typeof t&&(t=t()),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]&&(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=this.persistenceDriver.getItem("__spruce:"+e);if(!r)return null;var n=JSON.parse(r);return"object"==typeof n&&(delete(n=Object.assign(t,n)).__watchers,delete n.__key_name),n},updateLocalStorage:function(r){var n=function(r){for(var n=1;n0&&console.warn("[Spruce] You have already initialised a persisted store. Changing the driver may cause issues."),"function"!=typeof e.getItem)throw new Error("[Spruce] The persistence driver must have a `getItem(key)` method.");if("function"!=typeof e.setItem)throw new Error("[Spruce] The persistence driver must have a `setItem(key, value)` method.");if("function"!=typeof e.removeItem)throw new Error("[Spruce] The persistence driver must have a `removeItem(name)` method.");this.persistenceDriver=e}};window.Spruce=c;var a=window.deferLoadingAlpine||function(e){e()};window.deferLoadingAlpine=function(e){window.Spruce.start(),a(e)},module.exports=c; +function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var r=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("-"),s=r.substring(0,n).split(".");return s.push(r.substring(n+1)),s}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 s(e,s){[e,s].forEach(n);for(var i=t(e),o=t(s),c=0;cu)return 1;if(u>a)return-1}var f=i[i.length-1],h=o[o.length-1];if(f&&h){var l=f.split(".").map(r),p=h.split(".").map(r);for(c=0;cp[c])return 1;if(p[c]>l[c])return-1}}else if(f||h)return f?-1:1;return 0}var i=[">",">=","=","<","<="],o={">":[1],">=":[0,1],"=":[0],"<=":[-1,0],"<":[-1]};return s.validate=function(t){return"string"==typeof t&&e.test(t)},s.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===i.indexOf(e))throw new TypeError("Invalid operator, expected one of "+i.join("|"))}(r);var n=s(e,t);return o[r].indexOf(n)>-1},s}()}(t={exports:{}}),t.exports}(),n=function(e){return null==e},s=function(e){return Object.getPrototypeOf(e)===Object.prototype},i=function(e){return Array.isArray(e)},o=function(e,t){return Object.entries(e).forEach(function(r){var c=r[0],a=r[1];n(a)||!s(a)&&!i(a)||(e[c]=o(a,t))}),new Proxy(e,{get:function(e,r,n){return t.get(e,r,n)},set:function(e,r,c,a){n(c)||!s(c)&&!i(c)||(c=o(c,t));var u=e[r];return e[r]=c,n(u)||n(u.__watchers)||(e[r].__watchers=u.__watchers),t.set(e,r,e[r],a),!0}})},c={stores:{},persistenceDriver:window.localStorage,persisted:[],subscribers:[],watchers:{},disableReactivity:!1,startingCallbacks:[],startedCallbacks:[],hasStarted:!1,start:function(){var e=this;this.startingCallbacks.forEach(function(e){return e()}),this.attach(),this.stores=o(this.stores,{get:function(t,r,n){return Object.is(n,e.stores)&&["get","set","toggle","clear"].includes(r)?e[r].bind(e):Reflect.get(t,r,n)},set:function(t,r,n,s){if(!e.disableReactivity){e.updateSubscribers(),e.runWatchers(t,r,n,s),e.disableReactivity=!0;try{e.persisted.forEach(e.updateLocalStorage.bind(e))}catch(e){}e.disableReactivity=!1}}}),this.hasStarted=!0,this.disableReactivity=!0,Object.entries(this.watchers).forEach(function(t){var r=t[0];t[1].forEach(function(t){return e.watch(r,t)})}),this.disableReactivity=!1,this.startedCallbacks.forEach(function(e){return e()})},starting:function(e){this.startingCallbacks.push(e)},started:function(e){this.startedCallbacks.push(e)},attach:function(){if(!(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")||window.Alpine&&r.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),"function"==typeof t&&(t=t()),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]&&(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=this.persistenceDriver.getItem("__spruce:"+e);if(!r)return null;var n=JSON.parse(r);return"object"==typeof n&&(delete(n=Object.assign(t,n)).__watchers,delete n.__key_name),n},updateLocalStorage:function(r){var n=function(r){for(var n=1;n0&&console.warn("[Spruce] You have already initialised a persisted store. Changing the driver may cause issues."),"function"!=typeof e.getItem)throw new Error("[Spruce] The persistence driver must have a `getItem(key)` method.");if("function"!=typeof e.setItem)throw new Error("[Spruce] The persistence driver must have a `setItem(key, value)` method.");if("function"!=typeof e.removeItem)throw new Error("[Spruce] The persistence driver must have a `removeItem(name)` method.");this.persistenceDriver=e}};window.Spruce=c;var a=window.deferLoadingAlpine||function(e){e()};window.deferLoadingAlpine=function(e){window.Spruce.start(),a(e)},module.exports=c; //# sourceMappingURL=spruce.js.map diff --git a/dist/spruce.js.map b/dist/spruce.js.map index fea1858..54e18bc 100644 --- a/dist/spruce.js.map +++ b/dist/spruce.js.map @@ -1 +1 @@ -{"version":3,"file":"spruce.js","sources":["../node_modules/compare-versions/index.js","../src/utils.js","../src/observable.js","../src/index.js"],"sourcesContent":["/* global define */\n(function (root, factory) {\n /* istanbul ignore next */\n if (typeof define === 'function' && define.amd) {\n define([], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.compareVersions = factory();\n }\n}(this, function () {\n\n var semver = /^v?(?:\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+))?(?:-[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\n\n function indexOrEnd(str, q) {\n return str.indexOf(q) === -1 ? str.length : str.indexOf(q);\n }\n\n function split(v) {\n var c = v.replace(/^v/, '').replace(/\\+.*$/, '');\n var patchIndex = indexOrEnd(c, '-');\n var arr = c.substring(0, patchIndex).split('.');\n arr.push(c.substring(patchIndex + 1));\n return arr;\n }\n\n function tryParse(v) {\n return isNaN(Number(v)) ? v : Number(v);\n }\n\n function validate(version) {\n if (typeof version !== 'string') {\n throw new TypeError('Invalid argument expected string');\n }\n if (!semver.test(version)) {\n throw new Error('Invalid argument not valid semver (\\''+version+'\\' received)');\n }\n }\n\n function compareVersions(v1, v2) {\n [v1, v2].forEach(validate);\n\n var s1 = split(v1);\n var s2 = split(v2);\n\n for (var i = 0; i < Math.max(s1.length - 1, s2.length - 1); i++) {\n var n1 = parseInt(s1[i] || 0, 10);\n var n2 = parseInt(s2[i] || 0, 10);\n\n if (n1 > n2) return 1;\n if (n2 > n1) return -1;\n }\n\n var sp1 = s1[s1.length - 1];\n var sp2 = s2[s2.length - 1];\n\n if (sp1 && sp2) {\n var p1 = sp1.split('.').map(tryParse);\n var p2 = sp2.split('.').map(tryParse);\n\n for (i = 0; i < Math.max(p1.length, p2.length); i++) {\n if (p1[i] === undefined || typeof p2[i] === 'string' && typeof p1[i] === 'number') return -1;\n if (p2[i] === undefined || typeof p1[i] === 'string' && typeof p2[i] === 'number') return 1;\n\n if (p1[i] > p2[i]) return 1;\n if (p2[i] > p1[i]) return -1;\n }\n } else if (sp1 || sp2) {\n return sp1 ? -1 : 1;\n }\n\n return 0;\n };\n\n var allowedOperators = [\n '>',\n '>=',\n '=',\n '<',\n '<='\n ];\n\n var operatorResMap = {\n '>': [1],\n '>=': [0, 1],\n '=': [0],\n '<=': [-1, 0],\n '<': [-1]\n };\n\n function validateOperator(op) {\n if (typeof op !== 'string') {\n throw new TypeError('Invalid operator type, expected string but got ' + typeof op);\n }\n if (allowedOperators.indexOf(op) === -1) {\n throw new TypeError('Invalid operator, expected one of ' + allowedOperators.join('|'));\n }\n }\n\n compareVersions.validate = function(version) {\n return typeof version === 'string' && semver.test(version);\n }\n\n compareVersions.compare = function (v1, v2, operator) {\n // Validate operator\n validateOperator(operator);\n\n // since result of compareVersions can only be -1 or 0 or 1\n // a simple map can be used to replace switch\n var res = compareVersions(v1, v2);\n return operatorResMap[operator].indexOf(res) > -1;\n }\n\n return compareVersions;\n}));\n","import compareVersions from 'compare-versions'\n\nexport const isNullOrUndefined = value => {\n return value === null || value === undefined\n}\n\nexport const isObject = _ => {\n return Object.getPrototypeOf(_) === Object.prototype\n}\n\nexport const isArray = _ => Array.isArray(_)\n\nexport const getMethods = obj => {\n let methods = {}\n\n Object.entries(obj).filter(([_, value]) => typeof value === 'function').forEach(([key, value]) => methods[key] = value)\n\n return methods\n}\n\nexport const isTesting = () => {\n return navigator.userAgent, navigator.userAgent.includes(\"Node.js\")\n || navigator.userAgent.includes(\"jsdom\")\n}\n\nexport const checkForAlpine = () => {\n if (isTesting()) {\n return true\n }\n\n if (! window.Alpine) {\n return false\n }\n\n return compareVersions.compare(window.Alpine.version, '2.7.0', '>=')\n}","import { isNullOrUndefined, isObject, isArray } from './utils'\n\nexport const createObservable = (target, callbacks) => {\n Object.entries(target).forEach(([key, value]) => {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) { \n target[key] = createObservable(value, callbacks)\n }\n })\n\n return new Proxy(target, {\n get(target, key, receiver) {\n return callbacks.get(target, key, receiver)\n },\n set(target, key, value, receiver) {\n if (! isNullOrUndefined(value) && isObject(value)) {\n value = createObservable(value, callbacks)\n }\n\n callbacks.set(target, key, target[key] = value, receiver)\n\n return true\n }\n })\n}","import { getMethods, checkForAlpine, isObject, isArray, isNullOrUndefined } from './utils'\nimport { createObservable } from './observable'\n\nconst Spruce = {\n stores: {},\n\n persistenceDriver: window.localStorage,\n\n persisted: [],\n\n subscribers: [],\n\n watchers: {},\n\n disableReactivity: false,\n\n startingCallbacks: [],\n\n startedCallbacks: [],\n\n hasStarted: false,\n\n start() {\n this.startingCallbacks.forEach(fn => fn())\n\n this.attach()\n\n this.stores = createObservable(this.stores, {\n get: (target, key, receiver) => {\n if (Object.is(receiver, this.stores) && ['get', 'set', 'toggle', 'clear'].includes(key)) {\n return this[key].bind(this)\n }\n\n return Reflect.get(target, key, receiver)\n },\n set: (target, key, value, receiver) => {\n if (this.disableReactivity) {\n return\n }\n\n this.updateSubscribers()\n\n this.runWatchers(target, key, value, receiver)\n\n this.disableReactivity = true\n\n try {\n this.persisted.forEach(this.updateLocalStorage.bind(this))\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n\n this.disableReactivity = false\n }\n })\n\n this.hasStarted = true\n\n this.disableReactivity = true\n\n Object.entries(this.watchers).forEach(([name, callbacks]) => {\n callbacks.forEach(callback => this.watch(name, callback))\n })\n\n this.disableReactivity = false\n\n this.startedCallbacks.forEach(fn => fn())\n },\n\n starting(callback) {\n this.startingCallbacks.push(callback)\n },\n\n started(callback) {\n this.startedCallbacks.push(callback)\n },\n\n attach() {\n if (! checkForAlpine()) {\n throw new Error('[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.')\n }\n\n const self = this\n\n window.Alpine.addMagicProperty('store', el => {\n self.subscribe(el)\n\n return self.stores\n })\n },\n\n store(name, state, persist = false) {\n if (typeof state === 'function') {\n state = state()\n }\n \n if (persist) {\n try {\n this.stores[name] = this.retrieveFromLocalStorage(name, getMethods(state))\n\n if (!this.persisted.includes(name)) {\n this.persisted.push(name)\n }\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n }\n\n if (!this.stores[name]) {\n this.stores[name] = state\n }\n\n return this.stores[name]\n },\n\n reset(name, state) {\n if (! this.stores[name]) {\n return;\n }\n \n this.stores[name] = state\n },\n\n subscribe(el) {\n if (!this.subscribers.includes(el)) {\n this.subscribers.push(el)\n }\n\n return this.stores\n },\n\n updateSubscribers() {\n this.subscribers.filter(el => !!el.__x).forEach(el => {\n el.__x.updateElements(el)\n })\n },\n\n retrieveFromLocalStorage(name, methods = {}) {\n const value = this.persistenceDriver.getItem(`__spruce:${name}`)\n\n if (! value) {\n return null\n }\n\n let storage = JSON.parse(value)\n\n if (typeof storage === 'object') {\n storage = Object.assign(methods, storage)\n\n delete storage.__watchers\n delete storage.__key_name\n }\n\n return storage\n },\n\n updateLocalStorage(name) {\n const store = { ...this.store(name) }\n\n delete store.__watchers\n delete store.__key_name\n\n this.persistenceDriver.setItem(`__spruce:${name}`, JSON.stringify(this.store(name)))\n },\n\n get(name, target = this.stores) {\n return name.split('.').reduce((target, part) => target[part], target)\n },\n\n set(name, value, target = this.stores) {\n if (! isArray(name)) {\n name = name.split('.')\n }\n\n if (name.length === 1) return target[name[0]] = value\n\n if (target[name[0]]) {\n return this.set(name.slice(1), value, target[name[0]])\n } else {\n target[name[0]] = {}\n\n return this.set(name.slice(1), value, target[name[0]])\n }\n },\n\n toggle(name) {\n return this.set(name, ! this.get(name))\n },\n\n clear(name) {\n return this.persistenceDriver.removeItem(`__spruce:${name}`)\n },\n\n watch(name, callback) {\n if (! this.hasStarted) {\n this.watchers[name] || (this.watchers[name] = [])\n\n this.watchers[name].push(callback)\n\n return [() => this.unwatch(name, callback)]\n }\n\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n /**\n * If the target object / array is the property\n * that needs to be watched, a magic `__self` key is\n * used so that runner can pick up on it later.\n */\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n target.__watchers = new Map\n }\n \n if (! target.__watchers.has(part)) {\n target.__watchers.set(part, new Set)\n }\n\n target.__watchers.get(part).add(callback)\n\n return [() => this.unwatch(name, callback)]\n },\n\n unwatch(name, callback) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n const watchers = target.__watchers\n\n if (! watchers.has(part)) {\n return\n }\n\n watchers.get(part).delete(callback)\n },\n\n watchers(name) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n return {}\n }\n\n return target.__watchers.get(part)\n },\n\n runWatchers(target, key, value) {\n if (! target.__watchers) {\n return\n }\n\n if (target.__watchers.has(key)) {\n target.__watchers.get(key).forEach(f => f(value))\n }\n\n /**\n * The `__self` key is used for watchers that are registered\n * to the object or array being updated.\n */\n if (target.__watchers.has('__self')) {\n target.__watchers.get('__self').forEach(f => f(value, key))\n }\n },\n\n persistUsing(driver) {\n if (this.persisted.length > 0) {\n console.warn('[Spruce] You have already initialised a persisted store. Changing the driver may cause issues.')\n }\n\n if (typeof driver.getItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `getItem(key)` method.')\n }\n\n if (typeof driver.setItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `setItem(key, value)` method.')\n }\n\n if (typeof driver.removeItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `removeItem(name)` method.')\n }\n\n this.persistenceDriver = driver\n }\n}\n\nwindow.Spruce = Spruce\n\nconst deferrer = window.deferLoadingAlpine || function (callback) { callback() }\n\nwindow.deferLoadingAlpine = function (callback) {\n window.Spruce.start()\n\n deferrer(callback)\n}\n\nexport default Spruce\n"],"names":["module","semver","split","v","str","c","replace","patchIndex","indexOf","length","arr","substring","push","tryParse","isNaN","Number","validate","version","TypeError","test","Error","compareVersions","v1","v2","forEach","s1","s2","i","Math","max","n1","parseInt","n2","sp1","sp2","p1","map","p2","undefined","allowedOperators","operatorResMap",">",">=","=","<=","<","compare","operator","op","join","validateOperator","res","factory","isNullOrUndefined","value","isObject","_","Object","getPrototypeOf","prototype","isArray","Array","createObservable","target","callbacks","entries","key","Proxy","get","receiver","set","Spruce","stores","persistenceDriver","window","localStorage","persisted","subscribers","watchers","disableReactivity","startingCallbacks","startedCallbacks","hasStarted","start","fn","attach","this","is","includes","bind","Reflect","updateSubscribers","runWatchers","updateLocalStorage","e","callback","watch","name","starting","started","navigator","userAgent","Alpine","self","addMagicProperty","el","subscribe","store","state","persist","retrieveFromLocalStorage","methods","filter","reset","__x","updateElements","getItem","storage","JSON","parse","assign","__watchers","__key_name","setItem","stringify","reduce","part","slice","toggle","clear","removeItem","unwatch","nameParts","sub","Map","has","Set","add","delete","f","persistUsing","driver","console","warn","const","deferrer","deferLoadingAlpine"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"spruce.js","sources":["../node_modules/compare-versions/index.js","../src/utils.js","../src/observable.js","../src/index.js"],"sourcesContent":["/* global define */\n(function (root, factory) {\n /* istanbul ignore next */\n if (typeof define === 'function' && define.amd) {\n define([], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.compareVersions = factory();\n }\n}(this, function () {\n\n var semver = /^v?(?:\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+))?(?:-[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\n\n function indexOrEnd(str, q) {\n return str.indexOf(q) === -1 ? str.length : str.indexOf(q);\n }\n\n function split(v) {\n var c = v.replace(/^v/, '').replace(/\\+.*$/, '');\n var patchIndex = indexOrEnd(c, '-');\n var arr = c.substring(0, patchIndex).split('.');\n arr.push(c.substring(patchIndex + 1));\n return arr;\n }\n\n function tryParse(v) {\n return isNaN(Number(v)) ? v : Number(v);\n }\n\n function validate(version) {\n if (typeof version !== 'string') {\n throw new TypeError('Invalid argument expected string');\n }\n if (!semver.test(version)) {\n throw new Error('Invalid argument not valid semver (\\''+version+'\\' received)');\n }\n }\n\n function compareVersions(v1, v2) {\n [v1, v2].forEach(validate);\n\n var s1 = split(v1);\n var s2 = split(v2);\n\n for (var i = 0; i < Math.max(s1.length - 1, s2.length - 1); i++) {\n var n1 = parseInt(s1[i] || 0, 10);\n var n2 = parseInt(s2[i] || 0, 10);\n\n if (n1 > n2) return 1;\n if (n2 > n1) return -1;\n }\n\n var sp1 = s1[s1.length - 1];\n var sp2 = s2[s2.length - 1];\n\n if (sp1 && sp2) {\n var p1 = sp1.split('.').map(tryParse);\n var p2 = sp2.split('.').map(tryParse);\n\n for (i = 0; i < Math.max(p1.length, p2.length); i++) {\n if (p1[i] === undefined || typeof p2[i] === 'string' && typeof p1[i] === 'number') return -1;\n if (p2[i] === undefined || typeof p1[i] === 'string' && typeof p2[i] === 'number') return 1;\n\n if (p1[i] > p2[i]) return 1;\n if (p2[i] > p1[i]) return -1;\n }\n } else if (sp1 || sp2) {\n return sp1 ? -1 : 1;\n }\n\n return 0;\n };\n\n var allowedOperators = [\n '>',\n '>=',\n '=',\n '<',\n '<='\n ];\n\n var operatorResMap = {\n '>': [1],\n '>=': [0, 1],\n '=': [0],\n '<=': [-1, 0],\n '<': [-1]\n };\n\n function validateOperator(op) {\n if (typeof op !== 'string') {\n throw new TypeError('Invalid operator type, expected string but got ' + typeof op);\n }\n if (allowedOperators.indexOf(op) === -1) {\n throw new TypeError('Invalid operator, expected one of ' + allowedOperators.join('|'));\n }\n }\n\n compareVersions.validate = function(version) {\n return typeof version === 'string' && semver.test(version);\n }\n\n compareVersions.compare = function (v1, v2, operator) {\n // Validate operator\n validateOperator(operator);\n\n // since result of compareVersions can only be -1 or 0 or 1\n // a simple map can be used to replace switch\n var res = compareVersions(v1, v2);\n return operatorResMap[operator].indexOf(res) > -1;\n }\n\n return compareVersions;\n}));\n","import compareVersions from 'compare-versions'\n\nexport const isNullOrUndefined = value => {\n return value === null || value === undefined\n}\n\nexport const isObject = _ => {\n return Object.getPrototypeOf(_) === Object.prototype\n}\n\nexport const isArray = _ => Array.isArray(_)\n\nexport const getMethods = obj => {\n let methods = {}\n\n Object.entries(obj).filter(([_, value]) => typeof value === 'function').forEach(([key, value]) => methods[key] = value)\n\n return methods\n}\n\nexport const isTesting = () => {\n return navigator.userAgent, navigator.userAgent.includes(\"Node.js\")\n || navigator.userAgent.includes(\"jsdom\")\n}\n\nexport const checkForAlpine = () => {\n if (isTesting()) {\n return true\n }\n\n if (! window.Alpine) {\n return false\n }\n\n return compareVersions.compare(window.Alpine.version, '2.7.0', '>=')\n}","import { isNullOrUndefined, isObject, isArray } from './utils'\n\nexport const createObservable = (target, callbacks) => {\n Object.entries(target).forEach(([key, value]) => {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) { \n target[key] = createObservable(value, callbacks)\n }\n })\n\n return new Proxy(target, {\n get(target, key, receiver) {\n return callbacks.get(target, key, receiver)\n },\n set(target, key, value, receiver) {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) {\n value = createObservable(value, callbacks)\n }\n\n let originalValue = target[key]\n\n target[key] = value\n\n // Copy watchers from the original value if they exist\n if (!isNullOrUndefined(originalValue) && !isNullOrUndefined(originalValue.__watchers)) {\n target[key].__watchers = originalValue.__watchers\n }\n\n callbacks.set(target, key, target[key], receiver)\n\n return true\n }\n })\n}","import { getMethods, checkForAlpine, isObject, isArray, isNullOrUndefined } from './utils'\nimport { createObservable } from './observable'\n\nconst Spruce = {\n stores: {},\n\n persistenceDriver: window.localStorage,\n\n persisted: [],\n\n subscribers: [],\n\n watchers: {},\n\n disableReactivity: false,\n\n startingCallbacks: [],\n\n startedCallbacks: [],\n\n hasStarted: false,\n\n start() {\n this.startingCallbacks.forEach(fn => fn())\n\n this.attach()\n\n this.stores = createObservable(this.stores, {\n get: (target, key, receiver) => {\n if (Object.is(receiver, this.stores) && ['get', 'set', 'toggle', 'clear'].includes(key)) {\n return this[key].bind(this)\n }\n\n return Reflect.get(target, key, receiver)\n },\n set: (target, key, value, receiver) => {\n if (this.disableReactivity) {\n return\n }\n\n this.updateSubscribers()\n\n this.runWatchers(target, key, value, receiver)\n\n this.disableReactivity = true\n\n try {\n this.persisted.forEach(this.updateLocalStorage.bind(this))\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n\n this.disableReactivity = false\n }\n })\n\n this.hasStarted = true\n\n this.disableReactivity = true\n\n Object.entries(this.watchers).forEach(([name, callbacks]) => {\n callbacks.forEach(callback => this.watch(name, callback))\n })\n\n this.disableReactivity = false\n\n this.startedCallbacks.forEach(fn => fn())\n },\n\n starting(callback) {\n this.startingCallbacks.push(callback)\n },\n\n started(callback) {\n this.startedCallbacks.push(callback)\n },\n\n attach() {\n if (! checkForAlpine()) {\n throw new Error('[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.')\n }\n\n const self = this\n\n window.Alpine.addMagicProperty('store', el => {\n self.subscribe(el)\n\n return self.stores\n })\n },\n\n store(name, state, persist = false) {\n if (typeof state === 'function') {\n state = state()\n }\n \n if (persist) {\n try {\n this.stores[name] = this.retrieveFromLocalStorage(name, getMethods(state))\n\n if (!this.persisted.includes(name)) {\n this.persisted.push(name)\n }\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n }\n\n if (!this.stores[name]) {\n this.stores[name] = state\n }\n\n return this.stores[name]\n },\n\n reset(name, state) {\n if (! this.stores[name]) {\n return;\n }\n \n this.stores[name] = state\n },\n\n subscribe(el) {\n if (!this.subscribers.includes(el)) {\n this.subscribers.push(el)\n }\n\n return this.stores\n },\n\n updateSubscribers() {\n this.subscribers.filter(el => !!el.__x).forEach(el => {\n el.__x.updateElements(el)\n })\n },\n\n retrieveFromLocalStorage(name, methods = {}) {\n const value = this.persistenceDriver.getItem(`__spruce:${name}`)\n\n if (! value) {\n return null\n }\n\n let storage = JSON.parse(value)\n\n if (typeof storage === 'object') {\n storage = Object.assign(methods, storage)\n\n delete storage.__watchers\n delete storage.__key_name\n }\n\n return storage\n },\n\n updateLocalStorage(name) {\n const store = { ...this.store(name) }\n\n delete store.__watchers\n delete store.__key_name\n\n this.persistenceDriver.setItem(`__spruce:${name}`, JSON.stringify(this.store(name)))\n },\n\n get(name, target = this.stores) {\n return name.split('.').reduce((target, part) => target[part], target)\n },\n\n set(name, value, target = this.stores) {\n if (! isArray(name)) {\n name = name.split('.')\n }\n\n if (name.length === 1) return target[name[0]] = value\n\n if (target[name[0]]) {\n return this.set(name.slice(1), value, target[name[0]])\n } else {\n target[name[0]] = {}\n\n return this.set(name.slice(1), value, target[name[0]])\n }\n },\n\n toggle(name) {\n return this.set(name, ! this.get(name))\n },\n\n clear(name) {\n return this.persistenceDriver.removeItem(`__spruce:${name}`)\n },\n\n watch(name, callback) {\n if (! this.hasStarted) {\n this.watchers[name] || (this.watchers[name] = [])\n\n this.watchers[name].push(callback)\n\n return [() => this.unwatch(name, callback)]\n }\n\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n /**\n * If the target object / array is the property\n * that needs to be watched, a magic `__self` key is\n * used so that runner can pick up on it later.\n */\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n target.__watchers = new Map\n }\n \n if (! target.__watchers.has(part)) {\n target.__watchers.set(part, new Set)\n }\n\n target.__watchers.get(part).add(callback)\n\n return [() => this.unwatch(name, callback)]\n },\n\n unwatch(name, callback) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n const watchers = target.__watchers\n\n if (! watchers.has(part)) {\n return\n }\n\n watchers.get(part).delete(callback)\n },\n\n watchers(name) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n return {}\n }\n\n return target.__watchers.get(part)\n },\n\n runWatchers(target, key, value) {\n if (! target.__watchers) {\n return\n }\n\n if (target.__watchers.has(key)) {\n target.__watchers.get(key).forEach(f => f(value))\n }\n\n /**\n * The `__self` key is used for watchers that are registered\n * to the object or array being updated.\n */\n if (target.__watchers.has('__self')) {\n target.__watchers.get('__self').forEach(f => f(value, key))\n }\n },\n\n persistUsing(driver) {\n if (this.persisted.length > 0) {\n console.warn('[Spruce] You have already initialised a persisted store. Changing the driver may cause issues.')\n }\n\n if (typeof driver.getItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `getItem(key)` method.')\n }\n\n if (typeof driver.setItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `setItem(key, value)` method.')\n }\n\n if (typeof driver.removeItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `removeItem(name)` method.')\n }\n\n this.persistenceDriver = driver\n }\n}\n\nwindow.Spruce = Spruce\n\nconst deferrer = window.deferLoadingAlpine || function (callback) { callback() }\n\nwindow.deferLoadingAlpine = function (callback) {\n window.Spruce.start()\n\n deferrer(callback)\n}\n\nexport default Spruce\n"],"names":["module","semver","split","v","str","c","replace","patchIndex","indexOf","length","arr","substring","push","tryParse","isNaN","Number","validate","version","TypeError","test","Error","compareVersions","v1","v2","forEach","s1","s2","i","Math","max","n1","parseInt","n2","sp1","sp2","p1","map","p2","undefined","allowedOperators","operatorResMap",">",">=","=","<=","<","compare","operator","op","join","validateOperator","res","factory","isNullOrUndefined","value","isObject","_","Object","getPrototypeOf","prototype","isArray","Array","createObservable","target","callbacks","entries","key","Proxy","get","receiver","set","originalValue","__watchers","Spruce","stores","persistenceDriver","window","localStorage","persisted","subscribers","watchers","disableReactivity","startingCallbacks","startedCallbacks","hasStarted","start","fn","attach","this","is","includes","bind","Reflect","updateSubscribers","runWatchers","updateLocalStorage","e","callback","watch","name","starting","started","navigator","userAgent","Alpine","self","addMagicProperty","el","subscribe","store","state","persist","retrieveFromLocalStorage","methods","filter","reset","__x","updateElements","getItem","storage","JSON","parse","assign","__key_name","setItem","stringify","reduce","part","slice","toggle","clear","removeItem","unwatch","nameParts","sub","Map","has","Set","add","delete","f","persistUsing","driver","console","warn","const","deferrer","deferLoadingAlpine"],"mappings":"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"} \ No newline at end of file diff --git a/dist/spruce.module.js b/dist/spruce.module.js index 31b0164..3dcd102 100644 --- a/dist/spruce.module.js +++ b/dist/spruce.module.js @@ -1,2 +1,2 @@ -function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var r,n=(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 s=t(e),o=t(i),c=0;cu)return 1;if(u>a)return-1}var f=s[s.length-1],h=o[o.length-1];if(f&&h){var l=f.split(".").map(r),p=h.split(".").map(r);for(c=0;cp[c])return 1;if(p[c]>l[c])return-1}}else if(f||h)return f?-1:1;return 0}var s=[">",">=","=","<","<="],o={">":[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===s.indexOf(e))throw new TypeError("Invalid operator, expected one of "+s.join("|"))}(r);var n=i(e,t);return o[r].indexOf(n)>-1},i}()}(r={exports:{}}),r.exports),i=function(e){return null==e},s=function(e){return Object.getPrototypeOf(e)===Object.prototype},o=function(e){return Array.isArray(e)},c=function(e,t){return Object.entries(e).forEach(function(r){var n=r[0],a=r[1];i(a)||!s(a)&&!o(a)||(e[n]=c(a,t))}),new Proxy(e,{get:function(e,r,n){return t.get(e,r,n)},set:function(e,r,n,o){return!i(n)&&s(n)&&(n=c(n,t)),t.set(e,r,e[r]=n,o),!0}})},a={stores:{},persistenceDriver:window.localStorage,persisted:[],subscribers:[],watchers:{},disableReactivity:!1,startingCallbacks:[],startedCallbacks:[],hasStarted:!1,start:function(){var e=this;this.startingCallbacks.forEach(function(e){return e()}),this.attach(),this.stores=c(this.stores,{get:function(t,r,n){return Object.is(n,e.stores)&&["get","set","toggle","clear"].includes(r)?e[r].bind(e):Reflect.get(t,r,n)},set:function(t,r,n,i){if(!e.disableReactivity){e.updateSubscribers(),e.runWatchers(t,r,n,i),e.disableReactivity=!0;try{e.persisted.forEach(e.updateLocalStorage.bind(e))}catch(e){}e.disableReactivity=!1}}}),this.hasStarted=!0,this.disableReactivity=!0,Object.entries(this.watchers).forEach(function(t){var r=t[0];t[1].forEach(function(t){return e.watch(r,t)})}),this.disableReactivity=!1,this.startedCallbacks.forEach(function(e){return e()})},starting:function(e){this.startingCallbacks.push(e)},started:function(e){this.startedCallbacks.push(e)},attach:function(){if(!(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")||window.Alpine&&n.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),"function"==typeof t&&(t=t()),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]&&(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=this.persistenceDriver.getItem("__spruce:"+e);if(!r)return null;var n=JSON.parse(r);return"object"==typeof n&&(delete(n=Object.assign(t,n)).__watchers,delete n.__key_name),n},updateLocalStorage:function(r){var n=function(r){for(var n=1;n0&&console.warn("[Spruce] You have already initialised a persisted store. Changing the driver may cause issues."),"function"!=typeof e.getItem)throw new Error("[Spruce] The persistence driver must have a `getItem(key)` method.");if("function"!=typeof e.setItem)throw new Error("[Spruce] The persistence driver must have a `setItem(key, value)` method.");if("function"!=typeof e.removeItem)throw new Error("[Spruce] The persistence driver must have a `removeItem(name)` method.");this.persistenceDriver=e}};window.Spruce=a;var u=window.deferLoadingAlpine||function(e){e()};window.deferLoadingAlpine=function(e){window.Spruce.start(),u(e)};export default a; +function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var r,n=(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("-"),s=r.substring(0,n).split(".");return s.push(r.substring(n+1)),s}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 s(e,s){[e,s].forEach(n);for(var i=t(e),o=t(s),c=0;cu)return 1;if(u>a)return-1}var f=i[i.length-1],h=o[o.length-1];if(f&&h){var l=f.split(".").map(r),p=h.split(".").map(r);for(c=0;cp[c])return 1;if(p[c]>l[c])return-1}}else if(f||h)return f?-1:1;return 0}var i=[">",">=","=","<","<="],o={">":[1],">=":[0,1],"=":[0],"<=":[-1,0],"<":[-1]};return s.validate=function(t){return"string"==typeof t&&e.test(t)},s.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===i.indexOf(e))throw new TypeError("Invalid operator, expected one of "+i.join("|"))}(r);var n=s(e,t);return o[r].indexOf(n)>-1},s}()}(r={exports:{}}),r.exports),s=function(e){return null==e},i=function(e){return Object.getPrototypeOf(e)===Object.prototype},o=function(e){return Array.isArray(e)},c=function(e,t){return Object.entries(e).forEach(function(r){var n=r[0],a=r[1];s(a)||!i(a)&&!o(a)||(e[n]=c(a,t))}),new Proxy(e,{get:function(e,r,n){return t.get(e,r,n)},set:function(e,r,n,a){s(n)||!i(n)&&!o(n)||(n=c(n,t));var u=e[r];return e[r]=n,s(u)||s(u.__watchers)||(e[r].__watchers=u.__watchers),t.set(e,r,e[r],a),!0}})},a={stores:{},persistenceDriver:window.localStorage,persisted:[],subscribers:[],watchers:{},disableReactivity:!1,startingCallbacks:[],startedCallbacks:[],hasStarted:!1,start:function(){var e=this;this.startingCallbacks.forEach(function(e){return e()}),this.attach(),this.stores=c(this.stores,{get:function(t,r,n){return Object.is(n,e.stores)&&["get","set","toggle","clear"].includes(r)?e[r].bind(e):Reflect.get(t,r,n)},set:function(t,r,n,s){if(!e.disableReactivity){e.updateSubscribers(),e.runWatchers(t,r,n,s),e.disableReactivity=!0;try{e.persisted.forEach(e.updateLocalStorage.bind(e))}catch(e){}e.disableReactivity=!1}}}),this.hasStarted=!0,this.disableReactivity=!0,Object.entries(this.watchers).forEach(function(t){var r=t[0];t[1].forEach(function(t){return e.watch(r,t)})}),this.disableReactivity=!1,this.startedCallbacks.forEach(function(e){return e()})},starting:function(e){this.startingCallbacks.push(e)},started:function(e){this.startedCallbacks.push(e)},attach:function(){if(!(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")||window.Alpine&&n.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),"function"==typeof t&&(t=t()),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]&&(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=this.persistenceDriver.getItem("__spruce:"+e);if(!r)return null;var n=JSON.parse(r);return"object"==typeof n&&(delete(n=Object.assign(t,n)).__watchers,delete n.__key_name),n},updateLocalStorage:function(r){var n=function(r){for(var n=1;n0&&console.warn("[Spruce] You have already initialised a persisted store. Changing the driver may cause issues."),"function"!=typeof e.getItem)throw new Error("[Spruce] The persistence driver must have a `getItem(key)` method.");if("function"!=typeof e.setItem)throw new Error("[Spruce] The persistence driver must have a `setItem(key, value)` method.");if("function"!=typeof e.removeItem)throw new Error("[Spruce] The persistence driver must have a `removeItem(name)` method.");this.persistenceDriver=e}};window.Spruce=a;var u=window.deferLoadingAlpine||function(e){e()};window.deferLoadingAlpine=function(e){window.Spruce.start(),u(e)};export default a; //# sourceMappingURL=spruce.module.js.map diff --git a/dist/spruce.module.js.map b/dist/spruce.module.js.map index ed26b39..f51f736 100644 --- a/dist/spruce.module.js.map +++ b/dist/spruce.module.js.map @@ -1 +1 @@ -{"version":3,"file":"spruce.module.js","sources":["../node_modules/compare-versions/index.js","../src/utils.js","../src/observable.js","../src/index.js"],"sourcesContent":["/* global define */\n(function (root, factory) {\n /* istanbul ignore next */\n if (typeof define === 'function' && define.amd) {\n define([], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.compareVersions = factory();\n }\n}(this, function () {\n\n var semver = /^v?(?:\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+))?(?:-[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\n\n function indexOrEnd(str, q) {\n return str.indexOf(q) === -1 ? str.length : str.indexOf(q);\n }\n\n function split(v) {\n var c = v.replace(/^v/, '').replace(/\\+.*$/, '');\n var patchIndex = indexOrEnd(c, '-');\n var arr = c.substring(0, patchIndex).split('.');\n arr.push(c.substring(patchIndex + 1));\n return arr;\n }\n\n function tryParse(v) {\n return isNaN(Number(v)) ? v : Number(v);\n }\n\n function validate(version) {\n if (typeof version !== 'string') {\n throw new TypeError('Invalid argument expected string');\n }\n if (!semver.test(version)) {\n throw new Error('Invalid argument not valid semver (\\''+version+'\\' received)');\n }\n }\n\n function compareVersions(v1, v2) {\n [v1, v2].forEach(validate);\n\n var s1 = split(v1);\n var s2 = split(v2);\n\n for (var i = 0; i < Math.max(s1.length - 1, s2.length - 1); i++) {\n var n1 = parseInt(s1[i] || 0, 10);\n var n2 = parseInt(s2[i] || 0, 10);\n\n if (n1 > n2) return 1;\n if (n2 > n1) return -1;\n }\n\n var sp1 = s1[s1.length - 1];\n var sp2 = s2[s2.length - 1];\n\n if (sp1 && sp2) {\n var p1 = sp1.split('.').map(tryParse);\n var p2 = sp2.split('.').map(tryParse);\n\n for (i = 0; i < Math.max(p1.length, p2.length); i++) {\n if (p1[i] === undefined || typeof p2[i] === 'string' && typeof p1[i] === 'number') return -1;\n if (p2[i] === undefined || typeof p1[i] === 'string' && typeof p2[i] === 'number') return 1;\n\n if (p1[i] > p2[i]) return 1;\n if (p2[i] > p1[i]) return -1;\n }\n } else if (sp1 || sp2) {\n return sp1 ? -1 : 1;\n }\n\n return 0;\n };\n\n var allowedOperators = [\n '>',\n '>=',\n '=',\n '<',\n '<='\n ];\n\n var operatorResMap = {\n '>': [1],\n '>=': [0, 1],\n '=': [0],\n '<=': [-1, 0],\n '<': [-1]\n };\n\n function validateOperator(op) {\n if (typeof op !== 'string') {\n throw new TypeError('Invalid operator type, expected string but got ' + typeof op);\n }\n if (allowedOperators.indexOf(op) === -1) {\n throw new TypeError('Invalid operator, expected one of ' + allowedOperators.join('|'));\n }\n }\n\n compareVersions.validate = function(version) {\n return typeof version === 'string' && semver.test(version);\n }\n\n compareVersions.compare = function (v1, v2, operator) {\n // Validate operator\n validateOperator(operator);\n\n // since result of compareVersions can only be -1 or 0 or 1\n // a simple map can be used to replace switch\n var res = compareVersions(v1, v2);\n return operatorResMap[operator].indexOf(res) > -1;\n }\n\n return compareVersions;\n}));\n","import compareVersions from 'compare-versions'\n\nexport const isNullOrUndefined = value => {\n return value === null || value === undefined\n}\n\nexport const isObject = _ => {\n return Object.getPrototypeOf(_) === Object.prototype\n}\n\nexport const isArray = _ => Array.isArray(_)\n\nexport const getMethods = obj => {\n let methods = {}\n\n Object.entries(obj).filter(([_, value]) => typeof value === 'function').forEach(([key, value]) => methods[key] = value)\n\n return methods\n}\n\nexport const isTesting = () => {\n return navigator.userAgent, navigator.userAgent.includes(\"Node.js\")\n || navigator.userAgent.includes(\"jsdom\")\n}\n\nexport const checkForAlpine = () => {\n if (isTesting()) {\n return true\n }\n\n if (! window.Alpine) {\n return false\n }\n\n return compareVersions.compare(window.Alpine.version, '2.7.0', '>=')\n}","import { isNullOrUndefined, isObject, isArray } from './utils'\n\nexport const createObservable = (target, callbacks) => {\n Object.entries(target).forEach(([key, value]) => {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) { \n target[key] = createObservable(value, callbacks)\n }\n })\n\n return new Proxy(target, {\n get(target, key, receiver) {\n return callbacks.get(target, key, receiver)\n },\n set(target, key, value, receiver) {\n if (! isNullOrUndefined(value) && isObject(value)) {\n value = createObservable(value, callbacks)\n }\n\n callbacks.set(target, key, target[key] = value, receiver)\n\n return true\n }\n })\n}","import { getMethods, checkForAlpine, isObject, isArray, isNullOrUndefined } from './utils'\nimport { createObservable } from './observable'\n\nconst Spruce = {\n stores: {},\n\n persistenceDriver: window.localStorage,\n\n persisted: [],\n\n subscribers: [],\n\n watchers: {},\n\n disableReactivity: false,\n\n startingCallbacks: [],\n\n startedCallbacks: [],\n\n hasStarted: false,\n\n start() {\n this.startingCallbacks.forEach(fn => fn())\n\n this.attach()\n\n this.stores = createObservable(this.stores, {\n get: (target, key, receiver) => {\n if (Object.is(receiver, this.stores) && ['get', 'set', 'toggle', 'clear'].includes(key)) {\n return this[key].bind(this)\n }\n\n return Reflect.get(target, key, receiver)\n },\n set: (target, key, value, receiver) => {\n if (this.disableReactivity) {\n return\n }\n\n this.updateSubscribers()\n\n this.runWatchers(target, key, value, receiver)\n\n this.disableReactivity = true\n\n try {\n this.persisted.forEach(this.updateLocalStorage.bind(this))\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n\n this.disableReactivity = false\n }\n })\n\n this.hasStarted = true\n\n this.disableReactivity = true\n\n Object.entries(this.watchers).forEach(([name, callbacks]) => {\n callbacks.forEach(callback => this.watch(name, callback))\n })\n\n this.disableReactivity = false\n\n this.startedCallbacks.forEach(fn => fn())\n },\n\n starting(callback) {\n this.startingCallbacks.push(callback)\n },\n\n started(callback) {\n this.startedCallbacks.push(callback)\n },\n\n attach() {\n if (! checkForAlpine()) {\n throw new Error('[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.')\n }\n\n const self = this\n\n window.Alpine.addMagicProperty('store', el => {\n self.subscribe(el)\n\n return self.stores\n })\n },\n\n store(name, state, persist = false) {\n if (typeof state === 'function') {\n state = state()\n }\n \n if (persist) {\n try {\n this.stores[name] = this.retrieveFromLocalStorage(name, getMethods(state))\n\n if (!this.persisted.includes(name)) {\n this.persisted.push(name)\n }\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n }\n\n if (!this.stores[name]) {\n this.stores[name] = state\n }\n\n return this.stores[name]\n },\n\n reset(name, state) {\n if (! this.stores[name]) {\n return;\n }\n \n this.stores[name] = state\n },\n\n subscribe(el) {\n if (!this.subscribers.includes(el)) {\n this.subscribers.push(el)\n }\n\n return this.stores\n },\n\n updateSubscribers() {\n this.subscribers.filter(el => !!el.__x).forEach(el => {\n el.__x.updateElements(el)\n })\n },\n\n retrieveFromLocalStorage(name, methods = {}) {\n const value = this.persistenceDriver.getItem(`__spruce:${name}`)\n\n if (! value) {\n return null\n }\n\n let storage = JSON.parse(value)\n\n if (typeof storage === 'object') {\n storage = Object.assign(methods, storage)\n\n delete storage.__watchers\n delete storage.__key_name\n }\n\n return storage\n },\n\n updateLocalStorage(name) {\n const store = { ...this.store(name) }\n\n delete store.__watchers\n delete store.__key_name\n\n this.persistenceDriver.setItem(`__spruce:${name}`, JSON.stringify(this.store(name)))\n },\n\n get(name, target = this.stores) {\n return name.split('.').reduce((target, part) => target[part], target)\n },\n\n set(name, value, target = this.stores) {\n if (! isArray(name)) {\n name = name.split('.')\n }\n\n if (name.length === 1) return target[name[0]] = value\n\n if (target[name[0]]) {\n return this.set(name.slice(1), value, target[name[0]])\n } else {\n target[name[0]] = {}\n\n return this.set(name.slice(1), value, target[name[0]])\n }\n },\n\n toggle(name) {\n return this.set(name, ! this.get(name))\n },\n\n clear(name) {\n return this.persistenceDriver.removeItem(`__spruce:${name}`)\n },\n\n watch(name, callback) {\n if (! this.hasStarted) {\n this.watchers[name] || (this.watchers[name] = [])\n\n this.watchers[name].push(callback)\n\n return [() => this.unwatch(name, callback)]\n }\n\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n /**\n * If the target object / array is the property\n * that needs to be watched, a magic `__self` key is\n * used so that runner can pick up on it later.\n */\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n target.__watchers = new Map\n }\n \n if (! target.__watchers.has(part)) {\n target.__watchers.set(part, new Set)\n }\n\n target.__watchers.get(part).add(callback)\n\n return [() => this.unwatch(name, callback)]\n },\n\n unwatch(name, callback) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n const watchers = target.__watchers\n\n if (! watchers.has(part)) {\n return\n }\n\n watchers.get(part).delete(callback)\n },\n\n watchers(name) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n return {}\n }\n\n return target.__watchers.get(part)\n },\n\n runWatchers(target, key, value) {\n if (! target.__watchers) {\n return\n }\n\n if (target.__watchers.has(key)) {\n target.__watchers.get(key).forEach(f => f(value))\n }\n\n /**\n * The `__self` key is used for watchers that are registered\n * to the object or array being updated.\n */\n if (target.__watchers.has('__self')) {\n target.__watchers.get('__self').forEach(f => f(value, key))\n }\n },\n\n persistUsing(driver) {\n if (this.persisted.length > 0) {\n console.warn('[Spruce] You have already initialised a persisted store. Changing the driver may cause issues.')\n }\n\n if (typeof driver.getItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `getItem(key)` method.')\n }\n\n if (typeof driver.setItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `setItem(key, value)` method.')\n }\n\n if (typeof driver.removeItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `removeItem(name)` method.')\n }\n\n this.persistenceDriver = driver\n }\n}\n\nwindow.Spruce = Spruce\n\nconst deferrer = window.deferLoadingAlpine || function (callback) { callback() }\n\nwindow.deferLoadingAlpine = function (callback) {\n window.Spruce.start()\n\n deferrer(callback)\n}\n\nexport default Spruce\n"],"names":["module","semver","split","v","str","c","replace","patchIndex","indexOf","length","arr","substring","push","tryParse","isNaN","Number","validate","version","TypeError","test","Error","compareVersions","v1","v2","forEach","s1","s2","i","Math","max","n1","parseInt","n2","sp1","sp2","p1","map","p2","undefined","allowedOperators","operatorResMap",">",">=","=","<=","<","compare","operator","op","join","validateOperator","res","factory","isNullOrUndefined","value","isObject","_","Object","getPrototypeOf","prototype","isArray","Array","createObservable","target","callbacks","entries","key","Proxy","get","receiver","set","Spruce","stores","persistenceDriver","window","localStorage","persisted","subscribers","watchers","disableReactivity","startingCallbacks","startedCallbacks","hasStarted","start","fn","attach","this","is","includes","bind","Reflect","updateSubscribers","runWatchers","updateLocalStorage","e","callback","watch","name","starting","started","navigator","userAgent","Alpine","self","addMagicProperty","el","subscribe","store","state","persist","retrieveFromLocalStorage","methods","filter","reset","__x","updateElements","getItem","storage","JSON","parse","assign","__watchers","__key_name","setItem","stringify","reduce","part","slice","toggle","clear","removeItem","unwatch","nameParts","sub","Map","has","Set","add","delete","f","persistUsing","driver","console","warn","const","deferrer","deferLoadingAlpine"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"spruce.module.js","sources":["../node_modules/compare-versions/index.js","../src/utils.js","../src/observable.js","../src/index.js"],"sourcesContent":["/* global define */\n(function (root, factory) {\n /* istanbul ignore next */\n if (typeof define === 'function' && define.amd) {\n define([], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.compareVersions = factory();\n }\n}(this, function () {\n\n var semver = /^v?(?:\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+))?(?:-[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\n\n function indexOrEnd(str, q) {\n return str.indexOf(q) === -1 ? str.length : str.indexOf(q);\n }\n\n function split(v) {\n var c = v.replace(/^v/, '').replace(/\\+.*$/, '');\n var patchIndex = indexOrEnd(c, '-');\n var arr = c.substring(0, patchIndex).split('.');\n arr.push(c.substring(patchIndex + 1));\n return arr;\n }\n\n function tryParse(v) {\n return isNaN(Number(v)) ? v : Number(v);\n }\n\n function validate(version) {\n if (typeof version !== 'string') {\n throw new TypeError('Invalid argument expected string');\n }\n if (!semver.test(version)) {\n throw new Error('Invalid argument not valid semver (\\''+version+'\\' received)');\n }\n }\n\n function compareVersions(v1, v2) {\n [v1, v2].forEach(validate);\n\n var s1 = split(v1);\n var s2 = split(v2);\n\n for (var i = 0; i < Math.max(s1.length - 1, s2.length - 1); i++) {\n var n1 = parseInt(s1[i] || 0, 10);\n var n2 = parseInt(s2[i] || 0, 10);\n\n if (n1 > n2) return 1;\n if (n2 > n1) return -1;\n }\n\n var sp1 = s1[s1.length - 1];\n var sp2 = s2[s2.length - 1];\n\n if (sp1 && sp2) {\n var p1 = sp1.split('.').map(tryParse);\n var p2 = sp2.split('.').map(tryParse);\n\n for (i = 0; i < Math.max(p1.length, p2.length); i++) {\n if (p1[i] === undefined || typeof p2[i] === 'string' && typeof p1[i] === 'number') return -1;\n if (p2[i] === undefined || typeof p1[i] === 'string' && typeof p2[i] === 'number') return 1;\n\n if (p1[i] > p2[i]) return 1;\n if (p2[i] > p1[i]) return -1;\n }\n } else if (sp1 || sp2) {\n return sp1 ? -1 : 1;\n }\n\n return 0;\n };\n\n var allowedOperators = [\n '>',\n '>=',\n '=',\n '<',\n '<='\n ];\n\n var operatorResMap = {\n '>': [1],\n '>=': [0, 1],\n '=': [0],\n '<=': [-1, 0],\n '<': [-1]\n };\n\n function validateOperator(op) {\n if (typeof op !== 'string') {\n throw new TypeError('Invalid operator type, expected string but got ' + typeof op);\n }\n if (allowedOperators.indexOf(op) === -1) {\n throw new TypeError('Invalid operator, expected one of ' + allowedOperators.join('|'));\n }\n }\n\n compareVersions.validate = function(version) {\n return typeof version === 'string' && semver.test(version);\n }\n\n compareVersions.compare = function (v1, v2, operator) {\n // Validate operator\n validateOperator(operator);\n\n // since result of compareVersions can only be -1 or 0 or 1\n // a simple map can be used to replace switch\n var res = compareVersions(v1, v2);\n return operatorResMap[operator].indexOf(res) > -1;\n }\n\n return compareVersions;\n}));\n","import compareVersions from 'compare-versions'\n\nexport const isNullOrUndefined = value => {\n return value === null || value === undefined\n}\n\nexport const isObject = _ => {\n return Object.getPrototypeOf(_) === Object.prototype\n}\n\nexport const isArray = _ => Array.isArray(_)\n\nexport const getMethods = obj => {\n let methods = {}\n\n Object.entries(obj).filter(([_, value]) => typeof value === 'function').forEach(([key, value]) => methods[key] = value)\n\n return methods\n}\n\nexport const isTesting = () => {\n return navigator.userAgent, navigator.userAgent.includes(\"Node.js\")\n || navigator.userAgent.includes(\"jsdom\")\n}\n\nexport const checkForAlpine = () => {\n if (isTesting()) {\n return true\n }\n\n if (! window.Alpine) {\n return false\n }\n\n return compareVersions.compare(window.Alpine.version, '2.7.0', '>=')\n}","import { isNullOrUndefined, isObject, isArray } from './utils'\n\nexport const createObservable = (target, callbacks) => {\n Object.entries(target).forEach(([key, value]) => {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) { \n target[key] = createObservable(value, callbacks)\n }\n })\n\n return new Proxy(target, {\n get(target, key, receiver) {\n return callbacks.get(target, key, receiver)\n },\n set(target, key, value, receiver) {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) {\n value = createObservable(value, callbacks)\n }\n\n let originalValue = target[key]\n\n target[key] = value\n\n // Copy watchers from the original value if they exist\n if (!isNullOrUndefined(originalValue) && !isNullOrUndefined(originalValue.__watchers)) {\n target[key].__watchers = originalValue.__watchers\n }\n\n callbacks.set(target, key, target[key], receiver)\n\n return true\n }\n })\n}","import { getMethods, checkForAlpine, isObject, isArray, isNullOrUndefined } from './utils'\nimport { createObservable } from './observable'\n\nconst Spruce = {\n stores: {},\n\n persistenceDriver: window.localStorage,\n\n persisted: [],\n\n subscribers: [],\n\n watchers: {},\n\n disableReactivity: false,\n\n startingCallbacks: [],\n\n startedCallbacks: [],\n\n hasStarted: false,\n\n start() {\n this.startingCallbacks.forEach(fn => fn())\n\n this.attach()\n\n this.stores = createObservable(this.stores, {\n get: (target, key, receiver) => {\n if (Object.is(receiver, this.stores) && ['get', 'set', 'toggle', 'clear'].includes(key)) {\n return this[key].bind(this)\n }\n\n return Reflect.get(target, key, receiver)\n },\n set: (target, key, value, receiver) => {\n if (this.disableReactivity) {\n return\n }\n\n this.updateSubscribers()\n\n this.runWatchers(target, key, value, receiver)\n\n this.disableReactivity = true\n\n try {\n this.persisted.forEach(this.updateLocalStorage.bind(this))\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n\n this.disableReactivity = false\n }\n })\n\n this.hasStarted = true\n\n this.disableReactivity = true\n\n Object.entries(this.watchers).forEach(([name, callbacks]) => {\n callbacks.forEach(callback => this.watch(name, callback))\n })\n\n this.disableReactivity = false\n\n this.startedCallbacks.forEach(fn => fn())\n },\n\n starting(callback) {\n this.startingCallbacks.push(callback)\n },\n\n started(callback) {\n this.startedCallbacks.push(callback)\n },\n\n attach() {\n if (! checkForAlpine()) {\n throw new Error('[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.')\n }\n\n const self = this\n\n window.Alpine.addMagicProperty('store', el => {\n self.subscribe(el)\n\n return self.stores\n })\n },\n\n store(name, state, persist = false) {\n if (typeof state === 'function') {\n state = state()\n }\n \n if (persist) {\n try {\n this.stores[name] = this.retrieveFromLocalStorage(name, getMethods(state))\n\n if (!this.persisted.includes(name)) {\n this.persisted.push(name)\n }\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n }\n\n if (!this.stores[name]) {\n this.stores[name] = state\n }\n\n return this.stores[name]\n },\n\n reset(name, state) {\n if (! this.stores[name]) {\n return;\n }\n \n this.stores[name] = state\n },\n\n subscribe(el) {\n if (!this.subscribers.includes(el)) {\n this.subscribers.push(el)\n }\n\n return this.stores\n },\n\n updateSubscribers() {\n this.subscribers.filter(el => !!el.__x).forEach(el => {\n el.__x.updateElements(el)\n })\n },\n\n retrieveFromLocalStorage(name, methods = {}) {\n const value = this.persistenceDriver.getItem(`__spruce:${name}`)\n\n if (! value) {\n return null\n }\n\n let storage = JSON.parse(value)\n\n if (typeof storage === 'object') {\n storage = Object.assign(methods, storage)\n\n delete storage.__watchers\n delete storage.__key_name\n }\n\n return storage\n },\n\n updateLocalStorage(name) {\n const store = { ...this.store(name) }\n\n delete store.__watchers\n delete store.__key_name\n\n this.persistenceDriver.setItem(`__spruce:${name}`, JSON.stringify(this.store(name)))\n },\n\n get(name, target = this.stores) {\n return name.split('.').reduce((target, part) => target[part], target)\n },\n\n set(name, value, target = this.stores) {\n if (! isArray(name)) {\n name = name.split('.')\n }\n\n if (name.length === 1) return target[name[0]] = value\n\n if (target[name[0]]) {\n return this.set(name.slice(1), value, target[name[0]])\n } else {\n target[name[0]] = {}\n\n return this.set(name.slice(1), value, target[name[0]])\n }\n },\n\n toggle(name) {\n return this.set(name, ! this.get(name))\n },\n\n clear(name) {\n return this.persistenceDriver.removeItem(`__spruce:${name}`)\n },\n\n watch(name, callback) {\n if (! this.hasStarted) {\n this.watchers[name] || (this.watchers[name] = [])\n\n this.watchers[name].push(callback)\n\n return [() => this.unwatch(name, callback)]\n }\n\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n /**\n * If the target object / array is the property\n * that needs to be watched, a magic `__self` key is\n * used so that runner can pick up on it later.\n */\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n target.__watchers = new Map\n }\n \n if (! target.__watchers.has(part)) {\n target.__watchers.set(part, new Set)\n }\n\n target.__watchers.get(part).add(callback)\n\n return [() => this.unwatch(name, callback)]\n },\n\n unwatch(name, callback) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n const watchers = target.__watchers\n\n if (! watchers.has(part)) {\n return\n }\n\n watchers.get(part).delete(callback)\n },\n\n watchers(name) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n return {}\n }\n\n return target.__watchers.get(part)\n },\n\n runWatchers(target, key, value) {\n if (! target.__watchers) {\n return\n }\n\n if (target.__watchers.has(key)) {\n target.__watchers.get(key).forEach(f => f(value))\n }\n\n /**\n * The `__self` key is used for watchers that are registered\n * to the object or array being updated.\n */\n if (target.__watchers.has('__self')) {\n target.__watchers.get('__self').forEach(f => f(value, key))\n }\n },\n\n persistUsing(driver) {\n if (this.persisted.length > 0) {\n console.warn('[Spruce] You have already initialised a persisted store. Changing the driver may cause issues.')\n }\n\n if (typeof driver.getItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `getItem(key)` method.')\n }\n\n if (typeof driver.setItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `setItem(key, value)` method.')\n }\n\n if (typeof driver.removeItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `removeItem(name)` method.')\n }\n\n this.persistenceDriver = driver\n }\n}\n\nwindow.Spruce = Spruce\n\nconst deferrer = window.deferLoadingAlpine || function (callback) { callback() }\n\nwindow.deferLoadingAlpine = function (callback) {\n window.Spruce.start()\n\n deferrer(callback)\n}\n\nexport default Spruce\n"],"names":["module","semver","split","v","str","c","replace","patchIndex","indexOf","length","arr","substring","push","tryParse","isNaN","Number","validate","version","TypeError","test","Error","compareVersions","v1","v2","forEach","s1","s2","i","Math","max","n1","parseInt","n2","sp1","sp2","p1","map","p2","undefined","allowedOperators","operatorResMap",">",">=","=","<=","<","compare","operator","op","join","validateOperator","res","factory","isNullOrUndefined","value","isObject","_","Object","getPrototypeOf","prototype","isArray","Array","createObservable","target","callbacks","entries","key","Proxy","get","receiver","set","originalValue","__watchers","Spruce","stores","persistenceDriver","window","localStorage","persisted","subscribers","watchers","disableReactivity","startingCallbacks","startedCallbacks","hasStarted","start","fn","attach","this","is","includes","bind","Reflect","updateSubscribers","runWatchers","updateLocalStorage","e","callback","watch","name","starting","started","navigator","userAgent","Alpine","self","addMagicProperty","el","subscribe","store","state","persist","retrieveFromLocalStorage","methods","filter","reset","__x","updateElements","getItem","storage","JSON","parse","assign","__key_name","setItem","stringify","reduce","part","slice","toggle","clear","removeItem","unwatch","nameParts","sub","Map","has","Set","add","delete","f","persistUsing","driver","console","warn","const","deferrer","deferLoadingAlpine"],"mappings":"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"} \ No newline at end of file diff --git a/dist/spruce.umd.js b/dist/spruce.umd.js index ba10829..7b26fad 100644 --- a/dist/spruce.umd.js +++ b/dist/spruce.umd.js @@ -1,2 +1,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(){function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var r,n=(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 s=t(e),o=t(i),c=0;cu)return 1;if(u>a)return-1}var f=s[s.length-1],h=o[o.length-1];if(f&&h){var p=f.split(".").map(r),d=h.split(".").map(r);for(c=0;cd[c])return 1;if(d[c]>p[c])return-1}}else if(f||h)return f?-1:1;return 0}var s=[">",">=","=","<","<="],o={">":[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===s.indexOf(e))throw new TypeError("Invalid operator, expected one of "+s.join("|"))}(r);var n=i(e,t);return o[r].indexOf(n)>-1},i}()}(r={exports:{}}),r.exports),i=function(e){return null==e},s=function(e){return Object.getPrototypeOf(e)===Object.prototype},o=function(e){return Array.isArray(e)},c=function(e,t){return Object.entries(e).forEach(function(r){var n=r[0],a=r[1];i(a)||!s(a)&&!o(a)||(e[n]=c(a,t))}),new Proxy(e,{get:function(e,r,n){return t.get(e,r,n)},set:function(e,r,n,o){return!i(n)&&s(n)&&(n=c(n,t)),t.set(e,r,e[r]=n,o),!0}})},a={stores:{},persistenceDriver:window.localStorage,persisted:[],subscribers:[],watchers:{},disableReactivity:!1,startingCallbacks:[],startedCallbacks:[],hasStarted:!1,start:function(){var e=this;this.startingCallbacks.forEach(function(e){return e()}),this.attach(),this.stores=c(this.stores,{get:function(t,r,n){return Object.is(n,e.stores)&&["get","set","toggle","clear"].includes(r)?e[r].bind(e):Reflect.get(t,r,n)},set:function(t,r,n,i){if(!e.disableReactivity){e.updateSubscribers(),e.runWatchers(t,r,n,i),e.disableReactivity=!0;try{e.persisted.forEach(e.updateLocalStorage.bind(e))}catch(e){}e.disableReactivity=!1}}}),this.hasStarted=!0,this.disableReactivity=!0,Object.entries(this.watchers).forEach(function(t){var r=t[0];t[1].forEach(function(t){return e.watch(r,t)})}),this.disableReactivity=!1,this.startedCallbacks.forEach(function(e){return e()})},starting:function(e){this.startingCallbacks.push(e)},started:function(e){this.startedCallbacks.push(e)},attach:function(){if(!(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")||window.Alpine&&n.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),"function"==typeof t&&(t=t()),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]&&(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=this.persistenceDriver.getItem("__spruce:"+e);if(!r)return null;var n=JSON.parse(r);return"object"==typeof n&&(delete(n=Object.assign(t,n)).__watchers,delete n.__key_name),n},updateLocalStorage:function(r){var n=function(r){for(var n=1;n0&&console.warn("[Spruce] You have already initialised a persisted store. Changing the driver may cause issues."),"function"!=typeof e.getItem)throw new Error("[Spruce] The persistence driver must have a `getItem(key)` method.");if("function"!=typeof e.setItem)throw new Error("[Spruce] The persistence driver must have a `setItem(key, value)` method.");if("function"!=typeof e.removeItem)throw new Error("[Spruce] The persistence driver must have a `removeItem(name)` method.");this.persistenceDriver=e}};window.Spruce=a;var u=window.deferLoadingAlpine||function(e){e()};return window.deferLoadingAlpine=function(e){window.Spruce.start(),u(e)},a}); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.spruce=t()}(this,function(){function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var r,n=(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 s=t(e),o=t(i),c=0;cu)return 1;if(u>a)return-1}var f=s[s.length-1],h=o[o.length-1];if(f&&h){var p=f.split(".").map(r),d=h.split(".").map(r);for(c=0;cd[c])return 1;if(d[c]>p[c])return-1}}else if(f||h)return f?-1:1;return 0}var s=[">",">=","=","<","<="],o={">":[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===s.indexOf(e))throw new TypeError("Invalid operator, expected one of "+s.join("|"))}(r);var n=i(e,t);return o[r].indexOf(n)>-1},i}()}(r={exports:{}}),r.exports),i=function(e){return null==e},s=function(e){return Object.getPrototypeOf(e)===Object.prototype},o=function(e){return Array.isArray(e)},c=function(e,t){return Object.entries(e).forEach(function(r){var n=r[0],a=r[1];i(a)||!s(a)&&!o(a)||(e[n]=c(a,t))}),new Proxy(e,{get:function(e,r,n){return t.get(e,r,n)},set:function(e,r,n,a){i(n)||!s(n)&&!o(n)||(n=c(n,t));var u=e[r];return e[r]=n,i(u)||i(u.__watchers)||(e[r].__watchers=u.__watchers),t.set(e,r,e[r],a),!0}})},a={stores:{},persistenceDriver:window.localStorage,persisted:[],subscribers:[],watchers:{},disableReactivity:!1,startingCallbacks:[],startedCallbacks:[],hasStarted:!1,start:function(){var e=this;this.startingCallbacks.forEach(function(e){return e()}),this.attach(),this.stores=c(this.stores,{get:function(t,r,n){return Object.is(n,e.stores)&&["get","set","toggle","clear"].includes(r)?e[r].bind(e):Reflect.get(t,r,n)},set:function(t,r,n,i){if(!e.disableReactivity){e.updateSubscribers(),e.runWatchers(t,r,n,i),e.disableReactivity=!0;try{e.persisted.forEach(e.updateLocalStorage.bind(e))}catch(e){}e.disableReactivity=!1}}}),this.hasStarted=!0,this.disableReactivity=!0,Object.entries(this.watchers).forEach(function(t){var r=t[0];t[1].forEach(function(t){return e.watch(r,t)})}),this.disableReactivity=!1,this.startedCallbacks.forEach(function(e){return e()})},starting:function(e){this.startingCallbacks.push(e)},started:function(e){this.startedCallbacks.push(e)},attach:function(){if(!(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")||window.Alpine&&n.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),"function"==typeof t&&(t=t()),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]&&(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=this.persistenceDriver.getItem("__spruce:"+e);if(!r)return null;var n=JSON.parse(r);return"object"==typeof n&&(delete(n=Object.assign(t,n)).__watchers,delete n.__key_name),n},updateLocalStorage:function(r){var n=function(r){for(var n=1;n0&&console.warn("[Spruce] You have already initialised a persisted store. Changing the driver may cause issues."),"function"!=typeof e.getItem)throw new Error("[Spruce] The persistence driver must have a `getItem(key)` method.");if("function"!=typeof e.setItem)throw new Error("[Spruce] The persistence driver must have a `setItem(key, value)` method.");if("function"!=typeof e.removeItem)throw new Error("[Spruce] The persistence driver must have a `removeItem(name)` method.");this.persistenceDriver=e}};window.Spruce=a;var u=window.deferLoadingAlpine||function(e){e()};return window.deferLoadingAlpine=function(e){window.Spruce.start(),u(e)},a}); //# sourceMappingURL=spruce.umd.js.map diff --git a/dist/spruce.umd.js.map b/dist/spruce.umd.js.map index 73f6f2f..2da3c77 100644 --- a/dist/spruce.umd.js.map +++ b/dist/spruce.umd.js.map @@ -1 +1 @@ -{"version":3,"file":"spruce.umd.js","sources":["../node_modules/compare-versions/index.js","../src/utils.js","../src/observable.js","../src/index.js"],"sourcesContent":["/* global define */\n(function (root, factory) {\n /* istanbul ignore next */\n if (typeof define === 'function' && define.amd) {\n define([], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.compareVersions = factory();\n }\n}(this, function () {\n\n var semver = /^v?(?:\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+))?(?:-[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\n\n function indexOrEnd(str, q) {\n return str.indexOf(q) === -1 ? str.length : str.indexOf(q);\n }\n\n function split(v) {\n var c = v.replace(/^v/, '').replace(/\\+.*$/, '');\n var patchIndex = indexOrEnd(c, '-');\n var arr = c.substring(0, patchIndex).split('.');\n arr.push(c.substring(patchIndex + 1));\n return arr;\n }\n\n function tryParse(v) {\n return isNaN(Number(v)) ? v : Number(v);\n }\n\n function validate(version) {\n if (typeof version !== 'string') {\n throw new TypeError('Invalid argument expected string');\n }\n if (!semver.test(version)) {\n throw new Error('Invalid argument not valid semver (\\''+version+'\\' received)');\n }\n }\n\n function compareVersions(v1, v2) {\n [v1, v2].forEach(validate);\n\n var s1 = split(v1);\n var s2 = split(v2);\n\n for (var i = 0; i < Math.max(s1.length - 1, s2.length - 1); i++) {\n var n1 = parseInt(s1[i] || 0, 10);\n var n2 = parseInt(s2[i] || 0, 10);\n\n if (n1 > n2) return 1;\n if (n2 > n1) return -1;\n }\n\n var sp1 = s1[s1.length - 1];\n var sp2 = s2[s2.length - 1];\n\n if (sp1 && sp2) {\n var p1 = sp1.split('.').map(tryParse);\n var p2 = sp2.split('.').map(tryParse);\n\n for (i = 0; i < Math.max(p1.length, p2.length); i++) {\n if (p1[i] === undefined || typeof p2[i] === 'string' && typeof p1[i] === 'number') return -1;\n if (p2[i] === undefined || typeof p1[i] === 'string' && typeof p2[i] === 'number') return 1;\n\n if (p1[i] > p2[i]) return 1;\n if (p2[i] > p1[i]) return -1;\n }\n } else if (sp1 || sp2) {\n return sp1 ? -1 : 1;\n }\n\n return 0;\n };\n\n var allowedOperators = [\n '>',\n '>=',\n '=',\n '<',\n '<='\n ];\n\n var operatorResMap = {\n '>': [1],\n '>=': [0, 1],\n '=': [0],\n '<=': [-1, 0],\n '<': [-1]\n };\n\n function validateOperator(op) {\n if (typeof op !== 'string') {\n throw new TypeError('Invalid operator type, expected string but got ' + typeof op);\n }\n if (allowedOperators.indexOf(op) === -1) {\n throw new TypeError('Invalid operator, expected one of ' + allowedOperators.join('|'));\n }\n }\n\n compareVersions.validate = function(version) {\n return typeof version === 'string' && semver.test(version);\n }\n\n compareVersions.compare = function (v1, v2, operator) {\n // Validate operator\n validateOperator(operator);\n\n // since result of compareVersions can only be -1 or 0 or 1\n // a simple map can be used to replace switch\n var res = compareVersions(v1, v2);\n return operatorResMap[operator].indexOf(res) > -1;\n }\n\n return compareVersions;\n}));\n","import compareVersions from 'compare-versions'\n\nexport const isNullOrUndefined = value => {\n return value === null || value === undefined\n}\n\nexport const isObject = _ => {\n return Object.getPrototypeOf(_) === Object.prototype\n}\n\nexport const isArray = _ => Array.isArray(_)\n\nexport const getMethods = obj => {\n let methods = {}\n\n Object.entries(obj).filter(([_, value]) => typeof value === 'function').forEach(([key, value]) => methods[key] = value)\n\n return methods\n}\n\nexport const isTesting = () => {\n return navigator.userAgent, navigator.userAgent.includes(\"Node.js\")\n || navigator.userAgent.includes(\"jsdom\")\n}\n\nexport const checkForAlpine = () => {\n if (isTesting()) {\n return true\n }\n\n if (! window.Alpine) {\n return false\n }\n\n return compareVersions.compare(window.Alpine.version, '2.7.0', '>=')\n}","import { isNullOrUndefined, isObject, isArray } from './utils'\n\nexport const createObservable = (target, callbacks) => {\n Object.entries(target).forEach(([key, value]) => {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) { \n target[key] = createObservable(value, callbacks)\n }\n })\n\n return new Proxy(target, {\n get(target, key, receiver) {\n return callbacks.get(target, key, receiver)\n },\n set(target, key, value, receiver) {\n if (! isNullOrUndefined(value) && isObject(value)) {\n value = createObservable(value, callbacks)\n }\n\n callbacks.set(target, key, target[key] = value, receiver)\n\n return true\n }\n })\n}","import { getMethods, checkForAlpine, isObject, isArray, isNullOrUndefined } from './utils'\nimport { createObservable } from './observable'\n\nconst Spruce = {\n stores: {},\n\n persistenceDriver: window.localStorage,\n\n persisted: [],\n\n subscribers: [],\n\n watchers: {},\n\n disableReactivity: false,\n\n startingCallbacks: [],\n\n startedCallbacks: [],\n\n hasStarted: false,\n\n start() {\n this.startingCallbacks.forEach(fn => fn())\n\n this.attach()\n\n this.stores = createObservable(this.stores, {\n get: (target, key, receiver) => {\n if (Object.is(receiver, this.stores) && ['get', 'set', 'toggle', 'clear'].includes(key)) {\n return this[key].bind(this)\n }\n\n return Reflect.get(target, key, receiver)\n },\n set: (target, key, value, receiver) => {\n if (this.disableReactivity) {\n return\n }\n\n this.updateSubscribers()\n\n this.runWatchers(target, key, value, receiver)\n\n this.disableReactivity = true\n\n try {\n this.persisted.forEach(this.updateLocalStorage.bind(this))\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n\n this.disableReactivity = false\n }\n })\n\n this.hasStarted = true\n\n this.disableReactivity = true\n\n Object.entries(this.watchers).forEach(([name, callbacks]) => {\n callbacks.forEach(callback => this.watch(name, callback))\n })\n\n this.disableReactivity = false\n\n this.startedCallbacks.forEach(fn => fn())\n },\n\n starting(callback) {\n this.startingCallbacks.push(callback)\n },\n\n started(callback) {\n this.startedCallbacks.push(callback)\n },\n\n attach() {\n if (! checkForAlpine()) {\n throw new Error('[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.')\n }\n\n const self = this\n\n window.Alpine.addMagicProperty('store', el => {\n self.subscribe(el)\n\n return self.stores\n })\n },\n\n store(name, state, persist = false) {\n if (typeof state === 'function') {\n state = state()\n }\n \n if (persist) {\n try {\n this.stores[name] = this.retrieveFromLocalStorage(name, getMethods(state))\n\n if (!this.persisted.includes(name)) {\n this.persisted.push(name)\n }\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n }\n\n if (!this.stores[name]) {\n this.stores[name] = state\n }\n\n return this.stores[name]\n },\n\n reset(name, state) {\n if (! this.stores[name]) {\n return;\n }\n \n this.stores[name] = state\n },\n\n subscribe(el) {\n if (!this.subscribers.includes(el)) {\n this.subscribers.push(el)\n }\n\n return this.stores\n },\n\n updateSubscribers() {\n this.subscribers.filter(el => !!el.__x).forEach(el => {\n el.__x.updateElements(el)\n })\n },\n\n retrieveFromLocalStorage(name, methods = {}) {\n const value = this.persistenceDriver.getItem(`__spruce:${name}`)\n\n if (! value) {\n return null\n }\n\n let storage = JSON.parse(value)\n\n if (typeof storage === 'object') {\n storage = Object.assign(methods, storage)\n\n delete storage.__watchers\n delete storage.__key_name\n }\n\n return storage\n },\n\n updateLocalStorage(name) {\n const store = { ...this.store(name) }\n\n delete store.__watchers\n delete store.__key_name\n\n this.persistenceDriver.setItem(`__spruce:${name}`, JSON.stringify(this.store(name)))\n },\n\n get(name, target = this.stores) {\n return name.split('.').reduce((target, part) => target[part], target)\n },\n\n set(name, value, target = this.stores) {\n if (! isArray(name)) {\n name = name.split('.')\n }\n\n if (name.length === 1) return target[name[0]] = value\n\n if (target[name[0]]) {\n return this.set(name.slice(1), value, target[name[0]])\n } else {\n target[name[0]] = {}\n\n return this.set(name.slice(1), value, target[name[0]])\n }\n },\n\n toggle(name) {\n return this.set(name, ! this.get(name))\n },\n\n clear(name) {\n return this.persistenceDriver.removeItem(`__spruce:${name}`)\n },\n\n watch(name, callback) {\n if (! this.hasStarted) {\n this.watchers[name] || (this.watchers[name] = [])\n\n this.watchers[name].push(callback)\n\n return [() => this.unwatch(name, callback)]\n }\n\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n /**\n * If the target object / array is the property\n * that needs to be watched, a magic `__self` key is\n * used so that runner can pick up on it later.\n */\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n target.__watchers = new Map\n }\n \n if (! target.__watchers.has(part)) {\n target.__watchers.set(part, new Set)\n }\n\n target.__watchers.get(part).add(callback)\n\n return [() => this.unwatch(name, callback)]\n },\n\n unwatch(name, callback) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n const watchers = target.__watchers\n\n if (! watchers.has(part)) {\n return\n }\n\n watchers.get(part).delete(callback)\n },\n\n watchers(name) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n return {}\n }\n\n return target.__watchers.get(part)\n },\n\n runWatchers(target, key, value) {\n if (! target.__watchers) {\n return\n }\n\n if (target.__watchers.has(key)) {\n target.__watchers.get(key).forEach(f => f(value))\n }\n\n /**\n * The `__self` key is used for watchers that are registered\n * to the object or array being updated.\n */\n if (target.__watchers.has('__self')) {\n target.__watchers.get('__self').forEach(f => f(value, key))\n }\n },\n\n persistUsing(driver) {\n if (this.persisted.length > 0) {\n console.warn('[Spruce] You have already initialised a persisted store. Changing the driver may cause issues.')\n }\n\n if (typeof driver.getItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `getItem(key)` method.')\n }\n\n if (typeof driver.setItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `setItem(key, value)` method.')\n }\n\n if (typeof driver.removeItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `removeItem(name)` method.')\n }\n\n this.persistenceDriver = driver\n }\n}\n\nwindow.Spruce = Spruce\n\nconst deferrer = window.deferLoadingAlpine || function (callback) { callback() }\n\nwindow.deferLoadingAlpine = function (callback) {\n window.Spruce.start()\n\n deferrer(callback)\n}\n\nexport default Spruce\n"],"names":["module","semver","split","v","str","c","replace","patchIndex","indexOf","length","arr","substring","push","tryParse","isNaN","Number","validate","version","TypeError","test","Error","compareVersions","v1","v2","forEach","s1","s2","i","Math","max","n1","parseInt","n2","sp1","sp2","p1","map","p2","undefined","allowedOperators","operatorResMap",">",">=","=","<=","<","compare","operator","op","join","validateOperator","res","factory","isNullOrUndefined","value","isObject","_","Object","getPrototypeOf","prototype","isArray","Array","createObservable","target","callbacks","entries","key","Proxy","get","receiver","set","Spruce","stores","persistenceDriver","window","localStorage","persisted","subscribers","watchers","disableReactivity","startingCallbacks","startedCallbacks","hasStarted","start","fn","attach","this","is","includes","bind","Reflect","updateSubscribers","runWatchers","updateLocalStorage","e","callback","watch","name","starting","started","navigator","userAgent","Alpine","self","addMagicProperty","el","subscribe","store","state","persist","retrieveFromLocalStorage","methods","filter","reset","__x","updateElements","getItem","storage","JSON","parse","assign","__watchers","__key_name","setItem","stringify","reduce","part","slice","toggle","clear","removeItem","unwatch","nameParts","sub","Map","has","Set","add","delete","f","persistUsing","driver","console","warn","const","deferrer","deferLoadingAlpine"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"spruce.umd.js","sources":["../node_modules/compare-versions/index.js","../src/utils.js","../src/observable.js","../src/index.js"],"sourcesContent":["/* global define */\n(function (root, factory) {\n /* istanbul ignore next */\n if (typeof define === 'function' && define.amd) {\n define([], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.compareVersions = factory();\n }\n}(this, function () {\n\n var semver = /^v?(?:\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+))?(?:-[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\n\n function indexOrEnd(str, q) {\n return str.indexOf(q) === -1 ? str.length : str.indexOf(q);\n }\n\n function split(v) {\n var c = v.replace(/^v/, '').replace(/\\+.*$/, '');\n var patchIndex = indexOrEnd(c, '-');\n var arr = c.substring(0, patchIndex).split('.');\n arr.push(c.substring(patchIndex + 1));\n return arr;\n }\n\n function tryParse(v) {\n return isNaN(Number(v)) ? v : Number(v);\n }\n\n function validate(version) {\n if (typeof version !== 'string') {\n throw new TypeError('Invalid argument expected string');\n }\n if (!semver.test(version)) {\n throw new Error('Invalid argument not valid semver (\\''+version+'\\' received)');\n }\n }\n\n function compareVersions(v1, v2) {\n [v1, v2].forEach(validate);\n\n var s1 = split(v1);\n var s2 = split(v2);\n\n for (var i = 0; i < Math.max(s1.length - 1, s2.length - 1); i++) {\n var n1 = parseInt(s1[i] || 0, 10);\n var n2 = parseInt(s2[i] || 0, 10);\n\n if (n1 > n2) return 1;\n if (n2 > n1) return -1;\n }\n\n var sp1 = s1[s1.length - 1];\n var sp2 = s2[s2.length - 1];\n\n if (sp1 && sp2) {\n var p1 = sp1.split('.').map(tryParse);\n var p2 = sp2.split('.').map(tryParse);\n\n for (i = 0; i < Math.max(p1.length, p2.length); i++) {\n if (p1[i] === undefined || typeof p2[i] === 'string' && typeof p1[i] === 'number') return -1;\n if (p2[i] === undefined || typeof p1[i] === 'string' && typeof p2[i] === 'number') return 1;\n\n if (p1[i] > p2[i]) return 1;\n if (p2[i] > p1[i]) return -1;\n }\n } else if (sp1 || sp2) {\n return sp1 ? -1 : 1;\n }\n\n return 0;\n };\n\n var allowedOperators = [\n '>',\n '>=',\n '=',\n '<',\n '<='\n ];\n\n var operatorResMap = {\n '>': [1],\n '>=': [0, 1],\n '=': [0],\n '<=': [-1, 0],\n '<': [-1]\n };\n\n function validateOperator(op) {\n if (typeof op !== 'string') {\n throw new TypeError('Invalid operator type, expected string but got ' + typeof op);\n }\n if (allowedOperators.indexOf(op) === -1) {\n throw new TypeError('Invalid operator, expected one of ' + allowedOperators.join('|'));\n }\n }\n\n compareVersions.validate = function(version) {\n return typeof version === 'string' && semver.test(version);\n }\n\n compareVersions.compare = function (v1, v2, operator) {\n // Validate operator\n validateOperator(operator);\n\n // since result of compareVersions can only be -1 or 0 or 1\n // a simple map can be used to replace switch\n var res = compareVersions(v1, v2);\n return operatorResMap[operator].indexOf(res) > -1;\n }\n\n return compareVersions;\n}));\n","import compareVersions from 'compare-versions'\n\nexport const isNullOrUndefined = value => {\n return value === null || value === undefined\n}\n\nexport const isObject = _ => {\n return Object.getPrototypeOf(_) === Object.prototype\n}\n\nexport const isArray = _ => Array.isArray(_)\n\nexport const getMethods = obj => {\n let methods = {}\n\n Object.entries(obj).filter(([_, value]) => typeof value === 'function').forEach(([key, value]) => methods[key] = value)\n\n return methods\n}\n\nexport const isTesting = () => {\n return navigator.userAgent, navigator.userAgent.includes(\"Node.js\")\n || navigator.userAgent.includes(\"jsdom\")\n}\n\nexport const checkForAlpine = () => {\n if (isTesting()) {\n return true\n }\n\n if (! window.Alpine) {\n return false\n }\n\n return compareVersions.compare(window.Alpine.version, '2.7.0', '>=')\n}","import { isNullOrUndefined, isObject, isArray } from './utils'\n\nexport const createObservable = (target, callbacks) => {\n Object.entries(target).forEach(([key, value]) => {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) { \n target[key] = createObservable(value, callbacks)\n }\n })\n\n return new Proxy(target, {\n get(target, key, receiver) {\n return callbacks.get(target, key, receiver)\n },\n set(target, key, value, receiver) {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) {\n value = createObservable(value, callbacks)\n }\n\n let originalValue = target[key]\n\n target[key] = value\n\n // Copy watchers from the original value if they exist\n if (!isNullOrUndefined(originalValue) && !isNullOrUndefined(originalValue.__watchers)) {\n target[key].__watchers = originalValue.__watchers\n }\n\n callbacks.set(target, key, target[key], receiver)\n\n return true\n }\n })\n}","import { getMethods, checkForAlpine, isObject, isArray, isNullOrUndefined } from './utils'\nimport { createObservable } from './observable'\n\nconst Spruce = {\n stores: {},\n\n persistenceDriver: window.localStorage,\n\n persisted: [],\n\n subscribers: [],\n\n watchers: {},\n\n disableReactivity: false,\n\n startingCallbacks: [],\n\n startedCallbacks: [],\n\n hasStarted: false,\n\n start() {\n this.startingCallbacks.forEach(fn => fn())\n\n this.attach()\n\n this.stores = createObservable(this.stores, {\n get: (target, key, receiver) => {\n if (Object.is(receiver, this.stores) && ['get', 'set', 'toggle', 'clear'].includes(key)) {\n return this[key].bind(this)\n }\n\n return Reflect.get(target, key, receiver)\n },\n set: (target, key, value, receiver) => {\n if (this.disableReactivity) {\n return\n }\n\n this.updateSubscribers()\n\n this.runWatchers(target, key, value, receiver)\n\n this.disableReactivity = true\n\n try {\n this.persisted.forEach(this.updateLocalStorage.bind(this))\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n\n this.disableReactivity = false\n }\n })\n\n this.hasStarted = true\n\n this.disableReactivity = true\n\n Object.entries(this.watchers).forEach(([name, callbacks]) => {\n callbacks.forEach(callback => this.watch(name, callback))\n })\n\n this.disableReactivity = false\n\n this.startedCallbacks.forEach(fn => fn())\n },\n\n starting(callback) {\n this.startingCallbacks.push(callback)\n },\n\n started(callback) {\n this.startedCallbacks.push(callback)\n },\n\n attach() {\n if (! checkForAlpine()) {\n throw new Error('[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.')\n }\n\n const self = this\n\n window.Alpine.addMagicProperty('store', el => {\n self.subscribe(el)\n\n return self.stores\n })\n },\n\n store(name, state, persist = false) {\n if (typeof state === 'function') {\n state = state()\n }\n \n if (persist) {\n try {\n this.stores[name] = this.retrieveFromLocalStorage(name, getMethods(state))\n\n if (!this.persisted.includes(name)) {\n this.persisted.push(name)\n }\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n }\n\n if (!this.stores[name]) {\n this.stores[name] = state\n }\n\n return this.stores[name]\n },\n\n reset(name, state) {\n if (! this.stores[name]) {\n return;\n }\n \n this.stores[name] = state\n },\n\n subscribe(el) {\n if (!this.subscribers.includes(el)) {\n this.subscribers.push(el)\n }\n\n return this.stores\n },\n\n updateSubscribers() {\n this.subscribers.filter(el => !!el.__x).forEach(el => {\n el.__x.updateElements(el)\n })\n },\n\n retrieveFromLocalStorage(name, methods = {}) {\n const value = this.persistenceDriver.getItem(`__spruce:${name}`)\n\n if (! value) {\n return null\n }\n\n let storage = JSON.parse(value)\n\n if (typeof storage === 'object') {\n storage = Object.assign(methods, storage)\n\n delete storage.__watchers\n delete storage.__key_name\n }\n\n return storage\n },\n\n updateLocalStorage(name) {\n const store = { ...this.store(name) }\n\n delete store.__watchers\n delete store.__key_name\n\n this.persistenceDriver.setItem(`__spruce:${name}`, JSON.stringify(this.store(name)))\n },\n\n get(name, target = this.stores) {\n return name.split('.').reduce((target, part) => target[part], target)\n },\n\n set(name, value, target = this.stores) {\n if (! isArray(name)) {\n name = name.split('.')\n }\n\n if (name.length === 1) return target[name[0]] = value\n\n if (target[name[0]]) {\n return this.set(name.slice(1), value, target[name[0]])\n } else {\n target[name[0]] = {}\n\n return this.set(name.slice(1), value, target[name[0]])\n }\n },\n\n toggle(name) {\n return this.set(name, ! this.get(name))\n },\n\n clear(name) {\n return this.persistenceDriver.removeItem(`__spruce:${name}`)\n },\n\n watch(name, callback) {\n if (! this.hasStarted) {\n this.watchers[name] || (this.watchers[name] = [])\n\n this.watchers[name].push(callback)\n\n return [() => this.unwatch(name, callback)]\n }\n\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n /**\n * If the target object / array is the property\n * that needs to be watched, a magic `__self` key is\n * used so that runner can pick up on it later.\n */\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n target.__watchers = new Map\n }\n \n if (! target.__watchers.has(part)) {\n target.__watchers.set(part, new Set)\n }\n\n target.__watchers.get(part).add(callback)\n\n return [() => this.unwatch(name, callback)]\n },\n\n unwatch(name, callback) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n const watchers = target.__watchers\n\n if (! watchers.has(part)) {\n return\n }\n\n watchers.get(part).delete(callback)\n },\n\n watchers(name) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n return {}\n }\n\n return target.__watchers.get(part)\n },\n\n runWatchers(target, key, value) {\n if (! target.__watchers) {\n return\n }\n\n if (target.__watchers.has(key)) {\n target.__watchers.get(key).forEach(f => f(value))\n }\n\n /**\n * The `__self` key is used for watchers that are registered\n * to the object or array being updated.\n */\n if (target.__watchers.has('__self')) {\n target.__watchers.get('__self').forEach(f => f(value, key))\n }\n },\n\n persistUsing(driver) {\n if (this.persisted.length > 0) {\n console.warn('[Spruce] You have already initialised a persisted store. Changing the driver may cause issues.')\n }\n\n if (typeof driver.getItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `getItem(key)` method.')\n }\n\n if (typeof driver.setItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `setItem(key, value)` method.')\n }\n\n if (typeof driver.removeItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `removeItem(name)` method.')\n }\n\n this.persistenceDriver = driver\n }\n}\n\nwindow.Spruce = Spruce\n\nconst deferrer = window.deferLoadingAlpine || function (callback) { callback() }\n\nwindow.deferLoadingAlpine = function (callback) {\n window.Spruce.start()\n\n deferrer(callback)\n}\n\nexport default Spruce\n"],"names":["module","semver","split","v","str","c","replace","patchIndex","indexOf","length","arr","substring","push","tryParse","isNaN","Number","validate","version","TypeError","test","Error","compareVersions","v1","v2","forEach","s1","s2","i","Math","max","n1","parseInt","n2","sp1","sp2","p1","map","p2","undefined","allowedOperators","operatorResMap",">",">=","=","<=","<","compare","operator","op","join","validateOperator","res","factory","isNullOrUndefined","value","isObject","_","Object","getPrototypeOf","prototype","isArray","Array","createObservable","target","callbacks","entries","key","Proxy","get","receiver","set","originalValue","__watchers","Spruce","stores","persistenceDriver","window","localStorage","persisted","subscribers","watchers","disableReactivity","startingCallbacks","startedCallbacks","hasStarted","start","fn","attach","this","is","includes","bind","Reflect","updateSubscribers","runWatchers","updateLocalStorage","e","callback","watch","name","starting","started","navigator","userAgent","Alpine","self","addMagicProperty","el","subscribe","store","state","persist","retrieveFromLocalStorage","methods","filter","reset","__x","updateElements","getItem","storage","JSON","parse","assign","__key_name","setItem","stringify","reduce","part","slice","toggle","clear","removeItem","unwatch","nameParts","sub","Map","has","Set","add","delete","f","persistUsing","driver","console","warn","const","deferrer","deferLoadingAlpine"],"mappings":"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"} \ No newline at end of file From 9f0605adefa38836045c07d9efe86cccafc6ad7c Mon Sep 17 00:00:00 2001 From: Josh Hanley Date: Mon, 25 Jan 2021 08:29:35 +1100 Subject: [PATCH 4/5] Add two way watcher to test --- tests/cypress/fixtures/watchers/init.html | 77 +++++++++++++++++++++- tests/cypress/integration/watchers.spec.js | 18 ++++- 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/tests/cypress/fixtures/watchers/init.html b/tests/cypress/fixtures/watchers/init.html index cbd3b37..bd906e2 100644 --- a/tests/cypress/fixtures/watchers/init.html +++ b/tests/cypress/fixtures/watchers/init.html @@ -25,6 +25,34 @@ +
+ Two way watchers + +
+

Store 1

+
    + +
+ + + +
+ +
+

Store 2

+
    + +
+ + + +
+
+ - \ No newline at end of file + diff --git a/tests/cypress/integration/watchers.spec.js b/tests/cypress/integration/watchers.spec.js index 6b42d65..8a72b41 100644 --- a/tests/cypress/integration/watchers.spec.js +++ b/tests/cypress/integration/watchers.spec.js @@ -31,5 +31,21 @@ describe('watchers', () => { cy.get('[data-change-name]').click() cy.get('[data-todo-label]').should('have.text', 'Changed!') + + cy.get('[data-input-todo1]').type('sample') + cy.get('[data-add-todo1]').click() + cy.get('[data-todo1-item]').should('have.length', 1) + cy.get('[data-todo2-item]').should('have.length', 1) + cy.get('[data-todo1-item]').eq(0).should('contain.text', 'sample') + cy.get('[data-todo2-item]').eq(0).should('contain.text', 'sample') + + cy.get('[data-input-todo2]').type('sample2') + cy.get('[data-add-todo2]').click() + cy.get('[data-todo1-item]').should('have.length', 2) + cy.get('[data-todo2-item]').should('have.length', 2) + cy.get('[data-todo1-item]').eq(0).should('contain.text', 'sample') + cy.get('[data-todo2-item]').eq(0).should('contain.text', 'sample') + cy.get('[data-todo1-item]').eq(1).should('contain.text', 'sample2') + cy.get('[data-todo2-item]').eq(1).should('contain.text', 'sample2') }) -}) \ No newline at end of file +}) From 905e5c78377f42f2b9cd0c5cbeeb7c79851ac660 Mon Sep 17 00:00:00 2001 From: Josh Hanley Date: Wed, 3 Feb 2021 07:12:42 +1100 Subject: [PATCH 5/5] Build assets --- dist/spruce.js | 2 +- dist/spruce.js.map | 2 +- dist/spruce.module.js | 2 +- dist/spruce.module.js.map | 2 +- dist/spruce.umd.js | 2 +- dist/spruce.umd.js.map | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dist/spruce.js b/dist/spruce.js index c5f2fba..2d996ea 100644 --- a/dist/spruce.js +++ b/dist/spruce.js @@ -1,2 +1,2 @@ -function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var r=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("-"),s=r.substring(0,n).split(".");return s.push(r.substring(n+1)),s}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 s(e,s){[e,s].forEach(n);for(var i=t(e),o=t(s),c=0;cu)return 1;if(u>a)return-1}var f=i[i.length-1],h=o[o.length-1];if(f&&h){var l=f.split(".").map(r),p=h.split(".").map(r);for(c=0;cp[c])return 1;if(p[c]>l[c])return-1}}else if(f||h)return f?-1:1;return 0}var i=[">",">=","=","<","<="],o={">":[1],">=":[0,1],"=":[0],"<=":[-1,0],"<":[-1]};return s.validate=function(t){return"string"==typeof t&&e.test(t)},s.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===i.indexOf(e))throw new TypeError("Invalid operator, expected one of "+i.join("|"))}(r);var n=s(e,t);return o[r].indexOf(n)>-1},s}()}(t={exports:{}}),t.exports}(),n=function(e){return null==e},s=function(e){return Object.getPrototypeOf(e)===Object.prototype},i=function(e){return Array.isArray(e)},o=function(e,t){return Object.entries(e).forEach(function(r){var c=r[0],a=r[1];n(a)||!s(a)&&!i(a)||(e[c]=o(a,t))}),new Proxy(e,{get:function(e,r,n){return t.get(e,r,n)},set:function(e,r,c,a){n(c)||!s(c)&&!i(c)||(c=o(c,t));var u=e[r];return e[r]=c,n(u)||n(u.__watchers)||(e[r].__watchers=u.__watchers),t.set(e,r,e[r],a),!0}})},c={stores:{},persistenceDriver:window.localStorage,persisted:[],subscribers:[],watchers:{},disableReactivity:!1,startingCallbacks:[],startedCallbacks:[],hasStarted:!1,start:function(){var e=this;this.startingCallbacks.forEach(function(e){return e()}),this.attach(),this.stores=o(this.stores,{get:function(t,r,n){return Object.is(n,e.stores)&&["get","set","toggle","clear"].includes(r)?e[r].bind(e):Reflect.get(t,r,n)},set:function(t,r,n,s){if(!e.disableReactivity){e.updateSubscribers(),e.runWatchers(t,r,n,s),e.disableReactivity=!0;try{e.persisted.forEach(e.updateLocalStorage.bind(e))}catch(e){}e.disableReactivity=!1}}}),this.hasStarted=!0,this.disableReactivity=!0,Object.entries(this.watchers).forEach(function(t){var r=t[0];t[1].forEach(function(t){return e.watch(r,t)})}),this.disableReactivity=!1,this.startedCallbacks.forEach(function(e){return e()})},starting:function(e){this.startingCallbacks.push(e)},started:function(e){this.startedCallbacks.push(e)},attach:function(){if(!(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")||window.Alpine&&r.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),"function"==typeof t&&(t=t()),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]&&(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=this.persistenceDriver.getItem("__spruce:"+e);if(!r)return null;var n=JSON.parse(r);return"object"==typeof n&&(delete(n=Object.assign(t,n)).__watchers,delete n.__key_name),n},updateLocalStorage:function(r){var n=function(r){for(var n=1;n0&&console.warn("[Spruce] You have already initialised a persisted store. Changing the driver may cause issues."),"function"!=typeof e.getItem)throw new Error("[Spruce] The persistence driver must have a `getItem(key)` method.");if("function"!=typeof e.setItem)throw new Error("[Spruce] The persistence driver must have a `setItem(key, value)` method.");if("function"!=typeof e.removeItem)throw new Error("[Spruce] The persistence driver must have a `removeItem(name)` method.");this.persistenceDriver=e}};window.Spruce=c;var a=window.deferLoadingAlpine||function(e){e()};window.deferLoadingAlpine=function(e){window.Spruce.start(),a(e)},module.exports=c; +function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var r=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 s=t(e),o=t(i),c=0;cu)return 1;if(u>a)return-1}var f=s[s.length-1],h=o[o.length-1];if(f&&h){var l=f.split(".").map(r),p=h.split(".").map(r);for(c=0;cp[c])return 1;if(p[c]>l[c])return-1}}else if(f||h)return f?-1:1;return 0}var s=[">",">=","=","<","<="],o={">":[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===s.indexOf(e))throw new TypeError("Invalid operator, expected one of "+s.join("|"))}(r);var n=i(e,t);return o[r].indexOf(n)>-1},i}()}(t={exports:{}}),t.exports}(),n=function(e){return null==e},i=function(e){return Object.getPrototypeOf(e)===Object.prototype},s=function(e){return Array.isArray(e)},o=function(e,t){return Object.entries(e).forEach(function(r){var c=r[0],a=r[1];n(a)||!i(a)&&!s(a)||(e[c]=o(a,t))}),new Proxy(e,{get:function(e,r,n){return t.get(e,r,n)},set:function(e,r,c,a){n(c)||!i(c)&&!s(c)||(c=o(c,t));var u=e[r];return e[r]=c,n(u)||n(u.__watchers)||(e[r].__watchers=u.__watchers),t.set(e,r,e[r],a),!0}})},c={stores:{},persistenceDriver:window.localStorage,persisted:[],subscribers:[],pendingWatchers:{},disableReactivity:!1,startingCallbacks:[],startedCallbacks:[],hasStarted:!1,start:function(){var e=this;this.startingCallbacks.forEach(function(e){return e()}),this.attach(),this.stores=o(this.stores,{get:function(t,r,n){return Object.is(n,e.stores)&&["get","set","toggle","call","clear"].includes(r)?e[r].bind(e):Reflect.get(t,r,n)},set:function(t,r,n,i){if(!e.disableReactivity){e.updateSubscribers(),e.runWatchers(t,r,n,i),e.disableReactivity=!0;try{e.persisted.forEach(e.updateLocalStorage.bind(e))}catch(e){}e.disableReactivity=!1}}}),this.hasStarted=!0,this.disableReactivity=!0,Object.entries(this.pendingWatchers).forEach(function(t){var r=t[0];t[1].forEach(function(t){return e.watch(r,t)})}),this.disableReactivity=!1,this.startedCallbacks.forEach(function(e){return e()})},starting:function(e){this.startingCallbacks.push(e)},started:function(e){this.startedCallbacks.push(e)},attach:function(){if(!(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")||window.Alpine&&r.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),"function"==typeof t&&(t=t()),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){void 0!==this.stores[e]&&(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=this.persistenceDriver.getItem("__spruce:"+e);if(!r)return null;var n=JSON.parse(r);return"object"==typeof n&&(delete(n=Object.assign(t,n)).__watchers,delete n.__key_name),n},updateLocalStorage:function(r){var n=function(r){for(var n=1;n0;)t[r]=arguments[r+1];return this.get(e).apply(void 0,t)},clear:function(e){return this.persistenceDriver.removeItem("__spruce:"+e)},watch:function(e,t){var r=this;if(!this.hasStarted)return this.pendingWatchers[e]||(this.pendingWatchers[e]=[]),this.pendingWatchers[e].push(t),[function(){return r.unwatch(e,t)}];var o=e.split("."),c=o.reduce(function(e,t){var r=e[t];return n(r)||!i(r)&&!s(r)?e:r},this.stores),a=Object.is(c,this.get(e))?"__self":o[o.length-1];return c.__watchers||(c.__watchers=new Map),c.__watchers.has(a)||c.__watchers.set(a,new Set),c.__watchers.get(a).add(t),[function(){return r.unwatch(e,t)}]},unwatch:function(e,t){var r=e.split("."),o=r.reduce(function(e,t){var r=e[t];return n(r)||!i(r)&&!s(r)?e:r},this.stores),c=Object.is(o,this.get(e))?"__self":r[r.length-1],a=o.__watchers;a.has(c)&&a.get(c).delete(t)},watchers:function(e){var t=e.split("."),r=t.reduce(function(e,t){var r=e[t];return n(r)||!i(r)&&!s(r)?e:r},this.stores),o=Object.is(r,this.get(e))?"__self":t[t.length-1];return r.__watchers?r.__watchers.get(o):{}},runWatchers:function(e,t,r){e.__watchers&&(e.__watchers.has(t)&&e.__watchers.get(t).forEach(function(e){return e(r)}),e.__watchers.has("__self")&&e.__watchers.get("__self").forEach(function(e){return e(r,t)}))},persistUsing:function(e){if(this.persisted.length>0&&console.warn("[Spruce] You have already initialised a persisted store. Changing the driver may cause issues."),"function"!=typeof e.getItem)throw new Error("[Spruce] The persistence driver must have a `getItem(key)` method.");if("function"!=typeof e.setItem)throw new Error("[Spruce] The persistence driver must have a `setItem(key, value)` method.");if("function"!=typeof e.removeItem)throw new Error("[Spruce] The persistence driver must have a `removeItem(name)` method.");this.persistenceDriver=e}};window.Spruce=c;var a=window.deferLoadingAlpine||function(e){e()};window.deferLoadingAlpine=function(e){window.Spruce.start(),a(e)},module.exports=c; //# sourceMappingURL=spruce.js.map diff --git a/dist/spruce.js.map b/dist/spruce.js.map index 54e18bc..7fc87fb 100644 --- a/dist/spruce.js.map +++ b/dist/spruce.js.map @@ -1 +1 @@ -{"version":3,"file":"spruce.js","sources":["../node_modules/compare-versions/index.js","../src/utils.js","../src/observable.js","../src/index.js"],"sourcesContent":["/* global define */\n(function (root, factory) {\n /* istanbul ignore next */\n if (typeof define === 'function' && define.amd) {\n define([], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.compareVersions = factory();\n }\n}(this, function () {\n\n var semver = /^v?(?:\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+))?(?:-[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\n\n function indexOrEnd(str, q) {\n return str.indexOf(q) === -1 ? str.length : str.indexOf(q);\n }\n\n function split(v) {\n var c = v.replace(/^v/, '').replace(/\\+.*$/, '');\n var patchIndex = indexOrEnd(c, '-');\n var arr = c.substring(0, patchIndex).split('.');\n arr.push(c.substring(patchIndex + 1));\n return arr;\n }\n\n function tryParse(v) {\n return isNaN(Number(v)) ? v : Number(v);\n }\n\n function validate(version) {\n if (typeof version !== 'string') {\n throw new TypeError('Invalid argument expected string');\n }\n if (!semver.test(version)) {\n throw new Error('Invalid argument not valid semver (\\''+version+'\\' received)');\n }\n }\n\n function compareVersions(v1, v2) {\n [v1, v2].forEach(validate);\n\n var s1 = split(v1);\n var s2 = split(v2);\n\n for (var i = 0; i < Math.max(s1.length - 1, s2.length - 1); i++) {\n var n1 = parseInt(s1[i] || 0, 10);\n var n2 = parseInt(s2[i] || 0, 10);\n\n if (n1 > n2) return 1;\n if (n2 > n1) return -1;\n }\n\n var sp1 = s1[s1.length - 1];\n var sp2 = s2[s2.length - 1];\n\n if (sp1 && sp2) {\n var p1 = sp1.split('.').map(tryParse);\n var p2 = sp2.split('.').map(tryParse);\n\n for (i = 0; i < Math.max(p1.length, p2.length); i++) {\n if (p1[i] === undefined || typeof p2[i] === 'string' && typeof p1[i] === 'number') return -1;\n if (p2[i] === undefined || typeof p1[i] === 'string' && typeof p2[i] === 'number') return 1;\n\n if (p1[i] > p2[i]) return 1;\n if (p2[i] > p1[i]) return -1;\n }\n } else if (sp1 || sp2) {\n return sp1 ? -1 : 1;\n }\n\n return 0;\n };\n\n var allowedOperators = [\n '>',\n '>=',\n '=',\n '<',\n '<='\n ];\n\n var operatorResMap = {\n '>': [1],\n '>=': [0, 1],\n '=': [0],\n '<=': [-1, 0],\n '<': [-1]\n };\n\n function validateOperator(op) {\n if (typeof op !== 'string') {\n throw new TypeError('Invalid operator type, expected string but got ' + typeof op);\n }\n if (allowedOperators.indexOf(op) === -1) {\n throw new TypeError('Invalid operator, expected one of ' + allowedOperators.join('|'));\n }\n }\n\n compareVersions.validate = function(version) {\n return typeof version === 'string' && semver.test(version);\n }\n\n compareVersions.compare = function (v1, v2, operator) {\n // Validate operator\n validateOperator(operator);\n\n // since result of compareVersions can only be -1 or 0 or 1\n // a simple map can be used to replace switch\n var res = compareVersions(v1, v2);\n return operatorResMap[operator].indexOf(res) > -1;\n }\n\n return compareVersions;\n}));\n","import compareVersions from 'compare-versions'\n\nexport const isNullOrUndefined = value => {\n return value === null || value === undefined\n}\n\nexport const isObject = _ => {\n return Object.getPrototypeOf(_) === Object.prototype\n}\n\nexport const isArray = _ => Array.isArray(_)\n\nexport const getMethods = obj => {\n let methods = {}\n\n Object.entries(obj).filter(([_, value]) => typeof value === 'function').forEach(([key, value]) => methods[key] = value)\n\n return methods\n}\n\nexport const isTesting = () => {\n return navigator.userAgent, navigator.userAgent.includes(\"Node.js\")\n || navigator.userAgent.includes(\"jsdom\")\n}\n\nexport const checkForAlpine = () => {\n if (isTesting()) {\n return true\n }\n\n if (! window.Alpine) {\n return false\n }\n\n return compareVersions.compare(window.Alpine.version, '2.7.0', '>=')\n}","import { isNullOrUndefined, isObject, isArray } from './utils'\n\nexport const createObservable = (target, callbacks) => {\n Object.entries(target).forEach(([key, value]) => {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) { \n target[key] = createObservable(value, callbacks)\n }\n })\n\n return new Proxy(target, {\n get(target, key, receiver) {\n return callbacks.get(target, key, receiver)\n },\n set(target, key, value, receiver) {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) {\n value = createObservable(value, callbacks)\n }\n\n let originalValue = target[key]\n\n target[key] = value\n\n // Copy watchers from the original value if they exist\n if (!isNullOrUndefined(originalValue) && !isNullOrUndefined(originalValue.__watchers)) {\n target[key].__watchers = originalValue.__watchers\n }\n\n callbacks.set(target, key, target[key], receiver)\n\n return true\n }\n })\n}","import { getMethods, checkForAlpine, isObject, isArray, isNullOrUndefined } from './utils'\nimport { createObservable } from './observable'\n\nconst Spruce = {\n stores: {},\n\n persistenceDriver: window.localStorage,\n\n persisted: [],\n\n subscribers: [],\n\n watchers: {},\n\n disableReactivity: false,\n\n startingCallbacks: [],\n\n startedCallbacks: [],\n\n hasStarted: false,\n\n start() {\n this.startingCallbacks.forEach(fn => fn())\n\n this.attach()\n\n this.stores = createObservable(this.stores, {\n get: (target, key, receiver) => {\n if (Object.is(receiver, this.stores) && ['get', 'set', 'toggle', 'clear'].includes(key)) {\n return this[key].bind(this)\n }\n\n return Reflect.get(target, key, receiver)\n },\n set: (target, key, value, receiver) => {\n if (this.disableReactivity) {\n return\n }\n\n this.updateSubscribers()\n\n this.runWatchers(target, key, value, receiver)\n\n this.disableReactivity = true\n\n try {\n this.persisted.forEach(this.updateLocalStorage.bind(this))\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n\n this.disableReactivity = false\n }\n })\n\n this.hasStarted = true\n\n this.disableReactivity = true\n\n Object.entries(this.watchers).forEach(([name, callbacks]) => {\n callbacks.forEach(callback => this.watch(name, callback))\n })\n\n this.disableReactivity = false\n\n this.startedCallbacks.forEach(fn => fn())\n },\n\n starting(callback) {\n this.startingCallbacks.push(callback)\n },\n\n started(callback) {\n this.startedCallbacks.push(callback)\n },\n\n attach() {\n if (! checkForAlpine()) {\n throw new Error('[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.')\n }\n\n const self = this\n\n window.Alpine.addMagicProperty('store', el => {\n self.subscribe(el)\n\n return self.stores\n })\n },\n\n store(name, state, persist = false) {\n if (typeof state === 'function') {\n state = state()\n }\n \n if (persist) {\n try {\n this.stores[name] = this.retrieveFromLocalStorage(name, getMethods(state))\n\n if (!this.persisted.includes(name)) {\n this.persisted.push(name)\n }\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n }\n\n if (!this.stores[name]) {\n this.stores[name] = state\n }\n\n return this.stores[name]\n },\n\n reset(name, state) {\n if (! this.stores[name]) {\n return;\n }\n \n this.stores[name] = state\n },\n\n subscribe(el) {\n if (!this.subscribers.includes(el)) {\n this.subscribers.push(el)\n }\n\n return this.stores\n },\n\n updateSubscribers() {\n this.subscribers.filter(el => !!el.__x).forEach(el => {\n el.__x.updateElements(el)\n })\n },\n\n retrieveFromLocalStorage(name, methods = {}) {\n const value = this.persistenceDriver.getItem(`__spruce:${name}`)\n\n if (! value) {\n return null\n }\n\n let storage = JSON.parse(value)\n\n if (typeof storage === 'object') {\n storage = Object.assign(methods, storage)\n\n delete storage.__watchers\n delete storage.__key_name\n }\n\n return storage\n },\n\n updateLocalStorage(name) {\n const store = { ...this.store(name) }\n\n delete store.__watchers\n delete store.__key_name\n\n this.persistenceDriver.setItem(`__spruce:${name}`, JSON.stringify(this.store(name)))\n },\n\n get(name, target = this.stores) {\n return name.split('.').reduce((target, part) => target[part], target)\n },\n\n set(name, value, target = this.stores) {\n if (! isArray(name)) {\n name = name.split('.')\n }\n\n if (name.length === 1) return target[name[0]] = value\n\n if (target[name[0]]) {\n return this.set(name.slice(1), value, target[name[0]])\n } else {\n target[name[0]] = {}\n\n return this.set(name.slice(1), value, target[name[0]])\n }\n },\n\n toggle(name) {\n return this.set(name, ! this.get(name))\n },\n\n clear(name) {\n return this.persistenceDriver.removeItem(`__spruce:${name}`)\n },\n\n watch(name, callback) {\n if (! this.hasStarted) {\n this.watchers[name] || (this.watchers[name] = [])\n\n this.watchers[name].push(callback)\n\n return [() => this.unwatch(name, callback)]\n }\n\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n /**\n * If the target object / array is the property\n * that needs to be watched, a magic `__self` key is\n * used so that runner can pick up on it later.\n */\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n target.__watchers = new Map\n }\n \n if (! target.__watchers.has(part)) {\n target.__watchers.set(part, new Set)\n }\n\n target.__watchers.get(part).add(callback)\n\n return [() => this.unwatch(name, callback)]\n },\n\n unwatch(name, callback) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n const watchers = target.__watchers\n\n if (! watchers.has(part)) {\n return\n }\n\n watchers.get(part).delete(callback)\n },\n\n watchers(name) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n return {}\n }\n\n return target.__watchers.get(part)\n },\n\n runWatchers(target, key, value) {\n if (! target.__watchers) {\n return\n }\n\n if (target.__watchers.has(key)) {\n target.__watchers.get(key).forEach(f => f(value))\n }\n\n /**\n * The `__self` key is used for watchers that are registered\n * to the object or array being updated.\n */\n if (target.__watchers.has('__self')) {\n target.__watchers.get('__self').forEach(f => f(value, key))\n }\n },\n\n persistUsing(driver) {\n if (this.persisted.length > 0) {\n console.warn('[Spruce] You have already initialised a persisted store. Changing the driver may cause issues.')\n }\n\n if (typeof driver.getItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `getItem(key)` method.')\n }\n\n if (typeof driver.setItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `setItem(key, value)` method.')\n }\n\n if (typeof driver.removeItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `removeItem(name)` method.')\n }\n\n this.persistenceDriver = driver\n }\n}\n\nwindow.Spruce = Spruce\n\nconst deferrer = window.deferLoadingAlpine || function (callback) { callback() }\n\nwindow.deferLoadingAlpine = function (callback) {\n window.Spruce.start()\n\n deferrer(callback)\n}\n\nexport default Spruce\n"],"names":["module","semver","split","v","str","c","replace","patchIndex","indexOf","length","arr","substring","push","tryParse","isNaN","Number","validate","version","TypeError","test","Error","compareVersions","v1","v2","forEach","s1","s2","i","Math","max","n1","parseInt","n2","sp1","sp2","p1","map","p2","undefined","allowedOperators","operatorResMap",">",">=","=","<=","<","compare","operator","op","join","validateOperator","res","factory","isNullOrUndefined","value","isObject","_","Object","getPrototypeOf","prototype","isArray","Array","createObservable","target","callbacks","entries","key","Proxy","get","receiver","set","originalValue","__watchers","Spruce","stores","persistenceDriver","window","localStorage","persisted","subscribers","watchers","disableReactivity","startingCallbacks","startedCallbacks","hasStarted","start","fn","attach","this","is","includes","bind","Reflect","updateSubscribers","runWatchers","updateLocalStorage","e","callback","watch","name","starting","started","navigator","userAgent","Alpine","self","addMagicProperty","el","subscribe","store","state","persist","retrieveFromLocalStorage","methods","filter","reset","__x","updateElements","getItem","storage","JSON","parse","assign","__key_name","setItem","stringify","reduce","part","slice","toggle","clear","removeItem","unwatch","nameParts","sub","Map","has","Set","add","delete","f","persistUsing","driver","console","warn","const","deferrer","deferLoadingAlpine"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"spruce.js","sources":["../node_modules/compare-versions/index.js","../src/utils.js","../src/observable.js","../src/index.js"],"sourcesContent":["/* global define */\n(function (root, factory) {\n /* istanbul ignore next */\n if (typeof define === 'function' && define.amd) {\n define([], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.compareVersions = factory();\n }\n}(this, function () {\n\n var semver = /^v?(?:\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+))?(?:-[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\n\n function indexOrEnd(str, q) {\n return str.indexOf(q) === -1 ? str.length : str.indexOf(q);\n }\n\n function split(v) {\n var c = v.replace(/^v/, '').replace(/\\+.*$/, '');\n var patchIndex = indexOrEnd(c, '-');\n var arr = c.substring(0, patchIndex).split('.');\n arr.push(c.substring(patchIndex + 1));\n return arr;\n }\n\n function tryParse(v) {\n return isNaN(Number(v)) ? v : Number(v);\n }\n\n function validate(version) {\n if (typeof version !== 'string') {\n throw new TypeError('Invalid argument expected string');\n }\n if (!semver.test(version)) {\n throw new Error('Invalid argument not valid semver (\\''+version+'\\' received)');\n }\n }\n\n function compareVersions(v1, v2) {\n [v1, v2].forEach(validate);\n\n var s1 = split(v1);\n var s2 = split(v2);\n\n for (var i = 0; i < Math.max(s1.length - 1, s2.length - 1); i++) {\n var n1 = parseInt(s1[i] || 0, 10);\n var n2 = parseInt(s2[i] || 0, 10);\n\n if (n1 > n2) return 1;\n if (n2 > n1) return -1;\n }\n\n var sp1 = s1[s1.length - 1];\n var sp2 = s2[s2.length - 1];\n\n if (sp1 && sp2) {\n var p1 = sp1.split('.').map(tryParse);\n var p2 = sp2.split('.').map(tryParse);\n\n for (i = 0; i < Math.max(p1.length, p2.length); i++) {\n if (p1[i] === undefined || typeof p2[i] === 'string' && typeof p1[i] === 'number') return -1;\n if (p2[i] === undefined || typeof p1[i] === 'string' && typeof p2[i] === 'number') return 1;\n\n if (p1[i] > p2[i]) return 1;\n if (p2[i] > p1[i]) return -1;\n }\n } else if (sp1 || sp2) {\n return sp1 ? -1 : 1;\n }\n\n return 0;\n };\n\n var allowedOperators = [\n '>',\n '>=',\n '=',\n '<',\n '<='\n ];\n\n var operatorResMap = {\n '>': [1],\n '>=': [0, 1],\n '=': [0],\n '<=': [-1, 0],\n '<': [-1]\n };\n\n function validateOperator(op) {\n if (typeof op !== 'string') {\n throw new TypeError('Invalid operator type, expected string but got ' + typeof op);\n }\n if (allowedOperators.indexOf(op) === -1) {\n throw new TypeError('Invalid operator, expected one of ' + allowedOperators.join('|'));\n }\n }\n\n compareVersions.validate = function(version) {\n return typeof version === 'string' && semver.test(version);\n }\n\n compareVersions.compare = function (v1, v2, operator) {\n // Validate operator\n validateOperator(operator);\n\n // since result of compareVersions can only be -1 or 0 or 1\n // a simple map can be used to replace switch\n var res = compareVersions(v1, v2);\n return operatorResMap[operator].indexOf(res) > -1;\n }\n\n return compareVersions;\n}));\n","import compareVersions from 'compare-versions'\n\nexport const isNullOrUndefined = value => {\n return value === null || value === undefined\n}\n\nexport const isObject = _ => {\n return Object.getPrototypeOf(_) === Object.prototype\n}\n\nexport const isArray = _ => Array.isArray(_)\n\nexport const getMethods = obj => {\n let methods = {}\n\n Object.entries(obj).filter(([_, value]) => typeof value === 'function').forEach(([key, value]) => methods[key] = value)\n\n return methods\n}\n\nexport const isTesting = () => {\n return navigator.userAgent, navigator.userAgent.includes(\"Node.js\")\n || navigator.userAgent.includes(\"jsdom\")\n}\n\nexport const checkForAlpine = () => {\n if (isTesting()) {\n return true\n }\n\n if (! window.Alpine) {\n return false\n }\n\n return compareVersions.compare(window.Alpine.version, '2.7.0', '>=')\n}","import { isNullOrUndefined, isObject, isArray } from './utils'\n\nexport const createObservable = (target, callbacks) => {\n Object.entries(target).forEach(([key, value]) => {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) { \n target[key] = createObservable(value, callbacks)\n }\n })\n\n return new Proxy(target, {\n get(target, key, receiver) {\n return callbacks.get(target, key, receiver)\n },\n set(target, key, value, receiver) {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) {\n value = createObservable(value, callbacks)\n }\n\n let originalValue = target[key]\n\n target[key] = value\n\n // Copy watchers from the original value if they exist\n if (!isNullOrUndefined(originalValue) && !isNullOrUndefined(originalValue.__watchers)) {\n target[key].__watchers = originalValue.__watchers\n }\n\n callbacks.set(target, key, target[key], receiver)\n\n return true\n }\n })\n}","import { getMethods, checkForAlpine, isObject, isArray, isNullOrUndefined } from './utils'\nimport { createObservable } from './observable'\n\nconst Spruce = {\n stores: {},\n\n persistenceDriver: window.localStorage,\n\n persisted: [],\n\n subscribers: [],\n\n pendingWatchers: {},\n\n disableReactivity: false,\n\n startingCallbacks: [],\n\n startedCallbacks: [],\n\n hasStarted: false,\n\n start() {\n this.startingCallbacks.forEach(fn => fn())\n\n this.attach()\n\n this.stores = createObservable(this.stores, {\n get: (target, key, receiver) => {\n if (Object.is(receiver, this.stores) && ['get', 'set', 'toggle', 'call', 'clear'].includes(key)) {\n return this[key].bind(this)\n }\n\n return Reflect.get(target, key, receiver)\n },\n set: (target, key, value, receiver) => {\n if (this.disableReactivity) {\n return\n }\n\n this.updateSubscribers()\n\n this.runWatchers(target, key, value, receiver)\n\n this.disableReactivity = true\n\n try {\n this.persisted.forEach(this.updateLocalStorage.bind(this))\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n\n this.disableReactivity = false\n }\n })\n\n this.hasStarted = true\n\n this.disableReactivity = true\n\n Object.entries(this.pendingWatchers).forEach(([name, callbacks]) => {\n callbacks.forEach(callback => this.watch(name, callback))\n })\n\n this.disableReactivity = false\n\n this.startedCallbacks.forEach(fn => fn())\n },\n\n starting(callback) {\n this.startingCallbacks.push(callback)\n },\n\n started(callback) {\n this.startedCallbacks.push(callback)\n },\n\n attach() {\n if (! checkForAlpine()) {\n throw new Error('[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.')\n }\n\n const self = this\n\n window.Alpine.addMagicProperty('store', el => {\n self.subscribe(el)\n\n return self.stores\n })\n },\n\n store(name, state, persist = false) {\n if (typeof state === 'function') {\n state = state()\n }\n \n if (persist) {\n try {\n this.stores[name] = this.retrieveFromLocalStorage(name, getMethods(state))\n\n if (!this.persisted.includes(name)) {\n this.persisted.push(name)\n }\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n }\n\n if (!this.stores[name]) {\n this.stores[name] = state\n }\n\n return this.stores[name]\n },\n\n reset(name, state) {\n if (this.stores[name] === undefined) {\n return;\n }\n \n this.stores[name] = state\n },\n\n subscribe(el) {\n if (!this.subscribers.includes(el)) {\n this.subscribers.push(el)\n }\n\n return this.stores\n },\n\n updateSubscribers() {\n this.subscribers.filter(el => !!el.__x).forEach(el => {\n el.__x.updateElements(el)\n })\n },\n\n retrieveFromLocalStorage(name, methods = {}) {\n const value = this.persistenceDriver.getItem(`__spruce:${name}`)\n\n if (! value) {\n return null\n }\n\n let storage = JSON.parse(value)\n\n if (typeof storage === 'object') {\n storage = Object.assign(methods, storage)\n\n delete storage.__watchers\n delete storage.__key_name\n }\n\n return storage\n },\n\n updateLocalStorage(name) {\n const store = { ...this.store(name) }\n\n delete store.__watchers\n delete store.__key_name\n\n this.persistenceDriver.setItem(`__spruce:${name}`, JSON.stringify(this.store(name)))\n },\n\n get(name, target = this.stores) {\n return name.split('.').reduce((target, part) => target[part], target)\n },\n\n set(name, value, target = this.stores) {\n if (! isArray(name)) {\n name = name.split('.')\n }\n\n if (name.length === 1) return target[name[0]] = value\n\n if (target[name[0]]) {\n return this.set(name.slice(1), value, target[name[0]])\n } else {\n target[name[0]] = {}\n\n return this.set(name.slice(1), value, target[name[0]])\n }\n },\n\n toggle(name) {\n return this.set(name, ! this.get(name))\n },\n\n call(name, ...args) {\n return this.get(name)(...args)\n },\n\n clear(name) {\n return this.persistenceDriver.removeItem(`__spruce:${name}`)\n },\n\n watch(name, callback) {\n if (! this.hasStarted) {\n this.pendingWatchers[name] || (this.pendingWatchers[name] = [])\n\n this.pendingWatchers[name].push(callback)\n\n return [() => this.unwatch(name, callback)]\n }\n\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n /**\n * If the target object / array is the property\n * that needs to be watched, a magic `__self` key is\n * used so that runner can pick up on it later.\n */\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n target.__watchers = new Map\n }\n \n if (! target.__watchers.has(part)) {\n target.__watchers.set(part, new Set)\n }\n\n target.__watchers.get(part).add(callback)\n\n return [() => this.unwatch(name, callback)]\n },\n\n unwatch(name, callback) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n const watchers = target.__watchers\n\n if (! watchers.has(part)) {\n return\n }\n\n watchers.get(part).delete(callback)\n },\n\n watchers(name) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n return {}\n }\n\n return target.__watchers.get(part)\n },\n\n runWatchers(target, key, value) {\n if (! target.__watchers) {\n return\n }\n\n if (target.__watchers.has(key)) {\n target.__watchers.get(key).forEach(f => f(value))\n }\n\n /**\n * The `__self` key is used for watchers that are registered\n * to the object or array being updated.\n */\n if (target.__watchers.has('__self')) {\n target.__watchers.get('__self').forEach(f => f(value, key))\n }\n },\n\n persistUsing(driver) {\n if (this.persisted.length > 0) {\n console.warn('[Spruce] You have already initialised a persisted store. Changing the driver may cause issues.')\n }\n\n if (typeof driver.getItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `getItem(key)` method.')\n }\n\n if (typeof driver.setItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `setItem(key, value)` method.')\n }\n\n if (typeof driver.removeItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `removeItem(name)` method.')\n }\n\n this.persistenceDriver = driver\n }\n}\n\nwindow.Spruce = Spruce\n\nconst deferrer = window.deferLoadingAlpine || function (callback) { callback() }\n\nwindow.deferLoadingAlpine = function (callback) {\n window.Spruce.start()\n\n deferrer(callback)\n}\n\nexport default Spruce\n"],"names":["module","semver","split","v","str","c","replace","patchIndex","indexOf","length","arr","substring","push","tryParse","isNaN","Number","validate","version","TypeError","test","Error","compareVersions","v1","v2","forEach","s1","s2","i","Math","max","n1","parseInt","n2","sp1","sp2","p1","map","p2","undefined","allowedOperators","operatorResMap",">",">=","=","<=","<","compare","operator","op","join","validateOperator","res","factory","isNullOrUndefined","value","isObject","_","Object","getPrototypeOf","prototype","isArray","Array","createObservable","target","callbacks","entries","key","Proxy","get","receiver","set","originalValue","__watchers","Spruce","stores","persistenceDriver","window","localStorage","persisted","subscribers","pendingWatchers","disableReactivity","startingCallbacks","startedCallbacks","hasStarted","start","fn","attach","this","is","includes","bind","Reflect","updateSubscribers","runWatchers","updateLocalStorage","e","callback","watch","name","starting","started","navigator","userAgent","Alpine","self","addMagicProperty","el","subscribe","store","state","persist","retrieveFromLocalStorage","methods","filter","reset","__x","updateElements","getItem","storage","JSON","parse","assign","__key_name","setItem","stringify","reduce","part","slice","toggle","call","args","clear","removeItem","unwatch","nameParts","sub","Map","has","Set","add","watchers","delete","f","persistUsing","driver","console","warn","const","deferrer","deferLoadingAlpine"],"mappings":"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"} \ No newline at end of file diff --git a/dist/spruce.module.js b/dist/spruce.module.js index 3dcd102..7386157 100644 --- a/dist/spruce.module.js +++ b/dist/spruce.module.js @@ -1,2 +1,2 @@ -function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var r,n=(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("-"),s=r.substring(0,n).split(".");return s.push(r.substring(n+1)),s}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 s(e,s){[e,s].forEach(n);for(var i=t(e),o=t(s),c=0;cu)return 1;if(u>a)return-1}var f=i[i.length-1],h=o[o.length-1];if(f&&h){var l=f.split(".").map(r),p=h.split(".").map(r);for(c=0;cp[c])return 1;if(p[c]>l[c])return-1}}else if(f||h)return f?-1:1;return 0}var i=[">",">=","=","<","<="],o={">":[1],">=":[0,1],"=":[0],"<=":[-1,0],"<":[-1]};return s.validate=function(t){return"string"==typeof t&&e.test(t)},s.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===i.indexOf(e))throw new TypeError("Invalid operator, expected one of "+i.join("|"))}(r);var n=s(e,t);return o[r].indexOf(n)>-1},s}()}(r={exports:{}}),r.exports),s=function(e){return null==e},i=function(e){return Object.getPrototypeOf(e)===Object.prototype},o=function(e){return Array.isArray(e)},c=function(e,t){return Object.entries(e).forEach(function(r){var n=r[0],a=r[1];s(a)||!i(a)&&!o(a)||(e[n]=c(a,t))}),new Proxy(e,{get:function(e,r,n){return t.get(e,r,n)},set:function(e,r,n,a){s(n)||!i(n)&&!o(n)||(n=c(n,t));var u=e[r];return e[r]=n,s(u)||s(u.__watchers)||(e[r].__watchers=u.__watchers),t.set(e,r,e[r],a),!0}})},a={stores:{},persistenceDriver:window.localStorage,persisted:[],subscribers:[],watchers:{},disableReactivity:!1,startingCallbacks:[],startedCallbacks:[],hasStarted:!1,start:function(){var e=this;this.startingCallbacks.forEach(function(e){return e()}),this.attach(),this.stores=c(this.stores,{get:function(t,r,n){return Object.is(n,e.stores)&&["get","set","toggle","clear"].includes(r)?e[r].bind(e):Reflect.get(t,r,n)},set:function(t,r,n,s){if(!e.disableReactivity){e.updateSubscribers(),e.runWatchers(t,r,n,s),e.disableReactivity=!0;try{e.persisted.forEach(e.updateLocalStorage.bind(e))}catch(e){}e.disableReactivity=!1}}}),this.hasStarted=!0,this.disableReactivity=!0,Object.entries(this.watchers).forEach(function(t){var r=t[0];t[1].forEach(function(t){return e.watch(r,t)})}),this.disableReactivity=!1,this.startedCallbacks.forEach(function(e){return e()})},starting:function(e){this.startingCallbacks.push(e)},started:function(e){this.startedCallbacks.push(e)},attach:function(){if(!(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")||window.Alpine&&n.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),"function"==typeof t&&(t=t()),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]&&(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=this.persistenceDriver.getItem("__spruce:"+e);if(!r)return null;var n=JSON.parse(r);return"object"==typeof n&&(delete(n=Object.assign(t,n)).__watchers,delete n.__key_name),n},updateLocalStorage:function(r){var n=function(r){for(var n=1;n0&&console.warn("[Spruce] You have already initialised a persisted store. Changing the driver may cause issues."),"function"!=typeof e.getItem)throw new Error("[Spruce] The persistence driver must have a `getItem(key)` method.");if("function"!=typeof e.setItem)throw new Error("[Spruce] The persistence driver must have a `setItem(key, value)` method.");if("function"!=typeof e.removeItem)throw new Error("[Spruce] The persistence driver must have a `removeItem(name)` method.");this.persistenceDriver=e}};window.Spruce=a;var u=window.deferLoadingAlpine||function(e){e()};window.deferLoadingAlpine=function(e){window.Spruce.start(),u(e)};export default a; +function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var r,n=(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 s=t(e),o=t(i),a=0;au)return 1;if(u>c)return-1}var f=s[s.length-1],h=o[o.length-1];if(f&&h){var l=f.split(".").map(r),p=h.split(".").map(r);for(a=0;ap[a])return 1;if(p[a]>l[a])return-1}}else if(f||h)return f?-1:1;return 0}var s=[">",">=","=","<","<="],o={">":[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===s.indexOf(e))throw new TypeError("Invalid operator, expected one of "+s.join("|"))}(r);var n=i(e,t);return o[r].indexOf(n)>-1},i}()}(r={exports:{}}),r.exports),i=function(e){return null==e},s=function(e){return Object.getPrototypeOf(e)===Object.prototype},o=function(e){return Array.isArray(e)},a=function(e,t){return Object.entries(e).forEach(function(r){var n=r[0],c=r[1];i(c)||!s(c)&&!o(c)||(e[n]=a(c,t))}),new Proxy(e,{get:function(e,r,n){return t.get(e,r,n)},set:function(e,r,n,c){i(n)||!s(n)&&!o(n)||(n=a(n,t));var u=e[r];return e[r]=n,i(u)||i(u.__watchers)||(e[r].__watchers=u.__watchers),t.set(e,r,e[r],c),!0}})},c={stores:{},persistenceDriver:window.localStorage,persisted:[],subscribers:[],pendingWatchers:{},disableReactivity:!1,startingCallbacks:[],startedCallbacks:[],hasStarted:!1,start:function(){var e=this;this.startingCallbacks.forEach(function(e){return e()}),this.attach(),this.stores=a(this.stores,{get:function(t,r,n){return Object.is(n,e.stores)&&["get","set","toggle","call","clear"].includes(r)?e[r].bind(e):Reflect.get(t,r,n)},set:function(t,r,n,i){if(!e.disableReactivity){e.updateSubscribers(),e.runWatchers(t,r,n,i),e.disableReactivity=!0;try{e.persisted.forEach(e.updateLocalStorage.bind(e))}catch(e){}e.disableReactivity=!1}}}),this.hasStarted=!0,this.disableReactivity=!0,Object.entries(this.pendingWatchers).forEach(function(t){var r=t[0];t[1].forEach(function(t){return e.watch(r,t)})}),this.disableReactivity=!1,this.startedCallbacks.forEach(function(e){return e()})},starting:function(e){this.startingCallbacks.push(e)},started:function(e){this.startedCallbacks.push(e)},attach:function(){if(!(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")||window.Alpine&&n.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),"function"==typeof t&&(t=t()),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){void 0!==this.stores[e]&&(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=this.persistenceDriver.getItem("__spruce:"+e);if(!r)return null;var n=JSON.parse(r);return"object"==typeof n&&(delete(n=Object.assign(t,n)).__watchers,delete n.__key_name),n},updateLocalStorage:function(r){var n=function(r){for(var n=1;n0;)t[r]=arguments[r+1];return this.get(e).apply(void 0,t)},clear:function(e){return this.persistenceDriver.removeItem("__spruce:"+e)},watch:function(e,t){var r=this;if(!this.hasStarted)return this.pendingWatchers[e]||(this.pendingWatchers[e]=[]),this.pendingWatchers[e].push(t),[function(){return r.unwatch(e,t)}];var n=e.split("."),a=n.reduce(function(e,t){var r=e[t];return i(r)||!s(r)&&!o(r)?e:r},this.stores),c=Object.is(a,this.get(e))?"__self":n[n.length-1];return a.__watchers||(a.__watchers=new Map),a.__watchers.has(c)||a.__watchers.set(c,new Set),a.__watchers.get(c).add(t),[function(){return r.unwatch(e,t)}]},unwatch:function(e,t){var r=e.split("."),n=r.reduce(function(e,t){var r=e[t];return i(r)||!s(r)&&!o(r)?e:r},this.stores),a=Object.is(n,this.get(e))?"__self":r[r.length-1],c=n.__watchers;c.has(a)&&c.get(a).delete(t)},watchers:function(e){var t=e.split("."),r=t.reduce(function(e,t){var r=e[t];return i(r)||!s(r)&&!o(r)?e:r},this.stores),n=Object.is(r,this.get(e))?"__self":t[t.length-1];return r.__watchers?r.__watchers.get(n):{}},runWatchers:function(e,t,r){e.__watchers&&(e.__watchers.has(t)&&e.__watchers.get(t).forEach(function(e){return e(r)}),e.__watchers.has("__self")&&e.__watchers.get("__self").forEach(function(e){return e(r,t)}))},persistUsing:function(e){if(this.persisted.length>0&&console.warn("[Spruce] You have already initialised a persisted store. Changing the driver may cause issues."),"function"!=typeof e.getItem)throw new Error("[Spruce] The persistence driver must have a `getItem(key)` method.");if("function"!=typeof e.setItem)throw new Error("[Spruce] The persistence driver must have a `setItem(key, value)` method.");if("function"!=typeof e.removeItem)throw new Error("[Spruce] The persistence driver must have a `removeItem(name)` method.");this.persistenceDriver=e}};window.Spruce=c;var u=window.deferLoadingAlpine||function(e){e()};window.deferLoadingAlpine=function(e){window.Spruce.start(),u(e)};export default c; //# sourceMappingURL=spruce.module.js.map diff --git a/dist/spruce.module.js.map b/dist/spruce.module.js.map index f51f736..73a30c7 100644 --- a/dist/spruce.module.js.map +++ b/dist/spruce.module.js.map @@ -1 +1 @@ -{"version":3,"file":"spruce.module.js","sources":["../node_modules/compare-versions/index.js","../src/utils.js","../src/observable.js","../src/index.js"],"sourcesContent":["/* global define */\n(function (root, factory) {\n /* istanbul ignore next */\n if (typeof define === 'function' && define.amd) {\n define([], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.compareVersions = factory();\n }\n}(this, function () {\n\n var semver = /^v?(?:\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+))?(?:-[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\n\n function indexOrEnd(str, q) {\n return str.indexOf(q) === -1 ? str.length : str.indexOf(q);\n }\n\n function split(v) {\n var c = v.replace(/^v/, '').replace(/\\+.*$/, '');\n var patchIndex = indexOrEnd(c, '-');\n var arr = c.substring(0, patchIndex).split('.');\n arr.push(c.substring(patchIndex + 1));\n return arr;\n }\n\n function tryParse(v) {\n return isNaN(Number(v)) ? v : Number(v);\n }\n\n function validate(version) {\n if (typeof version !== 'string') {\n throw new TypeError('Invalid argument expected string');\n }\n if (!semver.test(version)) {\n throw new Error('Invalid argument not valid semver (\\''+version+'\\' received)');\n }\n }\n\n function compareVersions(v1, v2) {\n [v1, v2].forEach(validate);\n\n var s1 = split(v1);\n var s2 = split(v2);\n\n for (var i = 0; i < Math.max(s1.length - 1, s2.length - 1); i++) {\n var n1 = parseInt(s1[i] || 0, 10);\n var n2 = parseInt(s2[i] || 0, 10);\n\n if (n1 > n2) return 1;\n if (n2 > n1) return -1;\n }\n\n var sp1 = s1[s1.length - 1];\n var sp2 = s2[s2.length - 1];\n\n if (sp1 && sp2) {\n var p1 = sp1.split('.').map(tryParse);\n var p2 = sp2.split('.').map(tryParse);\n\n for (i = 0; i < Math.max(p1.length, p2.length); i++) {\n if (p1[i] === undefined || typeof p2[i] === 'string' && typeof p1[i] === 'number') return -1;\n if (p2[i] === undefined || typeof p1[i] === 'string' && typeof p2[i] === 'number') return 1;\n\n if (p1[i] > p2[i]) return 1;\n if (p2[i] > p1[i]) return -1;\n }\n } else if (sp1 || sp2) {\n return sp1 ? -1 : 1;\n }\n\n return 0;\n };\n\n var allowedOperators = [\n '>',\n '>=',\n '=',\n '<',\n '<='\n ];\n\n var operatorResMap = {\n '>': [1],\n '>=': [0, 1],\n '=': [0],\n '<=': [-1, 0],\n '<': [-1]\n };\n\n function validateOperator(op) {\n if (typeof op !== 'string') {\n throw new TypeError('Invalid operator type, expected string but got ' + typeof op);\n }\n if (allowedOperators.indexOf(op) === -1) {\n throw new TypeError('Invalid operator, expected one of ' + allowedOperators.join('|'));\n }\n }\n\n compareVersions.validate = function(version) {\n return typeof version === 'string' && semver.test(version);\n }\n\n compareVersions.compare = function (v1, v2, operator) {\n // Validate operator\n validateOperator(operator);\n\n // since result of compareVersions can only be -1 or 0 or 1\n // a simple map can be used to replace switch\n var res = compareVersions(v1, v2);\n return operatorResMap[operator].indexOf(res) > -1;\n }\n\n return compareVersions;\n}));\n","import compareVersions from 'compare-versions'\n\nexport const isNullOrUndefined = value => {\n return value === null || value === undefined\n}\n\nexport const isObject = _ => {\n return Object.getPrototypeOf(_) === Object.prototype\n}\n\nexport const isArray = _ => Array.isArray(_)\n\nexport const getMethods = obj => {\n let methods = {}\n\n Object.entries(obj).filter(([_, value]) => typeof value === 'function').forEach(([key, value]) => methods[key] = value)\n\n return methods\n}\n\nexport const isTesting = () => {\n return navigator.userAgent, navigator.userAgent.includes(\"Node.js\")\n || navigator.userAgent.includes(\"jsdom\")\n}\n\nexport const checkForAlpine = () => {\n if (isTesting()) {\n return true\n }\n\n if (! window.Alpine) {\n return false\n }\n\n return compareVersions.compare(window.Alpine.version, '2.7.0', '>=')\n}","import { isNullOrUndefined, isObject, isArray } from './utils'\n\nexport const createObservable = (target, callbacks) => {\n Object.entries(target).forEach(([key, value]) => {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) { \n target[key] = createObservable(value, callbacks)\n }\n })\n\n return new Proxy(target, {\n get(target, key, receiver) {\n return callbacks.get(target, key, receiver)\n },\n set(target, key, value, receiver) {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) {\n value = createObservable(value, callbacks)\n }\n\n let originalValue = target[key]\n\n target[key] = value\n\n // Copy watchers from the original value if they exist\n if (!isNullOrUndefined(originalValue) && !isNullOrUndefined(originalValue.__watchers)) {\n target[key].__watchers = originalValue.__watchers\n }\n\n callbacks.set(target, key, target[key], receiver)\n\n return true\n }\n })\n}","import { getMethods, checkForAlpine, isObject, isArray, isNullOrUndefined } from './utils'\nimport { createObservable } from './observable'\n\nconst Spruce = {\n stores: {},\n\n persistenceDriver: window.localStorage,\n\n persisted: [],\n\n subscribers: [],\n\n watchers: {},\n\n disableReactivity: false,\n\n startingCallbacks: [],\n\n startedCallbacks: [],\n\n hasStarted: false,\n\n start() {\n this.startingCallbacks.forEach(fn => fn())\n\n this.attach()\n\n this.stores = createObservable(this.stores, {\n get: (target, key, receiver) => {\n if (Object.is(receiver, this.stores) && ['get', 'set', 'toggle', 'clear'].includes(key)) {\n return this[key].bind(this)\n }\n\n return Reflect.get(target, key, receiver)\n },\n set: (target, key, value, receiver) => {\n if (this.disableReactivity) {\n return\n }\n\n this.updateSubscribers()\n\n this.runWatchers(target, key, value, receiver)\n\n this.disableReactivity = true\n\n try {\n this.persisted.forEach(this.updateLocalStorage.bind(this))\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n\n this.disableReactivity = false\n }\n })\n\n this.hasStarted = true\n\n this.disableReactivity = true\n\n Object.entries(this.watchers).forEach(([name, callbacks]) => {\n callbacks.forEach(callback => this.watch(name, callback))\n })\n\n this.disableReactivity = false\n\n this.startedCallbacks.forEach(fn => fn())\n },\n\n starting(callback) {\n this.startingCallbacks.push(callback)\n },\n\n started(callback) {\n this.startedCallbacks.push(callback)\n },\n\n attach() {\n if (! checkForAlpine()) {\n throw new Error('[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.')\n }\n\n const self = this\n\n window.Alpine.addMagicProperty('store', el => {\n self.subscribe(el)\n\n return self.stores\n })\n },\n\n store(name, state, persist = false) {\n if (typeof state === 'function') {\n state = state()\n }\n \n if (persist) {\n try {\n this.stores[name] = this.retrieveFromLocalStorage(name, getMethods(state))\n\n if (!this.persisted.includes(name)) {\n this.persisted.push(name)\n }\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n }\n\n if (!this.stores[name]) {\n this.stores[name] = state\n }\n\n return this.stores[name]\n },\n\n reset(name, state) {\n if (! this.stores[name]) {\n return;\n }\n \n this.stores[name] = state\n },\n\n subscribe(el) {\n if (!this.subscribers.includes(el)) {\n this.subscribers.push(el)\n }\n\n return this.stores\n },\n\n updateSubscribers() {\n this.subscribers.filter(el => !!el.__x).forEach(el => {\n el.__x.updateElements(el)\n })\n },\n\n retrieveFromLocalStorage(name, methods = {}) {\n const value = this.persistenceDriver.getItem(`__spruce:${name}`)\n\n if (! value) {\n return null\n }\n\n let storage = JSON.parse(value)\n\n if (typeof storage === 'object') {\n storage = Object.assign(methods, storage)\n\n delete storage.__watchers\n delete storage.__key_name\n }\n\n return storage\n },\n\n updateLocalStorage(name) {\n const store = { ...this.store(name) }\n\n delete store.__watchers\n delete store.__key_name\n\n this.persistenceDriver.setItem(`__spruce:${name}`, JSON.stringify(this.store(name)))\n },\n\n get(name, target = this.stores) {\n return name.split('.').reduce((target, part) => target[part], target)\n },\n\n set(name, value, target = this.stores) {\n if (! isArray(name)) {\n name = name.split('.')\n }\n\n if (name.length === 1) return target[name[0]] = value\n\n if (target[name[0]]) {\n return this.set(name.slice(1), value, target[name[0]])\n } else {\n target[name[0]] = {}\n\n return this.set(name.slice(1), value, target[name[0]])\n }\n },\n\n toggle(name) {\n return this.set(name, ! this.get(name))\n },\n\n clear(name) {\n return this.persistenceDriver.removeItem(`__spruce:${name}`)\n },\n\n watch(name, callback) {\n if (! this.hasStarted) {\n this.watchers[name] || (this.watchers[name] = [])\n\n this.watchers[name].push(callback)\n\n return [() => this.unwatch(name, callback)]\n }\n\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n /**\n * If the target object / array is the property\n * that needs to be watched, a magic `__self` key is\n * used so that runner can pick up on it later.\n */\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n target.__watchers = new Map\n }\n \n if (! target.__watchers.has(part)) {\n target.__watchers.set(part, new Set)\n }\n\n target.__watchers.get(part).add(callback)\n\n return [() => this.unwatch(name, callback)]\n },\n\n unwatch(name, callback) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n const watchers = target.__watchers\n\n if (! watchers.has(part)) {\n return\n }\n\n watchers.get(part).delete(callback)\n },\n\n watchers(name) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n return {}\n }\n\n return target.__watchers.get(part)\n },\n\n runWatchers(target, key, value) {\n if (! target.__watchers) {\n return\n }\n\n if (target.__watchers.has(key)) {\n target.__watchers.get(key).forEach(f => f(value))\n }\n\n /**\n * The `__self` key is used for watchers that are registered\n * to the object or array being updated.\n */\n if (target.__watchers.has('__self')) {\n target.__watchers.get('__self').forEach(f => f(value, key))\n }\n },\n\n persistUsing(driver) {\n if (this.persisted.length > 0) {\n console.warn('[Spruce] You have already initialised a persisted store. Changing the driver may cause issues.')\n }\n\n if (typeof driver.getItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `getItem(key)` method.')\n }\n\n if (typeof driver.setItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `setItem(key, value)` method.')\n }\n\n if (typeof driver.removeItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `removeItem(name)` method.')\n }\n\n this.persistenceDriver = driver\n }\n}\n\nwindow.Spruce = Spruce\n\nconst deferrer = window.deferLoadingAlpine || function (callback) { callback() }\n\nwindow.deferLoadingAlpine = function (callback) {\n window.Spruce.start()\n\n deferrer(callback)\n}\n\nexport default Spruce\n"],"names":["module","semver","split","v","str","c","replace","patchIndex","indexOf","length","arr","substring","push","tryParse","isNaN","Number","validate","version","TypeError","test","Error","compareVersions","v1","v2","forEach","s1","s2","i","Math","max","n1","parseInt","n2","sp1","sp2","p1","map","p2","undefined","allowedOperators","operatorResMap",">",">=","=","<=","<","compare","operator","op","join","validateOperator","res","factory","isNullOrUndefined","value","isObject","_","Object","getPrototypeOf","prototype","isArray","Array","createObservable","target","callbacks","entries","key","Proxy","get","receiver","set","originalValue","__watchers","Spruce","stores","persistenceDriver","window","localStorage","persisted","subscribers","watchers","disableReactivity","startingCallbacks","startedCallbacks","hasStarted","start","fn","attach","this","is","includes","bind","Reflect","updateSubscribers","runWatchers","updateLocalStorage","e","callback","watch","name","starting","started","navigator","userAgent","Alpine","self","addMagicProperty","el","subscribe","store","state","persist","retrieveFromLocalStorage","methods","filter","reset","__x","updateElements","getItem","storage","JSON","parse","assign","__key_name","setItem","stringify","reduce","part","slice","toggle","clear","removeItem","unwatch","nameParts","sub","Map","has","Set","add","delete","f","persistUsing","driver","console","warn","const","deferrer","deferLoadingAlpine"],"mappings":"wfAMIA,UAII,WAEN,IAAIC,EAAS,qIAMb,SAASC,EAAMC,GACb,IALkBC,EAKdC,EAAIF,EAAEG,QAAQ,KAAM,IAAIA,QAAQ,QAAS,IACzCC,GALuB,KADTH,EAMUC,GALjBG,QAKoB,KALAJ,EAAIK,OAASL,EAAII,QAKjB,KAC3BE,EAAML,EAAEM,UAAU,EAAGJ,GAAYL,MAAM,KAE3C,OADAQ,EAAIE,KAAKP,EAAEM,UAAUJ,EAAa,IAC3BG,EAGT,SAASG,EAASV,GAChB,OAAOW,MAAMC,OAAOZ,IAAMA,EAAIY,OAAOZ,GAGvC,SAASa,EAASC,GAChB,GAAuB,iBAAZA,EACT,MAAM,IAAIC,UAAU,oCAEtB,IAAKjB,EAAOkB,KAAKF,GACf,MAAM,IAAIG,MAAM,uCAAwCH,EAAQ,eAIpE,SAASI,EAAgBC,EAAIC,GAC3B,CAACD,EAAIC,GAAIC,QAAQR,GAKjB,IAHA,IAAIS,EAAKvB,EAAMoB,GACXI,EAAKxB,EAAMqB,GAENI,EAAI,EAAGA,EAAIC,KAAKC,IAAIJ,EAAGhB,OAAS,EAAGiB,EAAGjB,OAAS,GAAIkB,IAAK,CAC/D,IAAIG,EAAKC,SAASN,EAAGE,IAAM,EAAG,IAC1BK,EAAKD,SAASL,EAAGC,IAAM,EAAG,IAE9B,GAAIG,EAAKE,EAAI,OAAO,EACpB,GAAIA,EAAKF,EAAI,OAAQ,EAGvB,IAAIG,EAAMR,EAAGA,EAAGhB,OAAS,GACrByB,EAAMR,EAAGA,EAAGjB,OAAS,GAEzB,GAAIwB,GAAOC,EAAK,CACd,IAAIC,EAAKF,EAAI/B,MAAM,KAAKkC,IAAIvB,GACxBwB,EAAKH,EAAIhC,MAAM,KAAKkC,IAAIvB,GAE5B,IAAKc,EAAI,EAAGA,EAAIC,KAAKC,IAAIM,EAAG1B,OAAQ4B,EAAG5B,QAASkB,IAAK,CACnD,QAAcW,IAAVH,EAAGR,IAAqC,iBAAVU,EAAGV,IAAoC,iBAAVQ,EAAGR,GAAiB,OAAQ,EAC3F,QAAcW,IAAVD,EAAGV,IAAqC,iBAAVQ,EAAGR,IAAoC,iBAAVU,EAAGV,GAAiB,OAAO,EAE1F,GAAIQ,EAAGR,GAAKU,EAAGV,GAAI,OAAO,EAC1B,GAAIU,EAAGV,GAAKQ,EAAGR,GAAI,OAAQ,QAExB,GAAIM,GAAOC,EAChB,OAAOD,GAAO,EAAI,EAGpB,OAAO,EAGT,IAAIM,EAAmB,CACrB,IACA,KACA,IACA,IACA,MAGEC,EAAiB,CACnBC,IAAK,CAAC,GACNC,KAAM,CAAC,EAAG,GACVC,IAAK,CAAC,GACNC,KAAM,EAAE,EAAG,GACXC,IAAK,EAAE,IA0BT,OAdAxB,EAAgBL,SAAW,SAASC,GAClC,MAA0B,iBAAZA,GAAwBhB,EAAOkB,KAAKF,IAGpDI,EAAgByB,QAAU,SAAUxB,EAAIC,EAAIwB,IAb5C,SAA0BC,GACxB,GAAkB,iBAAPA,EACT,MAAM,IAAI9B,UAAU,yDAA2D8B,GAEjF,IAAsC,IAAlCT,EAAiB/B,QAAQwC,GAC3B,MAAM,IAAI9B,UAAU,qCAAuCqB,EAAiBU,KAAK,MAUnFC,CAAiBH,GAIjB,IAAII,EAAM9B,EAAgBC,EAAIC,GAC9B,OAAOiB,EAAeO,GAAUvC,QAAQ2C,IAAQ,GAG3C9B,EA3GY+B,+BCJRC,WAAoBC,UACtBA,MAAAA,GAGEC,WAAWC,UACbC,OAAOC,eAAeF,KAAOC,OAAOE,WAGlCC,WAAUJ,UAAKK,MAAMD,QAAQJ,ICR7BM,WAAoBC,EAAQC,UACrCP,OAAOQ,QAAQF,GAAQvC,sCACb6B,EAAkBC,KAAWC,EAASD,KAAUM,EAAQN,KAC1DS,EAAOG,GAAOJ,EAAiBR,EAAOU,MAIvC,IAAIG,MAAMJ,EAAQ,CACrBK,aAAIL,EAAQG,EAAKG,UACNL,EAAUI,IAAIL,EAAQG,EAAKG,IAEtCC,aAAIP,EAAQG,EAAKZ,EAAOe,GACdhB,EAAkBC,KAAWC,EAASD,KAAUM,EAAQN,KAC1DA,EAAQQ,EAAiBR,EAAOU,QAGhCO,EAAgBR,EAAOG,UAE3BH,EAAOG,GAAOZ,EAGTD,EAAkBkB,IAAmBlB,EAAkBkB,EAAcC,cACtET,EAAOG,GAAKM,WAAaD,EAAcC,YAG3CR,EAAUM,IAAIP,EAAQG,EAAKH,EAAOG,GAAMG,IAEjC,MC1BbI,EAAS,CACXC,OAAQ,GAERC,kBAAmBC,OAAOC,aAE1BC,UAAW,GAEXC,YAAa,GAEbC,SAAU,GAEVC,mBAAmB,EAEnBC,kBAAmB,GAEnBC,iBAAkB,GAElBC,YAAY,EAEZC,iCACSH,kBAAkB1D,iBAAQ8D,UAAMA,WAEhCC,cAEAb,OAASZ,EAAiB0B,KAAKd,OAAQ,CACxCN,aAAML,EAAQG,EAAKG,UACXZ,OAAOgC,GAAGpB,EAAUmB,EAAKd,SAAW,CAAC,MAAO,MAAO,SAAU,SAASgB,SAASxB,GACxEsB,EAAKtB,GAAKyB,KAAKH,GAGnBI,QAAQxB,IAAIL,EAAQG,EAAKG,IAEpCC,aAAMP,EAAQG,EAAKZ,EAAOe,OAClBmB,EAAKP,qBAIJY,sBAEAC,YAAY/B,EAAQG,EAAKZ,EAAOe,KAEhCY,mBAAoB,QAGhBH,UAAUtD,QAAQgE,EAAKO,mBAAmBJ,KAAKH,IACtD,MAAOQ,MAIJf,mBAAoB,WAI5BG,YAAa,OAEbH,mBAAoB,EAEzBxB,OAAOQ,QAAQuB,KAAKR,UAAUxD,oCAChBA,iBAAQyE,UAAYT,EAAKU,MAAMC,EAAMF,YAG9ChB,mBAAoB,OAEpBE,iBAAiB3D,iBAAQ8D,UAAMA,OAGxCc,kBAASH,QACAf,kBAAkBtE,KAAKqF,IAGhCI,iBAAQJ,QACCd,iBAAiBvE,KAAKqF,IAG/BV,uBFxDOe,UAA+BC,UAAUb,SAAS,YAClDY,UAAUC,UAAUb,SAAS,UAQ9Bd,OAAO4B,QAINnF,EAAgByB,QAAQ8B,OAAO4B,OAAOvF,QAAS,QAAS,aE6CjD,IAAIG,MAAM,iEAGdqF,EAAOjB,KAEbZ,OAAO4B,OAAOE,iBAAiB,iBAASC,UACpCF,EAAKG,UAAUD,GAERF,EAAK/B,UAIpBmC,eAAMV,EAAMW,EAAOC,sBAAU,GACJ,mBAAVD,IACPA,EAAQA,KAGRC,WAESrC,OAAOyB,GAAQX,KAAKwB,yBAAyBb,GFrF1Dc,EAAU,GAEdxD,OAAOQ,QEmFwE6C,GFnF3DI,yBAAwC,0BAAY1F,2BAA0ByF,eAE3FA,IEmFUzB,KAAKV,UAAUY,SAASS,SACpBrB,UAAUlE,KAAKuF,GAE1B,MAAOH,QF1FbiB,SE+FKzB,KAAKd,OAAOyB,UACRzB,OAAOyB,GAAQW,GAGjBtB,KAAKd,OAAOyB,IAGvBgB,eAAMhB,EAAMW,GACFtB,KAAKd,OAAOyB,UAIbzB,OAAOyB,GAAQW,IAGxBF,mBAAUD,UACDnB,KAAKT,YAAYW,SAASiB,SACtB5B,YAAYnE,KAAK+F,GAGnBnB,KAAKd,QAGhBmB,kCACSd,YAAYmC,gBAAOP,WAAQA,EAAGS,MAAK5F,iBAAQmF,GAC5CA,EAAGS,IAAIC,eAAeV,MAI9BK,kCAAyBb,EAAMc,kBAAU,QAC/B3D,EAAQkC,KAAKb,kBAAkB2C,oBAAoBnB,OAEnD7C,SACK,SAGPiE,EAAUC,KAAKC,MAAMnE,SAEF,iBAAZiE,WACPA,EAAU9D,OAAOiE,OAAOT,EAASM,IAElB/C,kBACR+C,EAAQI,YAGZJ,GAGXxB,4BAAmBI,OACTU,iWAAarB,KAAKqB,MAAMV,WAEvBU,EAAMrC,kBACNqC,EAAMc,gBAERhD,kBAAkBiD,oBAAoBzB,EAAQqB,KAAKK,UAAUrC,KAAKqB,MAAMV,MAGjF/B,aAAI+B,EAAMpC,yBAASyB,KAAKd,QACbyB,EAAKjG,MAAM,KAAK4H,gBAAQ/D,EAAQgE,UAAShE,EAAOgE,IAAOhE,IAGlEO,aAAI6B,EAAM7C,EAAOS,yBAASyB,KAAKd,QACrBd,EAAQuC,KACVA,EAAOA,EAAKjG,MAAM,MAGF,IAAhBiG,EAAK1F,OAAqBsD,EAAOoC,EAAK,IAAM7C,EAE5CS,EAAOoC,EAAK,IACLX,KAAKlB,IAAI6B,EAAK6B,MAAM,GAAI1E,EAAOS,EAAOoC,EAAK,MAElDpC,EAAOoC,EAAK,IAAM,GAEXX,KAAKlB,IAAI6B,EAAK6B,MAAM,GAAI1E,EAAOS,EAAOoC,EAAK,OAI1D8B,gBAAO9B,UACIX,KAAKlB,IAAI6B,GAAQX,KAAKpB,IAAI+B,KAGrC+B,eAAM/B,UACKX,KAAKb,kBAAkBwD,uBAAuBhC,IAGzDD,eAAMC,EAAMF,kBACFT,KAAKJ,uBACFJ,SAASmB,KAAUX,KAAKR,SAASmB,GAAQ,SAEzCnB,SAASmB,GAAMvF,KAAKqF,GAElB,mBAAOT,EAAK4C,QAAQjC,EAAMF,SAG/BoC,EAAYlC,EAAKjG,MAAM,KAEvB6D,EAASsE,EAAUP,gBAAQ/D,EAAQgE,OAC/BO,EAAMvE,EAAOgE,UAEb1E,EAAkBiF,KAAS/E,EAAS+E,KAAQ1E,EAAQ0E,GAInDvE,EAHIuE,GAIZ9C,KAAKd,QAOFqD,EAAOtE,OAAOgC,GAAG1B,EAAQyB,KAAKpB,IAAI+B,IAAS,SAAWkC,EAAUA,EAAU5H,OAAS,UAEnFsD,EAAOS,aACTT,EAAOS,WAAa,IAAI+D,KAGtBxE,EAAOS,WAAWgE,IAAIT,IACxBhE,EAAOS,WAAWF,IAAIyD,EAAM,IAAIU,KAGpC1E,EAAOS,WAAWJ,IAAI2D,GAAMW,IAAIzC,GAEzB,mBAAOT,EAAK4C,QAAQjC,EAAMF,MAGrCmC,iBAAQjC,EAAMF,OACJoC,EAAYlC,EAAKjG,MAAM,KAEvB6D,EAASsE,EAAUP,gBAAQ/D,EAAQgE,OAC/BO,EAAMvE,EAAOgE,UAEb1E,EAAkBiF,KAAS/E,EAAS+E,KAAQ1E,EAAQ0E,GAInDvE,EAHIuE,GAIZ9C,KAAKd,QAEFqD,EAAOtE,OAAOgC,GAAG1B,EAAQyB,KAAKpB,IAAI+B,IAAS,SAAWkC,EAAUA,EAAU5H,OAAS,GACnFuE,EAAWjB,EAAOS,WAElBQ,EAASwD,IAAIT,IAInB/C,EAASZ,IAAI2D,GAAMY,OAAO1C,IAG9BjB,kBAASmB,OACCkC,EAAYlC,EAAKjG,MAAM,KAEvB6D,EAASsE,EAAUP,gBAAQ/D,EAAQgE,OAC/BO,EAAMvE,EAAOgE,UAEb1E,EAAkBiF,KAAS/E,EAAS+E,KAAQ1E,EAAQ0E,GAInDvE,EAHIuE,GAIZ9C,KAAKd,QAEFqD,EAAOtE,OAAOgC,GAAG1B,EAAQyB,KAAKpB,IAAI+B,IAAS,SAAWkC,EAAUA,EAAU5H,OAAS,UAEnFsD,EAAOS,WAINT,EAAOS,WAAWJ,IAAI2D,GAHlB,IAMfjC,qBAAY/B,EAAQG,EAAKZ,GACfS,EAAOS,aAITT,EAAOS,WAAWgE,IAAItE,IACtBH,EAAOS,WAAWJ,IAAIF,GAAK1C,iBAAQoH,UAAKA,EAAEtF,KAO1CS,EAAOS,WAAWgE,IAAI,WACtBzE,EAAOS,WAAWJ,IAAI,UAAU5C,iBAAQoH,UAAKA,EAAEtF,EAAOY,OAI9D2E,sBAAaC,MACLtD,KAAKV,UAAUrE,OAAS,GACxBsI,QAAQC,KAAK,kGAGa,mBAAnBF,EAAOxB,cACR,IAAIlG,MAAM,yEAGU,mBAAnB0H,EAAOlB,cACR,IAAIxG,MAAM,gFAGa,mBAAtB0H,EAAOX,iBACR,IAAI/G,MAAM,+EAGfuD,kBAAoBmE,IAIjClE,OAAOH,OAASA,EAEhBwE,IAAMC,EAAWtE,OAAOuE,oBAAsB,SAAUlD,GAAYA,KAEpErB,OAAOuE,mBAAqB,SAAUlD,GAClCrB,OAAOH,OAAOY,QAEd6D,EAASjD"} \ No newline at end of file +{"version":3,"file":"spruce.module.js","sources":["../node_modules/compare-versions/index.js","../src/utils.js","../src/observable.js","../src/index.js"],"sourcesContent":["/* global define */\n(function (root, factory) {\n /* istanbul ignore next */\n if (typeof define === 'function' && define.amd) {\n define([], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.compareVersions = factory();\n }\n}(this, function () {\n\n var semver = /^v?(?:\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+))?(?:-[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\n\n function indexOrEnd(str, q) {\n return str.indexOf(q) === -1 ? str.length : str.indexOf(q);\n }\n\n function split(v) {\n var c = v.replace(/^v/, '').replace(/\\+.*$/, '');\n var patchIndex = indexOrEnd(c, '-');\n var arr = c.substring(0, patchIndex).split('.');\n arr.push(c.substring(patchIndex + 1));\n return arr;\n }\n\n function tryParse(v) {\n return isNaN(Number(v)) ? v : Number(v);\n }\n\n function validate(version) {\n if (typeof version !== 'string') {\n throw new TypeError('Invalid argument expected string');\n }\n if (!semver.test(version)) {\n throw new Error('Invalid argument not valid semver (\\''+version+'\\' received)');\n }\n }\n\n function compareVersions(v1, v2) {\n [v1, v2].forEach(validate);\n\n var s1 = split(v1);\n var s2 = split(v2);\n\n for (var i = 0; i < Math.max(s1.length - 1, s2.length - 1); i++) {\n var n1 = parseInt(s1[i] || 0, 10);\n var n2 = parseInt(s2[i] || 0, 10);\n\n if (n1 > n2) return 1;\n if (n2 > n1) return -1;\n }\n\n var sp1 = s1[s1.length - 1];\n var sp2 = s2[s2.length - 1];\n\n if (sp1 && sp2) {\n var p1 = sp1.split('.').map(tryParse);\n var p2 = sp2.split('.').map(tryParse);\n\n for (i = 0; i < Math.max(p1.length, p2.length); i++) {\n if (p1[i] === undefined || typeof p2[i] === 'string' && typeof p1[i] === 'number') return -1;\n if (p2[i] === undefined || typeof p1[i] === 'string' && typeof p2[i] === 'number') return 1;\n\n if (p1[i] > p2[i]) return 1;\n if (p2[i] > p1[i]) return -1;\n }\n } else if (sp1 || sp2) {\n return sp1 ? -1 : 1;\n }\n\n return 0;\n };\n\n var allowedOperators = [\n '>',\n '>=',\n '=',\n '<',\n '<='\n ];\n\n var operatorResMap = {\n '>': [1],\n '>=': [0, 1],\n '=': [0],\n '<=': [-1, 0],\n '<': [-1]\n };\n\n function validateOperator(op) {\n if (typeof op !== 'string') {\n throw new TypeError('Invalid operator type, expected string but got ' + typeof op);\n }\n if (allowedOperators.indexOf(op) === -1) {\n throw new TypeError('Invalid operator, expected one of ' + allowedOperators.join('|'));\n }\n }\n\n compareVersions.validate = function(version) {\n return typeof version === 'string' && semver.test(version);\n }\n\n compareVersions.compare = function (v1, v2, operator) {\n // Validate operator\n validateOperator(operator);\n\n // since result of compareVersions can only be -1 or 0 or 1\n // a simple map can be used to replace switch\n var res = compareVersions(v1, v2);\n return operatorResMap[operator].indexOf(res) > -1;\n }\n\n return compareVersions;\n}));\n","import compareVersions from 'compare-versions'\n\nexport const isNullOrUndefined = value => {\n return value === null || value === undefined\n}\n\nexport const isObject = _ => {\n return Object.getPrototypeOf(_) === Object.prototype\n}\n\nexport const isArray = _ => Array.isArray(_)\n\nexport const getMethods = obj => {\n let methods = {}\n\n Object.entries(obj).filter(([_, value]) => typeof value === 'function').forEach(([key, value]) => methods[key] = value)\n\n return methods\n}\n\nexport const isTesting = () => {\n return navigator.userAgent, navigator.userAgent.includes(\"Node.js\")\n || navigator.userAgent.includes(\"jsdom\")\n}\n\nexport const checkForAlpine = () => {\n if (isTesting()) {\n return true\n }\n\n if (! window.Alpine) {\n return false\n }\n\n return compareVersions.compare(window.Alpine.version, '2.7.0', '>=')\n}","import { isNullOrUndefined, isObject, isArray } from './utils'\n\nexport const createObservable = (target, callbacks) => {\n Object.entries(target).forEach(([key, value]) => {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) { \n target[key] = createObservable(value, callbacks)\n }\n })\n\n return new Proxy(target, {\n get(target, key, receiver) {\n return callbacks.get(target, key, receiver)\n },\n set(target, key, value, receiver) {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) {\n value = createObservable(value, callbacks)\n }\n\n let originalValue = target[key]\n\n target[key] = value\n\n // Copy watchers from the original value if they exist\n if (!isNullOrUndefined(originalValue) && !isNullOrUndefined(originalValue.__watchers)) {\n target[key].__watchers = originalValue.__watchers\n }\n\n callbacks.set(target, key, target[key], receiver)\n\n return true\n }\n })\n}","import { getMethods, checkForAlpine, isObject, isArray, isNullOrUndefined } from './utils'\nimport { createObservable } from './observable'\n\nconst Spruce = {\n stores: {},\n\n persistenceDriver: window.localStorage,\n\n persisted: [],\n\n subscribers: [],\n\n pendingWatchers: {},\n\n disableReactivity: false,\n\n startingCallbacks: [],\n\n startedCallbacks: [],\n\n hasStarted: false,\n\n start() {\n this.startingCallbacks.forEach(fn => fn())\n\n this.attach()\n\n this.stores = createObservable(this.stores, {\n get: (target, key, receiver) => {\n if (Object.is(receiver, this.stores) && ['get', 'set', 'toggle', 'call', 'clear'].includes(key)) {\n return this[key].bind(this)\n }\n\n return Reflect.get(target, key, receiver)\n },\n set: (target, key, value, receiver) => {\n if (this.disableReactivity) {\n return\n }\n\n this.updateSubscribers()\n\n this.runWatchers(target, key, value, receiver)\n\n this.disableReactivity = true\n\n try {\n this.persisted.forEach(this.updateLocalStorage.bind(this))\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n\n this.disableReactivity = false\n }\n })\n\n this.hasStarted = true\n\n this.disableReactivity = true\n\n Object.entries(this.pendingWatchers).forEach(([name, callbacks]) => {\n callbacks.forEach(callback => this.watch(name, callback))\n })\n\n this.disableReactivity = false\n\n this.startedCallbacks.forEach(fn => fn())\n },\n\n starting(callback) {\n this.startingCallbacks.push(callback)\n },\n\n started(callback) {\n this.startedCallbacks.push(callback)\n },\n\n attach() {\n if (! checkForAlpine()) {\n throw new Error('[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.')\n }\n\n const self = this\n\n window.Alpine.addMagicProperty('store', el => {\n self.subscribe(el)\n\n return self.stores\n })\n },\n\n store(name, state, persist = false) {\n if (typeof state === 'function') {\n state = state()\n }\n \n if (persist) {\n try {\n this.stores[name] = this.retrieveFromLocalStorage(name, getMethods(state))\n\n if (!this.persisted.includes(name)) {\n this.persisted.push(name)\n }\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n }\n\n if (!this.stores[name]) {\n this.stores[name] = state\n }\n\n return this.stores[name]\n },\n\n reset(name, state) {\n if (this.stores[name] === undefined) {\n return;\n }\n \n this.stores[name] = state\n },\n\n subscribe(el) {\n if (!this.subscribers.includes(el)) {\n this.subscribers.push(el)\n }\n\n return this.stores\n },\n\n updateSubscribers() {\n this.subscribers.filter(el => !!el.__x).forEach(el => {\n el.__x.updateElements(el)\n })\n },\n\n retrieveFromLocalStorage(name, methods = {}) {\n const value = this.persistenceDriver.getItem(`__spruce:${name}`)\n\n if (! value) {\n return null\n }\n\n let storage = JSON.parse(value)\n\n if (typeof storage === 'object') {\n storage = Object.assign(methods, storage)\n\n delete storage.__watchers\n delete storage.__key_name\n }\n\n return storage\n },\n\n updateLocalStorage(name) {\n const store = { ...this.store(name) }\n\n delete store.__watchers\n delete store.__key_name\n\n this.persistenceDriver.setItem(`__spruce:${name}`, JSON.stringify(this.store(name)))\n },\n\n get(name, target = this.stores) {\n return name.split('.').reduce((target, part) => target[part], target)\n },\n\n set(name, value, target = this.stores) {\n if (! isArray(name)) {\n name = name.split('.')\n }\n\n if (name.length === 1) return target[name[0]] = value\n\n if (target[name[0]]) {\n return this.set(name.slice(1), value, target[name[0]])\n } else {\n target[name[0]] = {}\n\n return this.set(name.slice(1), value, target[name[0]])\n }\n },\n\n toggle(name) {\n return this.set(name, ! this.get(name))\n },\n\n call(name, ...args) {\n return this.get(name)(...args)\n },\n\n clear(name) {\n return this.persistenceDriver.removeItem(`__spruce:${name}`)\n },\n\n watch(name, callback) {\n if (! this.hasStarted) {\n this.pendingWatchers[name] || (this.pendingWatchers[name] = [])\n\n this.pendingWatchers[name].push(callback)\n\n return [() => this.unwatch(name, callback)]\n }\n\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n /**\n * If the target object / array is the property\n * that needs to be watched, a magic `__self` key is\n * used so that runner can pick up on it later.\n */\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n target.__watchers = new Map\n }\n \n if (! target.__watchers.has(part)) {\n target.__watchers.set(part, new Set)\n }\n\n target.__watchers.get(part).add(callback)\n\n return [() => this.unwatch(name, callback)]\n },\n\n unwatch(name, callback) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n const watchers = target.__watchers\n\n if (! watchers.has(part)) {\n return\n }\n\n watchers.get(part).delete(callback)\n },\n\n watchers(name) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n return {}\n }\n\n return target.__watchers.get(part)\n },\n\n runWatchers(target, key, value) {\n if (! target.__watchers) {\n return\n }\n\n if (target.__watchers.has(key)) {\n target.__watchers.get(key).forEach(f => f(value))\n }\n\n /**\n * The `__self` key is used for watchers that are registered\n * to the object or array being updated.\n */\n if (target.__watchers.has('__self')) {\n target.__watchers.get('__self').forEach(f => f(value, key))\n }\n },\n\n persistUsing(driver) {\n if (this.persisted.length > 0) {\n console.warn('[Spruce] You have already initialised a persisted store. Changing the driver may cause issues.')\n }\n\n if (typeof driver.getItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `getItem(key)` method.')\n }\n\n if (typeof driver.setItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `setItem(key, value)` method.')\n }\n\n if (typeof driver.removeItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `removeItem(name)` method.')\n }\n\n this.persistenceDriver = driver\n }\n}\n\nwindow.Spruce = Spruce\n\nconst deferrer = window.deferLoadingAlpine || function (callback) { callback() }\n\nwindow.deferLoadingAlpine = function (callback) {\n window.Spruce.start()\n\n deferrer(callback)\n}\n\nexport default Spruce\n"],"names":["module","semver","split","v","str","c","replace","patchIndex","indexOf","length","arr","substring","push","tryParse","isNaN","Number","validate","version","TypeError","test","Error","compareVersions","v1","v2","forEach","s1","s2","i","Math","max","n1","parseInt","n2","sp1","sp2","p1","map","p2","undefined","allowedOperators","operatorResMap",">",">=","=","<=","<","compare","operator","op","join","validateOperator","res","factory","isNullOrUndefined","value","isObject","_","Object","getPrototypeOf","prototype","isArray","Array","createObservable","target","callbacks","entries","key","Proxy","get","receiver","set","originalValue","__watchers","Spruce","stores","persistenceDriver","window","localStorage","persisted","subscribers","pendingWatchers","disableReactivity","startingCallbacks","startedCallbacks","hasStarted","start","fn","attach","this","is","includes","bind","Reflect","updateSubscribers","runWatchers","updateLocalStorage","e","callback","watch","name","starting","started","navigator","userAgent","Alpine","self","addMagicProperty","el","subscribe","store","state","persist","retrieveFromLocalStorage","methods","filter","reset","__x","updateElements","getItem","storage","JSON","parse","assign","__key_name","setItem","stringify","reduce","part","slice","toggle","call","args","clear","removeItem","unwatch","nameParts","sub","Map","has","Set","add","watchers","delete","f","persistUsing","driver","console","warn","const","deferrer","deferLoadingAlpine"],"mappings":"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"} \ No newline at end of file diff --git a/dist/spruce.umd.js b/dist/spruce.umd.js index 7b26fad..a5cd6c6 100644 --- a/dist/spruce.umd.js +++ b/dist/spruce.umd.js @@ -1,2 +1,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(){function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var r,n=(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 s=t(e),o=t(i),c=0;cu)return 1;if(u>a)return-1}var f=s[s.length-1],h=o[o.length-1];if(f&&h){var p=f.split(".").map(r),d=h.split(".").map(r);for(c=0;cd[c])return 1;if(d[c]>p[c])return-1}}else if(f||h)return f?-1:1;return 0}var s=[">",">=","=","<","<="],o={">":[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===s.indexOf(e))throw new TypeError("Invalid operator, expected one of "+s.join("|"))}(r);var n=i(e,t);return o[r].indexOf(n)>-1},i}()}(r={exports:{}}),r.exports),i=function(e){return null==e},s=function(e){return Object.getPrototypeOf(e)===Object.prototype},o=function(e){return Array.isArray(e)},c=function(e,t){return Object.entries(e).forEach(function(r){var n=r[0],a=r[1];i(a)||!s(a)&&!o(a)||(e[n]=c(a,t))}),new Proxy(e,{get:function(e,r,n){return t.get(e,r,n)},set:function(e,r,n,a){i(n)||!s(n)&&!o(n)||(n=c(n,t));var u=e[r];return e[r]=n,i(u)||i(u.__watchers)||(e[r].__watchers=u.__watchers),t.set(e,r,e[r],a),!0}})},a={stores:{},persistenceDriver:window.localStorage,persisted:[],subscribers:[],watchers:{},disableReactivity:!1,startingCallbacks:[],startedCallbacks:[],hasStarted:!1,start:function(){var e=this;this.startingCallbacks.forEach(function(e){return e()}),this.attach(),this.stores=c(this.stores,{get:function(t,r,n){return Object.is(n,e.stores)&&["get","set","toggle","clear"].includes(r)?e[r].bind(e):Reflect.get(t,r,n)},set:function(t,r,n,i){if(!e.disableReactivity){e.updateSubscribers(),e.runWatchers(t,r,n,i),e.disableReactivity=!0;try{e.persisted.forEach(e.updateLocalStorage.bind(e))}catch(e){}e.disableReactivity=!1}}}),this.hasStarted=!0,this.disableReactivity=!0,Object.entries(this.watchers).forEach(function(t){var r=t[0];t[1].forEach(function(t){return e.watch(r,t)})}),this.disableReactivity=!1,this.startedCallbacks.forEach(function(e){return e()})},starting:function(e){this.startingCallbacks.push(e)},started:function(e){this.startedCallbacks.push(e)},attach:function(){if(!(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")||window.Alpine&&n.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),"function"==typeof t&&(t=t()),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]&&(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=this.persistenceDriver.getItem("__spruce:"+e);if(!r)return null;var n=JSON.parse(r);return"object"==typeof n&&(delete(n=Object.assign(t,n)).__watchers,delete n.__key_name),n},updateLocalStorage:function(r){var n=function(r){for(var n=1;n0&&console.warn("[Spruce] You have already initialised a persisted store. Changing the driver may cause issues."),"function"!=typeof e.getItem)throw new Error("[Spruce] The persistence driver must have a `getItem(key)` method.");if("function"!=typeof e.setItem)throw new Error("[Spruce] The persistence driver must have a `setItem(key, value)` method.");if("function"!=typeof e.removeItem)throw new Error("[Spruce] The persistence driver must have a `removeItem(name)` method.");this.persistenceDriver=e}};window.Spruce=a;var u=window.deferLoadingAlpine||function(e){e()};return window.deferLoadingAlpine=function(e){window.Spruce.start(),u(e)},a}); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.spruce=t()}(this,function(){function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var r,n=(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 s=t(e),o=t(i),c=0;cu)return 1;if(u>a)return-1}var f=s[s.length-1],h=o[o.length-1];if(f&&h){var p=f.split(".").map(r),d=h.split(".").map(r);for(c=0;cd[c])return 1;if(d[c]>p[c])return-1}}else if(f||h)return f?-1:1;return 0}var s=[">",">=","=","<","<="],o={">":[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===s.indexOf(e))throw new TypeError("Invalid operator, expected one of "+s.join("|"))}(r);var n=i(e,t);return o[r].indexOf(n)>-1},i}()}(r={exports:{}}),r.exports),i=function(e){return null==e},s=function(e){return Object.getPrototypeOf(e)===Object.prototype},o=function(e){return Array.isArray(e)},c=function(e,t){return Object.entries(e).forEach(function(r){var n=r[0],a=r[1];i(a)||!s(a)&&!o(a)||(e[n]=c(a,t))}),new Proxy(e,{get:function(e,r,n){return t.get(e,r,n)},set:function(e,r,n,a){i(n)||!s(n)&&!o(n)||(n=c(n,t));var u=e[r];return e[r]=n,i(u)||i(u.__watchers)||(e[r].__watchers=u.__watchers),t.set(e,r,e[r],a),!0}})},a={stores:{},persistenceDriver:window.localStorage,persisted:[],subscribers:[],pendingWatchers:{},disableReactivity:!1,startingCallbacks:[],startedCallbacks:[],hasStarted:!1,start:function(){var e=this;this.startingCallbacks.forEach(function(e){return e()}),this.attach(),this.stores=c(this.stores,{get:function(t,r,n){return Object.is(n,e.stores)&&["get","set","toggle","call","clear"].includes(r)?e[r].bind(e):Reflect.get(t,r,n)},set:function(t,r,n,i){if(!e.disableReactivity){e.updateSubscribers(),e.runWatchers(t,r,n,i),e.disableReactivity=!0;try{e.persisted.forEach(e.updateLocalStorage.bind(e))}catch(e){}e.disableReactivity=!1}}}),this.hasStarted=!0,this.disableReactivity=!0,Object.entries(this.pendingWatchers).forEach(function(t){var r=t[0];t[1].forEach(function(t){return e.watch(r,t)})}),this.disableReactivity=!1,this.startedCallbacks.forEach(function(e){return e()})},starting:function(e){this.startingCallbacks.push(e)},started:function(e){this.startedCallbacks.push(e)},attach:function(){if(!(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")||window.Alpine&&n.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),"function"==typeof t&&(t=t()),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){void 0!==this.stores[e]&&(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=this.persistenceDriver.getItem("__spruce:"+e);if(!r)return null;var n=JSON.parse(r);return"object"==typeof n&&(delete(n=Object.assign(t,n)).__watchers,delete n.__key_name),n},updateLocalStorage:function(r){var n=function(r){for(var n=1;n0;)t[r]=arguments[r+1];return this.get(e).apply(void 0,t)},clear:function(e){return this.persistenceDriver.removeItem("__spruce:"+e)},watch:function(e,t){var r=this;if(!this.hasStarted)return this.pendingWatchers[e]||(this.pendingWatchers[e]=[]),this.pendingWatchers[e].push(t),[function(){return r.unwatch(e,t)}];var n=e.split("."),c=n.reduce(function(e,t){var r=e[t];return i(r)||!s(r)&&!o(r)?e:r},this.stores),a=Object.is(c,this.get(e))?"__self":n[n.length-1];return c.__watchers||(c.__watchers=new Map),c.__watchers.has(a)||c.__watchers.set(a,new Set),c.__watchers.get(a).add(t),[function(){return r.unwatch(e,t)}]},unwatch:function(e,t){var r=e.split("."),n=r.reduce(function(e,t){var r=e[t];return i(r)||!s(r)&&!o(r)?e:r},this.stores),c=Object.is(n,this.get(e))?"__self":r[r.length-1],a=n.__watchers;a.has(c)&&a.get(c).delete(t)},watchers:function(e){var t=e.split("."),r=t.reduce(function(e,t){var r=e[t];return i(r)||!s(r)&&!o(r)?e:r},this.stores),n=Object.is(r,this.get(e))?"__self":t[t.length-1];return r.__watchers?r.__watchers.get(n):{}},runWatchers:function(e,t,r){e.__watchers&&(e.__watchers.has(t)&&e.__watchers.get(t).forEach(function(e){return e(r)}),e.__watchers.has("__self")&&e.__watchers.get("__self").forEach(function(e){return e(r,t)}))},persistUsing:function(e){if(this.persisted.length>0&&console.warn("[Spruce] You have already initialised a persisted store. Changing the driver may cause issues."),"function"!=typeof e.getItem)throw new Error("[Spruce] The persistence driver must have a `getItem(key)` method.");if("function"!=typeof e.setItem)throw new Error("[Spruce] The persistence driver must have a `setItem(key, value)` method.");if("function"!=typeof e.removeItem)throw new Error("[Spruce] The persistence driver must have a `removeItem(name)` method.");this.persistenceDriver=e}};window.Spruce=a;var u=window.deferLoadingAlpine||function(e){e()};return window.deferLoadingAlpine=function(e){window.Spruce.start(),u(e)},a}); //# sourceMappingURL=spruce.umd.js.map diff --git a/dist/spruce.umd.js.map b/dist/spruce.umd.js.map index 2da3c77..6c400fd 100644 --- a/dist/spruce.umd.js.map +++ b/dist/spruce.umd.js.map @@ -1 +1 @@ -{"version":3,"file":"spruce.umd.js","sources":["../node_modules/compare-versions/index.js","../src/utils.js","../src/observable.js","../src/index.js"],"sourcesContent":["/* global define */\n(function (root, factory) {\n /* istanbul ignore next */\n if (typeof define === 'function' && define.amd) {\n define([], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.compareVersions = factory();\n }\n}(this, function () {\n\n var semver = /^v?(?:\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+))?(?:-[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\n\n function indexOrEnd(str, q) {\n return str.indexOf(q) === -1 ? str.length : str.indexOf(q);\n }\n\n function split(v) {\n var c = v.replace(/^v/, '').replace(/\\+.*$/, '');\n var patchIndex = indexOrEnd(c, '-');\n var arr = c.substring(0, patchIndex).split('.');\n arr.push(c.substring(patchIndex + 1));\n return arr;\n }\n\n function tryParse(v) {\n return isNaN(Number(v)) ? v : Number(v);\n }\n\n function validate(version) {\n if (typeof version !== 'string') {\n throw new TypeError('Invalid argument expected string');\n }\n if (!semver.test(version)) {\n throw new Error('Invalid argument not valid semver (\\''+version+'\\' received)');\n }\n }\n\n function compareVersions(v1, v2) {\n [v1, v2].forEach(validate);\n\n var s1 = split(v1);\n var s2 = split(v2);\n\n for (var i = 0; i < Math.max(s1.length - 1, s2.length - 1); i++) {\n var n1 = parseInt(s1[i] || 0, 10);\n var n2 = parseInt(s2[i] || 0, 10);\n\n if (n1 > n2) return 1;\n if (n2 > n1) return -1;\n }\n\n var sp1 = s1[s1.length - 1];\n var sp2 = s2[s2.length - 1];\n\n if (sp1 && sp2) {\n var p1 = sp1.split('.').map(tryParse);\n var p2 = sp2.split('.').map(tryParse);\n\n for (i = 0; i < Math.max(p1.length, p2.length); i++) {\n if (p1[i] === undefined || typeof p2[i] === 'string' && typeof p1[i] === 'number') return -1;\n if (p2[i] === undefined || typeof p1[i] === 'string' && typeof p2[i] === 'number') return 1;\n\n if (p1[i] > p2[i]) return 1;\n if (p2[i] > p1[i]) return -1;\n }\n } else if (sp1 || sp2) {\n return sp1 ? -1 : 1;\n }\n\n return 0;\n };\n\n var allowedOperators = [\n '>',\n '>=',\n '=',\n '<',\n '<='\n ];\n\n var operatorResMap = {\n '>': [1],\n '>=': [0, 1],\n '=': [0],\n '<=': [-1, 0],\n '<': [-1]\n };\n\n function validateOperator(op) {\n if (typeof op !== 'string') {\n throw new TypeError('Invalid operator type, expected string but got ' + typeof op);\n }\n if (allowedOperators.indexOf(op) === -1) {\n throw new TypeError('Invalid operator, expected one of ' + allowedOperators.join('|'));\n }\n }\n\n compareVersions.validate = function(version) {\n return typeof version === 'string' && semver.test(version);\n }\n\n compareVersions.compare = function (v1, v2, operator) {\n // Validate operator\n validateOperator(operator);\n\n // since result of compareVersions can only be -1 or 0 or 1\n // a simple map can be used to replace switch\n var res = compareVersions(v1, v2);\n return operatorResMap[operator].indexOf(res) > -1;\n }\n\n return compareVersions;\n}));\n","import compareVersions from 'compare-versions'\n\nexport const isNullOrUndefined = value => {\n return value === null || value === undefined\n}\n\nexport const isObject = _ => {\n return Object.getPrototypeOf(_) === Object.prototype\n}\n\nexport const isArray = _ => Array.isArray(_)\n\nexport const getMethods = obj => {\n let methods = {}\n\n Object.entries(obj).filter(([_, value]) => typeof value === 'function').forEach(([key, value]) => methods[key] = value)\n\n return methods\n}\n\nexport const isTesting = () => {\n return navigator.userAgent, navigator.userAgent.includes(\"Node.js\")\n || navigator.userAgent.includes(\"jsdom\")\n}\n\nexport const checkForAlpine = () => {\n if (isTesting()) {\n return true\n }\n\n if (! window.Alpine) {\n return false\n }\n\n return compareVersions.compare(window.Alpine.version, '2.7.0', '>=')\n}","import { isNullOrUndefined, isObject, isArray } from './utils'\n\nexport const createObservable = (target, callbacks) => {\n Object.entries(target).forEach(([key, value]) => {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) { \n target[key] = createObservable(value, callbacks)\n }\n })\n\n return new Proxy(target, {\n get(target, key, receiver) {\n return callbacks.get(target, key, receiver)\n },\n set(target, key, value, receiver) {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) {\n value = createObservable(value, callbacks)\n }\n\n let originalValue = target[key]\n\n target[key] = value\n\n // Copy watchers from the original value if they exist\n if (!isNullOrUndefined(originalValue) && !isNullOrUndefined(originalValue.__watchers)) {\n target[key].__watchers = originalValue.__watchers\n }\n\n callbacks.set(target, key, target[key], receiver)\n\n return true\n }\n })\n}","import { getMethods, checkForAlpine, isObject, isArray, isNullOrUndefined } from './utils'\nimport { createObservable } from './observable'\n\nconst Spruce = {\n stores: {},\n\n persistenceDriver: window.localStorage,\n\n persisted: [],\n\n subscribers: [],\n\n watchers: {},\n\n disableReactivity: false,\n\n startingCallbacks: [],\n\n startedCallbacks: [],\n\n hasStarted: false,\n\n start() {\n this.startingCallbacks.forEach(fn => fn())\n\n this.attach()\n\n this.stores = createObservable(this.stores, {\n get: (target, key, receiver) => {\n if (Object.is(receiver, this.stores) && ['get', 'set', 'toggle', 'clear'].includes(key)) {\n return this[key].bind(this)\n }\n\n return Reflect.get(target, key, receiver)\n },\n set: (target, key, value, receiver) => {\n if (this.disableReactivity) {\n return\n }\n\n this.updateSubscribers()\n\n this.runWatchers(target, key, value, receiver)\n\n this.disableReactivity = true\n\n try {\n this.persisted.forEach(this.updateLocalStorage.bind(this))\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n\n this.disableReactivity = false\n }\n })\n\n this.hasStarted = true\n\n this.disableReactivity = true\n\n Object.entries(this.watchers).forEach(([name, callbacks]) => {\n callbacks.forEach(callback => this.watch(name, callback))\n })\n\n this.disableReactivity = false\n\n this.startedCallbacks.forEach(fn => fn())\n },\n\n starting(callback) {\n this.startingCallbacks.push(callback)\n },\n\n started(callback) {\n this.startedCallbacks.push(callback)\n },\n\n attach() {\n if (! checkForAlpine()) {\n throw new Error('[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.')\n }\n\n const self = this\n\n window.Alpine.addMagicProperty('store', el => {\n self.subscribe(el)\n\n return self.stores\n })\n },\n\n store(name, state, persist = false) {\n if (typeof state === 'function') {\n state = state()\n }\n \n if (persist) {\n try {\n this.stores[name] = this.retrieveFromLocalStorage(name, getMethods(state))\n\n if (!this.persisted.includes(name)) {\n this.persisted.push(name)\n }\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n }\n\n if (!this.stores[name]) {\n this.stores[name] = state\n }\n\n return this.stores[name]\n },\n\n reset(name, state) {\n if (! this.stores[name]) {\n return;\n }\n \n this.stores[name] = state\n },\n\n subscribe(el) {\n if (!this.subscribers.includes(el)) {\n this.subscribers.push(el)\n }\n\n return this.stores\n },\n\n updateSubscribers() {\n this.subscribers.filter(el => !!el.__x).forEach(el => {\n el.__x.updateElements(el)\n })\n },\n\n retrieveFromLocalStorage(name, methods = {}) {\n const value = this.persistenceDriver.getItem(`__spruce:${name}`)\n\n if (! value) {\n return null\n }\n\n let storage = JSON.parse(value)\n\n if (typeof storage === 'object') {\n storage = Object.assign(methods, storage)\n\n delete storage.__watchers\n delete storage.__key_name\n }\n\n return storage\n },\n\n updateLocalStorage(name) {\n const store = { ...this.store(name) }\n\n delete store.__watchers\n delete store.__key_name\n\n this.persistenceDriver.setItem(`__spruce:${name}`, JSON.stringify(this.store(name)))\n },\n\n get(name, target = this.stores) {\n return name.split('.').reduce((target, part) => target[part], target)\n },\n\n set(name, value, target = this.stores) {\n if (! isArray(name)) {\n name = name.split('.')\n }\n\n if (name.length === 1) return target[name[0]] = value\n\n if (target[name[0]]) {\n return this.set(name.slice(1), value, target[name[0]])\n } else {\n target[name[0]] = {}\n\n return this.set(name.slice(1), value, target[name[0]])\n }\n },\n\n toggle(name) {\n return this.set(name, ! this.get(name))\n },\n\n clear(name) {\n return this.persistenceDriver.removeItem(`__spruce:${name}`)\n },\n\n watch(name, callback) {\n if (! this.hasStarted) {\n this.watchers[name] || (this.watchers[name] = [])\n\n this.watchers[name].push(callback)\n\n return [() => this.unwatch(name, callback)]\n }\n\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n /**\n * If the target object / array is the property\n * that needs to be watched, a magic `__self` key is\n * used so that runner can pick up on it later.\n */\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n target.__watchers = new Map\n }\n \n if (! target.__watchers.has(part)) {\n target.__watchers.set(part, new Set)\n }\n\n target.__watchers.get(part).add(callback)\n\n return [() => this.unwatch(name, callback)]\n },\n\n unwatch(name, callback) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n const watchers = target.__watchers\n\n if (! watchers.has(part)) {\n return\n }\n\n watchers.get(part).delete(callback)\n },\n\n watchers(name) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n return {}\n }\n\n return target.__watchers.get(part)\n },\n\n runWatchers(target, key, value) {\n if (! target.__watchers) {\n return\n }\n\n if (target.__watchers.has(key)) {\n target.__watchers.get(key).forEach(f => f(value))\n }\n\n /**\n * The `__self` key is used for watchers that are registered\n * to the object or array being updated.\n */\n if (target.__watchers.has('__self')) {\n target.__watchers.get('__self').forEach(f => f(value, key))\n }\n },\n\n persistUsing(driver) {\n if (this.persisted.length > 0) {\n console.warn('[Spruce] You have already initialised a persisted store. Changing the driver may cause issues.')\n }\n\n if (typeof driver.getItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `getItem(key)` method.')\n }\n\n if (typeof driver.setItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `setItem(key, value)` method.')\n }\n\n if (typeof driver.removeItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `removeItem(name)` method.')\n }\n\n this.persistenceDriver = driver\n }\n}\n\nwindow.Spruce = Spruce\n\nconst deferrer = window.deferLoadingAlpine || function (callback) { callback() }\n\nwindow.deferLoadingAlpine = function (callback) {\n window.Spruce.start()\n\n deferrer(callback)\n}\n\nexport default Spruce\n"],"names":["module","semver","split","v","str","c","replace","patchIndex","indexOf","length","arr","substring","push","tryParse","isNaN","Number","validate","version","TypeError","test","Error","compareVersions","v1","v2","forEach","s1","s2","i","Math","max","n1","parseInt","n2","sp1","sp2","p1","map","p2","undefined","allowedOperators","operatorResMap",">",">=","=","<=","<","compare","operator","op","join","validateOperator","res","factory","isNullOrUndefined","value","isObject","_","Object","getPrototypeOf","prototype","isArray","Array","createObservable","target","callbacks","entries","key","Proxy","get","receiver","set","originalValue","__watchers","Spruce","stores","persistenceDriver","window","localStorage","persisted","subscribers","watchers","disableReactivity","startingCallbacks","startedCallbacks","hasStarted","start","fn","attach","this","is","includes","bind","Reflect","updateSubscribers","runWatchers","updateLocalStorage","e","callback","watch","name","starting","started","navigator","userAgent","Alpine","self","addMagicProperty","el","subscribe","store","state","persist","retrieveFromLocalStorage","methods","filter","reset","__x","updateElements","getItem","storage","JSON","parse","assign","__key_name","setItem","stringify","reduce","part","slice","toggle","clear","removeItem","unwatch","nameParts","sub","Map","has","Set","add","delete","f","persistUsing","driver","console","warn","const","deferrer","deferLoadingAlpine"],"mappings":"6pBAMIA,UAII,WAEN,IAAIC,EAAS,qIAMb,SAASC,EAAMC,GACb,IALkBC,EAKdC,EAAIF,EAAEG,QAAQ,KAAM,IAAIA,QAAQ,QAAS,IACzCC,GALuB,KADTH,EAMUC,GALjBG,QAKoB,KALAJ,EAAIK,OAASL,EAAII,QAKjB,KAC3BE,EAAML,EAAEM,UAAU,EAAGJ,GAAYL,MAAM,KAE3C,OADAQ,EAAIE,KAAKP,EAAEM,UAAUJ,EAAa,IAC3BG,EAGT,SAASG,EAASV,GAChB,OAAOW,MAAMC,OAAOZ,IAAMA,EAAIY,OAAOZ,GAGvC,SAASa,EAASC,GAChB,GAAuB,iBAAZA,EACT,MAAM,IAAIC,UAAU,oCAEtB,IAAKjB,EAAOkB,KAAKF,GACf,MAAM,IAAIG,MAAM,uCAAwCH,EAAQ,eAIpE,SAASI,EAAgBC,EAAIC,GAC3B,CAACD,EAAIC,GAAIC,QAAQR,GAKjB,IAHA,IAAIS,EAAKvB,EAAMoB,GACXI,EAAKxB,EAAMqB,GAENI,EAAI,EAAGA,EAAIC,KAAKC,IAAIJ,EAAGhB,OAAS,EAAGiB,EAAGjB,OAAS,GAAIkB,IAAK,CAC/D,IAAIG,EAAKC,SAASN,EAAGE,IAAM,EAAG,IAC1BK,EAAKD,SAASL,EAAGC,IAAM,EAAG,IAE9B,GAAIG,EAAKE,EAAI,OAAO,EACpB,GAAIA,EAAKF,EAAI,OAAQ,EAGvB,IAAIG,EAAMR,EAAGA,EAAGhB,OAAS,GACrByB,EAAMR,EAAGA,EAAGjB,OAAS,GAEzB,GAAIwB,GAAOC,EAAK,CACd,IAAIC,EAAKF,EAAI/B,MAAM,KAAKkC,IAAIvB,GACxBwB,EAAKH,EAAIhC,MAAM,KAAKkC,IAAIvB,GAE5B,IAAKc,EAAI,EAAGA,EAAIC,KAAKC,IAAIM,EAAG1B,OAAQ4B,EAAG5B,QAASkB,IAAK,CACnD,QAAcW,IAAVH,EAAGR,IAAqC,iBAAVU,EAAGV,IAAoC,iBAAVQ,EAAGR,GAAiB,OAAQ,EAC3F,QAAcW,IAAVD,EAAGV,IAAqC,iBAAVQ,EAAGR,IAAoC,iBAAVU,EAAGV,GAAiB,OAAO,EAE1F,GAAIQ,EAAGR,GAAKU,EAAGV,GAAI,OAAO,EAC1B,GAAIU,EAAGV,GAAKQ,EAAGR,GAAI,OAAQ,QAExB,GAAIM,GAAOC,EAChB,OAAOD,GAAO,EAAI,EAGpB,OAAO,EAGT,IAAIM,EAAmB,CACrB,IACA,KACA,IACA,IACA,MAGEC,EAAiB,CACnBC,IAAK,CAAC,GACNC,KAAM,CAAC,EAAG,GACVC,IAAK,CAAC,GACNC,KAAM,EAAE,EAAG,GACXC,IAAK,EAAE,IA0BT,OAdAxB,EAAgBL,SAAW,SAASC,GAClC,MAA0B,iBAAZA,GAAwBhB,EAAOkB,KAAKF,IAGpDI,EAAgByB,QAAU,SAAUxB,EAAIC,EAAIwB,IAb5C,SAA0BC,GACxB,GAAkB,iBAAPA,EACT,MAAM,IAAI9B,UAAU,yDAA2D8B,GAEjF,IAAsC,IAAlCT,EAAiB/B,QAAQwC,GAC3B,MAAM,IAAI9B,UAAU,qCAAuCqB,EAAiBU,KAAK,MAUnFC,CAAiBH,GAIjB,IAAII,EAAM9B,EAAgBC,EAAIC,GAC9B,OAAOiB,EAAeO,GAAUvC,QAAQ2C,IAAQ,GAG3C9B,EA3GY+B,+BCJRC,WAAoBC,UACtBA,MAAAA,GAGEC,WAAWC,UACbC,OAAOC,eAAeF,KAAOC,OAAOE,WAGlCC,WAAUJ,UAAKK,MAAMD,QAAQJ,ICR7BM,WAAoBC,EAAQC,UACrCP,OAAOQ,QAAQF,GAAQvC,sCACb6B,EAAkBC,KAAWC,EAASD,KAAUM,EAAQN,KAC1DS,EAAOG,GAAOJ,EAAiBR,EAAOU,MAIvC,IAAIG,MAAMJ,EAAQ,CACrBK,aAAIL,EAAQG,EAAKG,UACNL,EAAUI,IAAIL,EAAQG,EAAKG,IAEtCC,aAAIP,EAAQG,EAAKZ,EAAOe,GACdhB,EAAkBC,KAAWC,EAASD,KAAUM,EAAQN,KAC1DA,EAAQQ,EAAiBR,EAAOU,QAGhCO,EAAgBR,EAAOG,UAE3BH,EAAOG,GAAOZ,EAGTD,EAAkBkB,IAAmBlB,EAAkBkB,EAAcC,cACtET,EAAOG,GAAKM,WAAaD,EAAcC,YAG3CR,EAAUM,IAAIP,EAAQG,EAAKH,EAAOG,GAAMG,IAEjC,MC1BbI,EAAS,CACXC,OAAQ,GAERC,kBAAmBC,OAAOC,aAE1BC,UAAW,GAEXC,YAAa,GAEbC,SAAU,GAEVC,mBAAmB,EAEnBC,kBAAmB,GAEnBC,iBAAkB,GAElBC,YAAY,EAEZC,iCACSH,kBAAkB1D,iBAAQ8D,UAAMA,WAEhCC,cAEAb,OAASZ,EAAiB0B,KAAKd,OAAQ,CACxCN,aAAML,EAAQG,EAAKG,UACXZ,OAAOgC,GAAGpB,EAAUmB,EAAKd,SAAW,CAAC,MAAO,MAAO,SAAU,SAASgB,SAASxB,GACxEsB,EAAKtB,GAAKyB,KAAKH,GAGnBI,QAAQxB,IAAIL,EAAQG,EAAKG,IAEpCC,aAAMP,EAAQG,EAAKZ,EAAOe,OAClBmB,EAAKP,qBAIJY,sBAEAC,YAAY/B,EAAQG,EAAKZ,EAAOe,KAEhCY,mBAAoB,QAGhBH,UAAUtD,QAAQgE,EAAKO,mBAAmBJ,KAAKH,IACtD,MAAOQ,MAIJf,mBAAoB,WAI5BG,YAAa,OAEbH,mBAAoB,EAEzBxB,OAAOQ,QAAQuB,KAAKR,UAAUxD,oCAChBA,iBAAQyE,UAAYT,EAAKU,MAAMC,EAAMF,YAG9ChB,mBAAoB,OAEpBE,iBAAiB3D,iBAAQ8D,UAAMA,OAGxCc,kBAASH,QACAf,kBAAkBtE,KAAKqF,IAGhCI,iBAAQJ,QACCd,iBAAiBvE,KAAKqF,IAG/BV,uBFxDOe,UAA+BC,UAAUb,SAAS,YAClDY,UAAUC,UAAUb,SAAS,UAQ9Bd,OAAO4B,QAINnF,EAAgByB,QAAQ8B,OAAO4B,OAAOvF,QAAS,QAAS,aE6CjD,IAAIG,MAAM,iEAGdqF,EAAOjB,KAEbZ,OAAO4B,OAAOE,iBAAiB,iBAASC,UACpCF,EAAKG,UAAUD,GAERF,EAAK/B,UAIpBmC,eAAMV,EAAMW,EAAOC,sBAAU,GACJ,mBAAVD,IACPA,EAAQA,KAGRC,WAESrC,OAAOyB,GAAQX,KAAKwB,yBAAyBb,GFrF1Dc,EAAU,GAEdxD,OAAOQ,QEmFwE6C,GFnF3DI,yBAAwC,0BAAY1F,2BAA0ByF,eAE3FA,IEmFUzB,KAAKV,UAAUY,SAASS,SACpBrB,UAAUlE,KAAKuF,GAE1B,MAAOH,QF1FbiB,SE+FKzB,KAAKd,OAAOyB,UACRzB,OAAOyB,GAAQW,GAGjBtB,KAAKd,OAAOyB,IAGvBgB,eAAMhB,EAAMW,GACFtB,KAAKd,OAAOyB,UAIbzB,OAAOyB,GAAQW,IAGxBF,mBAAUD,UACDnB,KAAKT,YAAYW,SAASiB,SACtB5B,YAAYnE,KAAK+F,GAGnBnB,KAAKd,QAGhBmB,kCACSd,YAAYmC,gBAAOP,WAAQA,EAAGS,MAAK5F,iBAAQmF,GAC5CA,EAAGS,IAAIC,eAAeV,MAI9BK,kCAAyBb,EAAMc,kBAAU,QAC/B3D,EAAQkC,KAAKb,kBAAkB2C,oBAAoBnB,OAEnD7C,SACK,SAGPiE,EAAUC,KAAKC,MAAMnE,SAEF,iBAAZiE,WACPA,EAAU9D,OAAOiE,OAAOT,EAASM,IAElB/C,kBACR+C,EAAQI,YAGZJ,GAGXxB,4BAAmBI,OACTU,iWAAarB,KAAKqB,MAAMV,WAEvBU,EAAMrC,kBACNqC,EAAMc,gBAERhD,kBAAkBiD,oBAAoBzB,EAAQqB,KAAKK,UAAUrC,KAAKqB,MAAMV,MAGjF/B,aAAI+B,EAAMpC,yBAASyB,KAAKd,QACbyB,EAAKjG,MAAM,KAAK4H,gBAAQ/D,EAAQgE,UAAShE,EAAOgE,IAAOhE,IAGlEO,aAAI6B,EAAM7C,EAAOS,yBAASyB,KAAKd,QACrBd,EAAQuC,KACVA,EAAOA,EAAKjG,MAAM,MAGF,IAAhBiG,EAAK1F,OAAqBsD,EAAOoC,EAAK,IAAM7C,EAE5CS,EAAOoC,EAAK,IACLX,KAAKlB,IAAI6B,EAAK6B,MAAM,GAAI1E,EAAOS,EAAOoC,EAAK,MAElDpC,EAAOoC,EAAK,IAAM,GAEXX,KAAKlB,IAAI6B,EAAK6B,MAAM,GAAI1E,EAAOS,EAAOoC,EAAK,OAI1D8B,gBAAO9B,UACIX,KAAKlB,IAAI6B,GAAQX,KAAKpB,IAAI+B,KAGrC+B,eAAM/B,UACKX,KAAKb,kBAAkBwD,uBAAuBhC,IAGzDD,eAAMC,EAAMF,kBACFT,KAAKJ,uBACFJ,SAASmB,KAAUX,KAAKR,SAASmB,GAAQ,SAEzCnB,SAASmB,GAAMvF,KAAKqF,GAElB,mBAAOT,EAAK4C,QAAQjC,EAAMF,SAG/BoC,EAAYlC,EAAKjG,MAAM,KAEvB6D,EAASsE,EAAUP,gBAAQ/D,EAAQgE,OAC/BO,EAAMvE,EAAOgE,UAEb1E,EAAkBiF,KAAS/E,EAAS+E,KAAQ1E,EAAQ0E,GAInDvE,EAHIuE,GAIZ9C,KAAKd,QAOFqD,EAAOtE,OAAOgC,GAAG1B,EAAQyB,KAAKpB,IAAI+B,IAAS,SAAWkC,EAAUA,EAAU5H,OAAS,UAEnFsD,EAAOS,aACTT,EAAOS,WAAa,IAAI+D,KAGtBxE,EAAOS,WAAWgE,IAAIT,IACxBhE,EAAOS,WAAWF,IAAIyD,EAAM,IAAIU,KAGpC1E,EAAOS,WAAWJ,IAAI2D,GAAMW,IAAIzC,GAEzB,mBAAOT,EAAK4C,QAAQjC,EAAMF,MAGrCmC,iBAAQjC,EAAMF,OACJoC,EAAYlC,EAAKjG,MAAM,KAEvB6D,EAASsE,EAAUP,gBAAQ/D,EAAQgE,OAC/BO,EAAMvE,EAAOgE,UAEb1E,EAAkBiF,KAAS/E,EAAS+E,KAAQ1E,EAAQ0E,GAInDvE,EAHIuE,GAIZ9C,KAAKd,QAEFqD,EAAOtE,OAAOgC,GAAG1B,EAAQyB,KAAKpB,IAAI+B,IAAS,SAAWkC,EAAUA,EAAU5H,OAAS,GACnFuE,EAAWjB,EAAOS,WAElBQ,EAASwD,IAAIT,IAInB/C,EAASZ,IAAI2D,GAAMY,OAAO1C,IAG9BjB,kBAASmB,OACCkC,EAAYlC,EAAKjG,MAAM,KAEvB6D,EAASsE,EAAUP,gBAAQ/D,EAAQgE,OAC/BO,EAAMvE,EAAOgE,UAEb1E,EAAkBiF,KAAS/E,EAAS+E,KAAQ1E,EAAQ0E,GAInDvE,EAHIuE,GAIZ9C,KAAKd,QAEFqD,EAAOtE,OAAOgC,GAAG1B,EAAQyB,KAAKpB,IAAI+B,IAAS,SAAWkC,EAAUA,EAAU5H,OAAS,UAEnFsD,EAAOS,WAINT,EAAOS,WAAWJ,IAAI2D,GAHlB,IAMfjC,qBAAY/B,EAAQG,EAAKZ,GACfS,EAAOS,aAITT,EAAOS,WAAWgE,IAAItE,IACtBH,EAAOS,WAAWJ,IAAIF,GAAK1C,iBAAQoH,UAAKA,EAAEtF,KAO1CS,EAAOS,WAAWgE,IAAI,WACtBzE,EAAOS,WAAWJ,IAAI,UAAU5C,iBAAQoH,UAAKA,EAAEtF,EAAOY,OAI9D2E,sBAAaC,MACLtD,KAAKV,UAAUrE,OAAS,GACxBsI,QAAQC,KAAK,kGAGa,mBAAnBF,EAAOxB,cACR,IAAIlG,MAAM,yEAGU,mBAAnB0H,EAAOlB,cACR,IAAIxG,MAAM,gFAGa,mBAAtB0H,EAAOX,iBACR,IAAI/G,MAAM,+EAGfuD,kBAAoBmE,IAIjClE,OAAOH,OAASA,EAEhBwE,IAAMC,EAAWtE,OAAOuE,oBAAsB,SAAUlD,GAAYA,YAEpErB,OAAOuE,mBAAqB,SAAUlD,GAClCrB,OAAOH,OAAOY,QAEd6D,EAASjD"} \ No newline at end of file +{"version":3,"file":"spruce.umd.js","sources":["../node_modules/compare-versions/index.js","../src/utils.js","../src/observable.js","../src/index.js"],"sourcesContent":["/* global define */\n(function (root, factory) {\n /* istanbul ignore next */\n if (typeof define === 'function' && define.amd) {\n define([], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.compareVersions = factory();\n }\n}(this, function () {\n\n var semver = /^v?(?:\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+)(\\.(?:[x*]|\\d+))?(?:-[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\n\n function indexOrEnd(str, q) {\n return str.indexOf(q) === -1 ? str.length : str.indexOf(q);\n }\n\n function split(v) {\n var c = v.replace(/^v/, '').replace(/\\+.*$/, '');\n var patchIndex = indexOrEnd(c, '-');\n var arr = c.substring(0, patchIndex).split('.');\n arr.push(c.substring(patchIndex + 1));\n return arr;\n }\n\n function tryParse(v) {\n return isNaN(Number(v)) ? v : Number(v);\n }\n\n function validate(version) {\n if (typeof version !== 'string') {\n throw new TypeError('Invalid argument expected string');\n }\n if (!semver.test(version)) {\n throw new Error('Invalid argument not valid semver (\\''+version+'\\' received)');\n }\n }\n\n function compareVersions(v1, v2) {\n [v1, v2].forEach(validate);\n\n var s1 = split(v1);\n var s2 = split(v2);\n\n for (var i = 0; i < Math.max(s1.length - 1, s2.length - 1); i++) {\n var n1 = parseInt(s1[i] || 0, 10);\n var n2 = parseInt(s2[i] || 0, 10);\n\n if (n1 > n2) return 1;\n if (n2 > n1) return -1;\n }\n\n var sp1 = s1[s1.length - 1];\n var sp2 = s2[s2.length - 1];\n\n if (sp1 && sp2) {\n var p1 = sp1.split('.').map(tryParse);\n var p2 = sp2.split('.').map(tryParse);\n\n for (i = 0; i < Math.max(p1.length, p2.length); i++) {\n if (p1[i] === undefined || typeof p2[i] === 'string' && typeof p1[i] === 'number') return -1;\n if (p2[i] === undefined || typeof p1[i] === 'string' && typeof p2[i] === 'number') return 1;\n\n if (p1[i] > p2[i]) return 1;\n if (p2[i] > p1[i]) return -1;\n }\n } else if (sp1 || sp2) {\n return sp1 ? -1 : 1;\n }\n\n return 0;\n };\n\n var allowedOperators = [\n '>',\n '>=',\n '=',\n '<',\n '<='\n ];\n\n var operatorResMap = {\n '>': [1],\n '>=': [0, 1],\n '=': [0],\n '<=': [-1, 0],\n '<': [-1]\n };\n\n function validateOperator(op) {\n if (typeof op !== 'string') {\n throw new TypeError('Invalid operator type, expected string but got ' + typeof op);\n }\n if (allowedOperators.indexOf(op) === -1) {\n throw new TypeError('Invalid operator, expected one of ' + allowedOperators.join('|'));\n }\n }\n\n compareVersions.validate = function(version) {\n return typeof version === 'string' && semver.test(version);\n }\n\n compareVersions.compare = function (v1, v2, operator) {\n // Validate operator\n validateOperator(operator);\n\n // since result of compareVersions can only be -1 or 0 or 1\n // a simple map can be used to replace switch\n var res = compareVersions(v1, v2);\n return operatorResMap[operator].indexOf(res) > -1;\n }\n\n return compareVersions;\n}));\n","import compareVersions from 'compare-versions'\n\nexport const isNullOrUndefined = value => {\n return value === null || value === undefined\n}\n\nexport const isObject = _ => {\n return Object.getPrototypeOf(_) === Object.prototype\n}\n\nexport const isArray = _ => Array.isArray(_)\n\nexport const getMethods = obj => {\n let methods = {}\n\n Object.entries(obj).filter(([_, value]) => typeof value === 'function').forEach(([key, value]) => methods[key] = value)\n\n return methods\n}\n\nexport const isTesting = () => {\n return navigator.userAgent, navigator.userAgent.includes(\"Node.js\")\n || navigator.userAgent.includes(\"jsdom\")\n}\n\nexport const checkForAlpine = () => {\n if (isTesting()) {\n return true\n }\n\n if (! window.Alpine) {\n return false\n }\n\n return compareVersions.compare(window.Alpine.version, '2.7.0', '>=')\n}","import { isNullOrUndefined, isObject, isArray } from './utils'\n\nexport const createObservable = (target, callbacks) => {\n Object.entries(target).forEach(([key, value]) => {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) { \n target[key] = createObservable(value, callbacks)\n }\n })\n\n return new Proxy(target, {\n get(target, key, receiver) {\n return callbacks.get(target, key, receiver)\n },\n set(target, key, value, receiver) {\n if (! isNullOrUndefined(value) && (isObject(value) || isArray(value))) {\n value = createObservable(value, callbacks)\n }\n\n let originalValue = target[key]\n\n target[key] = value\n\n // Copy watchers from the original value if they exist\n if (!isNullOrUndefined(originalValue) && !isNullOrUndefined(originalValue.__watchers)) {\n target[key].__watchers = originalValue.__watchers\n }\n\n callbacks.set(target, key, target[key], receiver)\n\n return true\n }\n })\n}","import { getMethods, checkForAlpine, isObject, isArray, isNullOrUndefined } from './utils'\nimport { createObservable } from './observable'\n\nconst Spruce = {\n stores: {},\n\n persistenceDriver: window.localStorage,\n\n persisted: [],\n\n subscribers: [],\n\n pendingWatchers: {},\n\n disableReactivity: false,\n\n startingCallbacks: [],\n\n startedCallbacks: [],\n\n hasStarted: false,\n\n start() {\n this.startingCallbacks.forEach(fn => fn())\n\n this.attach()\n\n this.stores = createObservable(this.stores, {\n get: (target, key, receiver) => {\n if (Object.is(receiver, this.stores) && ['get', 'set', 'toggle', 'call', 'clear'].includes(key)) {\n return this[key].bind(this)\n }\n\n return Reflect.get(target, key, receiver)\n },\n set: (target, key, value, receiver) => {\n if (this.disableReactivity) {\n return\n }\n\n this.updateSubscribers()\n\n this.runWatchers(target, key, value, receiver)\n\n this.disableReactivity = true\n\n try {\n this.persisted.forEach(this.updateLocalStorage.bind(this))\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n\n this.disableReactivity = false\n }\n })\n\n this.hasStarted = true\n\n this.disableReactivity = true\n\n Object.entries(this.pendingWatchers).forEach(([name, callbacks]) => {\n callbacks.forEach(callback => this.watch(name, callback))\n })\n\n this.disableReactivity = false\n\n this.startedCallbacks.forEach(fn => fn())\n },\n\n starting(callback) {\n this.startingCallbacks.push(callback)\n },\n\n started(callback) {\n this.startedCallbacks.push(callback)\n },\n\n attach() {\n if (! checkForAlpine()) {\n throw new Error('[Spruce] You must be using Alpine >= 2.5.0 to use Spruce.')\n }\n\n const self = this\n\n window.Alpine.addMagicProperty('store', el => {\n self.subscribe(el)\n\n return self.stores\n })\n },\n\n store(name, state, persist = false) {\n if (typeof state === 'function') {\n state = state()\n }\n \n if (persist) {\n try {\n this.stores[name] = this.retrieveFromLocalStorage(name, getMethods(state))\n\n if (!this.persisted.includes(name)) {\n this.persisted.push(name)\n }\n } catch (e) {\n // Do nothing here (thanks Safari!)\n }\n }\n\n if (!this.stores[name]) {\n this.stores[name] = state\n }\n\n return this.stores[name]\n },\n\n reset(name, state) {\n if (this.stores[name] === undefined) {\n return;\n }\n \n this.stores[name] = state\n },\n\n subscribe(el) {\n if (!this.subscribers.includes(el)) {\n this.subscribers.push(el)\n }\n\n return this.stores\n },\n\n updateSubscribers() {\n this.subscribers.filter(el => !!el.__x).forEach(el => {\n el.__x.updateElements(el)\n })\n },\n\n retrieveFromLocalStorage(name, methods = {}) {\n const value = this.persistenceDriver.getItem(`__spruce:${name}`)\n\n if (! value) {\n return null\n }\n\n let storage = JSON.parse(value)\n\n if (typeof storage === 'object') {\n storage = Object.assign(methods, storage)\n\n delete storage.__watchers\n delete storage.__key_name\n }\n\n return storage\n },\n\n updateLocalStorage(name) {\n const store = { ...this.store(name) }\n\n delete store.__watchers\n delete store.__key_name\n\n this.persistenceDriver.setItem(`__spruce:${name}`, JSON.stringify(this.store(name)))\n },\n\n get(name, target = this.stores) {\n return name.split('.').reduce((target, part) => target[part], target)\n },\n\n set(name, value, target = this.stores) {\n if (! isArray(name)) {\n name = name.split('.')\n }\n\n if (name.length === 1) return target[name[0]] = value\n\n if (target[name[0]]) {\n return this.set(name.slice(1), value, target[name[0]])\n } else {\n target[name[0]] = {}\n\n return this.set(name.slice(1), value, target[name[0]])\n }\n },\n\n toggle(name) {\n return this.set(name, ! this.get(name))\n },\n\n call(name, ...args) {\n return this.get(name)(...args)\n },\n\n clear(name) {\n return this.persistenceDriver.removeItem(`__spruce:${name}`)\n },\n\n watch(name, callback) {\n if (! this.hasStarted) {\n this.pendingWatchers[name] || (this.pendingWatchers[name] = [])\n\n this.pendingWatchers[name].push(callback)\n\n return [() => this.unwatch(name, callback)]\n }\n\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n /**\n * If the target object / array is the property\n * that needs to be watched, a magic `__self` key is\n * used so that runner can pick up on it later.\n */\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n target.__watchers = new Map\n }\n \n if (! target.__watchers.has(part)) {\n target.__watchers.set(part, new Set)\n }\n\n target.__watchers.get(part).add(callback)\n\n return [() => this.unwatch(name, callback)]\n },\n\n unwatch(name, callback) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n const watchers = target.__watchers\n\n if (! watchers.has(part)) {\n return\n }\n\n watchers.get(part).delete(callback)\n },\n\n watchers(name) {\n const nameParts = name.split('.')\n\n const target = nameParts.reduce((target, part) => {\n const sub = target[part]\n\n if (! isNullOrUndefined(sub) && (isObject(sub) || isArray(sub))) {\n return sub\n }\n\n return target\n }, this.stores)\n\n const part = Object.is(target, this.get(name)) ? '__self' : nameParts[nameParts.length - 1]\n\n if (! target.__watchers) {\n return {}\n }\n\n return target.__watchers.get(part)\n },\n\n runWatchers(target, key, value) {\n if (! target.__watchers) {\n return\n }\n\n if (target.__watchers.has(key)) {\n target.__watchers.get(key).forEach(f => f(value))\n }\n\n /**\n * The `__self` key is used for watchers that are registered\n * to the object or array being updated.\n */\n if (target.__watchers.has('__self')) {\n target.__watchers.get('__self').forEach(f => f(value, key))\n }\n },\n\n persistUsing(driver) {\n if (this.persisted.length > 0) {\n console.warn('[Spruce] You have already initialised a persisted store. Changing the driver may cause issues.')\n }\n\n if (typeof driver.getItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `getItem(key)` method.')\n }\n\n if (typeof driver.setItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `setItem(key, value)` method.')\n }\n\n if (typeof driver.removeItem !== 'function') {\n throw new Error('[Spruce] The persistence driver must have a `removeItem(name)` method.')\n }\n\n this.persistenceDriver = driver\n }\n}\n\nwindow.Spruce = Spruce\n\nconst deferrer = window.deferLoadingAlpine || function (callback) { callback() }\n\nwindow.deferLoadingAlpine = function (callback) {\n window.Spruce.start()\n\n deferrer(callback)\n}\n\nexport default Spruce\n"],"names":["module","semver","split","v","str","c","replace","patchIndex","indexOf","length","arr","substring","push","tryParse","isNaN","Number","validate","version","TypeError","test","Error","compareVersions","v1","v2","forEach","s1","s2","i","Math","max","n1","parseInt","n2","sp1","sp2","p1","map","p2","undefined","allowedOperators","operatorResMap",">",">=","=","<=","<","compare","operator","op","join","validateOperator","res","factory","isNullOrUndefined","value","isObject","_","Object","getPrototypeOf","prototype","isArray","Array","createObservable","target","callbacks","entries","key","Proxy","get","receiver","set","originalValue","__watchers","Spruce","stores","persistenceDriver","window","localStorage","persisted","subscribers","pendingWatchers","disableReactivity","startingCallbacks","startedCallbacks","hasStarted","start","fn","attach","this","is","includes","bind","Reflect","updateSubscribers","runWatchers","updateLocalStorage","e","callback","watch","name","starting","started","navigator","userAgent","Alpine","self","addMagicProperty","el","subscribe","store","state","persist","retrieveFromLocalStorage","methods","filter","reset","__x","updateElements","getItem","storage","JSON","parse","assign","__key_name","setItem","stringify","reduce","part","slice","toggle","call","args","clear","removeItem","unwatch","nameParts","sub","Map","has","Set","add","watchers","delete","f","persistUsing","driver","console","warn","const","deferrer","deferLoadingAlpine"],"mappings":"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"} \ No newline at end of file