Wild
Wild
Explore posts from servers
SSolidJS
Created by Wild on 9/16/2024 in #support
Create one global store with multiple createResource
Hello, I am a beginner programmer developing a small local app with Tauri and SolidStart. In the past, I have already worked on a personal website with Nuxt/Vue/Pinia. The data being exclusively stored on a local sqlite database, I am trying to load all the data from the start of the program execution, and intend to make it available to all components from a store. How do I initialize my store within context with createResource ? my context is undefined I've made sure the data fetching part works. I tried to wrap the AppContext.Provider with Suspense, my guess being the async is messing things up here. Thank you
export type AppContextType = {
store: Store<any>;
setStore: SetStoreFunction<any>;
};

const AppContext = createContext<AppContextType>();

async function fetchDbData<T>(query: string) {
const db = await Database.load("sqlite:mydatabase.db");
return await db.select<T[]>(query);
}

const categories = createResource(async () =>
fetchDbData<Category>("SELECT * FROM category;"),
)[0]();

const items = createResource(async () =>
fetchDbData<Item>("SELECT * FROM item;"),
)[0]();

export const AppProvider: Component<any> = (props: any) => {
// function createDeepSignal<T>(value: T): Signal<T> {
// const [store, setStore] = createStore({
// value,
// });
// return [
// () => store.value,
// (v: T) => {
// const unwrapped = unwrap(store.value);
// typeof v === "function" && (v = v(unwrapped));
// setStore("value", reconcile(v));
// return store.value;
// },
// ] as Signal<T>;
// }

const [store, setStore] = createStore(
{
categories,
items
});
return (
<AppContext.Provider value={{ store, setStore }}>
{props.children}
</AppContext.Provider>
);
};

export const useStore = () => {
const context = useContext(AppContext);
if (!context) throw new Error("AppContext is not valid");
return context;
};
export type AppContextType = {
store: Store<any>;
setStore: SetStoreFunction<any>;
};

const AppContext = createContext<AppContextType>();

async function fetchDbData<T>(query: string) {
const db = await Database.load("sqlite:mydatabase.db");
return await db.select<T[]>(query);
}

const categories = createResource(async () =>
fetchDbData<Category>("SELECT * FROM category;"),
)[0]();

const items = createResource(async () =>
fetchDbData<Item>("SELECT * FROM item;"),
)[0]();

export const AppProvider: Component<any> = (props: any) => {
// function createDeepSignal<T>(value: T): Signal<T> {
// const [store, setStore] = createStore({
// value,
// });
// return [
// () => store.value,
// (v: T) => {
// const unwrapped = unwrap(store.value);
// typeof v === "function" && (v = v(unwrapped));
// setStore("value", reconcile(v));
// return store.value;
// },
// ] as Signal<T>;
// }

const [store, setStore] = createStore(
{
categories,
items
});
return (
<AppContext.Provider value={{ store, setStore }}>
{props.children}
</AppContext.Provider>
);
};

export const useStore = () => {
const context = useContext(AppContext);
if (!context) throw new Error("AppContext is not valid");
return context;
};
3 replies
NNuxt
Created by Wild on 5/3/2024 in #❓・help
useASyncData & watch issue
Hello friends, I've been having a hard time using watch. I've finally found a suitable ref for watch, but the refresh is too late. My store update but what is displayed is one step behind. If i change the lang from fr to en, it'll show fr, and from en to es, it'll show es. What am I missing ? If I use a plugin with
nuxtApp.hook('i18n:localeSwitched',
nuxtApp.hook('i18n:localeSwitched',
and manually call refresh, it works as I would like it to. Thanks for your time !
import { JobActionsLocal } from "./proto/job_action";
const key = 'job_action'

export const useJobActionStore = defineStore(key, () => {
function mapper(data: JobAction[]) {
return new Map(
data.map((raw) => {
return [raw.uid, raw]
})
)
}

const { locale } = useI18n()

const {data: actions, pending, error, refresh: clear_cache} = useAsyncData(
key,
() => ifetch(key, `jobs/actions`, JobActionsLocal, mapper),
{
server: false,
lazy: true,
watch: [locale],
deep: false
}
)

return {actions}
})

if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(useJobStore, import.meta.hot))
}
import { JobActionsLocal } from "./proto/job_action";
const key = 'job_action'

