@korajs/cli 0.3.4 → 0.5.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.
Files changed (104) hide show
  1. package/dist/bin.cjs +1839 -829
  2. package/dist/bin.cjs.map +1 -1
  3. package/dist/bin.js +1107 -146
  4. package/dist/bin.js.map +1 -1
  5. package/dist/{chunk-HNVCNPER.js → chunk-3WNFM3QB.js} +107 -97
  6. package/dist/chunk-3WNFM3QB.js.map +1 -0
  7. package/dist/{chunk-ULTO5NFA.js → chunk-PSRM56B7.js} +2 -2
  8. package/dist/chunk-PSRM56B7.js.map +1 -0
  9. package/dist/{chunk-MIMLCXSX.js → chunk-SOTZIWIF.js} +267 -228
  10. package/dist/chunk-SOTZIWIF.js.map +1 -0
  11. package/dist/create.cjs +58 -48
  12. package/dist/create.cjs.map +1 -1
  13. package/dist/create.js +2 -2
  14. package/dist/index.cjs +322 -273
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +31 -29
  17. package/dist/index.d.ts +31 -29
  18. package/dist/index.js +2 -2
  19. package/package.json +9 -3
  20. package/templates/react-basic/README.md.hbs +10 -1
  21. package/templates/react-basic/src/App.tsx +112 -126
  22. package/templates/react-basic/src/index.css +165 -159
  23. package/templates/react-basic/src/kora-worker.ts +0 -1
  24. package/templates/react-basic/src/main.tsx +12 -12
  25. package/templates/react-basic/src/modules/todos/todo.mutations.ts +25 -0
  26. package/templates/react-basic/src/modules/todos/todo.queries.ts +5 -0
  27. package/templates/react-basic/src/modules/todos/todo.schema.ts +10 -0
  28. package/templates/react-basic/src/modules/todos/useTodos.ts +31 -0
  29. package/templates/react-basic/src/schema.ts +6 -12
  30. package/templates/react-basic/src/vite-env.d.ts +17 -0
  31. package/templates/react-basic/{tsconfig.json → tsconfig.json.hbs} +1 -2
  32. package/templates/react-basic/vite.config.ts +57 -50
  33. package/templates/react-sync/.env.example +19 -0
  34. package/templates/react-sync/README.md.hbs +43 -1
  35. package/templates/react-sync/package.json.hbs +3 -0
  36. package/templates/react-sync/server.ts +90 -26
  37. package/templates/react-sync/src/App.tsx +132 -130
  38. package/templates/react-sync/src/auth.ts +25 -0
  39. package/templates/react-sync/src/index.css +212 -165
  40. package/templates/react-sync/src/kora-worker.ts +0 -1
  41. package/templates/react-sync/src/main.tsx +34 -18
  42. package/templates/react-sync/src/modules/todos/todo.mutations.ts +25 -0
  43. package/templates/react-sync/src/modules/todos/todo.queries.ts +5 -0
  44. package/templates/react-sync/src/modules/todos/todo.schema.ts +10 -0
  45. package/templates/react-sync/src/modules/todos/useTodos.ts +31 -0
  46. package/templates/react-sync/src/schema.ts +6 -12
  47. package/templates/react-sync/src/vite-env.d.ts +17 -0
  48. package/templates/react-sync/{tsconfig.json → tsconfig.json.hbs} +1 -2
  49. package/templates/react-sync/vite.config.ts +67 -60
  50. package/templates/react-tailwind/README.md.hbs +10 -1
  51. package/templates/react-tailwind/src/App.tsx +186 -197
  52. package/templates/react-tailwind/src/index.css +3 -3
  53. package/templates/react-tailwind/src/kora-worker.ts +0 -1
  54. package/templates/react-tailwind/src/main.tsx +19 -12
  55. package/templates/react-tailwind/src/modules/todos/todo.mutations.ts +25 -0
  56. package/templates/react-tailwind/src/modules/todos/todo.queries.ts +5 -0
  57. package/templates/react-tailwind/src/modules/todos/todo.schema.ts +10 -0
  58. package/templates/react-tailwind/src/modules/todos/useTodos.ts +31 -0
  59. package/templates/react-tailwind/src/schema.ts +6 -12
  60. package/templates/react-tailwind/src/vite-env.d.ts +17 -0
  61. package/templates/react-tailwind/{tsconfig.json → tsconfig.json.hbs} +1 -2
  62. package/templates/react-tailwind/vite.config.ts +57 -50
  63. package/templates/react-tailwind-sync/.env.example +19 -0
  64. package/templates/react-tailwind-sync/README.md.hbs +43 -1
  65. package/templates/react-tailwind-sync/package.json.hbs +3 -0
  66. package/templates/react-tailwind-sync/server.ts +90 -26
  67. package/templates/react-tailwind-sync/src/App.tsx +246 -222
  68. package/templates/react-tailwind-sync/src/auth.ts +25 -0
  69. package/templates/react-tailwind-sync/src/index.css +3 -3
  70. package/templates/react-tailwind-sync/src/kora-worker.ts +0 -1
  71. package/templates/react-tailwind-sync/src/main.tsx +48 -18
  72. package/templates/react-tailwind-sync/src/modules/todos/todo.mutations.ts +25 -0
  73. package/templates/react-tailwind-sync/src/modules/todos/todo.queries.ts +5 -0
  74. package/templates/react-tailwind-sync/src/modules/todos/todo.schema.ts +10 -0
  75. package/templates/react-tailwind-sync/src/modules/todos/useTodos.ts +31 -0
  76. package/templates/react-tailwind-sync/src/schema.ts +6 -12
  77. package/templates/react-tailwind-sync/src/vite-env.d.ts +17 -0
  78. package/templates/react-tailwind-sync/{tsconfig.json → tsconfig.json.hbs} +1 -2
  79. package/templates/react-tailwind-sync/vite.config.ts +67 -60
  80. package/templates/tauri-react/.env.example +20 -0
  81. package/templates/tauri-react/README.md.hbs +36 -1
  82. package/templates/tauri-react/dev.ts +11 -11
  83. package/templates/tauri-react/package.json.hbs +2 -0
  84. package/templates/tauri-react/server.ts +86 -12
  85. package/templates/tauri-react/src/App.tsx +769 -544
  86. package/templates/tauri-react/src/AppShell.tsx +125 -83
  87. package/templates/tauri-react/src/SetupScreen.tsx +257 -208
  88. package/templates/tauri-react/src/auth.ts +45 -0
  89. package/templates/tauri-react/src/main.tsx +3 -3
  90. package/templates/tauri-react/src/modules/todos/todo.mutations.ts +25 -0
  91. package/templates/tauri-react/src/modules/todos/todo.queries.ts +5 -0
  92. package/templates/tauri-react/src/modules/todos/todo.schema.ts +10 -0
  93. package/templates/tauri-react/src/modules/todos/useTodos.ts +31 -0
  94. package/templates/tauri-react/src/schema.ts +6 -12
  95. package/templates/tauri-react/src/sync-config.ts +47 -47
  96. package/templates/tauri-react/src/updater.ts +15 -15
  97. package/templates/tauri-react/src/vite-env.d.ts +17 -0
  98. package/templates/tauri-react/src-tauri/tauri.conf.json +2 -2
  99. package/templates/tauri-react/tsconfig.json.hbs +14 -0
  100. package/templates/tauri-react/vite.config.ts +9 -9
  101. package/dist/chunk-HNVCNPER.js.map +0 -1
  102. package/dist/chunk-MIMLCXSX.js.map +0 -1
  103. package/dist/chunk-ULTO5NFA.js.map +0 -1
  104. package/templates/tauri-react/tsconfig.json +0 -15
