Skip to content

Vue: useKizunaSync

useKizunaSync returns the IKizunaSync client the rest of the composables read. An explicit { client } override wins when the caller passes one. The provided instance is the default. With neither in place the composable throws, rather than returning a silent undefined.

Examples#

Basic#

<!-- src/components/SyncButton.vue -->
<script setup lang="ts">
import { useKizunaSync } from 'kizunasync/vue'

const kizunasync = useKizunaSync()
</script>

<template>
  <button type="button" @click="kizunasync.sync()">Sync now</button>
</template>

Override the provided client#

A component that takes an optional client prop reads that client when a parent passes one, and the provided client otherwise.

<!-- src/components/OutboxBadge.vue -->
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import type { IKizunaSync } from 'kizunasync'
import { useKizunaSync } from 'kizunasync/vue'

const props = defineProps<{ client?: IKizunaSync }>()
const kizunasync = useKizunaSync({ client: props.client })
const depth = ref(0)

onMounted(async () => {
  depth.value = await kizunasync.getOutboxDepth()
})
</script>

<template>
  <span>{{ depth }} waiting</span>
</template>

Parameters#

NameTypeRequiredDescription
optsIUseKizunaSyncOptionsNoThe single-property override object. Default: the provided client.
opts.clientIKizunaSyncNoUsed instead of the provided client for this call. Every other composable accepts the same property, so a subtree can read a second client without a second provider. Default: the value seeded by createKizunaSyncPlugin or provideKizunaSync.

Returns#

IKizunaSync, the client instance itself. Its members are documented field by field in JavaScript: Initializing; the composables in this package wrap the ones a component usually needs.

Composables in this package, and the client members each one wraps:

NameTypeRequiredDescription
useQuery(build, opts?) => IUseQueryResult<T>—Wraps from(table).select(...) and re-reads on every engine event. See useQuery.
useMutation(opts?) => IUseMutationResult—Wraps any write run against from(table). See useMutation.
useSyncStatus(opts?) => IUseSyncStatusResult—Wraps getOutboxDepth, getCheckpoint, getSyncHealth, onSyncHealth, and sync. See useSyncStatus.
useAttachment(ref, opts?) => IUseAttachmentResult—Wraps attachments.getStatus, attachments.watch, and attachments.resolveDownload. See useAttachment.
useRejections(opts?) => IUseRejectionsResult—Wraps rejections and dismissRejection. See useRejections.
useOverwrites(opts?) => IUseOverwritesResult—Wraps overwrites and dismissOverwrite. See useOverwrites.

useKizunaSync is the way to reach everything else: setBucket for a byColumn bucket, pullOnce and pushOnce for one half of a cycle, reset, and attachments.fromFile when a picker returns a file.

A byOwner bucket needs no setBucket call. The engine fills it with the user id of the signed-in session, which Supabase describes in What is a session. Kizuna reads only that id, as a pull parameter and never as an authorization decision, because the server judges every row under its own policies.

Errors#

useKizunaSync throws an Error when the composable runs outside the provide scope and passes no override.

useKizunaSync: no Kizuna client found. Pass an explicit { client }, or provide one from an ancestor: <KizunaSyncProvider client={kizunasync}> in React, provideKizunaSync(kizunasync) in Vue.

The same error surfaces from every other composable, because each one resolves its client through this function. kizunasync exports the text as MISSING_CLIENT_MESSAGE and both bindings throw it, so React: useKizunaSync fails with the same string and names both entry points.

Notes#

inject only works during setup(), so call useKizunaSync there rather than inside an event handler. The client it returns is a plain object, not a ref, and it stays the same instance for the life of the provide scope.

Calling kizunasync.sync() from a handler is a manual run alongside the automatic loop. Each call reaches the engine and runs a full cycle of its own, which Sync describes; only the scheduler's automatic ticks coalesce.

Found a problem? Edit this page on GitHub