feat: add mutations

This commit is contained in:
Max Koon
2025-10-13 23:45:20 -04:00
parent fb6b7ff683
commit 032f38b711
5 changed files with 56 additions and 52 deletions

View File

@@ -1,6 +1,5 @@
import { import {
type ReadonlyJSONValue, type ReadonlyJSONValue,
type ServerTransaction,
withValidation, withValidation,
} from "@rocicorp/zero"; } from "@rocicorp/zero";
import { import {
@@ -8,64 +7,33 @@ import {
PushProcessor, PushProcessor,
ZQLDatabase, ZQLDatabase,
} from "@rocicorp/zero/server"; } from "@rocicorp/zero/server";
import { PostgresJSConnection } from '@rocicorp/zero/pg';
import postgres from 'postgres';
import { import {
// createMutators as createMutatorsShared, createMutators as createMutatorsShared,
// isLoggedIn,
// type Mutators,
queries, queries,
schema, schema,
type Schema,
} from "@money/shared"; } from "@money/shared";
import type { AuthData } from "@money/shared/auth"; import type { AuthData } from "@money/shared/auth";
// import { auditLogs } from "@zslack/shared/db";
// import {
// NodePgConnection,
// type NodePgZeroTransaction,
// } from "drizzle-zero/node-postgres";
import crypto from "node:crypto";
// import { db } from "./db";
import { getHono } from "./hono"; import { getHono } from "./hono";
// type ServerTx = ServerTransaction<Schema, NodePgZeroTransaction<typeof db>>;
// const processor = new PushProcessor( const processor = new PushProcessor(
// new ZQLDatabase(new NodePgConnection(db), schema), new ZQLDatabase(
// ); new PostgresJSConnection(postgres(process.env.ZERO_UPSTREAM_DB! as string)),
// schema,
// const createMutators = (authData: AuthData | null) => { ),
// const mutators = createMutatorsShared(authData); );
//
// return {
// ...mutators,
// message: {
// ...mutators.message,
// async sendMessage(tx: ServerTx, params) {
// isLoggedIn(authData);
//
// await mutators.message.sendMessage(tx, params);
//
// // we can use the db tx to insert server-only data, like audit logs
// await tx.dbTransaction.wrappedTransaction.insert(auditLogs).values({
// id: crypto.randomUUID(),
// userId: authData.user.id,
// action: "sendMessage",
// });
// },
// },
// } as const satisfies Mutators;
// };
const zero = getHono() const zero = getHono()
// .post("/mutate", async (c) => { .post("/mutate", async (c) => {
// // get the auth data from betterauth const authData = c.get("auth");
// const authData = c.get("auth");
// const result = await processor.process(createMutatorsShared(authData), c.req.raw);
// const result = await processor.process(createMutators(authData), c.req.raw);
// return c.json(result);
// return c.json(result); })
// })
.post("/get-queries", async (c) => { .post("/get-queries", async (c) => {
// get the auth data from betterauth
const authData = c.get("auth"); const authData = c.get("auth");
const result = await handleGetQueriesRequest( const result = await handleGetQueriesRequest(

View File

@@ -7,7 +7,7 @@ import { useMemo } from 'react';
import { authDataSchema } from '@/shared/src/auth'; import { authDataSchema } from '@/shared/src/auth';
import { Platform } from 'react-native'; import { Platform } from 'react-native';
import type { ZeroOptions } from '@rocicorp/zero'; import type { ZeroOptions } from '@rocicorp/zero';
import { schema, type Schema } from '@/shared/src'; import { schema, type Schema, createMutators, type Mutators } from '@/shared/src';
import { expoSQLiteStoreProvider } from "@rocicorp/zero/react-native"; import { expoSQLiteStoreProvider } from "@rocicorp/zero/react-native";
export const unstable_settings = { export const unstable_settings = {
@@ -35,9 +35,9 @@ export default function RootLayout() {
server: 'http://localhost:4848', server: 'http://localhost:4848',
userID: authData?.user.id ?? "anon", userID: authData?.user.id ?? "anon",
schema, schema,
// mutators: createMutators(), mutators: createMutators(authData),
auth: cookie, auth: cookie,
} as const satisfies ZeroOptions<Schema>; } as const satisfies ZeroOptions<Schema, Mutators>;
}, [authData, cookie]); }, [authData, cookie]);
return ( return (

View File

@@ -2,20 +2,30 @@ import { SafeAreaView } from 'react-native-safe-area-context';
import { authClient } from '@/lib/auth-client'; import { authClient } from '@/lib/auth-client';
import { Button, Text } from 'react-native'; import { Button, Text } from 'react-native';
import { useQuery, useZero } from "@rocicorp/zero/react"; import { useQuery, useZero } from "@rocicorp/zero/react";
import { queries } from '@money/shared'; import { queries, type Mutators, type Schema } from '@money/shared';
export default function HomeScreen() { export default function HomeScreen() {
const { data: session } = authClient.useSession(); const { data: session } = authClient.useSession();
const onLogout = () => { const onLogout = () => {
authClient.signOut(); authClient.signOut();
} }
const z = useZero<Schema, Mutators>();
const [transactions] = useQuery(queries.allTransactions(session)); const [transactions] = useQuery(queries.allTransactions(session));
const onNew = () => {
z.mutate.transaction.create({
name: "Uber",
amount: 100,
})
};
return ( return (
<SafeAreaView> <SafeAreaView>
<Text>Hello {session?.user.name}</Text> <Text>Hello {session?.user.name}</Text>
<Button onPress={onLogout} title="Logout" /> <Button onPress={onLogout} title="Logout" />
<Text>Transactions: {JSON.stringify(transactions, null, 4)}</Text> <Text>Transactions: {JSON.stringify(transactions, null, 4)}</Text>
<Button onPress={onNew} title="New" />
</SafeAreaView> </SafeAreaView>
); );
} }

View File

@@ -1,2 +1,4 @@
export * from "./schema"; export * from "./schema";
export * from "./queries"; export * from "./queries";
export * from "./mutators";
export * from "./zql";

24
shared/src/mutators.ts Normal file
View File

@@ -0,0 +1,24 @@
import type { Transaction } from "@rocicorp/zero";
import type { AuthData } from "./auth";
import type { Schema } from "./schema";
import { isLoggedIn } from "./zql";
type Tx = Transaction<Schema>;
export function createMutators(authData: AuthData | null) {
return {
transaction: {
async create(tx: Tx, { name, amount }: { name: string, amount: number }) {
isLoggedIn(authData);
await tx.mutate.transaction.insert({
id: 'id-' + Math.random().toString(),
user_id: authData.user.id,
name,
amount,
})
}
}
} as const;
}
export type Mutators = ReturnType<typeof createMutators>;