]> git.ipfire.org Git - thirdparty/vuejs/pinia.git/commitdiff
chore: more testing on the playground
authorEduardo San Martin Morote <posva13@gmail.com>
Tue, 20 Jul 2021 15:57:24 +0000 (17:57 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Tue, 20 Jul 2021 15:57:24 +0000 (17:57 +0200)
12 files changed:
package.json
playground/src/App.vue
playground/src/stores/counter.ts
playground/src/stores/jokes.ts [new file with mode: 0644]
playground/src/stores/jokesUsePromised.ts [new file with mode: 0644]
playground/src/views/Jokes.vue [new file with mode: 0644]
playground/src/views/JokesPromised.vue [new file with mode: 0644]
playground/src/views/api/jokes.ts [new file with mode: 0644]
playground/src/views/api/nasa.ts [new file with mode: 0644]
playground/src/views/swrv.vue [new file with mode: 0644]
src/store.ts
yarn.lock

index edf321a72c63b1e4c6a80f9c6b6e3807ec92cf0d..b19b95daf6431ed4e65ad69037b6654bdcec18c0 100644 (file)
     "jest-mock-warn": "^1.1.0",
     "lint-staged": "^11.0.1",
     "lodash.kebabcase": "^4.1.1",
+    "mande": "^1.0.0",
     "pascalcase": "^1.0.0",
     "prettier": "^2.3.2",
     "rimraf": "^3.0.2",
     "rollup": "^2.53.2",
     "rollup-plugin-terser": "^7.0.2",
     "rollup-plugin-typescript2": "^0.30.0",
+    "swrv": "^1.0.0-beta.8",
     "typescript": "~4.3.5",
     "vite": "^2.4.1",
     "vitepress": "^0.15.6",
     "vue": "^3.2.0-beta.1",
+    "vue-promised": "^2.1.0",
     "vue-router": "^4.0.10",
     "yorkie": "^2.0.0"
   },
index 64c3209befb6b4c2a201cde622e2459d0f1f93bd..b83cadc4ccf3c9519754271394bcec7d833a53a8 100644 (file)
     </nav>
   </header>
 
-  <router-view />
+  <section>
+    <router-view />
+  </section>
+
+  <footer>
+    <p>
+      ©2021 Eduardo San Martin Morote
+      <br />
+      <a :href="sourceCodeLink">Source Code</a>
+    </p>
+  </footer>
 </template>
 
 <script lang="ts" setup>
-import { useRouter } from 'vue-router'
+import { computed } from 'vue'
+import { useRoute, useRouter } from 'vue-router'
 
 const router = useRouter()
+const route = useRoute()
 
 const pages = router
   .getRoutes()
   .filter((route) => !route.meta.hide)
   .map((route) => ({ name: route.name }))
+
+const sourceCodeLink = computed(() => {
+  if (route.name) {
+    return `https://github.com/posva/pinia/blob/v2/playground/src/views/${route.name}.vue`
+  } else {
+    return `https://github.com/posva/pinia/blob/v2/playground/src/`
+  }
+})
 </script>
 
 <style>