@@ -1,281 +1,287 @@
1
1
  *,
2
2
  *::before,
3
3
  *::after {
4
- box-sizing: border-box;
5
- margin: 0;
6
- padding: 0;
4
+ box-sizing: border-box;
5
+ margin: 0;
6
+ padding: 0;
7
7
  }
8
8
 
9
9
  :root {
10
- --color-bg: #0a0a0f;
11
- --color-surface: #111118;
12
- --color-border: #1e1e2a;
13
- --color-border-hover: #2a2a3a;
14
- --color-text: #e4e4e7;
15
- --color-text-muted: #71717a;
16
- --color-text-dim: #3f3f46;
17
- --color-primary: #6366f1;
18
- --color-primary-hover: #818cf8;
19
- --color-success: #34d399;
20
- --color-warning: #fbbf24;
21
- --color-danger: #f87171;
22
- --font-sans: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
23
- --radius: 8px;
10
+ --color-bg: #0a0a0f;
11
+ --color-surface: #111118;
12
+ --color-border: #1e1e2a;
13
+ --color-border-hover: #2a2a3a;
14
+ --color-text: #e4e4e7;
15
+ --color-text-muted: #71717a;
16
+ --color-text-dim: #3f3f46;
17
+ --color-primary: #6366f1;
18
+ --color-primary-hover: #818cf8;
19
+ --color-success: #34d399;
20
+ --color-warning: #fbbf24;
21
+ --color-danger: #f87171;
22
+ --font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
23
+ --radius: 8px;
24
24
  }
