create-fate 1.0.3 → 1.3.0
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 +3 -0
- package/bin/create-fate.mjs +594 -9
- package/package.json +2 -2
- package/templates/fate/README.md +3 -0
- package/templates/fate/_shared/vue-app/package.json +54 -0
- package/templates/fate/_shared/vue-app/pages/index.vue +57 -0
- package/templates/fate/_shared/vue-app/pages/layout.vue +32 -0
- package/templates/fate/_shared/vue-app/pages/post/[id].vue +24 -0
- package/templates/fate/_shared/vue-app/src/App.css +63 -0
- package/templates/fate/_shared/vue-app/src/fateViews.ts +14 -0
- package/templates/fate/_shared/vue-app/src/lib/cx.ts +6 -0
- package/templates/fate/_shared/vue-app/src/lib/env.ts +3 -0
- package/templates/fate/_shared/vue-app/src/ui/Button.vue +67 -0
- package/templates/fate/_shared/vue-app/src/ui/Card.vue +16 -0
- package/templates/fate/_shared/vue-app/src/ui/Error.vue +9 -0
- package/templates/fate/_shared/vue-app/src/ui/ErrorBoundary.vue +22 -0
- package/templates/fate/_shared/vue-app/src/ui/Header.vue +35 -0
- package/templates/fate/_shared/vue-app/src/ui/Link.vue +15 -0
- package/templates/fate/_shared/vue-app/src/ui/PostCard.vue +29 -0
- package/templates/fate/_shared/vue-app/src/ui/Section.vue +19 -0
- package/templates/fate/_shared/vue-app/src/ui/Thinking.vue +11 -0
- package/templates/fate/_shared/vue-app/src/ui/UserCard.vue +23 -0
- package/templates/fate/_shared/vue-app/src/vue-shims.d.ts +6 -0
- package/templates/fate/_shared/vue-app/tsconfig.json +22 -0
- package/templates/fate/_shared/vue-app/vite.config.ts +58 -0
- package/templates/fate/_shared/vue-app/void.json +5 -0
- package/templates/fate/cloudflare/.github/workflows/push.yml +27 -0
- package/templates/fate/cloudflare/.vite-hooks/pre-commit +1 -0
- package/templates/fate/cloudflare/.vscode/extensions.json +12 -0
- package/templates/fate/cloudflare/.vscode/settings.json +25 -0
- package/templates/fate/cloudflare/AGENTS.md +55 -0
- package/templates/fate/cloudflare/README.md +126 -0
- package/templates/fate/cloudflare/_gitignore +20 -0
- package/templates/fate/cloudflare/client/package.json +56 -0
- package/templates/fate/cloudflare/client/pages/index.tsx +96 -0
- package/templates/fate/cloudflare/client/pages/layout.tsx +82 -0
- package/templates/fate/cloudflare/client/pages/login.tsx +107 -0
- package/templates/fate/cloudflare/client/pages/post/[id].tsx +22 -0
- package/templates/fate/cloudflare/client/pages/search.tsx +99 -0
- package/templates/fate/cloudflare/client/public/icon.svg +1 -0
- package/templates/fate/cloudflare/client/src/App.css +153 -0
- package/templates/fate/cloudflare/client/src/lib/AvailableLanguages.tsx +5 -0
- package/templates/fate/cloudflare/client/src/lib/cx.tsx +6 -0
- package/templates/fate/cloudflare/client/src/lib/env.tsx +5 -0
- package/templates/fate/cloudflare/client/src/ui/Badge.tsx +31 -0
- package/templates/fate/cloudflare/client/src/ui/Button.tsx +108 -0
- package/templates/fate/cloudflare/client/src/ui/Card.tsx +32 -0
- package/templates/fate/cloudflare/client/src/ui/CommentCard.tsx +75 -0
- package/templates/fate/cloudflare/client/src/ui/Error.tsx +19 -0
- package/templates/fate/cloudflare/client/src/ui/H2.tsx +15 -0
- package/templates/fate/cloudflare/client/src/ui/H3.tsx +20 -0
- package/templates/fate/cloudflare/client/src/ui/Header.tsx +98 -0
- package/templates/fate/cloudflare/client/src/ui/Input.tsx +17 -0
- package/templates/fate/cloudflare/client/src/ui/Link.tsx +11 -0
- package/templates/fate/cloudflare/client/src/ui/LocaleSwitcher.tsx +52 -0
- package/templates/fate/cloudflare/client/src/ui/PostCard.tsx +303 -0
- package/templates/fate/cloudflare/client/src/ui/Section.tsx +23 -0
- package/templates/fate/cloudflare/client/src/ui/UserCard.tsx +131 -0
- package/templates/fate/cloudflare/client/src/user/AuthClient.tsx +6 -0
- package/templates/fate/cloudflare/client/translations/de_DE.json +689 -0
- package/templates/fate/cloudflare/client/translations/ja_JP.json +689 -0
- package/templates/fate/cloudflare/client/vite.config.ts +45 -0
- package/templates/fate/cloudflare/client/void.json +29 -0
- package/templates/fate/cloudflare/package.json +46 -0
- package/templates/fate/cloudflare/pnpm-workspace.yaml +39 -0
- package/templates/fate/cloudflare/server/.env.example +1 -0
- package/templates/fate/cloudflare/server/db/db.ts +30 -0
- package/templates/fate/cloudflare/server/db/migrations/20260508073357_initial_schema.sql +133 -0
- package/templates/fate/cloudflare/server/db/migrations/20260508120500_seed_cloudflare_demo.sql +170 -0
- package/templates/fate/cloudflare/server/db/migrations/meta/20260508073357_snapshot.json +868 -0
- package/templates/fate/cloudflare/server/db/migrations/meta/_journal.json +20 -0
- package/templates/fate/cloudflare/server/db/queries.ts +211 -0
- package/templates/fate/cloudflare/server/db/schema.ts +332 -0
- package/templates/fate/cloudflare/server/package.json +34 -0
- package/templates/fate/cloudflare/server/src/fate/commentPermissions.ts +17 -0
- package/templates/fate/cloudflare/server/src/fate/context.ts +15 -0
- package/templates/fate/cloudflare/server/src/fate/live.ts +7 -0
- package/templates/fate/cloudflare/server/src/fate/server.ts +411 -0
- package/templates/fate/cloudflare/server/src/fate/views.ts +164 -0
- package/templates/fate/cloudflare/server/src/index.ts +80 -0
- package/templates/fate/cloudflare/server/src/lib/auth.ts +66 -0
- package/templates/fate/cloudflare/server/src/lib/origins.ts +17 -0
- package/templates/fate/cloudflare/server/src/router.ts +2 -0
- package/templates/fate/cloudflare/server/src/user/SessionUser.tsx +17 -0
- package/templates/fate/cloudflare/server/tsconfig.json +10 -0
- package/templates/fate/cloudflare/server/wrangler.jsonc +29 -0
- package/templates/fate/cloudflare/tsconfig.json +33 -0
- package/templates/fate/cloudflare/vite.config.ts +72 -0
- package/templates/fate/drizzle/README.md +2 -8
- package/templates/fate/drizzle/client/pages/layout.tsx +2 -2
- package/templates/fate/drizzle/client/src/ui/PostCard.tsx +38 -15
- package/templates/fate/drizzle/pnpm-workspace.yaml +9 -3
- package/templates/fate/drizzle/server/vite.config.ts +1 -1
- package/templates/fate/graphql/.github/workflows/push.yml +27 -0
- package/templates/fate/graphql/.vite-hooks/pre-commit +1 -0
- package/templates/fate/graphql/.vscode/extensions.json +12 -0
- package/templates/fate/graphql/.vscode/settings.json +25 -0
- package/templates/fate/graphql/AGENTS.md +55 -0
- package/templates/fate/graphql/README.md +121 -0
- package/templates/fate/graphql/_gitignore +23 -0
- package/templates/fate/graphql/client/package.json +57 -0
- package/templates/fate/graphql/client/pages/index.tsx +96 -0
- package/templates/fate/graphql/client/pages/layout.tsx +83 -0
- package/templates/fate/graphql/client/pages/login.tsx +107 -0
- package/templates/fate/graphql/client/pages/post/[id].tsx +22 -0
- package/templates/fate/graphql/client/pages/search.tsx +99 -0
- package/templates/fate/graphql/client/public/icon.svg +1 -0
- package/templates/fate/graphql/client/src/App.css +153 -0
- package/templates/fate/graphql/client/src/lib/AvailableLanguages.tsx +5 -0
- package/templates/fate/graphql/client/src/lib/cx.tsx +6 -0
- package/templates/fate/graphql/client/src/lib/env.tsx +5 -0
- package/templates/fate/graphql/client/src/ui/Badge.tsx +31 -0
- package/templates/fate/graphql/client/src/ui/Button.tsx +108 -0
- package/templates/fate/graphql/client/src/ui/Card.tsx +32 -0
- package/templates/fate/graphql/client/src/ui/CommentCard.tsx +75 -0
- package/templates/fate/graphql/client/src/ui/Error.tsx +19 -0
- package/templates/fate/graphql/client/src/ui/H2.tsx +15 -0
- package/templates/fate/graphql/client/src/ui/H3.tsx +20 -0
- package/templates/fate/graphql/client/src/ui/Header.tsx +98 -0
- package/templates/fate/graphql/client/src/ui/Input.tsx +17 -0
- package/templates/fate/graphql/client/src/ui/Link.tsx +11 -0
- package/templates/fate/graphql/client/src/ui/LocaleSwitcher.tsx +52 -0
- package/templates/fate/graphql/client/src/ui/PostCard.tsx +303 -0
- package/templates/fate/graphql/client/src/ui/Section.tsx +23 -0
- package/templates/fate/graphql/client/src/ui/UserCard.tsx +131 -0
- package/templates/fate/graphql/client/src/user/AuthClient.tsx +6 -0
- package/templates/fate/graphql/client/translations/de_DE.json +689 -0
- package/templates/fate/graphql/client/translations/ja_JP.json +689 -0
- package/templates/fate/graphql/client/vite.config.ts +40 -0
- package/templates/fate/graphql/client/void.json +29 -0
- package/templates/fate/graphql/docker-compose.yml +11 -0
- package/templates/fate/graphql/package.json +47 -0
- package/templates/fate/graphql/pnpm-workspace.yaml +45 -0
- package/templates/fate/graphql/server/.env.example +5 -0
- package/templates/fate/graphql/server/README.md +27 -0
- package/templates/fate/graphql/server/package.json +64 -0
- package/templates/fate/graphql/server/prisma.config.ts +17 -0
- package/templates/fate/graphql/server/scripts/generate-graphql.tsx +40 -0
- package/templates/fate/graphql/server/src/__tests__/index.test.tsx +5 -0
- package/templates/fate/graphql/server/src/app.tsx +47 -0
- package/templates/fate/graphql/server/src/graphql/builder.tsx +121 -0
- package/templates/fate/graphql/server/src/graphql/context.tsx +22 -0
- package/templates/fate/graphql/server/src/graphql/fate.ts +85 -0
- package/templates/fate/graphql/server/src/graphql/lib/authDirectives.tsx +93 -0
- package/templates/fate/graphql/server/src/graphql/lib/decodeGlobalID.tsx +12 -0
- package/templates/fate/graphql/server/src/graphql/lib/decodeIDOrThrow.tsx +10 -0
- package/templates/fate/graphql/server/src/graphql/lib/encodeGlobalID.tsx +5 -0
- package/templates/fate/graphql/server/src/graphql/live.tsx +241 -0
- package/templates/fate/graphql/server/src/graphql/mutations.tsx +265 -0
- package/templates/fate/graphql/server/src/graphql/nodes/Category.tsx +35 -0
- package/templates/fate/graphql/server/src/graphql/nodes/Comment.tsx +46 -0
- package/templates/fate/graphql/server/src/graphql/nodes/Event.tsx +71 -0
- package/templates/fate/graphql/server/src/graphql/nodes/Post.tsx +45 -0
- package/templates/fate/graphql/server/src/graphql/nodes/Tag.tsx +11 -0
- package/templates/fate/graphql/server/src/graphql/nodes/User.tsx +28 -0
- package/templates/fate/graphql/server/src/graphql/schema.tsx +16 -0
- package/templates/fate/graphql/server/src/graphql/views.ts +193 -0
- package/templates/fate/graphql/server/src/index.tsx +45 -0
- package/templates/fate/graphql/server/src/lib/auth.tsx +31 -0
- package/templates/fate/graphql/server/src/lib/env.tsx +3 -0
- package/templates/fate/graphql/server/src/lib/origins.ts +18 -0
- package/templates/fate/graphql/server/src/prisma/prisma.tsx +9 -0
- package/templates/fate/graphql/server/src/prisma/schema.prisma +181 -0
- package/templates/fate/graphql/server/src/prisma/seed.tsx +161 -0
- package/templates/fate/graphql/server/src/user/SessionUser.tsx +17 -0
- package/templates/fate/graphql/server/src/user/isAdmin.tsx +3 -0
- package/templates/fate/graphql/server/tsconfig.json +33 -0
- package/templates/fate/graphql/server/vite.config.ts +55 -0
- package/templates/fate/graphql/tsconfig.json +33 -0
- package/templates/fate/graphql/vite.config.ts +80 -0
- package/templates/fate/graphql-client/.env.example +3 -0
- package/templates/fate/graphql-client/AGENTS.md +3 -0
- package/templates/fate/graphql-client/README.md +69 -0
- package/templates/fate/graphql-client/_gitignore +14 -0
- package/templates/fate/graphql-client/package.json +62 -0
- package/templates/fate/graphql-client/pages/index.tsx +69 -0
- package/templates/fate/graphql-client/pages/layout.tsx +41 -0
- package/templates/fate/graphql-client/pnpm-workspace.yaml +38 -0
- package/templates/fate/graphql-client/public/icon.svg +8 -0
- package/templates/fate/graphql-client/src/App.css +28 -0
- package/templates/fate/graphql-client/src/fate/graphql.ts +52 -0
- package/templates/fate/graphql-client/tsconfig.json +30 -0
- package/templates/fate/graphql-client/vite.config.ts +87 -0
- package/templates/fate/graphql-client/void.json +29 -0
- package/templates/fate/http/README.md +2 -8
- package/templates/fate/http/client/pages/layout.tsx +2 -2
- package/templates/fate/http/client/src/ui/PostCard.tsx +37 -15
- package/templates/fate/http/pnpm-workspace.yaml +9 -3
- package/templates/fate/http/server/vite.config.ts +1 -1
- package/templates/fate/prisma/README.md +2 -8
- package/templates/fate/prisma/client/pages/layout.tsx +2 -2
- package/templates/fate/prisma/client/src/ui/PostCard.tsx +37 -15
- package/templates/fate/prisma/pnpm-workspace.yaml +9 -3
- package/templates/fate/prisma/server/vite.config.ts +1 -1
- package/templates/fate/prisma/vite.config.ts +1 -1
- package/templates/fate/void/package.json +10 -2
- package/templates/fate/void/pages/login.tsx +3 -3
- package/templates/fate/void/pnpm-workspace.yaml +12 -4
- package/templates/fate/void/src/ui/Button.tsx +42 -26
- package/templates/fate/void/src/ui/CategoryCard.tsx +3 -7
- package/templates/fate/void/src/ui/PostCard.tsx +38 -15
- package/templates/fate/void/vite.config.ts +15 -14
- package/templates/fate/drizzle/public/fate-logo-dark.svg +0 -4
- package/templates/fate/drizzle/public/fate-logo.svg +0 -4
- package/templates/fate/http/public/fate-logo-dark.svg +0 -4
- package/templates/fate/http/public/fate-logo.svg +0 -4
- package/templates/fate/prisma/public/fate-logo-dark.svg +0 -4
- package/templates/fate/prisma/public/fate-logo.svg +0 -4
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import fbteePreset from '@nkzw/babel-preset-fbtee';
|
|
3
|
+
import babel from '@rolldown/plugin-babel';
|
|
4
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
5
|
+
import { reactCompilerPreset } from '@vitejs/plugin-react';
|
|
6
|
+
import { voidReact } from '@void/react/plugin';
|
|
7
|
+
import dotenv from 'dotenv';
|
|
8
|
+
import { fate } from 'react-fate/vite';
|
|
9
|
+
import { defineConfig, lazyPlugins } from 'vite-plus';
|
|
10
|
+
import { voidPlugin } from 'void';
|
|
11
|
+
|
|
12
|
+
const root = process.cwd();
|
|
13
|
+
const isDevelopment = process.env.NODE_ENV === 'development' || process.env.DEV;
|
|
14
|
+
|
|
15
|
+
dotenv.config({
|
|
16
|
+
path: join(root, '../server', isDevelopment ? '.env' : '.prod.env'),
|
|
17
|
+
quiet: true,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
if (isDevelopment && !process.env.VITE_SERVER_URL) {
|
|
21
|
+
process.env.VITE_SERVER_URL = 'http://localhost:8787';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!process.env.VITE_SERVER_URL) {
|
|
25
|
+
throw new Error(`client-build, vite.config: 'VITE_SERVER_URL' is missing.`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default defineConfig({
|
|
29
|
+
build: { outDir: join(root, '../dist/client') },
|
|
30
|
+
plugins: [
|
|
31
|
+
...(lazyPlugins(() => [
|
|
32
|
+
babel({
|
|
33
|
+
presets: [fbteePreset, reactCompilerPreset()],
|
|
34
|
+
}),
|
|
35
|
+
tailwindcss(),
|
|
36
|
+
voidPlugin(),
|
|
37
|
+
voidReact(),
|
|
38
|
+
]) ?? []),
|
|
39
|
+
fate({
|
|
40
|
+
module: '@app/server/src/router.ts',
|
|
41
|
+
transport: 'cloudflare',
|
|
42
|
+
}),
|
|
43
|
+
],
|
|
44
|
+
server: { port: 6001 },
|
|
45
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./node_modules/void/schema.json",
|
|
3
|
+
"target": "node",
|
|
4
|
+
"head": {
|
|
5
|
+
"title": "fate",
|
|
6
|
+
"htmlAttrs": {
|
|
7
|
+
"lang": "en"
|
|
8
|
+
},
|
|
9
|
+
"meta": [
|
|
10
|
+
{
|
|
11
|
+
"charset": "utf-8"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"name": "viewport",
|
|
15
|
+
"content": "width=device-width, initial-scale=1"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "theme-color",
|
|
19
|
+
"content": "#fff"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"link": [
|
|
23
|
+
{
|
|
24
|
+
"rel": "icon",
|
|
25
|
+
"href": "/icon.svg"
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fate-app",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"private": true,
|
|
5
|
+
"description": "fate is a modern data client for React.",
|
|
6
|
+
"author": "Christoph Nakazawa <christoph.pojer@gmail.com>",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git://github.com/nkzw-tech/fate.git"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "dotenv -e server/.env -- vp run --filter '@app/client' --filter '@app/server' build",
|
|
14
|
+
"deploy": "vp run --filter '@app/server' deploy",
|
|
15
|
+
"dev": "npm-run-all --parallel dev:client dev:server",
|
|
16
|
+
"dev:client": "cd client && vp dev",
|
|
17
|
+
"dev:server": "cd server && vp run dev",
|
|
18
|
+
"dev:setup": "vp run --filter '@app/server' dev:setup && vp run --filter '@app/client' dev:setup && vp run fate:generate",
|
|
19
|
+
"fate:generate": "vp run --filter '@app/client' fate:generate",
|
|
20
|
+
"prepare": "vp config"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@app/server": "workspace:*",
|
|
24
|
+
"@nkzw/eslint-plugin": "^2.0.0",
|
|
25
|
+
"@nkzw/oxlint-config": "^1.2.1",
|
|
26
|
+
"@swc/core": "^1.15.33",
|
|
27
|
+
"@types/node": "^25.6.0",
|
|
28
|
+
"@typescript/native-preview": "7.0.0-dev.20260505.1",
|
|
29
|
+
"babel-plugin-react-compiler": "^1.0.0",
|
|
30
|
+
"dotenv": "^17.4.2",
|
|
31
|
+
"dotenv-cli": "^11.0.0",
|
|
32
|
+
"eslint-plugin-no-only-tests": "^3.4.0",
|
|
33
|
+
"eslint-plugin-perfectionist": "^5.9.0",
|
|
34
|
+
"eslint-plugin-react-hooks": "^7.1.1",
|
|
35
|
+
"npm-run-all2": "^8.0.4",
|
|
36
|
+
"ts-node": "^10.9.2",
|
|
37
|
+
"vite": "catalog:",
|
|
38
|
+
"vite-plus": "catalog:",
|
|
39
|
+
"vitest": "catalog:"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=24.0.0",
|
|
43
|
+
"pnpm": ">=11.0.0"
|
|
44
|
+
},
|
|
45
|
+
"packageManager": "pnpm@11.0.6"
|
|
46
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
packages:
|
|
2
|
+
- client
|
|
3
|
+
- server
|
|
4
|
+
|
|
5
|
+
allowBuilds:
|
|
6
|
+
'@swc/core': true
|
|
7
|
+
esbuild: true
|
|
8
|
+
sharp: true
|
|
9
|
+
workerd: true
|
|
10
|
+
|
|
11
|
+
catalog:
|
|
12
|
+
vite: npm:@voidzero-dev/vite-plus-core@^0.1.23
|
|
13
|
+
vite-plus: ^0.1.23
|
|
14
|
+
vitest: npm:@voidzero-dev/vite-plus-test@^0.1.23
|
|
15
|
+
|
|
16
|
+
minimumReleaseAgeExclude:
|
|
17
|
+
- '@voidzero-dev/vite-plus-core'
|
|
18
|
+
- '@voidzero-dev/vite-plus-test'
|
|
19
|
+
- vite-plus
|
|
20
|
+
|
|
21
|
+
onlyBuiltDependencies:
|
|
22
|
+
- '@swc/core'
|
|
23
|
+
- '@tailwindcss/oxide'
|
|
24
|
+
- esbuild
|
|
25
|
+
- msgpackr-extract
|
|
26
|
+
- unrs-resolver
|
|
27
|
+
|
|
28
|
+
overrides:
|
|
29
|
+
kysely: 0.28.17
|
|
30
|
+
vite: 'catalog:'
|
|
31
|
+
vitest: 'catalog:'
|
|
32
|
+
|
|
33
|
+
peerDependencyRules:
|
|
34
|
+
allowAny:
|
|
35
|
+
- vite
|
|
36
|
+
- vitest
|
|
37
|
+
allowedVersions:
|
|
38
|
+
vite: '*'
|
|
39
|
+
vitest: '*'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VITE_SERVER_URL=http://localhost:8787
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
import { and, eq, gt, like, sql } from 'drizzle-orm';
|
|
3
|
+
import { drizzle, type DrizzleD1Database } from 'drizzle-orm/d1';
|
|
4
|
+
import schema from './schema.ts';
|
|
5
|
+
|
|
6
|
+
export type Database = DrizzleD1Database<typeof schema>;
|
|
7
|
+
export type D1Binding = Parameters<typeof drizzle>[0];
|
|
8
|
+
|
|
9
|
+
const store = new AsyncLocalStorage<Database>();
|
|
10
|
+
|
|
11
|
+
export const createDb = (binding: D1Binding): Database => drizzle(binding, { schema });
|
|
12
|
+
|
|
13
|
+
export const withDatabase = <T>(binding: D1Binding, callback: () => T): T =>
|
|
14
|
+
store.run(createDb(binding), callback);
|
|
15
|
+
|
|
16
|
+
const getDb = (): Database => {
|
|
17
|
+
const db = store.getStore();
|
|
18
|
+
if (!db) {
|
|
19
|
+
throw new Error('cloudflare example: D1 database is unavailable.');
|
|
20
|
+
}
|
|
21
|
+
return db;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const db = new Proxy({} as Database, {
|
|
25
|
+
get(_target, prop, receiver) {
|
|
26
|
+
return Reflect.get(getDb(), prop, receiver);
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export { and, eq, gt, like, sql };
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
CREATE TABLE `account` (
|
|
2
|
+
`accessToken` text,
|
|
3
|
+
`accessTokenExpiresAt` integer,
|
|
4
|
+
`accountId` text NOT NULL,
|
|
5
|
+
`createdAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
6
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
7
|
+
`idToken` text,
|
|
8
|
+
`password` text,
|
|
9
|
+
`providerId` text NOT NULL,
|
|
10
|
+
`refreshToken` text,
|
|
11
|
+
`refreshTokenExpiresAt` integer,
|
|
12
|
+
`scope` text,
|
|
13
|
+
`updatedAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
14
|
+
`userId` text NOT NULL,
|
|
15
|
+
FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
|
|
16
|
+
);
|
|
17
|
+
--> statement-breakpoint
|
|
18
|
+
CREATE UNIQUE INDEX `account_providerId_accountId_key` ON `account` (`providerId`,`accountId`);--> statement-breakpoint
|
|
19
|
+
CREATE TABLE `Category` (
|
|
20
|
+
`createdAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
21
|
+
`description` text,
|
|
22
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
23
|
+
`name` text NOT NULL
|
|
24
|
+
);
|
|
25
|
+
--> statement-breakpoint
|
|
26
|
+
CREATE UNIQUE INDEX `Category_name_key` ON `Category` (`name`);--> statement-breakpoint
|
|
27
|
+
CREATE TABLE `Comment` (
|
|
28
|
+
`authorId` text,
|
|
29
|
+
`content` text NOT NULL,
|
|
30
|
+
`createdAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
31
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
32
|
+
`postId` text NOT NULL,
|
|
33
|
+
FOREIGN KEY (`authorId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE set null,
|
|
34
|
+
FOREIGN KEY (`postId`) REFERENCES `Post`(`id`) ON UPDATE no action ON DELETE cascade
|
|
35
|
+
);
|
|
36
|
+
--> statement-breakpoint
|
|
37
|
+
CREATE INDEX `Comment_authorId_idx` ON `Comment` (`authorId`);--> statement-breakpoint
|
|
38
|
+
CREATE INDEX `Comment_postId_idx` ON `Comment` (`postId`);--> statement-breakpoint
|
|
39
|
+
CREATE TABLE `Event` (
|
|
40
|
+
`capacity` integer NOT NULL,
|
|
41
|
+
`createdAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
42
|
+
`description` text NOT NULL,
|
|
43
|
+
`endAt` integer NOT NULL,
|
|
44
|
+
`hostId` text NOT NULL,
|
|
45
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
46
|
+
`livestreamUrl` text,
|
|
47
|
+
`location` text NOT NULL,
|
|
48
|
+
`name` text NOT NULL,
|
|
49
|
+
`startAt` integer NOT NULL,
|
|
50
|
+
`topics` text DEFAULT '[]' NOT NULL,
|
|
51
|
+
`type` text DEFAULT 'MEETUP' NOT NULL,
|
|
52
|
+
`updatedAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
53
|
+
FOREIGN KEY (`hostId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
|
|
54
|
+
);
|
|
55
|
+
--> statement-breakpoint
|
|
56
|
+
CREATE INDEX `Event_hostId_idx` ON `Event` (`hostId`);--> statement-breakpoint
|
|
57
|
+
CREATE TABLE `EventAttendee` (
|
|
58
|
+
`createdAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
59
|
+
`eventId` text NOT NULL,
|
|
60
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
61
|
+
`notes` text,
|
|
62
|
+
`status` text DEFAULT 'INVITED' NOT NULL,
|
|
63
|
+
`userId` text NOT NULL,
|
|
64
|
+
FOREIGN KEY (`eventId`) REFERENCES `Event`(`id`) ON UPDATE no action ON DELETE cascade,
|
|
65
|
+
FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
|
|
66
|
+
);
|
|
67
|
+
--> statement-breakpoint
|
|
68
|
+
CREATE UNIQUE INDEX `EventAttendee_eventId_userId_key` ON `EventAttendee` (`eventId`,`userId`);--> statement-breakpoint
|
|
69
|
+
CREATE INDEX `EventAttendee_userId_idx` ON `EventAttendee` (`userId`);--> statement-breakpoint
|
|
70
|
+
CREATE TABLE `Post` (
|
|
71
|
+
`authorId` text NOT NULL,
|
|
72
|
+
`categoryId` text,
|
|
73
|
+
`content` text NOT NULL,
|
|
74
|
+
`createdAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
75
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
76
|
+
`likes` integer DEFAULT 0 NOT NULL,
|
|
77
|
+
`title` text NOT NULL,
|
|
78
|
+
`updatedAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
79
|
+
FOREIGN KEY (`authorId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade,
|
|
80
|
+
FOREIGN KEY (`categoryId`) REFERENCES `Category`(`id`) ON UPDATE no action ON DELETE set null
|
|
81
|
+
);
|
|
82
|
+
--> statement-breakpoint
|
|
83
|
+
CREATE INDEX `Post_authorId_idx` ON `Post` (`authorId`);--> statement-breakpoint
|
|
84
|
+
CREATE TABLE `_PostTags` (
|
|
85
|
+
`A` text NOT NULL,
|
|
86
|
+
`B` text NOT NULL,
|
|
87
|
+
PRIMARY KEY(`A`, `B`),
|
|
88
|
+
FOREIGN KEY (`A`) REFERENCES `Post`(`id`) ON UPDATE no action ON DELETE cascade,
|
|
89
|
+
FOREIGN KEY (`B`) REFERENCES `Tag`(`id`) ON UPDATE no action ON DELETE cascade
|
|
90
|
+
);
|
|
91
|
+
--> statement-breakpoint
|
|
92
|
+
CREATE INDEX `_PostTags_B_index` ON `_PostTags` (`B`);--> statement-breakpoint
|
|
93
|
+
CREATE TABLE `session` (
|
|
94
|
+
`createdAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
95
|
+
`expiresAt` integer NOT NULL,
|
|
96
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
97
|
+
`ipAddress` text,
|
|
98
|
+
`token` text NOT NULL,
|
|
99
|
+
`updatedAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
100
|
+
`userAgent` text,
|
|
101
|
+
`userId` text NOT NULL,
|
|
102
|
+
FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
|
|
103
|
+
);
|
|
104
|
+
--> statement-breakpoint
|
|
105
|
+
CREATE UNIQUE INDEX `session_token_key` ON `session` (`token`);--> statement-breakpoint
|
|
106
|
+
CREATE TABLE `Tag` (
|
|
107
|
+
`createdAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
108
|
+
`description` text,
|
|
109
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
110
|
+
`name` text NOT NULL
|
|
111
|
+
);
|
|
112
|
+
--> statement-breakpoint
|
|
113
|
+
CREATE UNIQUE INDEX `Tag_name_key` ON `Tag` (`name`);--> statement-breakpoint
|
|
114
|
+
CREATE TABLE `user` (
|
|
115
|
+
`banExpires` integer,
|
|
116
|
+
`banned` integer,
|
|
117
|
+
`banReason` text,
|
|
118
|
+
`createdAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
119
|
+
`displayUsername` text,
|
|
120
|
+
`email` text NOT NULL,
|
|
121
|
+
`emailVerified` integer DEFAULT false NOT NULL,
|
|
122
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
123
|
+
`image` text,
|
|
124
|
+
`name` text NOT NULL,
|
|
125
|
+
`password` text,
|
|
126
|
+
`role` text DEFAULT 'user' NOT NULL,
|
|
127
|
+
`updatedAt` integer DEFAULT (unixepoch()) NOT NULL,
|
|
128
|
+
`username` text
|
|
129
|
+
);
|
|
130
|
+
--> statement-breakpoint
|
|
131
|
+
CREATE UNIQUE INDEX `user_email_key` ON `user` (`email`);--> statement-breakpoint
|
|
132
|
+
CREATE UNIQUE INDEX `user_username_key` ON `user` (`username`);--> statement-breakpoint
|
|
133
|
+
CREATE INDEX `user_id_idx` ON `user` (`id`);
|
package/templates/fate/cloudflare/server/db/migrations/20260508120500_seed_cloudflare_demo.sql
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
-- Demo seed data for the Cloudflare template.
|
|
2
|
+
|
|
3
|
+
-- Password hashes use Better Auth format and match the example seed credentials.
|
|
4
|
+
|
|
5
|
+
INSERT OR IGNORE INTO user VALUES(NULL,0,NULL,1778241933,NULL,'alex@example.com',0,'744eda47-e9da-4145-a068-30e6905504a4',NULL,'Alex',NULL,'admin',1778241933,'alex');
|
|
6
|
+
INSERT OR IGNORE INTO user VALUES(NULL,0,NULL,1778241933,NULL,'ari@nakazawa.dev',0,'d8714b4a-3b36-4529-b806-3e654d0c51fa',NULL,'Ari',NULL,'user',1778241933,'ari');
|
|
7
|
+
INSERT OR IGNORE INTO user VALUES(NULL,0,NULL,1778241933,NULL,'dina@nakazawa.dev',0,'4b7e1e37-c199-44b3-96af-9591972fc40a',NULL,'Dina',NULL,'user',1778241933,'dina');
|
|
8
|
+
INSERT OR IGNORE INTO user VALUES(NULL,0,NULL,1778241933,NULL,'hana@nakazawa.dev',0,'cfdacdb3-7ad3-4158-b3fe-4baf6e197e64',NULL,'Hana',NULL,'user',1778241933,'hana');
|
|
9
|
+
INSERT OR IGNORE INTO user VALUES(NULL,0,NULL,1778241933,NULL,'jamal@nakazawa.dev',0,'38fbdd46-8410-4fc3-888b-bdcc21c1b725',NULL,'Jamal',NULL,'user',1778241933,'jamal');
|
|
10
|
+
INSERT OR IGNORE INTO user VALUES(NULL,0,NULL,1778241933,NULL,'kai@nakazawa.dev',0,'2c8a1b16-ae54-4a22-982b-148e469829e1',NULL,'Kai',NULL,'user',1778241933,'kai');
|
|
11
|
+
INSERT OR IGNORE INTO user VALUES(NULL,0,NULL,1778241933,NULL,'lena@nakazawa.dev',0,'69ad225c-a6d5-4747-8372-5c60da964497',NULL,'Lena',NULL,'user',1778241933,'lena');
|
|
12
|
+
INSERT OR IGNORE INTO user VALUES(NULL,0,NULL,1778241933,NULL,'mika@nakazawa.dev',0,'1418a697-43d9-4c3d-8f20-23ea82aa13a9',NULL,'Mika',NULL,'user',1778241933,'mika');
|
|
13
|
+
INSERT OR IGNORE INTO user VALUES(NULL,0,NULL,1778241933,NULL,'noah@nakazawa.dev',0,'22c06d32-a442-4cb4-83c3-da9cf6c37e77',NULL,'Noah',NULL,'user',1778241933,'noah');
|
|
14
|
+
INSERT OR IGNORE INTO user VALUES(NULL,0,NULL,1778241933,NULL,'sora@nakazawa.dev',0,'2a90a86b-fc30-43c6-bdc1-d3f71a65a939',NULL,'Sora',NULL,'user',1778241933,'sora');
|
|
15
|
+
INSERT OR IGNORE INTO account VALUES(NULL,NULL,'744eda47-e9da-4145-a068-30e6905504a4',1778241933,'915acc62-1d1d-4957-b992-95d6dcdd39a9',NULL,'f2719f081b49f54a6c78370c831671c7:664d06fe946fb341cd8e75f62fc7d93d7e3794b5a22651367e90362bd0117d86b8cbf8fb2f36723dcd685bc8fded937f918897b7aa2d219a74760103c087fa09','credential',NULL,NULL,NULL,1778241933,'744eda47-e9da-4145-a068-30e6905504a4');
|
|
16
|
+
INSERT OR IGNORE INTO account VALUES(NULL,NULL,'d8714b4a-3b36-4529-b806-3e654d0c51fa',1778241933,'5d970ce9-73b0-479f-b05c-601f98142a28',NULL,'14a0cd77ce86b7d97c958ef81fb562ce:d9ca8ff0a74377287cf17c8e94f79f651d5213eaf736528198c30f0078ca57f0ac743dd2517d9a2377b66066688b6a384f5cea05927ebca0a86fa9beb5d116f4','credential',NULL,NULL,NULL,1778241933,'d8714b4a-3b36-4529-b806-3e654d0c51fa');
|
|
17
|
+
INSERT OR IGNORE INTO account VALUES(NULL,NULL,'4b7e1e37-c199-44b3-96af-9591972fc40a',1778241933,'38b83e50-8605-4018-a069-b90b32da6689',NULL,'5c1ab9a33273657ebb1b5927d86b082a:31031b51ec680da4f7b4e8ce9cda019fc602380b978390e93a196112b4a1beff6c5e0d93eee79e168f06234822d4d75b5b759dc51dea7d292fe52f3892b3e166','credential',NULL,NULL,NULL,1778241933,'4b7e1e37-c199-44b3-96af-9591972fc40a');
|
|
18
|
+
INSERT OR IGNORE INTO account VALUES(NULL,NULL,'cfdacdb3-7ad3-4158-b3fe-4baf6e197e64',1778241933,'9400c04a-6a20-4021-8fbc-4e8504524b8d',NULL,'eea3549cc6868da66d4232e3d1a82ad5:559378d066ebade288f53e48c27ba1263efafbd7bff52a9632d6a6db9fe450b411e2dcc9d5b3911b1fdd702e4acf6e968110da5d5319118d65d18394ff3a062a','credential',NULL,NULL,NULL,1778241933,'cfdacdb3-7ad3-4158-b3fe-4baf6e197e64');
|
|
19
|
+
INSERT OR IGNORE INTO account VALUES(NULL,NULL,'38fbdd46-8410-4fc3-888b-bdcc21c1b725',1778241933,'f8b8771d-8be5-4cfa-9c4b-400c5bae5165',NULL,'b419b6c94bef7259f66c0be74c9a3432:14a99e424e55ceb60f8d531d0ae7c3d99a1f4a6ee5fc7b7eca6eca418f70f779bf7b9eaf3517055e087a77d27d21708104f11d62110ee9387db35043dd9e6880','credential',NULL,NULL,NULL,1778241933,'38fbdd46-8410-4fc3-888b-bdcc21c1b725');
|
|
20
|
+
INSERT OR IGNORE INTO account VALUES(NULL,NULL,'2c8a1b16-ae54-4a22-982b-148e469829e1',1778241933,'c595ac07-f429-4a29-9ae0-967c3b133547',NULL,'534eb9c097409217c1a3041a06ff333d:1a612a49dc299c98a73f30fe75b0c09a245cdd3f03b724b988846fc243bcde125c09ec1ea44420d8a947e76e2053bace6a43c87a895bd45cfc7cf18a0ce112f6','credential',NULL,NULL,NULL,1778241933,'2c8a1b16-ae54-4a22-982b-148e469829e1');
|
|
21
|
+
INSERT OR IGNORE INTO account VALUES(NULL,NULL,'69ad225c-a6d5-4747-8372-5c60da964497',1778241933,'f57fab4c-1f8a-49db-a455-4b87486f640e',NULL,'00209ffa555288a2cd74635775239e7e:7792f1f34937825312b4327caf9ef580861a9c6b22d0d9f237cf035e7b0de26a6ac342f5f36ad999a8adcc1b6f3c1861778a378bcaacd4aabac96db845eb68cb','credential',NULL,NULL,NULL,1778241933,'69ad225c-a6d5-4747-8372-5c60da964497');
|
|
22
|
+
INSERT OR IGNORE INTO account VALUES(NULL,NULL,'1418a697-43d9-4c3d-8f20-23ea82aa13a9',1778241933,'a48cf3b6-7154-4f5e-9831-e08ed2102e91',NULL,'ecfb5ea9555601d192c2be612a25203c:a79d092f9d74c5301f7e1f02e8a5d8f8563ac42a8e71fa78c184b4777831a1c7761ad5d021d796f765b15efdfdc1dc24d5c9b76818c9f224eb034fd573a7f260','credential',NULL,NULL,NULL,1778241933,'1418a697-43d9-4c3d-8f20-23ea82aa13a9');
|
|
23
|
+
INSERT OR IGNORE INTO account VALUES(NULL,NULL,'22c06d32-a442-4cb4-83c3-da9cf6c37e77',1778241933,'83dc5a0a-eb32-4b18-b848-abea62b999fa',NULL,'1c3bccdd22ab8c4b5b5438f86fdb4663:ff08e12ff1b871c4f5766bdc9430a2cf2276be8fe5a619a2b0381a94ec808357322eea1db221b014f3a6d67f7bda58079ab216f6afdd388d9a93784b420e5ec5','credential',NULL,NULL,NULL,1778241933,'22c06d32-a442-4cb4-83c3-da9cf6c37e77');
|
|
24
|
+
INSERT OR IGNORE INTO account VALUES(NULL,NULL,'2a90a86b-fc30-43c6-bdc1-d3f71a65a939',1778241933,'cce49048-9a28-4240-adbf-78d89e313d5c',NULL,'887dcbdfc479351196e8c81ca586d394:19c7229c0a074e88b8e9e3271a14dae07342dc502049a25957c8ce140642d64d1f08e38228492cf4fce227a8ab927e9a91923d2c2e3fd909c5384ea801da72ec','credential',NULL,NULL,NULL,1778241933,'2a90a86b-fc30-43c6-bdc1-d3f71a65a939');
|
|
25
|
+
INSERT OR IGNORE INTO Category VALUES(1778241933,'Core ideas behind views, ViewRefs, strict selection, and data masking.','4062b9a5-5fd2-4bca-8698-c8f3d673de79','Core Concepts');
|
|
26
|
+
INSERT OR IGNORE INTO Category VALUES(1778241933,'Async React, Suspense, Actions, and the react-fate hooks.','31dc1b32-c72d-414c-8683-9299647c8f76','React Integration');
|
|
27
|
+
INSERT OR IGNORE INTO Category VALUES(1778241933,'Cloudflare, D1, Drizzle, tRPC, and source adapter notes.','1f53b477-1823-4ae2-ad11-38d626f08c45','Server Integrations');
|
|
28
|
+
INSERT OR IGNORE INTO Category VALUES(1778241933,'Live views, live lists, SSE streams, and update events.','95212cad-8f8d-4752-90fc-54463b75eb05','Realtime');
|
|
29
|
+
INSERT OR IGNORE INTO Category VALUES(1778241933,'Progress reports from the alpha releases and example applications.','c7e25ec5-66b6-4d5f-93e8-d335b898105b','Release Notes');
|
|
30
|
+
INSERT OR IGNORE INTO Category VALUES(1778241933,'Practical migration notes for teams moving away from request-centric state.','9ff95004-3301-45b5-b494-ffe26b669db5','Migration Notes');
|
|
31
|
+
INSERT OR IGNORE INTO Tag VALUES(1778241933,'Co-located data requirements composed into one request.','49dd0ca0-a6bc-4236-bc93-0719fe670915','views');
|
|
32
|
+
INSERT OR IGNORE INTO Tag VALUES(1778241933,'Object records keyed by typename and id.','818334f8-4c06-49c5-a4eb-7eac795af7e2','normalized-cache');
|
|
33
|
+
INSERT OR IGNORE INTO Tag VALUES(1778241933,'Strict field selection and masked component data.','7127568b-62f2-4621-8970-8f9a00ad8959','data-masking');
|
|
34
|
+
INSERT OR IGNORE INTO Tag VALUES(1778241933,'Suspense, Actions, use, and concurrent rendering patterns.','d643467a-e3f9-40fa-b109-530c5ae22459','async-react');
|
|
35
|
+
INSERT OR IGNORE INTO Tag VALUES(1778241933,'Declarative optimistic updates and automatic rollback behavior.','c787e4ed-f223-402d-a46c-f775c2d41be3','optimistic-updates');
|
|
36
|
+
INSERT OR IGNORE INTO Tag VALUES(1778241933,'Connection-style lists with cursors and load-more flows.','13996323-715d-4203-9574-4ad918179a6d','pagination');
|
|
37
|
+
INSERT OR IGNORE INTO Tag VALUES(1778241933,'Object and connection subscriptions over a single SSE stream.','dbab4d43-4433-4861-97f3-57f801b2b8b7','live-views');
|
|
38
|
+
INSERT OR IGNORE INTO Tag VALUES(1778241933,'The Cloudflare fate transport for Workers and D1 apps.','aba3d06b-efb5-4244-a53a-33e9e4803451','cloudflare-transport');
|
|
39
|
+
INSERT OR IGNORE INTO Tag VALUES(1778241933,'Prisma, Drizzle, and server-side data view adapters.','f9b70ac0-2096-4345-ae59-d82f66f9ba27','server-adapters');
|
|
40
|
+
INSERT OR IGNORE INTO Tag VALUES(1778241933,'Generated client types produced by the Vite plugin.','b2f8e680-9083-4597-b2db-b4410c7fc406','vite-plugin');
|
|
41
|
+
INSERT OR IGNORE INTO Tag VALUES(1778241933,'The Cloudflare Worker and Durable Object live-update example.','7bfe64be-36c8-4c0c-ac76-ca0e13897861','cloudflare');
|
|
42
|
+
|
|
43
|
+
INSERT OR IGNORE INTO Post VALUES('744eda47-e9da-4145-a068-30e6905504a4','4062b9a5-5fd2-4bca-8698-c8f3d673de79','The first note in this demo restates the core promise from the announcement: fate keeps component data requirements co-located, then composes them into one request at the screen root. Instead of deciding when every component should fetch, you describe what each component needs. The result feels close to Relay fragments, but it stays in plain TypeScript with no GraphQL schema or query language to adopt.',1778241933,'369771a1-f3aa-4fd6-a1fa-2cfbc1a50bed',128,'Thinking in views instead of requests',1778241933);
|
|
44
|
+
INSERT OR IGNORE INTO Post VALUES('d8714b4a-3b36-4529-b806-3e654d0c51fa','4062b9a5-5fd2-4bca-8698-c8f3d673de79','ViewRefs are intentionally small: a typename, an id, and enough metadata for fate to resolve masked data against a view. Passing refs through the tree keeps component props light and lets each component declare the fields it reads. This post walks through how a PostCard can select title and author while a detail route adds comments, tags, and counts without creating another hand-written data shape.',1778241933,'fff329e4-9948-49e7-9fe6-1cacf76e89e2',93,'ViewRefs as the boundary between components',1778241933);
|
|
45
|
+
INSERT OR IGNORE INTO Post VALUES('4b7e1e37-c199-44b3-96af-9591972fc40a','4062b9a5-5fd2-4bca-8698-c8f3d673de79','Strict selection is the feature that makes a demo like this stay honest. If a component did not select content, content is not part of its usable data. That protects teams from accidental coupling, makes refactors smaller, and gives code generation tools a predictable surface. The cache may know more about an object, but the component only sees the fields its view asked for.',1778241933,'112a0063-2057-4b30-adf5-3e5a0c945108',87,'Data masking as a team contract',1778241933);
|
|
46
|
+
INSERT OR IGNORE INTO Post VALUES('cfdacdb3-7ad3-4158-b3fe-4baf6e197e64','4062b9a5-5fd2-4bca-8698-c8f3d673de79','fate stores records by __typename and id, then points roots and lists at those records. That is why liking a post can update every view that selected likes without touching views that only selected title. This article follows one Post record through the home feed, category page, search results, and detail route to show how normalized data removes duplicate cache entries.',1778241933,'5dd158a1-839b-4040-9fa8-4579f1345fbb',111,'A normalized cache without manual key math',1778241933);
|
|
47
|
+
INSERT OR IGNORE INTO Post VALUES('38fbdd46-8410-4fc3-888b-bdcc21c1b725','31dc1b32-c72d-414c-8683-9299647c8f76','The React integration leans on Suspense instead of local loading flags. A root useRequest call can suspend while the composed selection is fetched, and errors bubble to normal error boundaries. The components underneath can stay focused on rendering masked data. The post also shows why this is useful for AI-generated code: there are fewer branches and fewer imperative states to keep in sync.',1778241933,'f1ca824d-30da-4bfb-9637-b41a0a4142dd',76,'Suspense-first screens with useRequest',1778241933);
|
|
48
|
+
INSERT OR IGNORE INTO Post VALUES('2c8a1b16-ae54-4a22-982b-148e469829e1','31dc1b32-c72d-414c-8683-9299647c8f76','Actions in fate are exposed for useActionState, and mutations can carry an optimistic object alongside the input. The cache applies the optimistic update immediately, re-renders affected views, and rolls the affected records back if the server rejects the mutation. This example uses the like button because it is easy to see, but the same model works for comments and other records.',1778241933,'b5d4d8ac-d788-4e74-bc6e-57e4148c1f58',82,'Optimistic actions that roll back cleanly',1778241933);
|
|
49
|
+
INSERT OR IGNORE INTO Post VALUES('69ad225c-a6d5-4747-8372-5c60da964497','31dc1b32-c72d-414c-8683-9299647c8f76','The comments under each post use connection-style lists so the UI can load more without inventing a pagination protocol per screen. fate tracks cursor arguments as part of the list state, merges pages into the same connection, and keeps the records normalized. The home feed starts small on purpose so the load-more button exercises this path in the example.',1778241933,'33178d9c-7ea5-425b-8a8c-96f687d7d538',69,'Connection lists for comments and feeds',1778241933);
|
|
50
|
+
INSERT OR IGNORE INTO Post VALUES('1418a697-43d9-4c3d-8f20-23ea82aa13a9','95212cad-8f8d-4752-90fc-54463b75eb05','useLiveView has the same shape as useView, but it subscribes to updates for the selected object through the Cloudflare live transport. The client keeps one SSE stream open, sends subscribe and unsubscribe control messages, and merges returned records into the same normalized cache used by requests and mutations. Components keep their view definitions and just opt into live data.',1778241933,'fe785e82-b46b-4b27-b1c6-9e1e1cd6af73',104,'Live views over a single SSE stream',1778241933);
|
|
51
|
+
INSERT OR IGNORE INTO Post VALUES('22c06d32-a442-4cb4-83c3-da9cf6c37e77','95212cad-8f8d-4752-90fc-54463b75eb05','Live list views extend the same idea to connections. When a comment is added, the server can emit a prepend event for Post.comments and fate updates the visible connection without deleting the underlying Comment record. By default, pagination boundaries are respected, and streams like chat can opt into visible insertion. That gives realtime behavior without turning every list into special-case UI code.',1778241933,'138350a3-8b9e-415b-8fcc-5bfaec6751fc',97,'Live list views for active threads',1778241933);
|
|
52
|
+
INSERT OR IGNORE INTO Post VALUES('2a90a86b-fc30-43c6-bdc1-d3f71a65a939','95212cad-8f8d-4752-90fc-54463b75eb05','Deletion events are just as important as updates. If a comment disappears, fate removes the record from the normalized cache and prunes lists or object fields that reference it. The demo comment controls exercise that behavior so the post detail route, live comment list, and comment count stay aligned after a mutation completes.',1778241933,'8f140027-21d9-42d4-87a2-1f180fa2fcf9',64,'Keeping deletions consistent across lists',1778241933);
|
|
53
|
+
INSERT OR IGNORE INTO Post VALUES('d8714b4a-3b36-4529-b806-3e654d0c51fa','1f53b477-1823-4ae2-ad11-38d626f08c45','The launch post introduced fate with tRPC, but the repo now includes a Cloudflare transport too. The generated client can point at a fate endpoint, send requests through the protocol package, and use GET and POST routes for live updates. tRPC remains a supported adapter, but the core model no longer depends on it.',1778241933,'1c9368f3-8573-4d20-bf92-b4e0004e52fa',88,'Cloudflare transport after the alpha launch',1778241933);
|
|
54
|
+
INSERT OR IGNORE INTO Post VALUES('4b7e1e37-c199-44b3-96af-9591972fc40a','1f53b477-1823-4ae2-ad11-38d626f08c45','The server adapters now cover Prisma, Drizzle, and D1 with the same data view concepts. Sources describe how to resolve records, fields, lists, counts, and computed values, while fate builds the selected shape for the client. This makes the examples useful for teams with different database layers without changing the component data model.',1778241933,'419d0f1c-00ea-4a9b-baf2-5e90886c0b2e',84,'Prisma, Drizzle, and D1 source adapters',1778241933);
|
|
55
|
+
INSERT OR IGNORE INTO Post VALUES('cfdacdb3-7ad3-4158-b3fe-4baf6e197e64','1f53b477-1823-4ae2-ad11-38d626f08c45','Arguments are part of request identity, but pagination cursors are merged into the same connection when the user loads another page. This post explains why category filters, search terms, and sort options belong in the cache key while after and before control pagination state. The result follows Relay connection semantics without asking app code to manage query keys.',1778241933,'72ec3c4b-afd4-4096-87de-7d89100a8c1b',73,'Request arguments and connection identity',1778241933);
|
|
56
|
+
INSERT OR IGNORE INTO Post VALUES('38fbdd46-8410-4fc3-888b-bdcc21c1b725','c7e25ec5-66b6-4d5f-93e8-d335b898105b','The code generator is now optional for CI and custom workflows because the Vite plugin handles the common path during development. The plugin generates the typed client from the server surface, keeps imports fresh, and reduces the number of manual setup steps in a new app. It is one of the changes that makes the default template feel much closer to normal Vite development.',1778241933,'ec6a3200-bf9a-4bf3-8de2-5505e95d5f59',91,'The Vite plugin replaces everyday codegen',1778241933);
|
|
57
|
+
INSERT OR IGNORE INTO Post VALUES('2c8a1b16-ae54-4a22-982b-148e469829e1','c7e25ec5-66b6-4d5f-93e8-d335b898105b','The cache now tracks retained requests so screens can release data when they unmount and let garbage collection clean up records that are no longer needed. For manual client.request calls, code can retain the descriptor for as long as the work needs it. The important part is that cache lifetime becomes explicit without forcing every component to think about cleanup.',1778241933,'5bf6844d-6cef-4a53-b6f3-5860b7ff8dea',58,'Garbage collection for request lifetimes',1778241933);
|
|
58
|
+
INSERT OR IGNORE INTO Post VALUES('69ad225c-a6d5-4747-8372-5c60da964497','c7e25ec5-66b6-4d5f-93e8-d335b898105b','Stable refs were a small change with a large ergonomic payoff. When a record has not changed, fate can keep ViewRefs stable across renders, which helps memoized components and reduces avoidable updates. Combined with strict selection, this keeps rendering tied to the fields a component actually requested instead of the shape of a whole server response.',1778241933,'e506c96a-80b8-4f41-b91b-cd4a988b3652',67,'Stable refs and smaller rerenders',1778241933);
|
|
59
|
+
INSERT OR IGNORE INTO Post VALUES('1418a697-43d9-4c3d-8f20-23ea82aa13a9','9ff95004-3301-45b5-b494-ffe26b669db5','Migrating from request-centric libraries starts with a mindset shift. Instead of passing server data down as custom prop types, define small views next to the components that render them and compose those views at the route. The cache then works by object identity, so mutations and live updates update the relevant records rather than a spread of unrelated request results.',1778241933,'86e6b2c6-8e37-480d-9c19-de384fa8bbae',79,'Moving away from request-centric state',1778241933);
|
|
60
|
+
INSERT OR IGNORE INTO Post VALUES('22c06d32-a442-4cb4-83c3-da9cf6c37e77','9ff95004-3301-45b5-b494-ffe26b669db5','The safest adoption path is incremental. Add byId and list procedures or source adapters next to existing server routes, generate a client, and move one screen to views. The first win is usually removing loading branches and manual cache patches from a feed or detail page. From there, optimistic actions and live views can be introduced without rewriting the whole app.',1778241933,'f1faa9f8-f2db-4fd0-8c81-2809d6174611',62,'An incremental adoption checklist',1778241933);
|
|
61
|
+
INSERT OR IGNORE INTO Post VALUES('2a90a86b-fc30-43c6-bdc1-d3f71a65a939','c7e25ec5-66b6-4d5f-93e8-d335b898105b','The Cloudflare example uses the same fate ideas in a Cloudflare Worker app with D1, auth, mutations, live comments, categories, tags, and events. It exists to prove the core protocol and framework APIs are not tied to one server framework. The seed data includes this post so search and category views can show the newest example alongside the Prisma and Drizzle servers.',1778241933,'0e3c60e0-f7a3-4d6b-bdaf-1d7ab5c65035',86,'What the Cloudflare example proves',1778241933);
|
|
62
|
+
INSERT OR IGNORE INTO _PostTags VALUES('369771a1-f3aa-4fd6-a1fa-2cfbc1a50bed','49dd0ca0-a6bc-4236-bc93-0719fe670915');
|
|
63
|
+
INSERT OR IGNORE INTO _PostTags VALUES('369771a1-f3aa-4fd6-a1fa-2cfbc1a50bed','7127568b-62f2-4621-8970-8f9a00ad8959');
|
|
64
|
+
INSERT OR IGNORE INTO _PostTags VALUES('fff329e4-9948-49e7-9fe6-1cacf76e89e2','49dd0ca0-a6bc-4236-bc93-0719fe670915');
|
|
65
|
+
INSERT OR IGNORE INTO _PostTags VALUES('fff329e4-9948-49e7-9fe6-1cacf76e89e2','818334f8-4c06-49c5-a4eb-7eac795af7e2');
|
|
66
|
+
INSERT OR IGNORE INTO _PostTags VALUES('112a0063-2057-4b30-adf5-3e5a0c945108','7127568b-62f2-4621-8970-8f9a00ad8959');
|
|
67
|
+
INSERT OR IGNORE INTO _PostTags VALUES('112a0063-2057-4b30-adf5-3e5a0c945108','49dd0ca0-a6bc-4236-bc93-0719fe670915');
|
|
68
|
+
INSERT OR IGNORE INTO _PostTags VALUES('5dd158a1-839b-4040-9fa8-4579f1345fbb','818334f8-4c06-49c5-a4eb-7eac795af7e2');
|
|
69
|
+
INSERT OR IGNORE INTO _PostTags VALUES('5dd158a1-839b-4040-9fa8-4579f1345fbb','c787e4ed-f223-402d-a46c-f775c2d41be3');
|
|
70
|
+
INSERT OR IGNORE INTO _PostTags VALUES('f1ca824d-30da-4bfb-9637-b41a0a4142dd','d643467a-e3f9-40fa-b109-530c5ae22459');
|
|
71
|
+
INSERT OR IGNORE INTO _PostTags VALUES('f1ca824d-30da-4bfb-9637-b41a0a4142dd','49dd0ca0-a6bc-4236-bc93-0719fe670915');
|
|
72
|
+
INSERT OR IGNORE INTO _PostTags VALUES('b5d4d8ac-d788-4e74-bc6e-57e4148c1f58','d643467a-e3f9-40fa-b109-530c5ae22459');
|
|
73
|
+
INSERT OR IGNORE INTO _PostTags VALUES('b5d4d8ac-d788-4e74-bc6e-57e4148c1f58','c787e4ed-f223-402d-a46c-f775c2d41be3');
|
|
74
|
+
INSERT OR IGNORE INTO _PostTags VALUES('33178d9c-7ea5-425b-8a8c-96f687d7d538','13996323-715d-4203-9574-4ad918179a6d');
|
|
75
|
+
INSERT OR IGNORE INTO _PostTags VALUES('33178d9c-7ea5-425b-8a8c-96f687d7d538','818334f8-4c06-49c5-a4eb-7eac795af7e2');
|
|
76
|
+
INSERT OR IGNORE INTO _PostTags VALUES('fe785e82-b46b-4b27-b1c6-9e1e1cd6af73','dbab4d43-4433-4861-97f3-57f801b2b8b7');
|
|
77
|
+
INSERT OR IGNORE INTO _PostTags VALUES('fe785e82-b46b-4b27-b1c6-9e1e1cd6af73','818334f8-4c06-49c5-a4eb-7eac795af7e2');
|
|
78
|
+
INSERT OR IGNORE INTO _PostTags VALUES('138350a3-8b9e-415b-8fcc-5bfaec6751fc','dbab4d43-4433-4861-97f3-57f801b2b8b7');
|
|
79
|
+
INSERT OR IGNORE INTO _PostTags VALUES('138350a3-8b9e-415b-8fcc-5bfaec6751fc','13996323-715d-4203-9574-4ad918179a6d');
|
|
80
|
+
INSERT OR IGNORE INTO _PostTags VALUES('8f140027-21d9-42d4-87a2-1f180fa2fcf9','dbab4d43-4433-4861-97f3-57f801b2b8b7');
|
|
81
|
+
INSERT OR IGNORE INTO _PostTags VALUES('8f140027-21d9-42d4-87a2-1f180fa2fcf9','c787e4ed-f223-402d-a46c-f775c2d41be3');
|
|
82
|
+
INSERT OR IGNORE INTO _PostTags VALUES('1c9368f3-8573-4d20-bf92-b4e0004e52fa','aba3d06b-efb5-4244-a53a-33e9e4803451');
|
|
83
|
+
INSERT OR IGNORE INTO _PostTags VALUES('1c9368f3-8573-4d20-bf92-b4e0004e52fa','f9b70ac0-2096-4345-ae59-d82f66f9ba27');
|
|
84
|
+
INSERT OR IGNORE INTO _PostTags VALUES('419d0f1c-00ea-4a9b-baf2-5e90886c0b2e','f9b70ac0-2096-4345-ae59-d82f66f9ba27');
|
|
85
|
+
INSERT OR IGNORE INTO _PostTags VALUES('419d0f1c-00ea-4a9b-baf2-5e90886c0b2e','49dd0ca0-a6bc-4236-bc93-0719fe670915');
|
|
86
|
+
INSERT OR IGNORE INTO _PostTags VALUES('72ec3c4b-afd4-4096-87de-7d89100a8c1b','13996323-715d-4203-9574-4ad918179a6d');
|
|
87
|
+
INSERT OR IGNORE INTO _PostTags VALUES('72ec3c4b-afd4-4096-87de-7d89100a8c1b','f9b70ac0-2096-4345-ae59-d82f66f9ba27');
|
|
88
|
+
INSERT OR IGNORE INTO _PostTags VALUES('ec6a3200-bf9a-4bf3-8de2-5505e95d5f59','b2f8e680-9083-4597-b2db-b4410c7fc406');
|
|
89
|
+
INSERT OR IGNORE INTO _PostTags VALUES('ec6a3200-bf9a-4bf3-8de2-5505e95d5f59','aba3d06b-efb5-4244-a53a-33e9e4803451');
|
|
90
|
+
INSERT OR IGNORE INTO _PostTags VALUES('5bf6844d-6cef-4a53-b6f3-5860b7ff8dea','818334f8-4c06-49c5-a4eb-7eac795af7e2');
|
|
91
|
+
INSERT OR IGNORE INTO _PostTags VALUES('5bf6844d-6cef-4a53-b6f3-5860b7ff8dea','d643467a-e3f9-40fa-b109-530c5ae22459');
|
|
92
|
+
INSERT OR IGNORE INTO _PostTags VALUES('e506c96a-80b8-4f41-b91b-cd4a988b3652','49dd0ca0-a6bc-4236-bc93-0719fe670915');
|
|
93
|
+
INSERT OR IGNORE INTO _PostTags VALUES('e506c96a-80b8-4f41-b91b-cd4a988b3652','818334f8-4c06-49c5-a4eb-7eac795af7e2');
|
|
94
|
+
INSERT OR IGNORE INTO _PostTags VALUES('86e6b2c6-8e37-480d-9c19-de384fa8bbae','49dd0ca0-a6bc-4236-bc93-0719fe670915');
|
|
95
|
+
INSERT OR IGNORE INTO _PostTags VALUES('86e6b2c6-8e37-480d-9c19-de384fa8bbae','818334f8-4c06-49c5-a4eb-7eac795af7e2');
|
|
96
|
+
INSERT OR IGNORE INTO _PostTags VALUES('f1faa9f8-f2db-4fd0-8c81-2809d6174611','f9b70ac0-2096-4345-ae59-d82f66f9ba27');
|
|
97
|
+
INSERT OR IGNORE INTO _PostTags VALUES('f1faa9f8-f2db-4fd0-8c81-2809d6174611','d643467a-e3f9-40fa-b109-530c5ae22459');
|
|
98
|
+
INSERT OR IGNORE INTO _PostTags VALUES('0e3c60e0-f7a3-4d6b-bdaf-1d7ab5c65035','7bfe64be-36c8-4c0c-ac76-ca0e13897861');
|
|
99
|
+
INSERT OR IGNORE INTO _PostTags VALUES('0e3c60e0-f7a3-4d6b-bdaf-1d7ab5c65035','aba3d06b-efb5-4244-a53a-33e9e4803451');
|
|
100
|
+
|
|
101
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('2c8a1b16-ae54-4a22-982b-148e469829e1','The view-first framing is the clearest way I have seen to explain why request hooks create so much incidental state.',1778241933,'6a33dd97-4841-4b6a-b797-cba09563553f','369771a1-f3aa-4fd6-a1fa-2cfbc1a50bed');
|
|
102
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('2a90a86b-fc30-43c6-bdc1-d3f71a65a939','Passing ViewRefs through components made the example easier to read than a stack of custom DTO types.',1778241933,'4401461a-a135-48da-8edb-5a14994a65dc','fff329e4-9948-49e7-9fe6-1cacf76e89e2');
|
|
103
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('2c8a1b16-ae54-4a22-982b-148e469829e1','Strict selection caught a missing field in my test component immediately, which is exactly the kind of failure I want.',1778241933,'af5660e1-7de1-422d-ae7f-df7a5f5cbaca','112a0063-2057-4b30-adf5-3e5a0c945108');
|
|
104
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('2a90a86b-fc30-43c6-bdc1-d3f71a65a939','The normalized cache explanation finally connected likes, comments, categories, and search results for our team.',1778241933,'e544d8d8-4118-4c76-802d-984eaa3e559d','5dd158a1-839b-4040-9fa8-4579f1345fbb');
|
|
105
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('744eda47-e9da-4145-a068-30e6905504a4','Suspense at the request root keeps the route code small, and the error boundary story feels like normal React.',1778241933,'cc538178-f072-4513-9264-71b9e5f2e605','f1ca824d-30da-4bfb-9637-b41a0a4142dd');
|
|
106
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('4b7e1e37-c199-44b3-96af-9591972fc40a','The useActionState integration is practical because the form code still looks like React instead of a custom mutation framework.',1778241933,'36fbcd67-f2d1-487a-9499-86fb451f5d30','b5d4d8ac-d788-4e74-bc6e-57e4148c1f58');
|
|
107
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('38fbdd46-8410-4fc3-888b-bdcc21c1b725','Connection lists are a good fit for this demo because the small home feed forces loadNext to be exercised.',1778241933,'980827d4-8d71-49a5-b6af-7d9df1026384','33178d9c-7ea5-425b-8a8c-96f687d7d538');
|
|
108
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('744eda47-e9da-4145-a068-30e6905504a4','The single SSE connection model is reassuring; we were worried live views would create one stream per card.',1778241933,'81664ff5-fb55-48b5-896a-15a4898c9019','fe785e82-b46b-4b27-b1c6-9e1e1cd6af73');
|
|
109
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('2a90a86b-fc30-43c6-bdc1-d3f71a65a939','Live list events matching Post.comments is the detail that made the comment thread behavior click for me.',1778241933,'3c5fd5ff-e356-47a6-9737-94e16475bf44','138350a3-8b9e-415b-8fcc-5bfaec6751fc');
|
|
110
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('d8714b4a-3b36-4529-b806-3e654d0c51fa','Deletion pruning is the kind of edge case that usually gets missed in hand-written cache updates.',1778241933,'c161da1e-5e89-455d-8864-0f33fa36a3db','8f140027-21d9-42d4-87a2-1f180fa2fcf9');
|
|
111
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('4b7e1e37-c199-44b3-96af-9591972fc40a','Cloudflare transport makes adoption easier for teams that like the fate model but are not on tRPC.',1778241933,'1e692043-9f91-453e-beab-6319b28c7076','1c9368f3-8573-4d20-bf92-b4e0004e52fa');
|
|
112
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('1418a697-43d9-4c3d-8f20-23ea82aa13a9','Having Prisma and Drizzle examples side by side makes the server adapter story much more concrete.',1778241933,'63b2b76e-75ca-4c6e-bcd5-95318e37060b','419d0f1c-00ea-4a9b-baf2-5e90886c0b2e');
|
|
113
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('2c8a1b16-ae54-4a22-982b-148e469829e1','The distinction between filters and pagination cursors is useful for avoiding accidental cache fragmentation.',1778241933,'e92b0569-4ac1-409b-acdc-60c6866dc852','72ec3c4b-afd4-4096-87de-7d89100a8c1b');
|
|
114
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('2a90a86b-fc30-43c6-bdc1-d3f71a65a939','The Vite plugin removing the regular codegen step will help a lot in demos and fresh projects.',1778241933,'37a6be3e-86f1-44a6-9a60-0e414b8828e7','ec6a3200-bf9a-4bf3-8de2-5505e95d5f59');
|
|
115
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('2c8a1b16-ae54-4a22-982b-148e469829e1','Explicit retain and release behavior answers the question of how long normalized data should live.',1778241933,'d73507a6-d7fe-4800-be77-9775891b9ab4','5bf6844d-6cef-4a53-b6f3-5860b7ff8dea');
|
|
116
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('1418a697-43d9-4c3d-8f20-23ea82aa13a9','Stable refs should make a visible difference in large feeds with memoized cards.',1778241933,'d37b1e88-d41b-4601-a005-28a42f461115','e506c96a-80b8-4f41-b91b-cd4a988b3652');
|
|
117
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('1418a697-43d9-4c3d-8f20-23ea82aa13a9','The migration checklist is realistic because it starts with one screen instead of a full rewrite.',1778241933,'ef494c39-f666-4c14-a8e5-9511e62fccf8','86e6b2c6-8e37-480d-9c19-de384fa8bbae');
|
|
118
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('cfdacdb3-7ad3-4158-b3fe-4baf6e197e64','I appreciate that the examples still work with existing server routes while adding the fate procedures.',1778241933,'5926ab8c-1e38-4835-92e2-cb74480722cb','f1faa9f8-f2db-4fd0-8c81-2809d6174611');
|
|
119
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('cfdacdb3-7ad3-4158-b3fe-4baf6e197e64','The Cloudflare example is a nice proof that the transport and framework APIs are portable.',1778241933,'53da77ea-a95a-4c2b-af8b-61cb4c84a445','0e3c60e0-f7a3-4d6b-bdaf-1d7ab5c65035');
|
|
120
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('38fbdd46-8410-4fc3-888b-bdcc21c1b725','Search results and category pages sharing Post records is a good way to show the cache doing real work.',1778241933,'220d7202-e4de-4c2b-91ae-6f2599b05c0f','369771a1-f3aa-4fd6-a1fa-2cfbc1a50bed');
|
|
121
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('744eda47-e9da-4145-a068-30e6905504a4','Optimistic likes are simple, but they make the rollback behavior easy to test in front of someone.',1778241933,'8ea0a8d9-b1af-42b2-b9f4-0201e249bcf0','fff329e4-9948-49e7-9fe6-1cacf76e89e2');
|
|
122
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('d8714b4a-3b36-4529-b806-3e654d0c51fa','Live comments plus optimistic comments give the demo a lot more texture than a static blog feed.',1778241933,'00e58a49-ab94-466b-b08a-77146314af7e','112a0063-2057-4b30-adf5-3e5a0c945108');
|
|
123
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('4b7e1e37-c199-44b3-96af-9591972fc40a','The data masking examples should be required reading before anyone adds fields to a shared component.',1778241933,'7e63a74a-e6d9-4a3f-bcfc-4e72554cd87f','5dd158a1-839b-4040-9fa8-4579f1345fbb');
|
|
124
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('2a90a86b-fc30-43c6-bdc1-d3f71a65a939','I like that the posts use product language instead of pretending this is a generic social network.',1778241933,'dd4de019-0b54-41be-b9cc-70465509e749','f1ca824d-30da-4bfb-9637-b41a0a4142dd');
|
|
125
|
+
|
|
126
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('38fbdd46-8410-4fc3-888b-bdcc21c1b725','The server adapter notes helped me understand why fields and lists can share one selection pipeline.',1778241933,'52a938a2-c3d6-406d-9353-73ff0618c2dc','b5d4d8ac-d788-4e74-bc6e-57e4148c1f58');
|
|
127
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('4b7e1e37-c199-44b3-96af-9591972fc40a','The Cloudflare transport post answers the biggest question I had after reading the original announcement.',1778241933,'cd485197-9b2b-4b2b-a954-cc07c04d674d','33178d9c-7ea5-425b-8a8c-96f687d7d538');
|
|
128
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('69ad225c-a6d5-4747-8372-5c60da964497','Connection identity following Relay semantics is a strong choice for teams that already know that model.',1778241933,'fd3b1271-f167-4497-9de1-5607a9e395d4','fe785e82-b46b-4b27-b1c6-9e1e1cd6af73');
|
|
129
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('4b7e1e37-c199-44b3-96af-9591972fc40a','Garbage collection is easy to ignore until a long-lived app starts leaking records during navigation.',1778241933,'7b39109f-265b-475e-8b90-c7b50ef1feb0','138350a3-8b9e-415b-8fcc-5bfaec6751fc');
|
|
130
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('69ad225c-a6d5-4747-8372-5c60da964497','The stable ref change sounds small, but it explains a lot of the rerender fixes in the history.',1778241933,'60f233a1-66d8-4b9b-8845-c2230dc275e4','8f140027-21d9-42d4-87a2-1f180fa2fcf9');
|
|
131
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('1418a697-43d9-4c3d-8f20-23ea82aa13a9','The new seed data makes the event cards useful because the topics map to real fate features.',1778241933,'318d5d16-a2bc-4d1e-8203-09f1fa6f8865','1c9368f3-8573-4d20-bf92-b4e0004e52fa');
|
|
132
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('744eda47-e9da-4145-a068-30e6905504a4','I used the strict selection post to explain why overfetching is not just a network problem.',1778241933,'e40f3466-4555-439a-8432-abaefaddec24','419d0f1c-00ea-4a9b-baf2-5e90886c0b2e');
|
|
133
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('1418a697-43d9-4c3d-8f20-23ea82aa13a9','The live deletion path matters for moderation workflows where comments disappear from multiple views.',1778241933,'1cb7fda9-415c-4778-bda4-ae0526555891','72ec3c4b-afd4-4096-87de-7d89100a8c1b');
|
|
134
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('cfdacdb3-7ad3-4158-b3fe-4baf6e197e64','The Cloudflare transport should make it easier to build examples on Workers and D1.',1778241933,'d78d4967-544b-4518-ab5b-51aa76d2fe24','ec6a3200-bf9a-4bf3-8de2-5505e95d5f59');
|
|
135
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('2a90a86b-fc30-43c6-bdc1-d3f71a65a939','This makes me want a small debugging panel that shows which views selected a field.',1778241933,'e087df50-8e3f-4888-87ac-afe2a0a18be3','5bf6844d-6cef-4a53-b6f3-5860b7ff8dea');
|
|
136
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('cfdacdb3-7ad3-4158-b3fe-4baf6e197e64','The Vite plugin note clarifies why the generated client is still present without making codegen feel mandatory.',1778241933,'536096f6-67a3-4231-a3f8-2d1d1fd0e91c','e506c96a-80b8-4f41-b91b-cd4a988b3652');
|
|
137
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('4b7e1e37-c199-44b3-96af-9591972fc40a','The migration sequence matches how we would try this inside an existing dashboard.',1778241933,'150aaba5-c8dc-47e1-aba5-3f46c03b7823','86e6b2c6-8e37-480d-9c19-de384fa8bbae');
|
|
138
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('38fbdd46-8410-4fc3-888b-bdcc21c1b725','The comments list is long enough now to exercise load-more behavior without creating fake lorem ipsum.',1778241933,'c6f80cba-81c9-4517-a0d6-52c4e48b724d','f1faa9f8-f2db-4fd0-8c81-2809d6174611');
|
|
139
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('38fbdd46-8410-4fc3-888b-bdcc21c1b725','The category descriptions make the sidebar useful for navigating the demo.',1778241933,'da012227-a918-4e04-af5c-48572c004e35','0e3c60e0-f7a3-4d6b-bdaf-1d7ab5c65035');
|
|
140
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('4b7e1e37-c199-44b3-96af-9591972fc40a','Seeing optimistic actions and live updates use the same normalized cache is the key idea.',1778241933,'5111262f-ca98-4b4e-ab3c-b7c2c7cb17c5','369771a1-f3aa-4fd6-a1fa-2cfbc1a50bed');
|
|
141
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('cfdacdb3-7ad3-4158-b3fe-4baf6e197e64','The Cloudflare example deserves a walkthrough because it proves the framework integration boundary is small.',1778241933,'e64722d2-0601-4e1b-814c-0a27a1083e2e','fff329e4-9948-49e7-9fe6-1cacf76e89e2');
|
|
142
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('69ad225c-a6d5-4747-8372-5c60da964497','I would link the stable refs note from the performance section of the docs.',1778241933,'75b6779c-cfcc-48b3-9764-e1defccc49f8','112a0063-2057-4b30-adf5-3e5a0c945108');
|
|
143
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('2a90a86b-fc30-43c6-bdc1-d3f71a65a939','The source adapter post helped our backend team map data views to our existing models.',1778241933,'1030a756-0a9d-4311-933f-80b928480b1b','5dd158a1-839b-4040-9fa8-4579f1345fbb');
|
|
144
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('4b7e1e37-c199-44b3-96af-9591972fc40a','The React integration posts make it clear that fate is not trying to replace React state.',1778241933,'732e6d8d-90b5-4af2-81f0-5871f8295a62','f1ca824d-30da-4bfb-9637-b41a0a4142dd');
|
|
145
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('69ad225c-a6d5-4747-8372-5c60da964497','The event seed data now looks like something a real project would use for launch planning.',1778241933,'7ad192b2-eda9-4209-bd5b-e62f27d3d4eb','b5d4d8ac-d788-4e74-bc6e-57e4148c1f58');
|
|
146
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('69ad225c-a6d5-4747-8372-5c60da964497','The cache lifetime post is a good reminder to retain manual requests outside React.',1778241933,'182f299b-bad7-4551-8222-77122a8425aa','33178d9c-7ea5-425b-8a8c-96f687d7d538');
|
|
147
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('4b7e1e37-c199-44b3-96af-9591972fc40a','The search route feels more convincing when it can find live views, adapters, and migration content.',1778241933,'9007f719-aee5-46ed-9183-8d02c50d3b99','fe785e82-b46b-4b27-b1c6-9e1e1cd6af73');
|
|
148
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('4b7e1e37-c199-44b3-96af-9591972fc40a','The examples now cover the features added after the announcement instead of stopping at the initial alpha.',1778241933,'75ace0c4-ac80-4c59-b31e-95f752926e83','138350a3-8b9e-415b-8fcc-5bfaec6751fc');
|
|
149
|
+
INSERT OR IGNORE INTO `Comment` (`authorId`, `content`, `createdAt`, `id`, `postId`) VALUES('d8714b4a-3b36-4529-b806-3e654d0c51fa','I like that the same records can appear in the feed, categories, search, and detail pages without duplicate cache data.',1778241933,'24540d96-c4dd-4db7-a6af-adc4c69f2465','8f140027-21d9-42d4-87a2-1f180fa2fcf9');
|
|
150
|
+
|
|
151
|
+
INSERT OR IGNORE INTO Event VALUES(300,1778241933,'A guided tour of the current alpha covering views, normalized caching, Cloudflare transport, and the updated example apps.',1779301800,'744eda47-e9da-4145-a068-30e6905504a4','8fb13802-aa10-48e7-bfa6-8cf06c79e9da','https://fate.technology','Online','fate alpha progress call',1779298200,'["Views","Cloudflare","Examples"]','COMMUNITY_CALL',1778241933);
|
|
152
|
+
INSERT OR IGNORE INTO Event VALUES(120,1778241933,'Hands-on workshop for replacing request hooks with co-located views, root requests, and Suspense boundaries.',1779998400,'d8714b4a-3b36-4529-b806-3e654d0c51fa','436c9f5e-3e59-40cf-b686-e3ac7d061222','https://fate.technology','Nakazawa Tech Studio','From request hooks to views',1779984000,'["Migration","Suspense","Data masking"]','WORKSHOP',1778241933);
|
|
153
|
+
INSERT OR IGNORE INTO Event VALUES(180,1778241933,'Live demo of object updates, connection events, visible inserts, deletion pruning, and one SSE stream per client.',1780599600,'1418a697-43d9-4c3d-8f20-23ea82aa13a9','5cdf2ac8-5a64-4c18-9876-c62129fc9d2c','https://fate.technology','Online','Live views lab',1780594200,'["Live views","SSE","Pagination"]','MEETUP',1778241933);
|
|
154
|
+
INSERT OR IGNORE INTO Event VALUES(90,1778241933,'Server-focused session on data views, source adapters, Prisma, Drizzle, and the Cloudflare fate handler.',1781289000,'4b7e1e37-c199-44b3-96af-9591972fc40a','014c581d-bc2d-49b6-9450-3dd2b5b4a976','https://fate.technology','Online','Server adapter office hours',1781283600,'["Prisma","Drizzle","Cloudflare"]','AMA',1778241933);
|
|
155
|
+
INSERT OR IGNORE INTO Event VALUES(150,1778241933,'Launch review for the Cloudflare example, including Workers, D1, auth, seed data, live comments, and fate client generation.',1782324000,'2a90a86b-fc30-43c6-bdc1-d3f71a65a939','955e5ffc-7850-40c1-b645-ee2a9deef723','https://fate.technology','Online','Cloudflare example launch review',1782320400,'["Cloudflare","D1","Examples"]','LAUNCH',1778241933);
|
|
156
|
+
INSERT OR IGNORE INTO EventAttendee VALUES(1778241933,'8fb13802-aa10-48e7-bfa6-8cf06c79e9da','a781bef0-1cce-42ef-8291-1b32974d7220','Hosting the walkthrough and collecting alpha feedback.','GOING','744eda47-e9da-4145-a068-30e6905504a4');
|
|
157
|
+
INSERT OR IGNORE INTO EventAttendee VALUES(1778241933,'8fb13802-aa10-48e7-bfa6-8cf06c79e9da','722fca4c-8e70-4990-8f12-446087a3aef3','Preparing questions about Cloudflare deployments.','GOING','d8714b4a-3b36-4529-b806-3e654d0c51fa');
|
|
158
|
+
INSERT OR IGNORE INTO EventAttendee VALUES(1778241933,'8fb13802-aa10-48e7-bfa6-8cf06c79e9da','9886cf78-63e6-4be2-844b-f304f367c955','Wants to compare the tRPC and Cloudflare client setup.','INTERESTED','4b7e1e37-c199-44b3-96af-9591972fc40a');
|
|
159
|
+
INSERT OR IGNORE INTO EventAttendee VALUES(1778241933,'436c9f5e-3e59-40cf-b686-e3ac7d061222','425a9299-e8c7-493a-aa4a-673c64819fd0','Bringing a feed screen to convert during the session.','GOING','cfdacdb3-7ad3-4158-b3fe-4baf6e197e64');
|
|
160
|
+
INSERT OR IGNORE INTO EventAttendee VALUES(1778241933,'436c9f5e-3e59-40cf-b686-e3ac7d061222','f256d228-0ed7-4e6d-87e1-74a57cf8fee1','Interested in data masking and missing-field failures.','GOING','38fbdd46-8410-4fc3-888b-bdcc21c1b725');
|
|
161
|
+
INSERT OR IGNORE INTO EventAttendee VALUES(1778241933,'436c9f5e-3e59-40cf-b686-e3ac7d061222','cfaa6e6f-664c-4d9c-a57b-2cb8e6ecadba','Comparing ViewRefs with their current DTO props.','INTERESTED','2c8a1b16-ae54-4a22-982b-148e469829e1');
|
|
162
|
+
INSERT OR IGNORE INTO EventAttendee VALUES(1778241933,'5cdf2ac8-5a64-4c18-9876-c62129fc9d2c','5fbac02a-5cd3-4e49-9feb-e5ee14b67257','Showing comment prepend and delete events.','GOING','1418a697-43d9-4c3d-8f20-23ea82aa13a9');
|
|
163
|
+
INSERT OR IGNORE INTO EventAttendee VALUES(1778241933,'5cdf2ac8-5a64-4c18-9876-c62129fc9d2c','3d71f2d9-e10f-427c-aba5-e34a44712d4f','Testing reconnection behavior for event streams.','INTERESTED','22c06d32-a442-4cb4-83c3-da9cf6c37e77');
|
|
164
|
+
INSERT OR IGNORE INTO EventAttendee VALUES(1778241933,'5cdf2ac8-5a64-4c18-9876-c62129fc9d2c','cbdee438-9803-407c-80d9-1266ccb23e01','Taking notes for the live views guide.','GOING','2a90a86b-fc30-43c6-bdc1-d3f71a65a939');
|
|
165
|
+
INSERT OR IGNORE INTO EventAttendee VALUES(1778241933,'014c581d-bc2d-49b6-9450-3dd2b5b4a976','43a64e6a-fd33-4006-88a9-b5ab4f7b2dd7','Bringing a Prisma schema with computed counts.','GOING','4b7e1e37-c199-44b3-96af-9591972fc40a');
|
|
166
|
+
INSERT OR IGNORE INTO EventAttendee VALUES(1778241933,'014c581d-bc2d-49b6-9450-3dd2b5b4a976','4e23e3fb-5863-4ace-8de9-d7417e57367c','Mapping Drizzle relations to source adapters.','GOING','69ad225c-a6d5-4747-8372-5c60da964497');
|
|
167
|
+
INSERT OR IGNORE INTO EventAttendee VALUES(1778241933,'014c581d-bc2d-49b6-9450-3dd2b5b4a976','78280ac4-bbe0-4c93-9d37-64c8f547b30d','Checking how Cloudflare fits their deployment.','INTERESTED','d8714b4a-3b36-4529-b806-3e654d0c51fa');
|
|
168
|
+
INSERT OR IGNORE INTO EventAttendee VALUES(1778241933,'955e5ffc-7850-40c1-b645-ee2a9deef723','a06b3618-4149-4678-82b7-f9633f496897','Demoing the Cloudflare example home route.','GOING','2a90a86b-fc30-43c6-bdc1-d3f71a65a939');
|
|
169
|
+
INSERT OR IGNORE INTO EventAttendee VALUES(1778241933,'955e5ffc-7850-40c1-b645-ee2a9deef723','7d0906bd-e027-47a0-96e1-9211edfd656d','Testing the generated client in a full-stack app.','GOING','38fbdd46-8410-4fc3-888b-bdcc21c1b725');
|
|
170
|
+
INSERT OR IGNORE INTO EventAttendee VALUES(1778241933,'955e5ffc-7850-40c1-b645-ee2a9deef723','9790adf6-9ba2-4754-b56c-3e664577b463','Watching for SSR and routing integration notes.','INTERESTED','cfdacdb3-7ad3-4158-b3fe-4baf6e197e64');
|