basic redux setup

This commit is contained in:
2026-05-25 11:41:43 -04:00
parent 56c4b1bc03
commit 4471719b79
26 changed files with 8968 additions and 2 deletions

3571
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

31
redux/.gitignore vendored Normal file
View File

@@ -0,0 +1,31 @@
dist
.wrangler
.output
.vercel
.netlify
.vinxi
app.config.timestamp_*.js
# Environment
.env
.env*.local
# dependencies
/node_modules
# IDEs and editors
/.idea
.project
.classpath
*.launch
.settings/
# Drizzle
/drizzle/
# Temp
gitignore
# System Files
.DS_Store
Thumbs.db

32
redux/README.md Normal file
View File

@@ -0,0 +1,32 @@
# SolidStart
Everything you need to build a Solid project, powered by [`solid-start`](https://start.solidjs.com);
## Creating a project
```bash
# create a new project in the current directory
npm init solid@latest
# create a new project in my-app
npm init solid@latest my-app
```
## Developing
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
```bash
npm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
```
## Building
Solid apps are built with _presets_, which optimise your project for deployment to different environments.
By default, `npm run build` will generate a Node app that you can run with `npm start`. To use a different preset, add it to the `devDependencies` in `package.json` and specify in your `app.config.js`.
## This project was created with the [Solid CLI](https://github.com/solidjs-community/solid-cli)

12
redux/drizzle.config.ts Normal file
View File

@@ -0,0 +1,12 @@
import { defineConfig } from "drizzle-kit";
export default defineConfig({
schema: "./src/server/db/schema.ts",
out: "./drizzle",
dialect: "sqlite",
driver: "turso",
dbCredentials: {
url: process.env.DATABASE_URL!,
authToken: process.env.DATABASE_AUTH_TOKEN,
},
});

30
redux/package.json Normal file
View File

@@ -0,0 +1,30 @@
{
"name": "example-with-trpc",
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"start": "vite start",
"preview": "vite preview"
},
"dependencies": {
"@libsql/client": "^0.17.3",
"@solidjs/meta": "^0.29.4",
"@solidjs/router": "^0.15.0",
"@solidjs/start": "2.0.0-alpha.2",
"@solidjs/vite-plugin-nitro-2": "^0.1.0",
"@trpc/client": "^10.45.2",
"@trpc/server": "^10.45.2",
"@typeschema/valibot": "^0.13.4",
"drizzle-orm": "^0.45.2",
"solid-js": "^1.9.5",
"valibot": "^0.29.0",
"vite": "^7.0.0"
},
"engines": {
"node": ">=22"
},
"devDependencies": {
"drizzle-kit": "^0.31.10"
}
}

5040
redux/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

BIN
redux/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 664 B

1
redux/src/app.css Normal file
View File

@@ -0,0 +1 @@
@import "tailwindcss";

22
redux/src/app.tsx Normal file
View File

@@ -0,0 +1,22 @@
import { MetaProvider, Title } from "@solidjs/meta";
import { Router } from "@solidjs/router";
import { FileRoutes } from "@solidjs/start/router";
import { Suspense } from "solid-js";
import "./app.css";
export default function App() {
return (
<Router
root={props => (
<MetaProvider>
<Title>SolidStart - Basic</Title>
<a href="/">Index</a>
<a href="/about">About</a>
<Suspense>{props.children}</Suspense>
</MetaProvider>
)}
>
<FileRoutes />
</Router>
);
}

View File

@@ -0,0 +1,21 @@
.increment {
font-family: inherit;
font-size: inherit;
padding: 1em 2em;
color: #335d92;
background-color: rgba(68, 107, 158, 0.1);
border-radius: 2em;
border: 2px solid rgba(68, 107, 158, 0);
outline: none;
width: 200px;
font-variant-numeric: tabular-nums;
cursor: pointer;
}
.increment:focus {
border: 2px solid #335d92;
}
.increment:active {
background-color: rgba(68, 107, 158, 0.2);
}

View File

@@ -0,0 +1,11 @@
import { createSignal } from "solid-js";
import "./Counter.css";
export default function Counter() {
const [count, setCount] = createSignal(0);
return (
<button class="increment" onClick={() => setCount(count() + 1)} type="button">
Clicks: {count()}
</button>
);
}

View File

@@ -0,0 +1,4 @@
// @refresh reload
import { mount, StartClient } from "@solidjs/start/client";
mount(() => <StartClient />, document.getElementById("app")!);

View File

@@ -0,0 +1,21 @@
// @refresh reload
import { createHandler, StartServer } from "@solidjs/start/server";
export default createHandler(() => (
<StartServer
document={({ assets, children, scripts }) => (
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
{assets}
</head>
<body>
<div id="app">{children}</div>
{scripts}
</body>
</html>
)}
/>
));

1
redux/src/global.d.ts vendored Normal file
View File

@@ -0,0 +1 @@
/// <reference types="@solidjs/start/env" />

