@weirdscience/based-client 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +187 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# @weirdscience/based-client
|
|
2
|
+
|
|
3
|
+
React SDK for [Based](https://based.weirdscience.dev) — a minimal self-hosted Backend-as-a-Service.
|
|
4
|
+
|
|
5
|
+
Hooks for auth, queries, and mutations. Type-safe end-to-end when paired with `based typegen`.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
bun add @weirdscience/based-client
|
|
11
|
+
# or: npm install @weirdscience/based-client
|
|
12
|
+
# or: pnpm add @weirdscience/based-client
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Peer dependency: `react >=18`.
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { createClient, BasedProvider } from "@weirdscience/based-client";
|
|
21
|
+
|
|
22
|
+
const based = createClient({
|
|
23
|
+
url: process.env.NEXT_PUBLIC_BASED_URL!,
|
|
24
|
+
anonKey: process.env.NEXT_PUBLIC_BASED_ANON_KEY!,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export default function App({ children }: { children: React.ReactNode }) {
|
|
28
|
+
return <BasedProvider client={based}>{children}</BasedProvider>;
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Hooks
|
|
33
|
+
|
|
34
|
+
### `useUser()`
|
|
35
|
+
|
|
36
|
+
Current authenticated user.
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
import { useUser } from "@weirdscience/based-client";
|
|
40
|
+
|
|
41
|
+
function Profile() {
|
|
42
|
+
const { user, isLoading } = useUser();
|
|
43
|
+
if (isLoading) return <p>...</p>;
|
|
44
|
+
if (!user) return <p>Not logged in</p>;
|
|
45
|
+
return <p>{user.email}</p>;
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### `useQuery(table, options?)`
|
|
50
|
+
|
|
51
|
+
Read rows from a table. Returns `{ data, total, isLoading, error, refetch }`.
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import { useQuery } from "@weirdscience/based-client";
|
|
55
|
+
|
|
56
|
+
const { data, total, isLoading } = useQuery("posts", {
|
|
57
|
+
filter: { status: "published" },
|
|
58
|
+
limit: 20,
|
|
59
|
+
offset: 0,
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### `useMutation(table, operation)`
|
|
64
|
+
|
|
65
|
+
Write rows. `operation` is `"create" | "update" | "delete"`. Returns `{ mutate, isLoading, error }`.
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
import { useMutation } from "@weirdscience/based-client";
|
|
69
|
+
|
|
70
|
+
function NewPost() {
|
|
71
|
+
const { mutate, isLoading } = useMutation("posts", "create");
|
|
72
|
+
return (
|
|
73
|
+
<button
|
|
74
|
+
onClick={() => mutate({ title: "Hello", content: "World" })}
|
|
75
|
+
disabled={isLoading}
|
|
76
|
+
>
|
|
77
|
+
Create
|
|
78
|
+
</button>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`update` and `delete` require an `id` field:
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
const { mutate: update } = useMutation("posts", "update");
|
|
87
|
+
await update({ id: "abc", title: "Renamed" });
|
|
88
|
+
|
|
89
|
+
const { mutate: remove } = useMutation("posts", "delete");
|
|
90
|
+
await remove({ id: "abc" });
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Auth
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
import { useBasedClient } from "@weirdscience/based-client";
|
|
97
|
+
|
|
98
|
+
function LoginForm() {
|
|
99
|
+
const client = useBasedClient();
|
|
100
|
+
|
|
101
|
+
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
|
|
102
|
+
e.preventDefault();
|
|
103
|
+
const fd = new FormData(e.currentTarget);
|
|
104
|
+
await client.auth.signIn(
|
|
105
|
+
fd.get("email") as string,
|
|
106
|
+
fd.get("password") as string
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<form onSubmit={handleSubmit}>
|
|
112
|
+
<input name="email" type="email" />
|
|
113
|
+
<input name="password" type="password" />
|
|
114
|
+
<button type="submit">Sign in</button>
|
|
115
|
+
</form>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Methods on `client.auth`:
|
|
121
|
+
|
|
122
|
+
- `signUp(email, password)` → creates an account and signs in
|
|
123
|
+
- `signIn(email, password)` → signs in
|
|
124
|
+
- `signOut()` → invalidates the session
|
|
125
|
+
- `refreshSession()` → manually refresh (happens automatically on 401)
|
|
126
|
+
|
|
127
|
+
Access tokens auto-refresh on `401`. Sessions are stored in memory.
|
|
128
|
+
|
|
129
|
+
## Type safety
|
|
130
|
+
|
|
131
|
+
Generate types for your tables from the server:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
based typegen
|
|
135
|
+
# writes based.d.ts
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Pass the generated `Tables` type as a generic:
|
|
139
|
+
|
|
140
|
+
```tsx
|
|
141
|
+
import type { Tables } from "./based.d.ts";
|
|
142
|
+
import { useQuery, useMutation } from "@weirdscience/based-client";
|
|
143
|
+
|
|
144
|
+
// data is typed as Tables["posts"][]
|
|
145
|
+
const { data } = useQuery<Tables, "posts">("posts", {
|
|
146
|
+
filter: { status: "published" }, // typed keys
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
const { mutate } = useMutation<Tables, "posts">("posts", "create");
|
|
150
|
+
await mutate({ title: "Hello", content: "World" }); // typed payload
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Re-run `based typegen` after any schema change.
|
|
154
|
+
|
|
155
|
+
## Row-level isolation
|
|
156
|
+
|
|
157
|
+
If a table has a `user_id` (or `userId`) column, Based auto-scopes CRUD to the authenticated user. No configuration needed — just add the column:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
based table create notes user_id:text:required title:text:required body:text
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
After that:
|
|
164
|
+
|
|
165
|
+
- `useQuery("notes")` only returns the caller's notes
|
|
166
|
+
- `useMutation("notes", "create")` auto-fills `user_id`
|
|
167
|
+
- Other users' rows return 404
|
|
168
|
+
|
|
169
|
+
## Upsert
|
|
170
|
+
|
|
171
|
+
`PUT /api/:table/:id` creates if missing, updates if present. From the SDK:
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
const { mutate: upsert } = useMutation("preferences", "update");
|
|
175
|
+
|
|
176
|
+
// The URL id becomes the row id — perfect for deterministic keys like userId:key
|
|
177
|
+
await upsert({ id: "alice:theme", value: "dark" });
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Links
|
|
181
|
+
|
|
182
|
+
- [Based docs](https://based.weirdscience.dev/docs)
|
|
183
|
+
- [GitHub](https://github.com/WeirdScience-dev/based)
|
|
184
|
+
|
|
185
|
+
## License
|
|
186
|
+
|
|
187
|
+
MIT
|