export const useJobActionStore = defineStore(key, () => {
function mapper(data: JobAction[]) {
return new Map(
data.map((raw) => {
return [raw.uid, raw]
})
)
}

const { locale } = useI18n()

const {data: actions, pending, error, refresh: clear_cache} = useAsyncData(
key,
() => ifetch(key, `jobs/actions`, JobActionsLocal, mapper),
{
server: false,
lazy: true,
watch: [locale],
deep: false
}
)

return {actions}
})

if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(useJobStore, import.meta.hot))
}
2 replies
NNuxt
Created by Wild on 5/1/2024 in #❓・help
Is it possible to initialize store state with async function ?
Hello friends, I am trying to set up my store from indexedDb. I've seen an example with useLocalStorage from vueUse, but how can I make it works with custom function ? Thank for the help
8 replies
NNuxt
Created by Wild on 4/27/2024 in #❓・help
How to share an indexedDb
Hello friends, pretty new to nuxt and js/ts, so maybe a trivial question there, forgive me. How do I instantiate an indexedb and access it through all of my nuxt app ? Many thanks
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hooks.hookOnce('app:suspense:resolve', () => {
isHydrated.value = true

const db_open_request = window.indexedDB.open("app");
db_open_request.onerror = (event) => {
let indexedDb = false
};
db_open_request.onupgradeneeded = (event) => {
const db = event.target!.result
const objectStore = db.createObjectStore("data");
}
db_open_request.onsuccess = (event) => {
let ddb = event.target!.result // how do I share this
let indexedDb = true // and maybe this too

ddb.onerror = (event: Event) => {
console.error(`Database error: ${event.target!.errorCode}`);
};
};

})
})
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hooks.hookOnce('app:suspense:resolve', () => {
isHydrated.value = true

const db_open_request = window.indexedDB.open("app");
db_open_request.onerror = (event) => {
let indexedDb = false
};
db_open_request.onupgradeneeded = (event) => {
const db = event.target!.result
const objectStore = db.createObjectStore("data");
}
db_open_request.onsuccess = (event) => {
let ddb = event.target!.result // how do I share this
let indexedDb = true // and maybe this too

ddb.onerror = (event: Event) => {
console.error(`Database error: ${event.target!.errorCode}`);
};
};

})
})
53 replies
NNuxt
Created by Wild on 4/24/2024 in #❓・help
useFetch triggers on ssr while server: false ?
I put console.log in my useFetch, and I can see that getCachedData get triggered twice while on ssr. Why is that and how can i prevent this ? Thanks
// /stores/items.ts
export const useItemStore = defineStore('items', () => {
const key = 'items'
const lang = computed(() => {return useCookieLocale().value})
const {data: items, refresh} = useFetch(
`https://api.profus.net/datacenter/dofus2/items`,
{
method: 'GET',
params: {
lang: lang
},
key: key,
server: false,
lazy: true,
immediate: false,
deep: false,
transform(raw_items:Item[]) {
return new Map<number, Item>(
raw_items.map(raw_item => {
return [raw_item.id, raw_item];
}),)
},
getCachedData(key, nuxtapp) {
if (nuxtapp.static.data[key] !== undefined) {
console.log({step: 'static'})
return nuxtapp.static.data[key]
}
if (process.client) {
if (localStorage.hasOwnProperty(key)) {
const arr_buffer = JSON.parse(localStorage.getItem(key))
let map_buffer = new Map<number, Item>(
arr_buffer.map(raw_item => {
return [raw_item.id, raw_item];
})
)
console.log({step: 'localstorage'})
nuxtapp.static.data[key] = map_buffer
return map_buffer
}
else {
return null
}
}
console.log({step: 'not cached'})
return {}
},
onResponse({ request, response, options }) {
console.log({step: 'resp'})
localStorage.setItem('items', JSON.stringify(response._data))
},
},
)

async function clear_cache() {
await refresh()
}

onHydrated(async () => {
const nuxtApp = useNuxtApp()
if (!localStorage.hasOwnProperty(key) || items.value == null) {
await refresh()
}
})

return {items, clear_cache}
})

}
// /stores/items.ts
export const useItemStore = defineStore('items', () => {
const key = 'items'
const lang = computed(() => {return useCookieLocale().value})
const {data: items, refresh} = useFetch(
`https://api.profus.net/datacenter/dofus2/items`,
{
method: 'GET',
params: {
lang: lang
},
key: key,
server: false,
lazy: true,
immediate: false,
deep: false,
transform(raw_items:Item[]) {
return new Map<number, Item>(
raw_items.map(raw_item => {
return [raw_item.id, raw_item];
}),)
},
getCachedData(key, nuxtapp) {
if (nuxtapp.static.data[key] !== undefined) {
console.log({step: 'static'})
return nuxtapp.static.data[key]
}
if (process.client) {
if (localStorage.hasOwnProperty(key)) {
const arr_buffer = JSON.parse(localStorage.getItem(key))
let map_buffer = new Map<number, Item>(
arr_buffer.map(raw_item => {
return [raw_item.id, raw_item];
})
)
console.log({step: 'localstorage'})
nuxtapp.static.data[key] = map_buffer
return map_buffer
}
else {
return null
}
}
console.log({step: 'not cached'})
return {}
},
onResponse({ request, response, options }) {
console.log({step: 'resp'})
localStorage.setItem('items', JSON.stringify(response._data))
},
},
)

async function clear_cache() {
await refresh()
}

onHydrated(async () => {
const nuxtApp = useNuxtApp()
if (!localStorage.hasOwnProperty(key) || items.value == null) {
await refresh()
}
})

return {items, clear_cache}
})

}
3 replies
NNuxt
Created by Wild on 4/23/2024 in #❓・help
Need some help about useFetch usage
Hello friends, anyone knows why a useFetch would trigger once on the client although the getCachedData return data from localstorage ? I got getCachedData into getCachedData into onReponse into Transform. Some code since it might help :
export const useItemStore = defineStore('items', () => {
const lang = computed(() => {return useCookieLocale().value})
const {data: items, refresh} = useFetch(
`some url`,
{
method: 'GET',
params: {
lang: lang,
limit: 25000
},
headers: { 'Content-Type': 'application/json' },
key: "items",
server: false,
lazy: true,
immediate: false,
deep: false,
transform(raw_items:Item[]) {
console.log({step: 'transform', data: raw_items})
return new Map(
raw_items.map(raw_item => {
return [raw_item.id, raw_item];
}),)
},
getCachedData(key) {
if (localStorage.hasOwnProperty(key)) {
const buffer = JSON.parse(localStorage.getItem(key))
console.log({step: 'buffer', data: buffer})
return buffer
}
},
onResponse({ request, response, options }) {
console.log({step: 'resp', data: response._data})
localStorage.setItem('items', JSON.stringify(response._data))
return response._data
},
},
)

async function clear_cache() {
localStorage.removeItem('items')
await refresh()
}

onHydrated(async () => {
await refresh();
})

return {items, clear_cache}
})