23
redux/src/lib/api.ts Normal file
View File

@@ -0,0 +1,23 @@
import {
createTRPCProxyClient,
httpBatchLink,
loggerLink,
} from '@trpc/client';
import { AppRouter } from "~/server/api/root";
const getBaseUrl = () => {
if (typeof window !== "undefined") return "";
// replace example.com with your actual production url
if (process.env.NODE_ENV === "production") return "https://example.com";
return `http://localhost:${process.env.PORT ?? 3000}`;
};
// create the client, export it
export const api = createTRPCProxyClient<AppRouter>({
links: [
// will print out helpful logs when using client
loggerLink(),
// identifies what url will handle trpc requests
httpBatchLink({ url: `${getBaseUrl()}/api/trpc` })
],
});

View File

@@ -0,0 +1,19 @@
import { Title } from "@solidjs/meta";
import { HttpStatusCode } from "@solidjs/start";
export default function NotFound() {
return (
<main>
<Title>Not Found</Title>
<HttpStatusCode code={404} />
<h1>Page Not Found</h1>
<p>
Visit{" "}
<a href="https://start.solidjs.com" target="_blank">
start.solidjs.com
</a>{" "}
to learn how to build SolidStart apps.
</p>
</main>
);
}

View File

@@ -0,0 +1,10 @@
import { Title } from "@solidjs/meta";
export default function About() {
return (
<main>
<Title>About</Title>
<h1>About</h1>
</main>
);
}

View File

@@ -0,0 +1,19 @@
import type { APIEvent } from "@solidjs/start/server";
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
import { appRouter } from "~/server/api/root";
const handler = (event: APIEvent) =>
// adapts tRPC to fetch API style requests
fetchRequestHandler({
// the endpoint handling the requests
endpoint: "/api/trpc",
// the request object
req: event.request,
// the router for handling the requests
router: appRouter,
// any arbitrary data that should be available to all actions
createContext: () => event
});
export const GET = handler;
export const POST = handler;

View File

@@ -0,0 +1,25 @@
import { Title } from "@solidjs/meta";
import { createAsync } from "@solidjs/router";
import Counter from "~/components/Counter";
import { api } from "~/lib/api";
export default function Home() {
const hello = createAsync(() => api.example.hello.query("world"));
return (
<main>
<Title>Hello World</Title>
<h1>Hello world!</h1>
<Counter />
<p>
Visit{" "}
<a href="https://start.solidjs.com" target="_blank">
start.solidjs.com
</a>{" "}
to learn how to build SolidStart apps.
</p>
<pre>
<code>{JSON.stringify(hello(), null, 2)}</code>
</pre>
</main>
);
}

View File

@@ -0,0 +1,8 @@
import { exampleRouter } from "./routers/example";
import { createTRPCRouter } from "./utils";
export const appRouter = createTRPCRouter({
example: exampleRouter
});
export type AppRouter = typeof appRouter;

View File

@@ -0,0 +1,11 @@
import { wrap } from "@typeschema/valibot";
import { string } from "valibot";
import { createTRPCRouter, publicProcedure } from "../utils";
export const exampleRouter = createTRPCRouter({
hello: publicProcedure
.input(wrap(string()))
.query(({ input }) => {
return `Hello ${input}!`;
})
});

View File

@@ -0,0 +1,6 @@
import { initTRPC } from "@trpc/server";
export const t = initTRPC.create();
export const createTRPCRouter = t.router;
export const publicProcedure = t.procedure;

View File

@@ -0,0 +1,11 @@
import { createClient } from "@libsql/client";
import { drizzle } from "drizzle-orm/libsql";
import * as schema from "./schema";
const client = createClient({
url: process.env.DATABASE_URL ?? "file:local.db",
authToken: process.env.DATABASE_AUTH_TOKEN,
});
export const db = drizzle(client, { schema });

View File

@@ -0,0 +1,10 @@
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
export const users = sqliteTable("users", {
id: integer("id").primaryKey({ autoIncrement: true }),
name: text("name").notNull(),
email: text("email").notNull().unique(),
createdAt: integer("created_at", { mode: "timestamp" })
.notNull()
.$defaultFn(() => new Date()),
});

19
redux/tsconfig.json Normal file
View File

@@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"jsx": "preserve",
"jsxImportSource": "solid-js",
"allowJs": true,
"strict": true,
"noEmit": true,
"types": ["vite/client"],
"isolatedModules": true,
"paths": {
"~/*": ["./src/*"]
}
}
}

12
redux/vite.config.ts Normal file
View File

@@ -0,0 +1,12 @@
import { defineConfig } from "vite";
import { nitroV2Plugin as nitro } from "@solidjs/vite-plugin-nitro-2";
import tailwindcss from "@tailwindcss/vite";
import { solidStart } from "@solidjs/start/config";
export default defineConfig({
plugins: [solidStart(),
tailwindcss(),
nitro()
]
});