UNPKG

@logux/client

Version:

Logux base components to build web client

199 lines (188 loc) 4.68 kB
import type { LoguxNotFoundError, SyncMapValues } from '@logux/actions' import type { StoreValue } from 'nanostores' import type { App, Component, ComponentPublicInstance, ComputedRef, DeepReadonly, InjectionKey, Ref } from 'vue' import type { Client } from '../client/index.js' import type { Filter, FilterOptions, FilterStore } from '../create-filter/index.js' import type { ChannelError } from '../logux-undo-error/index.js' import type { SyncMapTemplate, SyncMapTemplateLike, SyncMapValue } from '../sync-map-template/index.js' export type Refable<Type> = Ref<Type> | Type type ReadonlyRef<Type> = DeepReadonly<Ref<Type>> export const ClientKey: InjectionKey<Client> export const ErrorsKey: InjectionKey<ChannelErrorsSlotProps> /** * Plugin that injects Logux Client into all components within the application. * * ```js * import { createApp } from 'vue' * import { loguxPlugin } from '@logux/client/vue' * import { CrossTabClient } from '@logux/client' * * let client = new CrossTabClient(…) * let app = createApp(…) * * app.use(loguxPlugin, client) * ``` */ export function loguxPlugin(app: App, client: Client): void /** * Returns the Logux Client instance. * * ```html * <script> * import { useClient } from '@logux/client/vue' * * import { User } from '../stores/user' * * let client = useClient() * let onAdd = data => { * User.create(client, data) * } * </script> * ``` */ export function useClient(): Client /** * Create store by ID, subscribe to store changes and get store’s value. * * ```html * <template> * <loader v-if="user.isLoading" /> * <h1 v-else>{{ user.name }}</h1> * </template> * * <script> * import { useSync } from '@logux/client/vue' * * import { User } from '../stores/user' * * export default { * props: ['id'], * setup (props) { * let user = useSync(User, props.id) * return { user } * } * } * </script> * ``` * * @param Template Store template. * @param id Store ID. * @param args Other store arguments. * @returns Store value. */ export function useSync<Value extends SyncMapValues>( Template: SyncMapTemplate<Value> | SyncMapTemplateLike<Value>, id: Refable<string> ): ReadonlyRef<SyncMapValue<Value>> export function useSync<Value extends object, Args extends any[]>( Template: SyncMapTemplate<Value> | SyncMapTemplateLike<Value, Args>, id: Refable<string>, ...args: Args ): ReadonlyRef<Value> /** * The way to {@link createFilter} in Vue. * * ```html * <template> * <loader v-if="users.isLoading" /> * <user v-else v-for="user in users" :user="user" /> * </template> * * <script> * import { useFilter } from '@logux/client/vue' * * import { User } from '../stores/user' * * export default { * props: ['projectId'], * setup (props) { * let users = useFilter(User, { projectId: props.projectId }) * return { users } * } * } * </script> * ``` * * @param Template Store class. * @param filter Key-value filter for stores. * @param opts Filter options. * @returns Filter store to use with map. */ export function useFilter<Value extends SyncMapValues>( Template: SyncMapTemplate<Value> | SyncMapTemplateLike<Value>, filter?: Refable<Filter<Value>>, opts?: Refable<FilterOptions> ): ReadonlyRef<StoreValue<FilterStore<Value>>> /** * Show error message to user on subscription errors in components * deep in the tree. * * ```html * <template> * <channel-errors v-slot="{ code, error }"> * <layout v-if="!error" /> * <error v-else-if="code === 500" /> * <error-not-found v-else-if="code === 404" /> * <error-access-denied v-else-if="code === 403" /> * </channel-errors> * </template> * * <script> * import { ChannelErrors } from '@logux/client/vue' * * export default { * components: { ChannelErrors } * } * </script> * ``` */ export const ChannelErrors: Component export interface ChannelErrorsSlotProps { code: ReadonlyRef<number | undefined> error: ReadonlyRef<{ data: ChannelError | LoguxNotFoundError info: string instance: ComponentPublicInstance } | null> } /** * Returns user's current authentication state and ID. * * ```html * <template> * <user v-if="isAuthenticated" :id="userId" /> * <sign-in v-else /> * </template> * * <script> * import { useAuth } from '@logux/client/vue' * * export default () => { * let { isAuthenticated, userId } = useAuth() * return { isAuthenticated, userId } * } * </script> * ``` * * @param client Logux Client instance. */ export function useAuth(client?: Client): { isAuthenticated: ComputedRef<boolean> userId: ComputedRef<string> }