if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(useItemStore, import.meta.hot))
}
export const useItemStore = defineStore('items', () => {
const lang = computed(() => {return useCookieLocale().value})
const {data: items, refresh} = useFetch(
`some url`,
{
method: 'GET',
params: {
lang: lang,
limit: 25000
},
headers: { 'Content-Type': 'application/json' },
key: "items",
server: false,
lazy: true,
immediate: false,
deep: false,
transform(raw_items:Item[]) {
console.log({step: 'transform', data: raw_items})
return new Map(
raw_items.map(raw_item => {
return [raw_item.id, raw_item];
}),)
},
getCachedData(key) {
if (localStorage.hasOwnProperty(key)) {
const buffer = JSON.parse(localStorage.getItem(key))
console.log({step: 'buffer', data: buffer})
return buffer
}
},
onResponse({ request, response, options }) {
console.log({step: 'resp', data: response._data})
localStorage.setItem('items', JSON.stringify(response._data))
return response._data
},
},
)

async function clear_cache() {
localStorage.removeItem('items')
await refresh()
}

onHydrated(async () => {
await refresh();
})

return {items, clear_cache}
})

if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(useItemStore, import.meta.hot))
}
2 replies
NNuxt
Created by Wild on 4/20/2024 in #❓・help
Data Fetching, Store and LocalStorage
Hello friends, I am trying to understand the store lifecycle, but I have yet to find a good article / document on the topic. I understand that there is data fetching from the server and from the client. I was originally planning to set up a store and initializing some state from the server, for website often-updated data with usefetch server true, and some persitent data with a mix of usefetch server false and localstorage. My issue is that I cannot control when the state is set up, and so localstorage and client side state initialization fails unless I use some kind of onMounted, getCurrentInstance and process.server shenanigans. I want control when the state is set up, because at the moment I just get an empty {} : the state try to initialize once, fails which is normal cause SSR. Should I just trigger some actions from the client ? This seems like a lot of boilerplate. Any relevant resource or document ? Is there a way to control when the store is set up ? How would you approach this kind of thing ? I was trying to keep things simple because all that's needed is a nicely timed localstorage getitem and setitem, but maybe I should look into some persisted state plugin. Thank you very much for your help, insight and time
7 replies