소스 검색

Create global Alpine.$persist to enable persisting in Alpine.store (#2191)

* wip

* Finish global Alpine. and add a test.

* Add back index.html

* Adding docs, code review clean up.

* Run build

Co-authored-by: Caleb Porzio <calebporzio@gmail.com>
MalcolmKnott 3 년 전
부모
커밋
5c5d1a0f47
5개의 변경된 파일65개의 추가작업 그리고 11개의 파일을 삭제
  1. 18 7
      package-lock.json
  2. 3 0
      packages/alpinejs/src/store.js
  3. 11 0
      packages/docs/src/en/plugins/persist.md
  4. 6 4
      packages/persist/src/index.js
  5. 27 0
      tests/cypress/integration/plugins/persist.spec.js

+ 18 - 7
package-lock.json

@@ -18,6 +18,10 @@
                 "jest": "^26.6.3"
             }
         },
+        "node_modules/@alpinejs/collapse": {
+            "resolved": "packages/collapse",
+            "link": true
+        },
         "node_modules/@alpinejs/csp": {
             "resolved": "packages/csp",
             "link": true
@@ -7794,12 +7798,16 @@
             }
         },
         "packages/alpinejs": {
-            "version": "3.3.3",
+            "version": "3.4.2",
             "license": "MIT",
             "dependencies": {
-                "@vue/reactivity": "^3.0.2"
+                "@vue/reactivity": "~3.1.1"
             }
         },
+        "packages/collapse": {
+            "version": "3.4.2",
+            "license": "MIT"
+        },
         "packages/csp": {
             "name": "@alpinejs/csp",
             "version": "3.0.0-alpha.0",
@@ -7810,7 +7818,7 @@
         },
         "packages/docs": {
             "name": "@alpinejs/docs",
-            "version": "3.3.3-revision.1",
+            "version": "3.4.2-revision.2",
             "license": "MIT"
         },
         "packages/history": {
@@ -7823,7 +7831,7 @@
         },
         "packages/intersect": {
             "name": "@alpinejs/intersect",
-            "version": "3.3.3",
+            "version": "3.4.2",
             "license": "MIT"
         },
         "packages/morph": {
@@ -7836,12 +7844,12 @@
         },
         "packages/persist": {
             "name": "@alpinejs/persist",
-            "version": "3.3.3",
+            "version": "3.4.2",
             "license": "MIT"
         },
         "packages/trap": {
             "name": "@alpinejs/trap",
-            "version": "3.3.3",
+            "version": "3.4.2",
             "license": "MIT",
             "dependencies": {
                 "focus-trap": "^6.6.1"
@@ -7849,6 +7857,9 @@
         }
     },
     "dependencies": {
+        "@alpinejs/collapse": {
+            "version": "file:packages/collapse"
+        },
         "@alpinejs/csp": {
             "version": "file:packages/csp",
             "requires": {
@@ -8876,7 +8887,7 @@
         "alpinejs": {
             "version": "file:packages/alpinejs",
             "requires": {
-                "@vue/reactivity": "^3.0.2"
+                "@vue/reactivity": "~3.1.1"
             }
         },
         "ansi-escapes": {

+ 3 - 0
packages/alpinejs/src/store.js

@@ -1,3 +1,4 @@
+import { initInterceptors } from "./interceptor";
 import { reactive } from "./reactivity"
 
 let stores = {}
@@ -15,6 +16,8 @@ export function store(name, value) {
     if (typeof value === 'object' && value !== null && value.hasOwnProperty('init') && typeof value.init === 'function') {
         stores[name].init()
     }
+
+    initInterceptors(stores[name])
 }
 
 export function getStores() { return stores }

+ 11 - 0
packages/docs/src/en/plugins/persist.md

@@ -194,3 +194,14 @@ Alpine.data('dropdown', function () {
     }
 })
 ```
+
+<a name="using-alpine-persist-global"></a>
+## Using the Alpine.$persist global
+
+`Alpine.$persist` is exposed globally so it can be used outside of `x-data` contexts. This is useful to persist data from other sources such as `Alpine.store`.
+
+```js
+Alpine.store('darkMode', {
+    on: Alpine.$persist(true).as('darkMode_on')
+});
+```

+ 6 - 4
packages/persist/src/index.js

@@ -1,10 +1,9 @@
-
 export default function (Alpine) {
-    Alpine.magic('persist', (el, { interceptor }) => {
+    let persist = () => {
         let alias
         let storage = localStorage
 
-        return interceptor((initialValue, getter, setter, path, key) => {
+        return Alpine.interceptor((initialValue, getter, setter, path, key) => {
             let lookup = alias || `_x_${path}`
 
             let initial = storageHas(lookup, storage)
@@ -26,7 +25,10 @@ export default function (Alpine) {
             func.as = key => { alias = key; return func },
             func.using = target => { storage = target; return func }
         })
-    })
+    }
+
+    Alpine.$persist = persist()
+    Alpine.magic('persist', persist)
 }
 
 function storageHas(key, storage) {

+ 27 - 0
tests/cypress/integration/plugins/persist.spec.js

@@ -181,6 +181,9 @@ test('can persist to custom storage',
         reload()
         get('span').should(haveText('bar'))
         window().its('sessionStorage._x_message').should(beEqualTo(JSON.stringify('bar')))
+        window().then((win) => {
+            win.sessionStorage.clear()
+        });
     },
 )
 
@@ -197,5 +200,29 @@ test('can persist to custom storage using an alias',
         get('input').clear().type('bar')
         get('span').should(haveText('bar'))
         window().its('sessionStorage.mymessage').should(beEqualTo(JSON.stringify('bar')))
+        window().then((win) => {
+            win.sessionStorage.clear()
+        });
+    },
+)
+
+test('can persist using global Alpine.$persist within Alpine.store',
+    [html`
+        <div x-data>
+            <input x-model="$store.name.firstName">
+
+            <span x-text="$store.name.firstName"></span>
+        </div>
+    `, `
+        Alpine.store('name', {
+            firstName: Alpine.$persist('Daniel').as('dev-name')
+        })
+    `],
+    ({ get, window }, reload) => {
+        get('span').should(haveText('Daniel'))
+        get('input').clear().type('Malcolm')
+        get('span').should(haveText('Malcolm'))
+        reload()
+        get('span').should(haveText('Malcolm'))
     },
 )