25
25
 
26
26
  body {
27
- font-family: var(--font-sans);
28
- background: var(--color-bg);
29
- color: var(--color-text);
30
- line-height: 1.6;
31
- -webkit-font-smoothing: antialiased;
27
+ font-family: var(--font-sans);
28
+ background: var(--color-bg);
29
+ color: var(--color-text);
30
+ line-height: 1.6;
31
+ -webkit-font-smoothing: antialiased;
32
32
  }
33
33
 
34
34
  .app {
35
- max-width: 640px;
36
- margin: 0 auto;
37
- padding: 48px 16px;
35
+ max-width: 640px;
36
+ margin: 0 auto;
37
+ padding: 48px 16px;
38
38
  }
39
39
 
40
40
  .header {
41
- display: flex;
42
- align-items: center;
43
- justify-content: space-between;
44
- margin-bottom: 32px;
41
+ display: flex;
42
+ align-items: center;
43
+ justify-content: space-between;
44
+ margin-bottom: 32px;
45
45
  }
46
46
 
47
47
  .header h1 {
48
- font-size: 1.5rem;
49
- font-weight: 700;
48
+ font-size: 1.5rem;
49
+ font-weight: 700;
50
50
  }
51
51
 
52
52
  .local-badge {
53
- display: inline-flex;
54
- align-items: center;
55
- gap: 6px;
56
- padding: 4px 12px;
57
- border-radius: 999px;
58
- background: var(--color-surface);
59
- font-size: 0.8rem;
60
- color: var(--color-text-muted);
53
+ display: inline-flex;
54
+ align-items: center;
55
+ gap: 6px;
56
+ padding: 4px 12px;
57
+ border-radius: 999px;
58
+ background: var(--color-surface);
59
+ font-size: 0.8rem;
60
+ color: var(--color-text-muted);
61
61
  }
62
62
 
63
63
  .stats {
64
- display: grid;
65
- grid-template-columns: repeat(3, 1fr);
66
- gap: 12px;
67
- margin-bottom: 32px;
64
+ display: grid;
65
+ grid-template-columns: repeat(3, 1fr);
66
+ gap: 12px;
67
+ margin-bottom: 32px;
68
68
  }
69
69
 
70
70
  .stat-card {
71
- background: var(--color-surface);
72
- border: 1px solid var(--color-border);
73
- border-radius: var(--radius);
74
- padding: 16px;
71
+ background: var(--color-surface);
72
+ border: 1px solid var(--color-border);
73
+ border-radius: var(--radius);
74
+ padding: 16px;
75
75
  }
76
76
 
77
77
  .stat-card .label {
78
- font-size: 0.8rem;
79
- color: var(--color-text-muted);
78
+ font-size: 0.8rem;
79
+ color: var(--color-text-muted);
80
80
  }