index 8645e35382a39db926cd278a451dd32447c9049d..bc1d0c9cd5e5ca40b35c2c88f9eedf03baa6a160 100644 (file)
@@ -6,7 +6,7 @@ export const useCounter = defineStore({
   id: 'counter',
 
   state: () => ({
-    n: 0,
+    n: 2,
     incrementedTimes: 0,
     decrementedTimes: 0,
     numbers: [] as number[],
diff --git a/playground/src/stores/jokes.ts b/playground/src/stores/jokes.ts
new file mode 100644 (file)
index 0000000..8c13f16
--- /dev/null
@@ -0,0 +1,49 @@
+import { ref, unref } from 'vue'
+import { acceptHMRUpdate, defineStore } from '../../../src'
+import { getRandomJoke, Joke } from '../views/api/jokes'
+
+export const useJokes = defineStore('jokes', {
+  state: () => ({
+    current: null as null | Joke,
+    jokes: [] as Joke[],
+  }),
+  actions: {
+    async fetchJoke() {
+      if (
+        this.current &&
+        // if the request below fails, avoid adding it twice
+        !this.jokes.includes(this.current)
+      ) {
+        this.jokes.push(this.current)
+      }
+
+      this.current = await getRandomJoke()
+    },
+  },
+})
+
+export const useJokesSetup = defineStore('jokes-setup', () => {
+  const current = ref<null | Joke>(null)
+  const history = ref<Joke[]>([])
+
+  async function fetchJoke() {
+    const cur = unref(current.value)
+    if (
+      cur &&
+      // if the request below fails, avoid adding it twice
+      !history.value.find((joke) => joke.id === cur.id)
+    ) {
+      history.value.push(cur)
+    }
+
+    current.value = await getRandomJoke()
+    return current.value
+  }
+
+  return { current, history, fetchJoke }
+})
+
+if (import.meta.hot) {
+  import.meta.hot.accept(acceptHMRUpdate(useJokes, import.meta.hot))
+  import.meta.hot.accept(acceptHMRUpdate(useJokesSetup, import.meta.hot))
+}
diff --git a/playground/src/stores/jokesUsePromised.ts b/playground/src/stores/jokesUsePromised.ts
new file mode 100644 (file)
index 0000000..dfcaf96
--- /dev/null
@@ -0,0 +1,90 @@
+import { acceptHMRUpdate, defineStore } from '../../../src'
+import { getRandomJoke, Joke } from '../views/api/jokes'
+import { usePromise } from 'vue-promised'
+import { ref, watch } from 'vue'
+
+export const useJokes = defineStore({
+  id: 'jokes-vue-promised',
+
+  state: () => {
+    const promise = ref(getRandomJoke())
+
+    watch(promise, () => {
+      console.log('promise changed')
+    })
+
+    const promised = usePromise(promise)
+
+    return {
+      promise,
+      ...promised,
+      history: [] as Joke[],
+    }
+  },
+
+  actions: {
+    waitForJoke() {
+      return this.promise
+    },
+
+    fetchJoke() {
+      if (
+        this.data &&
+        // if the request below fails, avoid adding it twice
+        !this.history.includes(this.data)
+      ) {
+        this.history.push(this.data)
+      }
+
+      console.log('fetching')
+      // this.$state.promise = getRandomJoke()
+      // Will fail because we initially had a ref
+      this.promise = getRandomJoke()
+
+      return this.$state.promise
+    },
+  },
+})
+
+export const useSetupJokes = defineStore('jokes-setup-vue-promised', () => {
+  const history = ref<Joke[]>([])
+  const promise = ref(getRandomJoke())
+  watch(promise, () => {
+    console.log('promise changed')
+  })
+
+  const promised = usePromise(promise)
+
+  function fetchJoke() {
+    if (
+      promised.data.value &&
+      // if the request below fails, avoid adding it twice
+      !history.value.includes(promised.data.value)
+    ) {
+      history.value.push(promised.data.value)
+    }
+
+    console.log('fetching')
+    // this.$state.promise = getRandomJoke()
+    // Will fail because we initially had a ref
+    promise.value = getRandomJoke()
+
+    promise.value.then((joke) => {
+      console.log('got', joke)
+    })
+
+    return promise.value
+  }
+
+  return {
+    promise,
+    ...promised,
+    history,
+    fetchJoke,
+  }
+})
+
+if (import.meta.hot) {
+  // import.meta.hot.accept(acceptHMRUpdate(useJokes, import.meta.hot))
+  // import.meta.hot.accept(acceptHMRUpdate(useSetupJokes, import.meta.hot))
+}
diff --git a/playground/src/views/Jokes.vue b/playground/src/views/Jokes.vue
new file mode 100644 (file)
index 0000000..2554d5d
--- /dev/null
@@ -0,0 +1,83 @@
+<template>
+  <h3>
+    Pinia + <a href="https://github.com/posva/vue-promised">Vue Promised</a>
+  </h3>
+
+  <main>
+    <section>
+      <button
+        :disabled="state !== 'ready'"
+        @click="fetchRandomJoke"
+        style="margin-bottom: 4px"
+      >
+        {{ buttonText }}
+      </button>
+
+      <div style="min-height: 9rem" v-if="jokes.current">
+
+          <blockquote :key="jokes.current.id">
+            <i>{{ jokes.current.setup }}</i>
+            <br />
+            <br />
+            <p class="appear" @animationend="state = 'ready'">
+              {{ jokes.current.punchline }}
+            </p>
+          </blockquote>
+      </div>
+    </section>
+  </main>
+
+  <pre>{{ jokes.$state }}</pre>
+</template>
+
+<script lang="ts" setup>
+import { computed, onMounted, ref } from 'vue'
+import { useJokes, useJokesSetup } from '../stores/jokes'
+
+// const jokes = useJokes()
+const jokes = useJokesSetup()
+
+const texts = {
+  loading: 'Fetching the joke...',
+  waiting: 'Wait for it...',
+  ready: 'Another one?',
+}
+
+const state = ref<'waiting' | 'loading' | 'ready'>('waiting')
+
+const buttonText = computed(() => texts[state.value])
+
+function fetchRandomJoke() {
+  state.value = 'loading'
+
+  jokes.fetchJoke().finally(() => {
+    state.value = 'waiting'
+    console.log('done fetching', jokes.current)
+  })
+}
+
+onMounted(() => {
+  console.log('mounted')
+  // @ts-expect-error
+  window.jo = jokes
+    console.log('new pending')
+    fetchRandomJoke()
+})
+</script>
+
+<style>
+@keyframes appear {
+  from {
+    opacity: 0;
+  }
+  to {
+    opacity: 1;
+  }
+}
+
+.appear {
+  opacity: 0;
+  animation: appear 1s ease-in-out 3s;
+  animation-fill-mode: forwards;
+}
+</style>
diff --git a/playground/src/views/JokesPromised.vue b/playground/src/views/JokesPromised.vue
new file mode 100644 (file)
index 0000000..ba6d520
--- /dev/null
@@ -0,0 +1,94 @@
+<template>
+  <h3>
+    Pinia + <a href="https://github.com/posva/vue-promised">Vue Promised</a>
+  </h3>
+
+  <main>
+    <section>
+      <button
+        :disabled="state !== 'ready'"
+        @click="fetchRandomJoke"
+        style="margin-bottom: 4px"
+      >
+        {{ buttonText }}
+      </button>
+
+      <div style="min-height: 9rem">
+        <template v-if="jokes.isPending && jokes.isDelayElapsed">
+          <div class="spinner"></div>
+        </template>
+
+        <template v-else-if="jokes.data">
+          <blockquote :key="jokes.data.id">
+            <i>{{ jokes.data.setup }}</i>
+            <br />
+            <br />
+            <p class="appear" @animationend="state = 'ready'">
+              {{ jokes.data.punchline }}
+            </p>
+          </blockquote>
+        </template>
+
+        <template v-else-if="jokes.error">
+          <p>Error: {{ jokes.error.message }}</p>
+        </template>
+      </div>
+    </section>
+  </main>
+
+  <pre>{{ jokes.$state }}</pre>
+</template>
+
+<script lang="ts" setup>
+import { computed, onMounted, ref } from 'vue'
+import { useJokes, useSetupJokes } from '../stores/jokesUsePromised'
+
+// const jokes = useJokes()
+const jokes = useSetupJokes()
+
+const texts = {
+  loading: 'Fetching the joke...',
+  waiting: 'Wait for it...',
+  ready: 'Another one?',
+}
+
+const state = ref<'waiting' | 'loading' | 'ready'>('waiting')
+
+const buttonText = computed(() => texts[state.value])
+
+function fetchRandomJoke() {
+  state.value = 'loading'
+
+  jokes.fetchJoke().finally(() => {
+    state.value = 'waiting'
+    console.log('done fetching', jokes.data)
+  })
+}
+
+onMounted(() => {
+  console.log('mounted')
+  // @ts-expect-error
+  window.jo = jokes
+  if (!jokes.isPending) {
+    console.log('new pending')
+    fetchRandomJoke()
+  }
+})
+</script>
+
+<style>
+@keyframes appear {
+  from {
+    opacity: 0;
+  }
+  to {
+    opacity: 1;
+  }
+}
+
+.appear {
+  opacity: 0;
+  animation: appear 1s ease-in-out 3s;
+  animation-fill-mode: forwards;
+}
+</style>
diff --git a/playground/src/views/api/jokes.ts b/playground/src/views/api/jokes.ts
new file mode 100644 (file)
index 0000000..3cd63f0
--- /dev/null
@@ -0,0 +1,18 @@
+import { mande } from 'mande'
+
+export const jokes = mande('https://official-joke-api.appspot.com', {
+  headers: {
+    'Content-Type': null,
+  },
+})
+
+export interface Joke {
+  id: number
+  type: string
+  setup: string
+  punchline: string
+}
+
+export function getRandomJoke() {
+  return jokes.get<Joke>('/jokes/random')
+}
diff --git a/playground/src/views/api/nasa.ts b/playground/src/views/api/nasa.ts
new file mode 100644 (file)
index 0000000..3cd9495
--- /dev/null
@@ -0,0 +1,31 @@
+import { mande } from 'mande'
+
+/**
+ * Go to https://api.nasa.gov/ and generate a key. Put it in your `.env` file
+ * next to the `package.json` file:
+ *
+ * VITE_API_KEY_NASA=<your_key>
+ */
+const API_KEY = import.meta.env.VITE_API_KEY_NASA || 'DEMO_KEY'
+
+const nasaPlanetary = mande('https://api.nasa.gov/planetary', {
+  query: { api_key: API_KEY, thumbs: true },
+})
+
+export interface NASAPOD {
+  copyright: string
+  date: string
+  explanation: string
+  hdurl: string
+  media_type: 'image' | 'video'
+  title: string
+  url: string
+}
+
+export function getNASAPOD(date: Date | string = new Date()) {
+  if (typeof date !== 'string') {
+    date = date.toISOString().slice(0, 10)
+  }
+
+  return nasaPlanetary.get<NASAPOD>('/apod', { query: { date } })
+}
diff --git a/playground/src/views/swrv.vue b/playground/src/views/swrv.vue
new file mode 100644 (file)
index 0000000..a63adb8
--- /dev/null
@@ -0,0 +1,3 @@
+<template>
+  <h1></h1>
+</template>
index 281fe49d7ee4bf35877df9fe5c998ab9c23d7c74..d2415e2f31231b4678404b50ee09d064f5108ad2 100644 (file)
@@ -380,7 +380,7 @@ function createSetupStore<
         hotState.value[key] = toRef(setupStore as any, key)
         // createOptionStore already did this
       } else if (!buildState) {
-        pinia.state.value[$id][key] = toRef(setupStore as any, key)
+        pinia.state.value[$id][key] = prop
         // TODO: avoid if state exists for SSR
       }
 
index 7e74a2690c3dee2d5260167ab2852c1546d7b0d5..9b2496ab36d43a25f1eba5c20b3816a2fe1e4113 100644 (file)
--- a/yarn.lock
+++ b/yarn.lock
@@ -3997,6 +3997,11 @@ makeerror@1.0.x:
   dependencies:
     tmpl "1.0.x"
 
+mande@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/mande/-/mande-1.0.0.tgz#80f1faae62ebe9bebdd37093794d25de39ceafab"
+  integrity sha512-SKNhkHOvXXFOGCgOvqD9EUKDiNZFXvfACfED+Omw7dXTq/NmHJ83QhHte3wOIiQ7bwLh7F/uotJ2djqcN0JgpA==
+
 map-cache@^0.2.2:
   version "0.2.2"
   resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf"
@@ -5446,6 +5451,11 @@ supports-hyperlinks@^2.0.0:
     has-flag "^4.0.0"
     supports-color "^7.0.0"
 
+swrv@^1.0.0-beta.8:
+  version "1.0.0-beta.8"
+  resolved "https://registry.yarnpkg.com/swrv/-/swrv-1.0.0-beta.8.tgz#745723f5ca8a7a7e290e911cf7da34cecaf356d3"
+  integrity sha512-MsjaMOvZODfM0cess/HhbSrNbAotYinv4vzipLckKYBo/QmrvjNUPGZSRSqByXy/9AjrMRFWo0YanaVPbqADPQ==
+
 symbol-tree@^3.2.4:
   version "3.2.4"
   resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
@@ -5843,11 +5853,18 @@ vitepress@^0.15.6:
     vite "^2.3.7"
     vue "^3.1.1"
 
-vue-demi@*:
+vue-demi@*, vue-demi@latest:
   version "0.11.2"
   resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.11.2.tgz#faa06da53887c493a695b997f4fcb4784a667990"
   integrity sha512-J+X8Au6BhQdcej6LY4O986634hZLu55L0ewU2j8my7WIKlu8cK0dqmdUxqVHHMd/cMrKKZ9SywB/id6aLhwCtA==
 
+vue-promised@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/vue-promised/-/vue-promised-2.1.0.tgz#dd565da4c24f0c974ccafc56def2514d9411b73b"
+  integrity sha512-AEcIeOR0bzSr5E1wq9MOSiX9ERO5zxi6jCOU3269EZbc+z6KXGOHIzPpeU+/SnvhTCXqJx9Nj3ff/KiFtgDfHA==
+  dependencies:
+    vue-demi latest
+
 vue-router@^4.0.10:
   version "4.0.10"
   resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.0.10.tgz#ec8fda032949b2a31d3273170f8f376e86eb52ac"