diff --git a/.changeset/shy-coins-give.md b/.changeset/shy-coins-give.md
new file mode 100644
index 00000000..ba3adbf4
--- /dev/null
+++ b/.changeset/shy-coins-give.md
@@ -0,0 +1,5 @@
+---
+'@electric-sql/pglite-vue': patch
+---
+
+Include both utility for typed injection and static injectors.
diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts
index 99c85c66..0644dde0 100644
--- a/docs/.vitepress/config.mts
+++ b/docs/.vitepress/config.mts
@@ -103,7 +103,10 @@ export default defineConfig({
link: '/react',
base: '/docs/framework-hooks',
collapsed: true,
- items: [{ text: 'React', link: '/react' }],
+ items: [
+ { text: 'React', link: '/react' },
+ { text: 'Vue', link: '/vue' },
+ ],
},
{ text: 'Multi-tab Worker', link: '/docs/multi-tab-worker' },
{ text: 'REPL Component', link: '/docs/repl' },
diff --git a/docs/docs/framework-hooks/vue.md b/docs/docs/framework-hooks/vue.md
new file mode 100644
index 00000000..b23e28e1
--- /dev/null
+++ b/docs/docs/framework-hooks/vue.md
@@ -0,0 +1,149 @@
+---
+outline: [2, 3]
+---
+
+# Vue
+
+To aid integration of PGlite into a [Vue](https://vuejs.org/) project we have a `providePGlite` with a corresponding `injectPGlite` and hooks for the [live query](../live-queries.md) plugin.
+
+### providePGlite
+
+The `providePGlite` API, which follows the [Vue provide / inject pattern](https://vuejs.org/guide/components/provide-inject), enables you to initiate a PGlite database and pass it to all child components for use with the corresponding [`injectPGlite`](#injectpglite) method, as well as with the [`useLiveQuery`](#uselivequery) and [`useLiveIncrementalQuery`](#useliveincrementalquery) hooks.
+
+To use it, pass a PGlite instance as the `db` property.
+
+```vue
+
+// ...
+```
+
+### injectPGlite
+
+You can retrieve the provided PGlite instance using `injectPGlite` and then query it from within your components.
+
+```vue
+
+
+
+ // ...
+
+ // ...
+
+```
+
+### makePGliteDependencyInjector
+
+The `makePGliteDependencyInjector` function returns typed versions of `providePGlite` and `injectPGlite`, which enables you to provide a PGlite instance with all added extensions and retain then namespaces and types added to it.
+
+```ts
+import { PGlite, PGliteInterfaceExtensions } from '@electric-sql/pglite'
+import { live } from '@electric-sql/pglite/live'
+import { vector } from '@electric-sql/pglite/vector'
+import { makePGliteDependencyInjector } from '@electric-sql/pglite-vue'
+
+const { providePGlite, injectPGlite } = makePGliteDependencyInjector<
+ PGlite &
+ PGliteInterfaceExtensions<{
+ live: typeof live
+ vector: typeof vector
+ }>
+>()
+
+export { providePGlite, injectPGlite }
+```
+
+### useLiveQuery
+
+The `useLiveQuery` hook enables you to reactively receive updates to the results of a live query change. It wraps the [`.live.query()`](../live-queries.md#livequery) API.
+
+It has the interface:
+
+```ts
+function useLiveQuery(
+ query: string | WatchSource,
+ params?: QueryParams | WatchSource,
+): LiveQueryResults
+```
+
+And its arguments, which can also be [watch sources](https://vuejs.org/guide/essentials/watchers.html#watch-source-types) that will trigger a re-run, are:
+
+1. the SQL query
+2. optional parameters for the query
+
+```vue
+
+
+
+
+
+```
+
+### useLiveIncrementalQuery
+
+The `useLiveIncrementalQuery` hook enables you to reactively receive updates whenever the results of a live query change. It wraps the [`.live.incrementalQuery()`](../live-queries.md#liveincrementalquery) API, which provides a way to efficiently diff the query results in Postgres.
+
+It has the interface:
+
+```ts
+export function useLiveIncrementalQuery(
+ query: string | WatchSource,
+ params: QueryParams | WatchSource,
+ key: string | WatchSource,
+): LiveQueryResults
+```
+
+And its arguments, which can also be [watch sources](https://vuejs.org/guide/essentials/watchers.html#watch-source-types) that will trigger a re-run, are:
+
+1. the SQL query
+2. optional parameters for the query
+3. the name of the column to key the diff algorithm on
+
+```vue
+
+
+
+
+
+```
diff --git a/packages/pglite-react/test/provider.test-d.tsx b/packages/pglite-react/test/provider.test-d.tsx
index 6cbe9f67..5f56cd87 100644
--- a/packages/pglite-react/test/provider.test-d.tsx
+++ b/packages/pglite-react/test/provider.test-d.tsx
@@ -1,5 +1,5 @@
import { describe, it, expectTypeOf } from 'vitest'
-import { PGlite } from '@electric-sql/pglite'
+import { PGlite, PGliteInterfaceExtensions } from '@electric-sql/pglite'
import { live } from '@electric-sql/pglite/live'
import { vector } from '@electric-sql/pglite/vector'
import { makePGliteProvider } from '../src/provider.js'
@@ -18,8 +18,13 @@ describe('provider', () => {
},
})
- const { PGliteProvider, usePGlite } =
- makePGliteProvider()
+ const { PGliteProvider, usePGlite } = makePGliteProvider<
+ PGlite &
+ PGliteInterfaceExtensions<{
+ live: typeof live
+ vector: typeof vector
+ }>
+ >()
// @ts-expect-error cannot pass db with just live extension
;() =>
diff --git a/packages/pglite-vue/README.md b/packages/pglite-vue/README.md
index c206a86c..4d690312 100644
--- a/packages/pglite-vue/README.md
+++ b/packages/pglite-vue/README.md
@@ -1,6 +1,6 @@
-# PGlite Vue.js Bindings
+# PGlite Vue Bindings
-This package implements Vue.js hooks for [PGLite](https://pglite.dev/) on top of the [live query plugin](https://pglite.dev/docs/live-queries). Full documentation is available at [pglite.dev/docs/framework-hooks](https://pglite.dev/docs/framework-hooks#react).
+This package implements Vue hooks for [PGLite](https://pglite.dev/) on top of the [live query plugin](https://pglite.dev/docs/live-queries). Full documentation is available at [pglite.dev/docs/framework-hooks](https://pglite.dev/docs/framework-hooks#react).
To install:
@@ -10,7 +10,8 @@ npm install @electric-sql/pglite-vue
The hooks this package provides are:
-- [proidePGlite](https://pglite.dev/docs/framework-hooks#providepglite): Provide a PGlite instance to all child components.
-- [injectPGlite](https://pglite.dev/docs/framework-hooks#injectpglite): Retrieve the provided PGlite instance.
+- [providePGlite](https://pglite.dev/docs/framework-hook/vuevye#providepglite): Provide a PGlite instance to all child components.
+- [injectPGlite](https://pglite.dev/docs/framework-hooks/vue#injectpglite): Retrieve the provided PGlite instance.
+- [makePGliteDependencyInjector](https://pglite.dev/docs/framework-hooks/vue#makepglitedependencyinjector): Utility to create a typed version of `providePGlite` and `injectPGlite`.
- [useLiveQuery](https://pglite.dev/docs/framework-hooks#uselivequery): Reactively receive results of a live query change
- [useLiveIncrementalQuery](https://pglite.dev/docs/framework-hooks#useliveincrementalquery): Reactively receive results of a live query change by offloading the diff to PGlite
diff --git a/packages/pglite-vue/package.json b/packages/pglite-vue/package.json
index 6e0fe0c5..6210e752 100644
--- a/packages/pglite-vue/package.json
+++ b/packages/pglite-vue/package.json
@@ -1,7 +1,7 @@
{
"name": "@electric-sql/pglite-vue",
"version": "0.2.0",
- "description": "Vue.js hooks for using PGlite",
+ "description": "Vue hooks for using PGlite",
"type": "module",
"private": false,
"publishConfig": {
diff --git a/packages/pglite-vue/src/dependency-injection.ts b/packages/pglite-vue/src/dependency-injection.ts
index 2a468b08..e4ea3c39 100644
--- a/packages/pglite-vue/src/dependency-injection.ts
+++ b/packages/pglite-vue/src/dependency-injection.ts
@@ -25,7 +25,7 @@ const PGliteKey = Symbol('PGliteProvider')
* @returns An object with two functions: `providePGlite` and `injectPGlite`.
*
*/
-export function makePGliteDependencyInjector<
+function makePGliteDependencyInjector<
T extends PGliteWithLive,
>(): PGliteDependencyInjection {
const providePGlite = (db: Ref | (T | undefined)): void =>
@@ -42,14 +42,7 @@ export function makePGliteDependencyInjector<
}
}
-/**
- * This "static" injector is used internally by our reactive methods
- * to get access to the provided PGlite instance.
- * It loses information about the extensions present on PGlite,
- * but we only need the `live` extension information for our methods.
- * However, users preferably don't lose extension type information,
- * therefore, they can use {@link makePGliteDependencyInjector}.
- */
-const { injectPGlite: injectPGliteUntyped } = makePGliteDependencyInjector()
+const { injectPGlite, providePGlite } =
+ makePGliteDependencyInjector()
-export { injectPGliteUntyped }
+export { makePGliteDependencyInjector, injectPGlite, providePGlite }
diff --git a/packages/pglite-vue/src/hooks.ts b/packages/pglite-vue/src/hooks.ts
index e30c8b7a..6233adf7 100644
--- a/packages/pglite-vue/src/hooks.ts
+++ b/packages/pglite-vue/src/hooks.ts
@@ -12,7 +12,7 @@ import {
isRef,
} from 'vue-demi'
import { Results } from '@electric-sql/pglite'
-import { injectPGliteUntyped } from './dependency-injection'
+import { injectPGlite } from './dependency-injection'
type UnsubscribeFn = () => Promise
type QueryParams = unknown[] | undefined | null
@@ -25,8 +25,8 @@ function useLiveQueryImpl(
query: string | WatchSource,
params?: QueryParams | WatchSource,
key?: string | WatchSource,
-): LiveQueryResults | undefined {
- const db = injectPGliteUntyped()!
+): LiveQueryResults {
+ const db = injectPGlite()!
const liveUpdate = shallowReactive<
| Omit, 'affectedRows'>
@@ -86,7 +86,7 @@ function useLiveQueryImpl(
export function useLiveQuery(
query: string | WatchSource,
params?: QueryParams | WatchSource,
-): LiveQueryResults | undefined {
+): LiveQueryResults {
return useLiveQueryImpl(query, params)
}
@@ -94,6 +94,6 @@ export function useLiveIncrementalQuery(
query: string | WatchSource,
params: QueryParams | WatchSource,
key: string | WatchSource,
-): LiveQueryResults | undefined {
+): LiveQueryResults {
return useLiveQueryImpl(query, params, key)
}
diff --git a/packages/pglite-vue/test/injection.test-d.ts b/packages/pglite-vue/test/injection.test-d.ts
index 7e78a4f3..472908a2 100644
--- a/packages/pglite-vue/test/injection.test-d.ts
+++ b/packages/pglite-vue/test/injection.test-d.ts
@@ -2,7 +2,7 @@
* @vitest-environment node
*/
import { describe, it, expectTypeOf } from 'vitest'
-import { PGlite } from '@electric-sql/pglite'
+import { PGlite, PGliteInterfaceExtensions } from '@electric-sql/pglite'
import { live } from '@electric-sql/pglite/live'
import { makePGliteDependencyInjector } from '../src'
import { vector } from '@electric-sql/pglite/vector'
@@ -21,8 +21,13 @@ describe('dependency injection', () => {
vector,
},
})
- const { providePGlite, injectPGlite } =
- makePGliteDependencyInjector()
+ const { providePGlite, injectPGlite } = makePGliteDependencyInjector<
+ PGlite &
+ PGliteInterfaceExtensions<{
+ live: typeof live
+ vector: typeof vector
+ }>
+ >()
// @ts-expect-error name is a string
providePGlite(dbLive)