81
81
 
82
82
  .stat-card .value {
83
- font-size: 1.5rem;
84
- font-weight: 700;
83
+ font-size: 1.5rem;
84
+ font-weight: 700;
85
85
  }
86
86
 
87
- .stat-card .value.muted { color: var(--color-text-muted); }
88
- .stat-card .value.warning { color: var(--color-warning); }
89
- .stat-card .value.success { color: var(--color-success); }
87
+ .stat-card .value.muted {
88
+ color: var(--color-text-muted);
89
+ }
90
+ .stat-card .value.warning {
91
+ color: var(--color-warning);
92
+ }
93
+ .stat-card .value.success {
94
+ color: var(--color-success);
95
+ }
90
96
 
91
97
  .add-form {
92
- display: flex;
93
- gap: 12px;
94
- margin-bottom: 32px;
98
+ display: flex;
99
+ gap: 12px;
100
+ margin-bottom: 32px;
95
101
  }
96
102
 
97
103
  .add-form input {
98
- flex: 1;
99
- padding: 10px 16px;
100
- border: 1px solid var(--color-border);
101
- border-radius: var(--radius);
102
- background: var(--color-surface);
103
- color: var(--color-text);
104
- font-size: 0.95rem;
105
- outline: none;
104
+ flex: 1;
105
+ padding: 10px 16px;
106
+ border: 1px solid var(--color-border);
107
+ border-radius: var(--radius);
108
+ background: var(--color-surface);
109
+ color: var(--color-text);
110
+ font-size: 0.95rem;
111
+ outline: none;
106
112
  }
107
113
 
108
114
  .add-form input:focus {
109
- border-color: var(--color-primary);
115
+ border-color: var(--color-primary);
110
116
  }
111
117
 
112
118
  .add-form input::placeholder {
113
- color: var(--color-text-muted);
119
+ color: var(--color-text-muted);
114
120
  }
115
121
 
116
122
  .add-form button {
117
- padding: 10px 20px;
118
- border: none;
119
- border-radius: var(--radius);
120
- background: var(--color-primary);
121
- color: white;
122
- font-size: 0.95rem;
123
- font-weight: 500;
124
- cursor: pointer;
123
+ padding: 10px 20px;
124
+ border: none;
125
+ border-radius: var(--radius);
126
+ background: var(--color-primary);
127
+ color: white;
128
+ font-size: 0.95rem;
129
+ font-weight: 500;
130
+ cursor: pointer;
125
131
  }
126
132
 
127
133
  .add-form button:hover {
128
- background: var(--color-primary-hover);
134
+ background: var(--color-primary-hover);
129
135
  }
130
136
 
131
137
  .add-form button:disabled {
132
- opacity: 0.5;
133
- cursor: not-allowed;
138
+ opacity: 0.5;
139
+ cursor: not-allowed;
134
140
  }
135
141
 
136
142
  .filters {
137
- display: flex;
138
- gap: 8px;
139
- margin-bottom: 24px;
143
+ display: flex;
144
+ gap: 8px;
145
+ margin-bottom: 24px;
140
146
  }
141
147
 
142
148
  .filter-btn {
143
- padding: 6px 16px;
144
- border: none;
145
- border-radius: var(--radius);
146
- background: var(--color-surface);
147
- color: var(--color-text-muted);
148
- font-size: 0.85rem;
149
- font-weight: 500;
150
- cursor: pointer;
149
+ padding: 6px 16px;
150
+ border: none;
151
+ border-radius: var(--radius);
152
+ background: var(--color-surface);
153
+ color: var(--color-text-muted);
154
+ font-size: 0.85rem;
155
+ font-weight: 500;
156
+ cursor: pointer;
151
157
  }
152
158
 
153
159
  .filter-btn:hover {
154
- background: var(--color-border-hover);
155
- color: var(--color-text);
160
+ background: var(--color-border-hover);
161
+ color: var(--color-text);
156
162
  }
157
163
 
