add i18n; add signal-db with first test
This commit is contained in:
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
/// <reference types="vite/client" />
|
/// <reference types="vite/client" />
|
||||||
Generated
+115
@@ -8,8 +8,12 @@
|
|||||||
"name": "just",
|
"name": "just",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@signaldb/core": "^1.3.1",
|
||||||
|
"@signaldb/indexeddb": "^1.0.0",
|
||||||
|
"@signaldb/vue": "^1.0.0",
|
||||||
"pinia": "^3.0.1",
|
"pinia": "^3.0.1",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
|
"vue-i18n": "^11.1.1",
|
||||||
"vue-router": "^4.5.0"
|
"vue-router": "^4.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -1337,6 +1341,50 @@
|
|||||||
"url": "https://github.com/sponsors/nzakas"
|
"url": "https://github.com/sponsors/nzakas"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@intlify/core-base": {
|
||||||
|
"version": "11.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-11.1.1.tgz",
|
||||||
|
"integrity": "sha512-bb8gZvoeKExCI2r/NVCK9E4YyOkvYGaSCPxVZe8T0jz8aX+dHEOZWxK06Z/Y9mWRkJfBiCH4aOhDF1yr1t5J8Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@intlify/message-compiler": "11.1.1",
|
||||||
|
"@intlify/shared": "11.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/kazupon"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@intlify/message-compiler": {
|
||||||
|
"version": "11.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-11.1.1.tgz",
|
||||||
|
"integrity": "sha512-4iEsUZ3aF7jXY19CJFN5VP+pPyLITD9FVsjB13z9TU1UxaZLlFsmNhvRxlPDSOfHAP5RpNF2QKKdZ3DHVf4Yzw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@intlify/shared": "11.1.1",
|
||||||
|
"source-map-js": "^1.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/kazupon"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@intlify/shared": {
|
||||||
|
"version": "11.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-11.1.1.tgz",
|
||||||
|
"integrity": "sha512-2kGiWoXaeV8HZlhU/Nml12oTbhv7j2ufsJ5vQaa0VTjzUmZVdd/nmKFRAOJ/FtjO90Qba5AnZDwsrY7ZND5udA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/kazupon"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@isaacs/cliui": {
|
"node_modules/@isaacs/cliui": {
|
||||||
"version": "8.0.2",
|
"version": "8.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
||||||
@@ -1792,6 +1840,35 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@signaldb/core": {
|
||||||
|
"version": "1.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@signaldb/core/-/core-1.3.1.tgz",
|
||||||
|
"integrity": "sha512-6w1bnYS1LcnbQi9rAXo61fT2eYm1Anzbs4l+Ca2uTBJOerj5zGQSIysrc8bRfPInUvuebsS0kc9kwJcaZnFa8g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"fast-sort": "^3.4.1",
|
||||||
|
"mingo": "^6.5.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@signaldb/indexeddb": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@signaldb/indexeddb/-/indexeddb-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-hqRt/ZeMBJXYqQNtalhT6R2fRlmT5niOXwIzaZ7mOV74YoyDOFyu7zk47GIGnFn3D84qQ3fhHBdFeyyf213uTg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@signaldb/core": "1.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@signaldb/vue": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@signaldb/vue/-/vue-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-VWm1XY+hfnbA7xAA3LSILadN5w7auIfPKSsGJ16duTtRWnTsjgaUJBKIa2GkxxgVoYregoqh9L5wdi+vhAxNAQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@signaldb/core": "1.x",
|
||||||
|
"vue": "3.x.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@sindresorhus/merge-streams": {
|
"node_modules/@sindresorhus/merge-streams": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz",
|
||||||
@@ -3725,6 +3802,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-sort": {
|
||||||
|
"version": "3.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-sort/-/fast-sort-3.4.1.tgz",
|
||||||
|
"integrity": "sha512-76uvGPsF6So53sZAqenP9UVT3p5l7cyTHkLWVCMinh41Y8NDrK1IYXJgaBMfc1gk7nJiSRZp676kddFG2Aa5+A==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/fastq": {
|
"node_modules/fastq": {
|
||||||
"version": "1.19.1",
|
"version": "1.19.1",
|
||||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
|
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
|
||||||
@@ -4725,6 +4808,12 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mingo": {
|
||||||
|
"version": "6.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/mingo/-/mingo-6.5.3.tgz",
|
||||||
|
"integrity": "sha512-jp8AhCM871cDUZLTXt9jTsA5rwW74Zp+mYnbMO97PZCpVKI2UOhAamszpZp1wuXJOBnKiEQfkpGsEHj4AmadOg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/minimatch": {
|
"node_modules/minimatch": {
|
||||||
"version": "9.0.5",
|
"version": "9.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||||
@@ -6392,6 +6481,32 @@
|
|||||||
"url": "https://opencollective.com/eslint"
|
"url": "https://opencollective.com/eslint"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vue-i18n": {
|
||||||
|
"version": "11.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-11.1.1.tgz",
|
||||||
|
"integrity": "sha512-0P6DkKy96R4Wh2sIZJEHw8ivnlD1pnB6Ib/eldoF1SUpQutfKZv6aMqZwICS1gW0rwq24ZSXw7y3jW+PRVYqWA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@intlify/core-base": "11.1.1",
|
||||||
|
"@intlify/shared": "11.1.1",
|
||||||
|
"@vue/devtools-api": "^6.5.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/kazupon"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"vue": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/vue-i18n/node_modules/@vue/devtools-api": {
|
||||||
|
"version": "6.6.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
|
||||||
|
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/vue-router": {
|
"node_modules/vue-router": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.0.tgz",
|
||||||
|
|||||||
@@ -14,8 +14,12 @@
|
|||||||
"format": "prettier --write src/"
|
"format": "prettier --write src/"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@signaldb/core": "^1.3.1",
|
||||||
|
"@signaldb/indexeddb": "^1.0.0",
|
||||||
|
"@signaldb/vue": "^1.0.0",
|
||||||
"pinia": "^3.0.1",
|
"pinia": "^3.0.1",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
|
"vue-i18n": "^11.1.1",
|
||||||
"vue-router": "^4.5.0"
|
"vue-router": "^4.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
+18
-6
@@ -1,14 +1,9 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { RouterLink, RouterView } from 'vue-router'
|
|
||||||
import HelloWorld from './components/HelloWorld.vue'
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<header>
|
<header>
|
||||||
<img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" />
|
<img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" />
|
||||||
|
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<HelloWorld msg="You did it!" />
|
<HelloWorld :msg="$t('app.name')" />
|
||||||
|
|
||||||
<nav>
|
<nav>
|
||||||
<RouterLink to="/">Home</RouterLink>
|
<RouterLink to="/">Home</RouterLink>
|
||||||
@@ -20,6 +15,23 @@ import HelloWorld from './components/HelloWorld.vue'
|
|||||||
<RouterView />
|
<RouterView />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { RouterLink, RouterView } from 'vue-router'
|
||||||
|
import HelloWorld from './components/HelloWorld.vue'
|
||||||
|
import { posts } from '@/db';
|
||||||
|
|
||||||
|
// posts.insert({
|
||||||
|
// name: 'Wie geht es dir?'
|
||||||
|
// });
|
||||||
|
// posts.insert({
|
||||||
|
// name: 'How to do not suck!'
|
||||||
|
// })
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
console.info(posts.find().fetch());
|
||||||
|
}, 0);
|
||||||
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
header {
|
header {
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import { createPersistenceAdapter } from '@signaldb/core'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a persistence adapter for managing a SignalDB collection using IndexedDB.
|
||||||
|
* This adapter reads and writes data to an IndexedDB object store, with customizable serialization and deserialization.
|
||||||
|
* @template T - The type of the items in the collection.
|
||||||
|
* @template I - The type of the unique identifier for the items.
|
||||||
|
* @param name - A unique name for the collection, used as the database name.
|
||||||
|
* @returns A SignalDB persistence adapter for managing data in IndexedDB.
|
||||||
|
*/
|
||||||
|
export default function createIndexedDBAdapter<
|
||||||
|
T extends { id: I } & Record<string, any>,
|
||||||
|
I extends IDBValidKey,
|
||||||
|
>(name: string) {
|
||||||
|
const databaseName = `just-${name}`
|
||||||
|
const storeName = 'items'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the IndexedDB database and creates the object store if it doesn't exist.
|
||||||
|
* @returns A promise that resolves with the opened database.
|
||||||
|
*/
|
||||||
|
function openDatabase(): Promise<IDBDatabase> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const request = indexedDB.open(databaseName, 1)
|
||||||
|
request.addEventListener('upgradeneeded', () => {
|
||||||
|
const database = request.result
|
||||||
|
if (!database.objectStoreNames.contains(storeName)) {
|
||||||
|
database.createObjectStore(storeName, { keyPath: 'id' })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
request.addEventListener('success', () => resolve(request.result))
|
||||||
|
request.addEventListener('error', () => reject(new Error(request.error?.message || 'Database error')))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all items from the IndexedDB object store.
|
||||||
|
* @returns A promise that resolves with an array of items.
|
||||||
|
*/
|
||||||
|
async function getAllItems(): Promise<T[]> {
|
||||||
|
const database = await openDatabase()
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const transaction = database.transaction(storeName, 'readonly')
|
||||||
|
const store = transaction.objectStore(storeName)
|
||||||
|
const request = store.getAll()
|
||||||
|
request.addEventListener('success', () => resolve(request.result as T[]))
|
||||||
|
request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error fetching items')))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return createPersistenceAdapter<T, I>({
|
||||||
|
async load() {
|
||||||
|
const items = await getAllItems()
|
||||||
|
return { items }
|
||||||
|
},
|
||||||
|
async save(items, { added, modified, removed }) {
|
||||||
|
const database = await openDatabase()
|
||||||
|
const transaction = database.transaction(storeName, 'readwrite')
|
||||||
|
const store = transaction.objectStore(storeName)
|
||||||
|
|
||||||
|
added.forEach(item => store.add(item))
|
||||||
|
modified.forEach(item => store.put(item))
|
||||||
|
removed.forEach(item => store.delete(item.id))
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
transaction.addEventListener('complete', () => resolve())
|
||||||
|
transaction.addEventListener('error', () => reject(new Error(transaction.error?.message || 'Transaction error')))
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async register() {
|
||||||
|
return
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { Collection } from '@signaldb/core'
|
||||||
|
import { type Post } from '@/models';
|
||||||
|
import createIndexedDBAdapter from './createIndexedDBAdapter';
|
||||||
|
|
||||||
|
const posts = new Collection<Post>({
|
||||||
|
persistence: createIndexedDBAdapter('posts')
|
||||||
|
});
|
||||||
|
|
||||||
|
export {
|
||||||
|
posts,
|
||||||
|
createIndexedDBAdapter
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"app.name": "Just"
|
||||||
|
}
|
||||||
+10
-2
@@ -1,14 +1,22 @@
|
|||||||
import './assets/main.css'
|
|
||||||
|
|
||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import { createPinia } from 'pinia'
|
import { createPinia } from 'pinia'
|
||||||
|
import { createI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
import './assets/main.css'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import router from './router'
|
import router from './router'
|
||||||
|
import en_translations from './locales/en.json'
|
||||||
|
type en_messageSchema = typeof en_translations
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
|
|
||||||
app.use(createPinia())
|
app.use(createPinia())
|
||||||
|
app.use(createI18n<[en_messageSchema], 'en'>({
|
||||||
|
locale: 'en',
|
||||||
|
messages: {
|
||||||
|
en: en_translations
|
||||||
|
}
|
||||||
|
}));
|
||||||
app.use(router)
|
app.use(router)
|
||||||
|
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
export { type Post } from './post'
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
export type Post = {
|
||||||
|
id: string,
|
||||||
|
name: string
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user