chore: restructure vue-sync-engine workspace and remove unused files
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
import { inject, type InjectionKey } from 'vue'
|
||||
import type { TabRuntime } from '../tab/runtime'
|
||||
|
||||
export const EngineKey: InjectionKey<TabRuntime> = Symbol('SyncEngine')
|
||||
|
||||
export function useEngine(): TabRuntime {
|
||||
const rt = inject(EngineKey)
|
||||
if (!rt) throw new Error('SyncEngine is not provided. Call app.provide(EngineKey, runtime).')
|
||||
return rt
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { computed, type ComputedRef, type MaybeRefOrGetter, toValue } from 'vue'
|
||||
import type { EntityDef, EntityId } from '../core/types'
|
||||
import { useEngine } from './useEngine'
|
||||
|
||||
export function useEntity<T>(
|
||||
def: EntityDef<T>,
|
||||
id: MaybeRefOrGetter<EntityId | undefined>,
|
||||
): ComputedRef<T | undefined> {
|
||||
const engine = useEngine()
|
||||
return computed(() => {
|
||||
const v = toValue(id)
|
||||
if (v === undefined || v === null) return undefined
|
||||
return engine.mirror.getEntity<T>(def.name, v)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import { computed, onScopeDispose, watch, type ComputedRef, type MaybeRefOrGetter, toValue } from 'vue'
|
||||
import type { InfiniteQueryDef, QueryStatus } from '../core/types'
|
||||
import { Status } from '../core/flags'
|
||||
import { hashKey } from '../core/queryKey'
|
||||
import { useEngine } from './useEngine'
|
||||
|
||||
export interface UseInfiniteQueryReturn<TResult> {
|
||||
pages: ComputedRef<TResult[]>
|
||||
pageParams: ComputedRef<unknown[]>
|
||||
status: ComputedRef<QueryStatus>
|
||||
error: ComputedRef<{ message: string } | undefined>
|
||||
isLoading: ComputedRef<boolean>
|
||||
fetchNextPage: () => void
|
||||
}
|
||||
|
||||
interface InfinitePayload<T> {
|
||||
pages: T[]
|
||||
pageParams: unknown[]
|
||||
}
|
||||
|
||||
export function useInfiniteQuery<TArgs, TResp, TPageParam, TResult>(
|
||||
def: InfiniteQueryDef<TArgs, TResp, TPageParam, TResult> & { name: string },
|
||||
args: MaybeRefOrGetter<TArgs>,
|
||||
): UseInfiniteQueryReturn<TResult> {
|
||||
const engine = useEngine()
|
||||
|
||||
const initial = toValue(args)
|
||||
let handle = engine.subscribeQuery(def.name, def.key(initial), initial)
|
||||
let stateRef = engine.mirror.ensureQuery<InfinitePayload<TResult>>(handle.subId)
|
||||
|
||||
if (!def.staticHash) {
|
||||
watch(
|
||||
() => hashKey(def.key(toValue(args))),
|
||||
() => {
|
||||
const next = toValue(args)
|
||||
const prev = handle
|
||||
handle = engine.subscribeQuery(def.name, def.key(next), next)
|
||||
stateRef = engine.mirror.ensureQuery<InfinitePayload<TResult>>(handle.subId)
|
||||
prev.release()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
onScopeDispose(() => handle.release())
|
||||
|
||||
return {
|
||||
pages: computed(() => stateRef.value.data?.pages ?? []),
|
||||
pageParams: computed(() => stateRef.value.data?.pageParams ?? []),
|
||||
status: computed(() => stateRef.value.status),
|
||||
error: computed(() => stateRef.value.error),
|
||||
isLoading: computed(() => stateRef.value.status === Status.Pending),
|
||||
fetchNextPage: () => handle.fetchNextPage(),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import { shallowRef, type ShallowRef } from 'vue'
|
||||
import type { MutationDef, QueryStatus } from '../core/types'
|
||||
import { Status } from '../core/flags'
|
||||
import { useEngine } from './useEngine'
|
||||
|
||||
export interface UseMutationReturn<TInput, TResp> {
|
||||
mutate: (input: TInput) => void
|
||||
mutateAsync: (input: TInput) => Promise<TResp>
|
||||
status: ShallowRef<QueryStatus>
|
||||
error: ShallowRef<Error | undefined>
|
||||
data: ShallowRef<TResp | undefined>
|
||||
}
|
||||
|
||||
export function useMutation<TInput, TResp>(
|
||||
def: MutationDef<TInput, TResp>,
|
||||
): UseMutationReturn<TInput, TResp> {
|
||||
const engine = useEngine()
|
||||
const status = shallowRef<QueryStatus>(Status.Idle)
|
||||
const error = shallowRef<Error | undefined>(undefined)
|
||||
const data = shallowRef<TResp | undefined>(undefined)
|
||||
|
||||
async function mutateAsync(input: TInput): Promise<TResp> {
|
||||
status.value = Status.Pending
|
||||
error.value = undefined
|
||||
try {
|
||||
const resp = (await engine.mutate(def.name, input)) as TResp
|
||||
data.value = resp
|
||||
status.value = Status.Success
|
||||
return resp
|
||||
} catch (e) {
|
||||
error.value = e as Error
|
||||
status.value = Status.Error
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
function mutate(input: TInput): void {
|
||||
void mutateAsync(input).catch(() => {})
|
||||
}
|
||||
|
||||
return { mutate, mutateAsync, status, error, data }
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import { computed, onScopeDispose, watch, type ComputedRef, type MaybeRefOrGetter, toValue } from 'vue'
|
||||
import type { InfiniteQueryDef, QueryDef, QueryStatus } from '../core/types'
|
||||
import { Status } from '../core/flags'
|
||||
import { hashKey } from '../core/queryKey'
|
||||
import { useEngine } from './useEngine'
|
||||
|
||||
export interface UseQueryReturn<T> {
|
||||
data: ComputedRef<T | undefined>
|
||||
status: ComputedRef<QueryStatus>
|
||||
error: ComputedRef<{ message: string } | undefined>
|
||||
isLoading: ComputedRef<boolean>
|
||||
isSuccess: ComputedRef<boolean>
|
||||
isError: ComputedRef<boolean>
|
||||
}
|
||||
|
||||
export function useQuery<TArgs, TResp, TResult>(
|
||||
def: (QueryDef<TArgs, TResp, TResult> | InfiniteQueryDef<TArgs, TResp, any, TResult>) & { name: string },
|
||||
args: MaybeRefOrGetter<TArgs>,
|
||||
): UseQueryReturn<TResult> {
|
||||
const engine = useEngine()
|
||||
|
||||
const initial = toValue(args)
|
||||
let currentHandle = engine.subscribeQuery(def.name, def.key(initial), initial)
|
||||
let currentRef = engine.mirror.ensureQuery<TResult>(currentHandle.subId)
|
||||
|
||||
if (!def.staticHash) {
|
||||
watch(
|
||||
() => hashKey(def.key(toValue(args))),
|
||||
() => {
|
||||
const next = toValue(args)
|
||||
const prev = currentHandle
|
||||
currentHandle = engine.subscribeQuery(def.name, def.key(next), next)
|
||||
currentRef = engine.mirror.ensureQuery<TResult>(currentHandle.subId)
|
||||
prev.release()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
onScopeDispose(() => currentHandle.release())
|
||||
|
||||
return {
|
||||
data: computed(() => currentRef.value.data),
|
||||
status: computed(() => currentRef.value.status),
|
||||
error: computed(() => currentRef.value.error),
|
||||
isLoading: computed(() => currentRef.value.status === Status.Pending),
|
||||
isSuccess: computed(() => currentRef.value.status === Status.Success),
|
||||
isError: computed(() => currentRef.value.status === Status.Error),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user