158
164
  .filter-btn.active {
159
- background: var(--color-primary);
160
- color: white;
165
+ background: var(--color-primary);
166
+ color: white;
161
167
  }
162
168
 
163
169
  .filter-btn .badge {
164
- display: inline-block;
165
- margin-left: 6px;
166
- padding: 1px 6px;
167
- border-radius: 999px;
168
- font-size: 0.75rem;
169
- background: rgba(255, 255, 255, 0.15);
170
+ display: inline-block;
171
+ margin-left: 6px;
172
+ padding: 1px 6px;
173
+ border-radius: 999px;
174
+ font-size: 0.75rem;
175
+ background: rgba(255, 255, 255, 0.15);
170
176
  }
171
177
 
172
178
  .filter-btn:not(.active) .badge {
173
- background: var(--color-border);
179
+ background: var(--color-border);
174
180
  }
175
181
 
176
182
  .todo-list {
177
- display: flex;
178
- flex-direction: column;
179
- gap: 8px;
183
+ display: flex;
184
+ flex-direction: column;
185
+ gap: 8px;
180
186
  }
181
187
 
182
188
  .todo-item {
183
- display: flex;
184
- align-items: center;
185
- gap: 12px;
186
- padding: 12px 16px;
187
- border: 1px solid var(--color-border);
188
- border-radius: var(--radius);
189
- background: var(--color-surface);
189
+ display: flex;
190
+ align-items: center;
191
+ gap: 12px;
192
+ padding: 12px 16px;
193
+ border: 1px solid var(--color-border);
194
+ border-radius: var(--radius);
195
+ background: var(--color-surface);
190
196
  }
191
197
 
192
198
  .todo-item:hover {
193
- border-color: var(--color-border-hover);
199
+ border-color: var(--color-border-hover);
194
200
  }
195
201
 
196
202
  .todo-item .toggle {
197
- background: none;
198
- border: 2px solid var(--color-text-muted);
199
- width: 20px;
200
- height: 20px;
201
- border-radius: 50%;
202
- cursor: pointer;
203
- display: flex;
204
- align-items: center;
205
- justify-content: center;
206
- color: transparent;
207
- font-size: 0.7rem;
208
- flex-shrink: 0;
203
+ background: none;
204
+ border: 2px solid var(--color-text-muted);
205
+ width: 20px;
206
+ height: 20px;
207
+ border-radius: 50%;
208
+ cursor: pointer;
209
+ display: flex;
210
+ align-items: center;
211
+ justify-content: center;
212
+ color: transparent;
213
+ font-size: 0.7rem;
214
+ flex-shrink: 0;
209
215
  }
210
216
 
211
217
  .todo-item .toggle.checked {
212
- border-color: var(--color-success);
213
- background: var(--color-success);
214
- color: white;
218
+ border-color: var(--color-success);
219
+ background: var(--color-success);
220
+ color: white;
215
221
  }
216
222
 
217
223
  .todo-item .title {
218
- flex: 1;
224
+ flex: 1;
219
225
  }
220
226
 
221
227
  .todo-item .title.done {
222
- text-decoration: line-through;
223
- color: var(--color-text-muted);
228
+ text-decoration: line-through;
229
+ color: var(--color-text-muted);
224
230
  }
225
231
 
226
232
  .todo-item .time {
227
- font-size: 0.75rem;
228
- color: var(--color-text-dim);
233
+ font-size: 0.75rem;
234
+ color: var(--color-text-dim);
229
235
  }
230
236
 
231
237
  .todo-item .delete-btn {
232
- background: none;
233
- border: none;
234
- color: var(--color-text-dim);
235
- cursor: pointer;
236
- padding: 4px;
237
- opacity: 0;
238
- transition: opacity 0.15s;
238
+ background: none;
239
+ border: none;
240
+ color: var(--color-text-dim);
241
+ cursor: pointer;
242
+ padding: 4px;
243
+ opacity: 0;
244
+ transition: opacity 0.15s;
239
245
  }
240
246
 
