Skip to content

Commit a730379

Browse files
committed
feat: add Svelte support
1 parent a73674e commit a730379

8 files changed

Lines changed: 1032 additions & 81 deletions

File tree

packages/svelte-db/README.md

Lines changed: 2 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,3 @@
1-
# Svelte library
1+
# @tanstack/react-db
22

3-
Everything you need to build a Svelte library, powered by [`sv`](https://npmjs.com/package/sv).
4-
5-
Read more about creating a library [in the docs](https://svelte.dev/docs/kit/packaging).
6-
7-
## Creating a project
8-
9-
If you're seeing this, you've probably already done this step. Congrats!
10-
11-
```bash
12-
# create a new project in the current directory
13-
npx sv create
14-
15-
# create a new project in my-app
16-
npx sv create my-app
17-
```
18-
19-
## Developing
20-
21-
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
22-
23-
```bash
24-
npm run dev
25-
26-
# or start the server and open the app in a new browser tab
27-
npm run dev -- --open
28-
```
29-
30-
Everything inside `src/lib` is part of your library, everything inside `src/routes` can be used as a showcase or preview app.
31-
32-
## Building
33-
34-
To build your library:
35-
36-
```bash
37-
npm run package
38-
```
39-
40-
To create a production version of your showcase app:
41-
42-
```bash
43-
npm run build
44-
```
45-
46-
You can preview the production build with `npm run preview`.
47-
48-
> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
49-
50-
## Publishing
51-
52-
Go into the `package.json` and give your package the desired name through the `"name"` option. Also consider adding a `"license"` field and point it to a `LICENSE` file which you can create from a template (one popular option is the [MIT license](https://opensource.org/license/mit/)).
53-
54-
To publish your library to [npm](https://www.npmjs.com):
55-
56-
```bash
57-
npm publish
58-
```
3+
Svelte hooks for TanStack DB. See [TanStack/db](https://github.com/TanStack/db) for more details.

packages/svelte-db/package.json

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"prepare": "svelte-kit sync || echo ''",
1010
"prepack": "svelte-kit sync && svelte-package && publint",
1111
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
12-
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
12+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
13+
"test": "npx vitest --run"
1314
},
1415
"files": [
1516
"dist",
@@ -28,19 +29,24 @@
2829
"svelte": "./dist/index.js"
2930
}
3031
},
32+
"dependencies": {
33+
"@tanstack/db": "workspace:*",
34+
"@tanstack/svelte-store": "^0.7.0"
35+
},
3136
"peerDependencies": {
3237
"svelte": "^5.0.0"
3338
},
3439
"devDependencies": {
35-
"@sveltejs/adapter-auto": "^6.0.0",
36-
"@sveltejs/kit": "^2.16.0",
37-
"@sveltejs/package": "^2.0.0",
38-
"@sveltejs/vite-plugin-svelte": "^5.0.0",
40+
"@testing-library/jest-dom": "^6.6.3",
41+
"@testing-library/svelte": "^5.2.4",
42+
"@sveltejs/adapter-auto": "^6.0.1",
43+
"@sveltejs/kit": "^2.21.0",
44+
"@sveltejs/package": "^2.3.11",
45+
"@vitest/coverage-istanbul": "^3.0.9",
46+
"@sveltejs/vite-plugin-svelte": "^5.0.3",
3947
"publint": "^0.3.2",
40-
"svelte": "^5.0.0",
41-
"svelte-check": "^4.0.0",
42-
"typescript": "^5.0.0",
43-
"vite": "^6.2.6"
48+
"svelte": "^5.28.6",
49+
"svelte-check": "^4.2.0"
4450
},
4551
"keywords": [
4652
"optimistic",
Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,10 @@
1-
// Reexport your entry components here
1+
// Re-export all public APIs
2+
export * from "./useOptimisticMutation.js"
3+
export * from "./useLiveQuery.svelte.js"
4+
5+
// Re-export everything from @tanstack/db
6+
export * from "@tanstack/db"
7+
8+
// Re-export some stuff explicitly to ensure the type & value is exported
9+
export { Collection } from "@tanstack/db"
10+
export { createTransaction } from "@tanstack/db"
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { useStore } from "@tanstack/svelte-store"
2+
import { compileQuery, queryBuilder } from "@tanstack/db"
3+
import type {
4+
Collection,
5+
Context,
6+
InitialQueryBuilder,
7+
QueryBuilder,
8+
ResultsFromContext,
9+
Schema,
10+
} from "@tanstack/db"
11+
12+
type ComputedRef<T> = {
13+
get current(): T
14+
}
15+
16+
type Getter<T> = () => T
17+
18+
function toValue<T>() {}
19+
20+
export interface UseLiveQueryReturn<T extends object> {
21+
state: Map<string, T>
22+
data: Array<T>
23+
collection: Collection<T>
24+
}
25+
26+
export function useLiveQuery<
27+
TResultContext extends Context<Schema> = Context<Schema>,
28+
>(
29+
queryFn: (
30+
q: InitialQueryBuilder<Context<Schema>>
31+
) => QueryBuilder<TResultContext>,
32+
deps: Array<Getter<unknown>> = []
33+
): UseLiveQueryReturn<ResultsFromContext<TResultContext>> {
34+
const compiledQuery = $derived.by(() => {
35+
// Just reference deps to make derived reactive to them
36+
// deps.forEach((dep) => toValue(dep))
37+
38+
const query = queryFn(queryBuilder())
39+
const compiled = compileQuery(query)
40+
compiled.start()
41+
return compiled
42+
})
43+
44+
const state = $derived(useStore(compiledQuery.results.derivedState).current)
45+
const data = $derived(useStore(compiledQuery.results.derivedArray).current)
46+
const collection = $derived(compiledQuery.results)
47+
48+
$effect(() => {
49+
if (compiledQuery.state === `stopped`) {
50+
compiledQuery.start()
51+
}
52+
53+
return () => {
54+
compiledQuery.stop()
55+
}
56+
})
57+
58+
return {
59+
get state() {
60+
return state
61+
},
62+
get data() {
63+
return data
64+
},
65+
get collection() {
66+
return collection as any
67+
},
68+
}
69+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { createTransaction } from "@tanstack/db"
2+
import type { Transaction, TransactionConfig } from "@tanstack/db"
3+
4+
export function useOptimisticMutation(config: TransactionConfig) {
5+
return {
6+
mutate: (callback: () => void): Transaction => {
7+
const transaction = createTransaction(config)
8+
transaction.mutate(callback)
9+
return transaction
10+
},
11+
createTransaction: (): Transaction => {
12+
return createTransaction({ ...config, autoCommit: false })
13+
},
14+
}
15+
}

0 commit comments

Comments
 (0)