Skip to content

Commit eef4d8f

Browse files
committed
feat: integrate Supabase Realtime
1 parent f2460f1 commit eef4d8f

39 files changed

+3483
-2801
lines changed

.github/ISSUE_TEMPLATE/custom.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,3 @@ labels: ''
66
assignees: ''
77

88
---
9-
10-

backend/package.json

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"type": "module",
44
"version": "0.0.0",
55
"private": true,
6-
"packageManager": "pnpm@9.11.0",
6+
"packageManager": "pnpm@9.12.0",
77
"scripts": {
88
"dev": "tsx watch app",
99
"introspect": "drizzle-kit introspect",
@@ -14,7 +14,6 @@
1414
"lint:fix": "eslint . --fix"
1515
},
1616
"dependencies": {
17-
"@t3-oss/env-core": "^0.11.1",
1817
"@trpc/react-query": "11.0.0-rc.502",
1918
"@trpc/server": "11.0.0-rc.502",
2019
"@types/cookie": "^0.6.0",
@@ -26,11 +25,8 @@
2625
"drizzle-orm": "^0.33.0",
2726
"express": "^5.0.0",
2827
"http-errors": "^2.0.0",
29-
"lru-cache": "^11.0.1",
3028
"morgan": "^1.10.0",
31-
"postgres": "^3.4.4",
32-
"sql-template-tag": "^5.2.1",
33-
"zod": "^3.23.8"
29+
"postgres": "^3.4.4"
3430
},
3531
"devDependencies": {
3632
"@types/cookie-parser": "^1.4.7",

package.json

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
"type": "module",
44
"version": "0.3.0",
55
"private": true,
6-
"packageManager": "pnpm@9.11.0",
6+
"packageManager": "pnpm@9.12.0",
77
"scripts": {
88
"backend": "pnpm --filter @sub-vocab/backend",
99
"ui": "pnpm --filter @sub-vocab/ui",
10-
"bump": "ncu react, react-dom, eslint-plugin-react-hooks --target @next --deep -u && taze -r && pnpm up && pnpm i",
10+
"bump": "ncu react, react-dom, eslint-plugin-react-hooks --target @next --deep -u && ncu react-router --target @pre --deep -u && taze -r && pnpm up && pnpm i",
1111
"lint:pkg": "eslint --fix package.json **/package.json",
1212
"introspect": "pnpm --recursive run introspect",
1313
"lint:fix": "pnpm --recursive run lint:fix"
@@ -18,15 +18,17 @@
1818
"type-fest": "^4.26.1"
1919
},
2020
"devDependencies": {
21-
"@antfu/eslint-config": "^3.6.2",
22-
"@stylistic/eslint-plugin": "^2.8.0",
21+
"@antfu/eslint-config": "^3.7.3",
22+
"@stylistic/eslint-plugin": "^2.9.0",
23+
"@t3-oss/env-core": "^0.11.1",
2324
"@total-typescript/ts-reset": "^0.6.1",
24-
"@types/node": "^22.5.5",
25-
"eslint": "^9.10.0",
25+
"@types/node": "^22.7.4",
26+
"eslint": "^9.12.0",
2627
"pathe": "^1.1.2",
2728
"prettier": "^3.3.3",
2829
"taze": "^0.16.9",
29-
"typescript": "^5.6.2"
30+
"typescript": "^5.6.2",
31+
"zod": "^3.23.8"
3032
},
3133
"pnpm": {
3234
"overrides": {

pnpm-lock.yaml

Lines changed: 3030 additions & 2523 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ui/auto-imports.d.ts

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
// biome-ignore lint: disable
77
export {}
88
declare global {
9-
const AcquaintAllDialog: typeof import('./src/components/ui/VocabSource')['AcquaintAllDialog']
109
const Alert: typeof import('./src/components/ui/alert')['Alert']
1110
const AlertDescription: typeof import('./src/components/ui/alert')['AlertDescription']
1211
const AlertDialog: typeof import('./src/components/ui/alert-dialog')['AlertDialog']
@@ -119,7 +118,6 @@ declare global {
119118
const Input: typeof import('./src/components/ui/input')['Input']
120119
const InputWrapper: typeof import('./src/components/ui/input')['InputWrapper']
121120
const Label: typeof import('./src/components/ui/label')['Label']
122-
const Link: typeof import('react-router-dom')['Link']
123121
const Menubar: typeof import('./src/components/ui/menubar')['Menubar']
124122
const MenubarCheckboxItem: typeof import('./src/components/ui/menubar')['MenubarCheckboxItem']
125123
const MenubarContent: typeof import('./src/components/ui/menubar')['MenubarContent']
@@ -136,18 +134,12 @@ declare global {
136134
const MenubarSubContent: typeof import('./src/components/ui/menubar')['MenubarSubContent']
137135
const MenubarSubTrigger: typeof import('./src/components/ui/menubar')['MenubarSubTrigger']
138136
const MenubarTrigger: typeof import('./src/components/ui/menubar')['MenubarTrigger']
139-
const NavLink: typeof import('react-router-dom')['NavLink']
140-
const Navigate: typeof import('react-router-dom')['Navigate']
141-
const Outlet: typeof import('react-router-dom')['Outlet']
142137
const Popover: typeof import('./src/components/ui/popover')['Popover']
143138
const PopoverContent: typeof import('./src/components/ui/popover')['PopoverContent']
144139
const PopoverTrigger: typeof import('./src/components/ui/popover')['PopoverTrigger']
145140
const ResizableHandle: typeof import('./src/components/ui/resizable')['ResizableHandle']
146141
const ResizablePanel: typeof import('./src/components/ui/resizable')['ResizablePanel']
147142
const ResizablePanelGroup: typeof import('./src/components/ui/resizable')['ResizablePanelGroup']
148-
const Route: typeof import('react-router-dom')['Route']
149-
const Routes: typeof import('react-router-dom')['Routes']
150-
const SVGSlot: typeof import('./src/components/ui/icon')['SVGSlot']
151143
const SearchWidget: typeof import('./src/components/ui/search-widget')['SearchWidget']
152144
const SegmentedControl: typeof import('./src/components/ui/SegmentedControl')['SegmentedControl']
153145
const Select: typeof import('./src/components/ui/select')['Select']
@@ -184,8 +176,6 @@ declare global {
184176
const ToastViewport: typeof import('./src/components/ui/toast')['ToastViewport']
185177
const Toaster: typeof import('./src/components/ui/sonner')['Toaster']
186178
const Toggle: typeof import('./src/components/ui/toggle')['Toggle']
187-
const VocabDataTable: typeof import('./src/components/ui/VocabData')['VocabDataTable']
188-
const VocabSourceTable: typeof import('./src/components/ui/VocabSource')['VocabSourceTable']
189179
const VocabStatics: typeof import('./src/components/ui/vocab-statics-bar')['VocabStatics']
190180
const VocabToggle: typeof import('./src/components/ui/ToggleButton')['VocabToggle']
191181
const add: typeof import('date-fns')['add']
@@ -200,7 +190,10 @@ declare global {
200190
const addSeconds: typeof import('date-fns')['addSeconds']
201191
const addWeeks: typeof import('date-fns')['addWeeks']
202192
const addYears: typeof import('date-fns')['addYears']
193+
const afterAll: typeof import('vitest')['afterAll']
194+
const afterEach: typeof import('vitest')['afterEach']
203195
const areIntervalsOverlapping: typeof import('date-fns')['areIntervalsOverlapping']
196+
const assert: typeof import('vitest')['assert']
204197
const atom: typeof import('jotai')['atom']
205198
const atomFamily: typeof import('jotai/utils')['atomFamily']
206199
const atomWithDefault: typeof import('jotai/utils')['atomWithDefault']
@@ -209,7 +202,10 @@ declare global {
209202
const atomWithReducer: typeof import('jotai/utils')['atomWithReducer']
210203
const atomWithReset: typeof import('jotai/utils')['atomWithReset']
211204
const atomWithStorage: typeof import('jotai/utils')['atomWithStorage']
205+
const beforeAll: typeof import('vitest')['beforeAll']
206+
const beforeEach: typeof import('vitest')['beforeEach']
212207
const buttonVariants: typeof import('./src/components/ui/button')['buttonVariants']
208+
const chai: typeof import('vitest')['chai']
213209
const clamp: typeof import('date-fns')['clamp']
214210
const closestIndexTo: typeof import('date-fns')['closestIndexTo']
215211
const closestTo: typeof import('date-fns')['closestTo']
@@ -221,6 +217,7 @@ declare global {
221217
const createJSONStorage: typeof import('jotai/utils')['createJSONStorage']
222218
const createRef: typeof import('react')['createRef']
223219
const daysToWeeks: typeof import('date-fns')['daysToWeeks']
220+
const describe: typeof import('vitest')['describe']
224221
const differenceInBusinessDays: typeof import('date-fns')['differenceInBusinessDays']
225222
const differenceInCalendarDays: typeof import('date-fns')['differenceInCalendarDays']
226223
const differenceInCalendarISOWeekYears: typeof import('date-fns')['differenceInCalendarISOWeekYears']
@@ -263,6 +260,7 @@ declare global {
263260
const endOfWeek: typeof import('date-fns')['endOfWeek']
264261
const endOfYear: typeof import('date-fns')['endOfYear']
265262
const endOfYesterday: typeof import('date-fns')['endOfYesterday']
263+
const expect: typeof import('vitest')['expect']
266264
const format: typeof import('date-fns')['format']
267265
const formatDistance: typeof import('date-fns')['formatDistance']
268266
const formatDistanceStrict: typeof import('date-fns')['formatDistanceStrict']
@@ -352,6 +350,7 @@ declare global {
352350
const isWeekend: typeof import('date-fns')['isWeekend']
353351
const isWithinInterval: typeof import('date-fns')['isWithinInterval']
354352
const isYesterday: typeof import('date-fns')['isYesterday']
353+
const it: typeof import('vitest')['it']
355354
const lastDayOfDecade: typeof import('date-fns')['lastDayOfDecade']
356355
const lastDayOfISOWeek: typeof import('date-fns')['lastDayOfISOWeek']
357356
const lastDayOfISOWeekYear: typeof import('date-fns')['lastDayOfISOWeekYear']
@@ -449,6 +448,8 @@ declare global {
449448
const subSeconds: typeof import('date-fns')['subSeconds']
450449
const subWeeks: typeof import('date-fns')['subWeeks']
451450
const subYears: typeof import('date-fns')['subYears']
451+
const suite: typeof import('vitest')['suite']
452+
const test: typeof import('vitest')['test']
452453
const toDate: typeof import('date-fns')['toDate']
453454
const toast: typeof import('./src/components/ui/use-toast')['toast']
454455
const toggleVariants: typeof import('./src/components/ui/toggle')['toggleVariants']
@@ -462,34 +463,24 @@ declare global {
462463
const useDeferredValue: typeof import('react')['useDeferredValue']
463464
const useEffect: typeof import('react')['useEffect']
464465
const useFormField: typeof import('./src/components/ui/form')['useFormField']
465-
const useHref: typeof import('react-router-dom')['useHref']
466466
const useHydrateAtoms: typeof import('jotai/utils')['useHydrateAtoms']
467467
const useId: typeof import('react')['useId']
468468
const useImperativeHandle: typeof import('react')['useImperativeHandle']
469-
const useInRouterContext: typeof import('react-router-dom')['useInRouterContext']
470469
const useInsertionEffect: typeof import('react')['useInsertionEffect']
471470
const useLayoutEffect: typeof import('react')['useLayoutEffect']
472-
const useLinkClickHandler: typeof import('react-router-dom')['useLinkClickHandler']
473-
const useLocation: typeof import('react-router-dom')['useLocation']
474471
const useMemo: typeof import('react')['useMemo']
475-
const useNavigate: typeof import('react-router-dom')['useNavigate']
476-
const useNavigationType: typeof import('react-router-dom')['useNavigationType']
477-
const useOutlet: typeof import('react-router-dom')['useOutlet']
478-
const useOutletContext: typeof import('react-router-dom')['useOutletContext']
479-
const useParams: typeof import('react-router-dom')['useParams']
480472
const useReducer: typeof import('react')['useReducer']
481473
const useReducerAtom: typeof import('jotai/utils')['useReducerAtom']
482474
const useRef: typeof import('react')['useRef']
483475
const useResetAtom: typeof import('jotai/utils')['useResetAtom']
484-
const useResolvedPath: typeof import('react-router-dom')['useResolvedPath']
485-
const useRoutes: typeof import('react-router-dom')['useRoutes']
486-
const useSearchParams: typeof import('react-router-dom')['useSearchParams']
487476
const useSetAtom: typeof import('jotai')['useSetAtom']
488477
const useState: typeof import('react')['useState']
489478
const useSyncExternalStore: typeof import('react')['useSyncExternalStore']
490479
const useToast: typeof import('./src/components/ui/use-toast')['useToast']
491480
const useTransition: typeof import('react')['useTransition']
492481
const useTranslation: typeof import('react-i18next')['useTranslation']
482+
const vi: typeof import('vitest')['vi']
483+
const vitest: typeof import('vitest')['vitest']
493484
const waitForAll: typeof import('jotai/utils')['waitForAll']
494485
const weeksToDays: typeof import('date-fns')['weeksToDays']
495486
const yearsToMonths: typeof import('date-fns')['yearsToMonths']

ui/eslint.config.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import antfu from '@antfu/eslint-config'
2-
import { fixupConfigRules } from '@eslint/compat'
32
import { FlatCompat } from '@eslint/eslintrc'
43
import pluginQuery from '@tanstack/eslint-plugin-query'
54
import eslintPluginTailwindCss from 'eslint-plugin-tailwindcss'
@@ -42,14 +41,14 @@ export default antfu(
4241
],
4342
},
4443
},
45-
...fixupConfigRules(compat.config({
44+
compat.config({
4645
plugins: [
4746
'eslint-plugin-react-compiler',
4847
],
4948
rules: {
5049
'react-compiler/react-compiler': 2,
5150
},
52-
})),
51+
}),
5352
...pluginQuery.configs['flat/recommended'],
5453
...eslintPluginTailwindCss.configs['flat/recommended'],
5554
{

ui/package.json

Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
"type": "module",
44
"version": "0.3.0",
55
"private": true,
6-
"packageManager": "pnpm@9.11.0",
6+
"packageManager": "pnpm@9.12.0",
77
"scripts": {
88
"dev": "vite",
99
"devH": "vite --host",
10+
"test": "vitest --ui",
1011
"introspect": "supabase gen types --lang=typescript --project-id PROJECT_REF --schema public > database.types.ts",
1112
"build": "tsc && vite build",
1213
"lint": "eslint . --report-unused-disable-directives --max-warnings 0",
@@ -18,31 +19,31 @@
1819
"@date-fns/utc": "^2.1.0",
1920
"@emotion/react": "^11.13.3",
2021
"@emotion/styled": "^11.13.0",
21-
"@headlessui/react": "^2.1.8",
22+
"@headlessui/react": "^2.1.9",
2223
"@heroicons/react": "^2.1.5",
23-
"@mui/material": "^6.1.1",
24+
"@mui/material": "^6.1.2",
2425
"@radix-ui/colors": "^3.0.0",
25-
"@radix-ui/react-alert-dialog": "^1.1.1",
26-
"@radix-ui/react-checkbox": "^1.1.1",
27-
"@radix-ui/react-dialog": "^1.1.1",
28-
"@radix-ui/react-dropdown-menu": "^2.1.1",
26+
"@radix-ui/react-alert-dialog": "^1.1.2",
27+
"@radix-ui/react-checkbox": "^1.1.2",
28+
"@radix-ui/react-dialog": "^1.1.2",
29+
"@radix-ui/react-dropdown-menu": "^2.1.2",
2930
"@radix-ui/react-icons": "^1.3.0",
3031
"@radix-ui/react-label": "^2.1.0",
31-
"@radix-ui/react-menubar": "^1.1.1",
32-
"@radix-ui/react-popover": "^1.1.1",
33-
"@radix-ui/react-select": "^2.1.1",
32+
"@radix-ui/react-menubar": "^1.1.2",
33+
"@radix-ui/react-popover": "^1.1.2",
34+
"@radix-ui/react-select": "^2.1.2",
3435
"@radix-ui/react-separator": "^1.1.0",
3536
"@radix-ui/react-slot": "^1.1.0",
36-
"@radix-ui/react-toast": "^1.2.1",
37+
"@radix-ui/react-toast": "^1.2.2",
3738
"@radix-ui/react-toggle": "^1.1.0",
3839
"@react-hook/resize-observer": "^2.0.2",
39-
"@sentry/react": "^8.30.0",
40-
"@tanstack/query-async-storage-persister": "^5.56.2",
41-
"@tanstack/query-core": "^5.56.2",
42-
"@tanstack/query-sync-storage-persister": "^5.56.2",
43-
"@tanstack/react-query": "^5.56.2",
44-
"@tanstack/react-query-devtools": "^5.56.2",
45-
"@tanstack/react-query-persist-client": "^5.56.2",
40+
"@sentry/react": "^8.33.1",
41+
"@tanstack/query-async-storage-persister": "^5.59.0",
42+
"@tanstack/query-core": "^5.59.0",
43+
"@tanstack/query-sync-storage-persister": "^5.59.0",
44+
"@tanstack/react-query": "^5.59.0",
45+
"@tanstack/react-query-devtools": "^5.59.0",
46+
"@tanstack/react-query-persist-client": "^5.59.0",
4647
"@tanstack/react-table": "^8.20.5",
4748
"@trpc/client": "11.0.0-rc.502",
4849
"@trpc/react-query": "11.0.0-rc.502",
@@ -58,7 +59,7 @@
5859
"figma-squircle": "^1.1.0",
5960
"file-type": "^19.5.0",
6061
"foxact": "^0.2.38",
61-
"i18next": "^23.15.1",
62+
"i18next": "^23.15.2",
6263
"immer": "^10.1.1",
6364
"jotai": "^2.10.0",
6465
"jotai-devtools": "^0.10.1",
@@ -69,60 +70,60 @@
6970
"next-themes": "^0.3.0",
7071
"pdfjs-dist": "^4.6.82",
7172
"polished": "^4.3.1",
72-
"react": "19.0.0-rc-e740d4b1-20240919",
73-
"react-aria-components": "^1.3.3",
73+
"react": "19.0.0-rc-1460d67c-20241003",
74+
"react-aria-components": "^1.4.0",
7475
"react-chartjs-2": "^5.2.0",
75-
"react-dom": "19.0.0-rc-e740d4b1-20240919",
76+
"react-dom": "19.0.0-rc-1460d67c-20241003",
7677
"react-hook-form": "^7.53.0",
7778
"react-i18next": "^15.0.2",
7879
"react-lazily": "^0.9.2",
7980
"react-merge-refs": "^2.1.1",
80-
"react-resizable-panels": "^2.1.3",
81-
"react-router-dom": "^6.26.2",
81+
"react-resizable-panels": "^2.1.4",
82+
"react-router": "^7.0.0-pre.0",
8283
"react-use": "^17.5.1",
83-
"socket.io-client": "^4.7.5",
8484
"sonner": "^1.5.0",
85-
"tailwind-merge": "^2.5.2",
85+
"tailwind-merge": "^2.5.3",
8686
"tailwindcss-signals": "^0.0.25",
8787
"ua-parser-js": "2.0.0-beta.3",
88-
"vaul": "^0.9.4",
89-
"zod": "^3.23.8"
88+
"vaul": "^1.0.0"
9089
},
9190
"devDependencies": {
92-
"@eslint-react/eslint-plugin": "^1.14.2",
93-
"@eslint/compat": "^1.1.1",
91+
"@eslint-react/eslint-plugin": "^1.14.3",
92+
"@eslint/compat": "^1.2.0",
9493
"@iconify-icon/react": "^2.1.0",
95-
"@iconify/json": "^2.2.250",
94+
"@iconify/json": "^2.2.256",
9695
"@iconify/react": "^5.0.2",
9796
"@svgr/core": "^8.1.0",
9897
"@svgr/plugin-jsx": "^8.1.0",
9998
"@tailwindcss/typography": "^0.5.15",
100-
"@tanstack/eslint-plugin-query": "^5.56.1",
99+
"@tanstack/eslint-plugin-query": "^5.59.1",
101100
"@types/chrome": "^0.0.270",
102101
"@types/eslint__eslintrc": "^2.1.2",
103102
"@types/lodash-es": "^4.17.12",
104103
"@types/react": "npm:types-react@rc",
105104
"@types/react-dom": "npm:types-react-dom@rc",
106-
"@vitejs/plugin-react": "^4.3.1",
105+
"@vitejs/plugin-react": "^4.3.2",
106+
"@vitest/ui": "^2.1.2",
107107
"autoprefixer": "^10.4.20",
108108
"eslint-plugin-react-compiler": "latest",
109-
"eslint-plugin-react-hooks": "5.1.0-rc-e740d4b1-20240919",
109+
"eslint-plugin-react-hooks": "5.1.0-rc-1460d67c-20241003",
110110
"eslint-plugin-react-refresh": "^0.4.12",
111111
"eslint-plugin-tailwindcss": "^3.17.4",
112112
"postcss": "^8.4.47",
113113
"prettier": "^3.3.3",
114-
"prettier-plugin-tailwindcss": "^0.6.6",
115-
"rollup": "^4.22.2",
114+
"prettier-plugin-tailwindcss": "^0.6.8",
115+
"rollup": "^4.24.0",
116116
"rollup-plugin-visualizer": "^5.12.0",
117-
"supabase": "^1.192.5",
118-
"tailwindcss": "^3.4.12",
117+
"supabase": "^1.200.3",
118+
"tailwindcss": "^3.4.13",
119119
"tailwindcss-3d": "^1.0.7",
120120
"typed-query-selector": "^2.12.0",
121121
"unplugin-auto-import": "^0.18.3",
122122
"unplugin-icons": "^0.19.3",
123123
"util": "npm:browserify-util@^0.12.6",
124-
"vite": "^5.4.6",
124+
"vite": "^5.4.8",
125125
"vite-plugin-checker": "^0.8.0",
126-
"vite-plugin-html": "^3.2.2"
126+
"vite-plugin-html": "^3.2.2",
127+
"vitest": "^2.1.2"
127128
}
128129
}

0 commit comments

Comments
 (0)