241
247
  .todo-item:hover .delete-btn {
242
- opacity: 1;
248
+ opacity: 1;
243
249
  }
244
250
 
245
251
  .todo-item .delete-btn:hover {
246
- color: var(--color-danger);
252
+ color: var(--color-danger);
247
253
  }
248
254
 
249
255
  .empty-state {
250
- padding: 48px 0;
251
- text-align: center;
252
- color: var(--color-text-dim);
253
- border: 1px dashed var(--color-border);
254
- border-radius: var(--radius);
256
+ padding: 48px 0;
257
+ text-align: center;
258
+ color: var(--color-text-dim);
259
+ border: 1px dashed var(--color-border);
260
+ border-radius: var(--radius);
255
261
  }
256
262
 
257
263
  .footer {
258
- display: flex;
259
- justify-content: space-between;
260
- margin-top: 24px;
261
- font-size: 0.85rem;
262
- color: var(--color-text-muted);
264
+ display: flex;
265
+ justify-content: space-between;
266
+ margin-top: 24px;
267
+ font-size: 0.85rem;
268
+ color: var(--color-text-muted);
263
269
  }
264
270
 
265
271
  .footer button {
266
- background: none;
267
- border: none;
268
- color: var(--color-text-muted);
269
- cursor: pointer;
272
+ background: none;
273
+ border: none;
274
+ color: var(--color-text-muted);
275
+ cursor: pointer;
270
276
  }
271
277
 
272
278
  .footer button:hover {
273
- color: var(--color-text);
279
+ color: var(--color-text);
274
280
  }
275
281
 
276
282
  .branding {
277
- margin-top: 48px;
278
- text-align: center;
279
- font-size: 0.75rem;
280
- color: var(--color-text-dim);
283
+ margin-top: 48px;
284
+ text-align: center;
285
+ font-size: 0.75rem;
286
+ color: var(--color-text-dim);
281
287
  }
@@ -4,7 +4,6 @@
4
4
  // Import the WASM binary URL so Vite resolves it with the correct content hash.
5
5
  // Without this, production builds fail because sqlite3 looks for the unhashed filename.
6
6
  import sqliteWasmUrl from '@sqlite.org/sqlite-wasm/sqlite3.wasm?url'
7
-
8
7
  ;(globalThis as Record<string, unknown>).__KORA_SQLITE_WASM_URL = sqliteWasmUrl
9
8
 
10
9
  import '@korajs/store/sqlite-wasm/worker'
@@ -1,24 +1,24 @@
1
- import { createApp } from 'korajs'
2
1
  import { KoraProvider } from '@korajs/react'
2
+ import { createApp } from 'korajs'
3
3
  import { StrictMode } from 'react'
4
4
  import { createRoot } from 'react-dom/client'
5
- import schema from './schema'
6
5
  import { App } from './App'
6
+ import schema from './schema'
7
7
  import './index.css'
8
8
  import koraWorkerUrl from './kora-worker.ts?worker&url'
9
9
 
10
10
  const app = createApp({
11
- schema,
12
- store: {
13
- workerUrl: koraWorkerUrl,
14
- },
15
- devtools: true,
11
+ schema,
12
+ store: {
13
+ workerUrl: koraWorkerUrl,
14
+ },
15
+ devtools: true,
16
16
  })
17
17
 
18
18
  createRoot(document.getElementById('root')!).render(
19
- <StrictMode>
20
- <KoraProvider app={app} fallback={<div>Loading...</div>}>
21
- <App />
22
- </KoraProvider>
23
- </StrictMode>,
19
+ <StrictMode>
20
+ <KoraProvider app={app} fallback={<div>Loading...</div>}>
21
+ <App />
22
+ </KoraProvider>
23
+ </StrictMode>,
24
24
  )
@@ -0,0 +1,25 @@
1
+ import type { CollectionAccessor } from 'korajs'
2
+
3
+ export interface CreateTodoInput {
4
+ title: string
5
+ }
6
+
7
+ export interface UpdateTodoStatusInput {
8
+ completed: boolean
9
+ }
10
+
11
+ export function createTodo(todos: CollectionAccessor, data: CreateTodoInput) {
12
+ return todos.insert({ title: data.title })
13
+ }
14
+
15
+ export function updateTodoStatus(
16
+ todos: CollectionAccessor,
17
+ id: string,
18
+ data: UpdateTodoStatusInput,
19
+ ) {
20
+ return todos.update(id, { completed: data.completed })
21
+ }
22
+
23
+ export function deleteTodo(todos: CollectionAccessor, id: string) {
24
+ return todos.delete(id)
25
+ }
@@ -0,0 +1,5 @@
1
+ import type { CollectionAccessor } from 'korajs'
2
+
3
+ export function orderedTodos(todos: CollectionAccessor) {
4
+ return todos.where({}).orderBy('createdAt', 'desc')
5
+ }
@@ -0,0 +1,10 @@
1
+ import { t } from 'korajs'
2
+
3
+ export const todos = {
4
+ fields: {
5
+ title: t.string(),
6
+ completed: t.boolean().default(false),
7
+ createdAt: t.timestamp().auto(),
8
+ },
9
+ indexes: ['completed', 'createdAt'],
10
+ }
@@ -0,0 +1,31 @@
1
+ import { useCollection, useMutation, useQuery } from '@korajs/react'
2
+ import {
3
+ type CreateTodoInput,
4
+ type UpdateTodoStatusInput,
5
+ createTodo,
6
+ deleteTodo,
7
+ updateTodoStatus,
8
+ } from './todo.mutations'
9
+ import { orderedTodos } from './todo.queries'
10
+
11
+ export function useTodos() {
12
+ const todos = useCollection('todos')
13
+ const allTodos = useQuery(orderedTodos(todos))
14
+ const addTodo = useMutation((data: CreateTodoInput) => createTodo(todos, data))
15
+ const toggleTodo = useMutation((id: string, data: UpdateTodoStatusInput) =>
16
+ updateTodoStatus(todos, id, data),
17
+ )
18
+ const removeTodo = useMutation((id: string) => deleteTodo(todos, id))
19
+
20
+ const activeTodos = allTodos.filter((todo) => !todo.completed)
21
+ const completedTodos = allTodos.filter((todo) => !!todo.completed)
22
+
23
+ return {
24
+ allTodos,
25
+ activeTodos,
26
+ completedTodos,
27
+ addTodo,
28
+ toggleTodo,
29
+ deleteTodo: removeTodo,
30
+ }
31
+ }
@@ -1,15 +1,9 @@
1
- import { defineSchema, t } from 'korajs'
1
+ import { defineSchema } from 'korajs'
2
+ import { todos } from './modules/todos/todo.schema'
2
3
 
3
4
  export default defineSchema({
4
- version: 1,
5
- collections: {
6
- todos: {
7
- fields: {
8
- title: t.string(),
9
- completed: t.boolean().default(false),
10
- createdAt: t.timestamp().auto(),
11
- },
12
- indexes: ['completed'],
13
- },
14
- },
5
+ version: 1,
6
+ collections: {
7
+ todos,
8
+ },
15
9
  })
@@ -0,0 +1,17 @@
1
+ interface ImportMetaEnv {
2
+ readonly VITE_SYNC_URL?: string
3
+ }
4
+
5
+ interface ImportMeta {
6
+ readonly env: ImportMetaEnv
7
+ }
8
+
9
+ declare module '*?worker&url' {
10
+ const url: string
11
+ export default url
12
+ }
13
+
14
+ declare module '*?url' {
15
+ const url: string
16
+ export default url
17
+ }
@@ -8,8 +8,7 @@
8
8
  "noUncheckedIndexedAccess": true,
9
9
  "esModuleInterop": true,
10
10
  "skipLibCheck": true,
11
- "outDir": "dist",
12
- "types": ["vite/client"]
11
+ "outDir": "dist"
13
12
  },
14
13
  "include": ["src"]
15
14
  }