@korajs/cli 0.4.0 → 0.6.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/dist/bin.cjs +1636 -601
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1086 -139
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-MVP5PDT4.js → chunk-EEZNRI5W.js} +51 -6
- package/dist/chunk-EEZNRI5W.js.map +1 -0
- package/dist/{chunk-YGVO4POI.js → chunk-Q2FBCOQD.js} +27 -15
- package/dist/chunk-Q2FBCOQD.js.map +1 -0
- package/dist/{chunk-CMSX76KM.js → chunk-VLTPEATY.js} +172 -99
- package/dist/chunk-VLTPEATY.js.map +1 -0
- package/dist/create.cjs +130 -54
- package/dist/create.cjs.map +1 -1
- package/dist/create.js +2 -2
- package/dist/index.cjs +143 -62
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -6
- package/dist/index.d.ts +8 -6
- package/dist/index.js +2 -2
- package/package.json +9 -3
- package/templates/react-basic/README.md.hbs +10 -1
- package/templates/react-basic/src/App.tsx +112 -126
- package/templates/react-basic/src/index.css +165 -159
- package/templates/react-basic/src/kora-worker.ts +0 -1
- package/templates/react-basic/src/main.tsx +12 -12
- package/templates/react-basic/src/modules/todos/todo.mutations.ts +25 -0
- package/templates/react-basic/src/modules/todos/todo.queries.ts +5 -0
- package/templates/react-basic/src/modules/todos/todo.schema.ts +10 -0
- package/templates/react-basic/src/modules/todos/useTodos.ts +31 -0
- package/templates/react-basic/src/schema.ts +6 -12
- package/templates/react-basic/src/vite-env.d.ts +17 -0
- package/templates/react-basic/{tsconfig.json → tsconfig.json.hbs} +1 -2
- package/templates/react-basic/vite.config.ts +57 -50
- package/templates/react-sync/.env.example +19 -0
- package/templates/react-sync/README.md.hbs +43 -1
- package/templates/react-sync/package.json.hbs +3 -0
- package/templates/react-sync/server.ts +90 -26
- package/templates/react-sync/src/App.tsx +132 -130
- package/templates/react-sync/src/auth.ts +25 -0
- package/templates/react-sync/src/index.css +212 -165
- package/templates/react-sync/src/kora-worker.ts +0 -1
- package/templates/react-sync/src/main.tsx +34 -18
- package/templates/react-sync/src/modules/todos/todo.mutations.ts +25 -0
- package/templates/react-sync/src/modules/todos/todo.queries.ts +5 -0
- package/templates/react-sync/src/modules/todos/todo.schema.ts +10 -0
- package/templates/react-sync/src/modules/todos/useTodos.ts +31 -0
- package/templates/react-sync/src/schema.ts +6 -12
- package/templates/react-sync/src/vite-env.d.ts +17 -0
- package/templates/react-sync/{tsconfig.json → tsconfig.json.hbs} +1 -2
- package/templates/react-sync/vite.config.ts +67 -60
- package/templates/react-tailwind/README.md.hbs +10 -1
- package/templates/react-tailwind/src/App.tsx +186 -197
- package/templates/react-tailwind/src/index.css +3 -3
- package/templates/react-tailwind/src/kora-worker.ts +0 -1
- package/templates/react-tailwind/src/main.tsx +19 -12
- package/templates/react-tailwind/src/modules/todos/todo.mutations.ts +25 -0
- package/templates/react-tailwind/src/modules/todos/todo.queries.ts +5 -0
- package/templates/react-tailwind/src/modules/todos/todo.schema.ts +10 -0
- package/templates/react-tailwind/src/modules/todos/useTodos.ts +31 -0
- package/templates/react-tailwind/src/schema.ts +6 -12
- package/templates/react-tailwind/src/vite-env.d.ts +17 -0
- package/templates/react-tailwind/{tsconfig.json → tsconfig.json.hbs} +1 -2
- package/templates/react-tailwind/vite.config.ts +57 -50
- package/templates/react-tailwind-sync/.env.example +19 -0
- package/templates/react-tailwind-sync/README.md.hbs +43 -1
- package/templates/react-tailwind-sync/package.json.hbs +3 -0
- package/templates/react-tailwind-sync/server.ts +90 -26
- package/templates/react-tailwind-sync/src/App.tsx +246 -222
- package/templates/react-tailwind-sync/src/auth.ts +25 -0
- package/templates/react-tailwind-sync/src/index.css +3 -3
- package/templates/react-tailwind-sync/src/kora-worker.ts +0 -1
- package/templates/react-tailwind-sync/src/main.tsx +48 -18
- package/templates/react-tailwind-sync/src/modules/todos/todo.mutations.ts +25 -0
- package/templates/react-tailwind-sync/src/modules/todos/todo.queries.ts +5 -0
- package/templates/react-tailwind-sync/src/modules/todos/todo.schema.ts +10 -0
- package/templates/react-tailwind-sync/src/modules/todos/useTodos.ts +31 -0
- package/templates/react-tailwind-sync/src/schema.ts +6 -12
- package/templates/react-tailwind-sync/src/vite-env.d.ts +17 -0
- package/templates/react-tailwind-sync/{tsconfig.json → tsconfig.json.hbs} +1 -2
- package/templates/react-tailwind-sync/vite.config.ts +67 -60
- package/templates/svelte-basic/.env.example +3 -0
- package/templates/svelte-basic/README.md.hbs +62 -0
- package/templates/svelte-basic/index.html.hbs +12 -0
- package/templates/svelte-basic/kora.config.ts +12 -0
- package/templates/svelte-basic/package.json.hbs +27 -0
- package/templates/svelte-basic/src/App.svelte +131 -0
- package/templates/svelte-basic/src/Root.svelte +14 -0
- package/templates/svelte-basic/src/index.css +287 -0
- package/templates/svelte-basic/src/kora-worker.ts +9 -0
- package/templates/svelte-basic/src/main.ts +16 -0
- package/templates/svelte-basic/src/modules/todos/todo.mutations.ts +25 -0
- package/templates/svelte-basic/src/modules/todos/todo.queries.ts +5 -0
- package/templates/svelte-basic/src/modules/todos/todo.schema.ts +10 -0
- package/templates/svelte-basic/src/modules/todos/useTodos.ts +25 -0
- package/templates/svelte-basic/src/schema.ts +9 -0
- package/templates/svelte-basic/src/vite-env.d.ts +12 -0
- package/templates/svelte-basic/svelte.config.js +5 -0
- package/templates/svelte-basic/tsconfig.json.hbs +14 -0
- package/templates/svelte-basic/vite.config.ts +52 -0
- package/templates/svelte-sync/.env.example +25 -0
- package/templates/svelte-sync/README.md.hbs +105 -0
- package/templates/svelte-sync/index.html.hbs +12 -0
- package/templates/svelte-sync/kora.config.ts +17 -0
- package/templates/svelte-sync/package.json.hbs +43 -0
- package/templates/svelte-sync/server.ts +90 -0
- package/templates/svelte-sync/src/App.svelte +154 -0
- package/templates/svelte-sync/src/Root.svelte +22 -0
- package/templates/svelte-sync/src/auth.ts +25 -0
- package/templates/svelte-sync/src/index.css +339 -0
- package/templates/svelte-sync/src/kora-worker.ts +9 -0
- package/templates/svelte-sync/src/main.ts +32 -0
- package/templates/svelte-sync/src/modules/todos/todo.mutations.ts +25 -0
- package/templates/svelte-sync/src/modules/todos/todo.queries.ts +5 -0
- package/templates/svelte-sync/src/modules/todos/todo.schema.ts +10 -0
- package/templates/svelte-sync/src/modules/todos/useTodos.ts +25 -0
- package/templates/svelte-sync/src/schema.ts +9 -0
- package/templates/svelte-sync/src/vite-env.d.ts +21 -0
- package/templates/svelte-sync/svelte.config.js +5 -0
- package/templates/svelte-sync/tsconfig.json.hbs +14 -0
- package/templates/svelte-sync/vite.config.ts +79 -0
- package/templates/svelte-tailwind/README.md.hbs +62 -0
- package/templates/svelte-tailwind/index.html.hbs +12 -0
- package/templates/svelte-tailwind/kora.config.ts +12 -0
- package/templates/svelte-tailwind/package.json.hbs +30 -0
- package/templates/svelte-tailwind/src/App.svelte +79 -0
- package/templates/svelte-tailwind/src/Root.svelte +14 -0
- package/templates/svelte-tailwind/src/index.css +7 -0
- package/templates/svelte-tailwind/src/kora-worker.ts +9 -0
- package/templates/svelte-tailwind/src/main.ts +16 -0
- package/templates/svelte-tailwind/src/modules/todos/todo.mutations.ts +25 -0
- package/templates/svelte-tailwind/src/modules/todos/todo.queries.ts +5 -0
- package/templates/svelte-tailwind/src/modules/todos/todo.schema.ts +10 -0
- package/templates/svelte-tailwind/src/modules/todos/useTodos.ts +25 -0
- package/templates/svelte-tailwind/src/schema.ts +9 -0
- package/templates/svelte-tailwind/src/vite-env.d.ts +12 -0
- package/templates/svelte-tailwind/svelte.config.js +5 -0
- package/templates/svelte-tailwind/tsconfig.json.hbs +14 -0
- package/templates/svelte-tailwind/vite.config.ts +53 -0
- package/templates/svelte-tailwind-sync/.env.example +25 -0
- package/templates/svelte-tailwind-sync/README.md.hbs +105 -0
- package/templates/svelte-tailwind-sync/index.html.hbs +12 -0
- package/templates/svelte-tailwind-sync/kora.config.ts +17 -0
- package/templates/svelte-tailwind-sync/package.json.hbs +46 -0
- package/templates/svelte-tailwind-sync/server.ts +90 -0
- package/templates/svelte-tailwind-sync/src/App.svelte +196 -0
- package/templates/svelte-tailwind-sync/src/Root.svelte +26 -0
- package/templates/svelte-tailwind-sync/src/auth.ts +25 -0
- package/templates/svelte-tailwind-sync/src/index.css +7 -0
- package/templates/svelte-tailwind-sync/src/kora-worker.ts +9 -0
- package/templates/svelte-tailwind-sync/src/main.ts +32 -0
- package/templates/svelte-tailwind-sync/src/modules/todos/todo.mutations.ts +25 -0
- package/templates/svelte-tailwind-sync/src/modules/todos/todo.queries.ts +5 -0
- package/templates/svelte-tailwind-sync/src/modules/todos/todo.schema.ts +10 -0
- package/templates/svelte-tailwind-sync/src/modules/todos/useTodos.ts +25 -0
- package/templates/svelte-tailwind-sync/src/schema.ts +9 -0
- package/templates/svelte-tailwind-sync/src/vite-env.d.ts +21 -0
- package/templates/svelte-tailwind-sync/svelte.config.js +5 -0
- package/templates/svelte-tailwind-sync/tsconfig.json.hbs +14 -0
- package/templates/svelte-tailwind-sync/vite.config.ts +80 -0
- package/templates/tauri-react/.env.example +20 -0
- package/templates/tauri-react/README.md.hbs +36 -1
- package/templates/tauri-react/dev.ts +11 -11
- package/templates/tauri-react/package.json.hbs +2 -0
- package/templates/tauri-react/server.ts +86 -12
- package/templates/tauri-react/src/App.tsx +769 -544
- package/templates/tauri-react/src/AppShell.tsx +125 -83
- package/templates/tauri-react/src/SetupScreen.tsx +257 -208
- package/templates/tauri-react/src/auth.ts +45 -0
- package/templates/tauri-react/src/main.tsx +3 -3
- package/templates/tauri-react/src/modules/todos/todo.mutations.ts +25 -0
- package/templates/tauri-react/src/modules/todos/todo.queries.ts +5 -0
- package/templates/tauri-react/src/modules/todos/todo.schema.ts +10 -0
- package/templates/tauri-react/src/modules/todos/useTodos.ts +31 -0
- package/templates/tauri-react/src/schema.ts +6 -12
- package/templates/tauri-react/src/sync-config.ts +47 -47
- package/templates/tauri-react/src/updater.ts +15 -15
- package/templates/tauri-react/src/vite-env.d.ts +17 -0
- package/templates/tauri-react/src-tauri/tauri.conf.json +1 -1
- package/templates/tauri-react/tsconfig.json.hbs +14 -0
- package/templates/tauri-react/vite.config.ts +9 -9
- package/templates/vue-basic/README.md.hbs +62 -0
- package/templates/vue-basic/index.html.hbs +12 -0
- package/templates/vue-basic/kora.config.ts +12 -0
- package/templates/vue-basic/package.json.hbs +26 -0
- package/templates/vue-basic/src/App.vue +117 -0
- package/templates/vue-basic/src/index.css +287 -0
- package/templates/vue-basic/src/kora-worker.ts +9 -0
- package/templates/vue-basic/src/main.ts +20 -0
- package/templates/vue-basic/src/modules/todos/todo.mutations.ts +25 -0
- package/templates/vue-basic/src/modules/todos/todo.queries.ts +5 -0
- package/templates/vue-basic/src/modules/todos/todo.schema.ts +10 -0
- package/templates/vue-basic/src/modules/todos/useTodos.ts +32 -0
- package/templates/vue-basic/src/schema.ts +9 -0
- package/templates/vue-basic/src/vite-env.d.ts +17 -0
- package/templates/vue-basic/tsconfig.json.hbs +15 -0
- package/templates/vue-basic/vite.config.ts +69 -0
- package/templates/vue-sync/.env.example +25 -0
- package/templates/vue-sync/README.md.hbs +105 -0
- package/templates/vue-sync/index.html.hbs +12 -0
- package/templates/vue-sync/kora.config.ts +17 -0
- package/templates/vue-sync/package.json.hbs +42 -0
- package/templates/vue-sync/server.ts +90 -0
- package/templates/vue-sync/src/App.vue +135 -0
- package/templates/vue-sync/src/auth.ts +25 -0
- package/templates/vue-sync/src/index.css +339 -0
- package/templates/vue-sync/src/kora-worker.ts +9 -0
- package/templates/vue-sync/src/main.ts +43 -0
- package/templates/vue-sync/src/modules/todos/todo.mutations.ts +25 -0
- package/templates/vue-sync/src/modules/todos/todo.queries.ts +5 -0
- package/templates/vue-sync/src/modules/todos/todo.schema.ts +10 -0
- package/templates/vue-sync/src/modules/todos/useTodos.ts +32 -0
- package/templates/vue-sync/src/schema.ts +9 -0
- package/templates/vue-sync/src/vite-env.d.ts +26 -0
- package/templates/vue-sync/tsconfig.json.hbs +15 -0
- package/templates/vue-sync/vite.config.ts +79 -0
- package/templates/vue-tailwind/README.md.hbs +62 -0
- package/templates/vue-tailwind/index.html.hbs +12 -0
- package/templates/vue-tailwind/kora.config.ts +12 -0
- package/templates/vue-tailwind/package.json.hbs +29 -0
- package/templates/vue-tailwind/src/App.vue +142 -0
- package/templates/vue-tailwind/src/index.css +7 -0
- package/templates/vue-tailwind/src/kora-worker.ts +9 -0
- package/templates/vue-tailwind/src/main.ts +31 -0
- package/templates/vue-tailwind/src/modules/todos/todo.mutations.ts +25 -0
- package/templates/vue-tailwind/src/modules/todos/todo.queries.ts +5 -0
- package/templates/vue-tailwind/src/modules/todos/todo.schema.ts +10 -0
- package/templates/vue-tailwind/src/modules/todos/useTodos.ts +32 -0
- package/templates/vue-tailwind/src/schema.ts +9 -0
- package/templates/vue-tailwind/src/vite-env.d.ts +17 -0
- package/templates/vue-tailwind/tsconfig.json.hbs +15 -0
- package/templates/vue-tailwind/vite.config.ts +70 -0
- package/templates/vue-tailwind-sync/.env.example +25 -0
- package/templates/vue-tailwind-sync/README.md.hbs +105 -0
- package/templates/vue-tailwind-sync/index.html.hbs +12 -0
- package/templates/vue-tailwind-sync/kora.config.ts +17 -0
- package/templates/vue-tailwind-sync/package.json.hbs +45 -0
- package/templates/vue-tailwind-sync/server.ts +90 -0
- package/templates/vue-tailwind-sync/src/App.vue +245 -0
- package/templates/vue-tailwind-sync/src/auth.ts +25 -0
- package/templates/vue-tailwind-sync/src/index.css +7 -0
- package/templates/vue-tailwind-sync/src/kora-worker.ts +9 -0
- package/templates/vue-tailwind-sync/src/main.ts +56 -0
- package/templates/vue-tailwind-sync/src/modules/todos/todo.mutations.ts +25 -0
- package/templates/vue-tailwind-sync/src/modules/todos/todo.queries.ts +5 -0
- package/templates/vue-tailwind-sync/src/modules/todos/todo.schema.ts +10 -0
- package/templates/vue-tailwind-sync/src/modules/todos/useTodos.ts +32 -0
- package/templates/vue-tailwind-sync/src/schema.ts +9 -0
- package/templates/vue-tailwind-sync/src/vite-env.d.ts +26 -0
- package/templates/vue-tailwind-sync/tsconfig.json.hbs +15 -0
- package/templates/vue-tailwind-sync/vite.config.ts +80 -0
- package/dist/chunk-CMSX76KM.js.map +0 -1
- package/dist/chunk-MVP5PDT4.js.map +0 -1
- package/dist/chunk-YGVO4POI.js.map +0 -1
- package/templates/tauri-react/tsconfig.json +0 -15
|
@@ -16,26 +16,26 @@ const SYNC_CONFIGURED_KEY = 'kora-sync-configured'
|
|
|
16
16
|
* Priority: localStorage → VITE_SYNC_URL env var → null (needs setup).
|
|
17
17
|
*/
|
|
18
18
|
export function getSyncUrl(): string | null {
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
const stored = localStorage.getItem(SYNC_URL_KEY)
|
|
20
|
+
if (stored) return stored
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
// Compile-time default (set via VITE_SYNC_URL when building)
|
|
23
|
+
const envUrl = import.meta.env.VITE_SYNC_URL
|
|
24
|
+
if (envUrl) return envUrl
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
return null
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/** Save a sync server URL to persistent local config. */
|
|
30
30
|
export function setSyncUrl(url: string): void {
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
localStorage.setItem(SYNC_URL_KEY, url)
|
|
32
|
+
localStorage.setItem(SYNC_CONFIGURED_KEY, 'true')
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/** Clear the stored sync server URL (returns to setup screen). */
|
|
36
36
|
export function clearSyncUrl(): void {
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
localStorage.removeItem(SYNC_URL_KEY)
|
|
38
|
+
localStorage.removeItem(SYNC_CONFIGURED_KEY)
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/**
|
|
@@ -43,14 +43,14 @@ export function clearSyncUrl(): void {
|
|
|
43
43
|
* This is separate from getSyncUrl() — a user who skipped still completed setup.
|
|
44
44
|
*/
|
|
45
45
|
export function hasCompletedSetup(): boolean {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
// If there's a compile-time URL, setup is not needed
|
|
47
|
+
if (import.meta.env.VITE_SYNC_URL) return true
|
|
48
|
+
return localStorage.getItem(SYNC_CONFIGURED_KEY) === 'true'
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
/** Mark setup as completed (used when user skips sync). */
|
|
52
52
|
export function markSetupComplete(): void {
|
|
53
|
-
|
|
53
|
+
localStorage.setItem(SYNC_CONFIGURED_KEY, 'true')
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
/**
|
|
@@ -58,46 +58,46 @@ export function markSetupComplete(): void {
|
|
|
58
58
|
* The app reloads with a fresh state, showing the setup screen.
|
|
59
59
|
*/
|
|
60
60
|
export function factoryReset(): void {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
// Clear sync config
|
|
62
|
+
clearSyncUrl()
|
|
63
|
+
localStorage.removeItem(SYNC_CONFIGURED_KEY)
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
65
|
+
// Clear all Kora local data by removing IndexedDB databases
|
|
66
|
+
// and any other localStorage keys the app may have set.
|
|
67
|
+
const keysToRemove: string[] = []
|
|
68
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
69
|
+
const key = localStorage.key(i)
|
|
70
|
+
if (key?.startsWith('kora-')) {
|
|
71
|
+
keysToRemove.push(key)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
for (const key of keysToRemove) {
|
|
75
|
+
localStorage.removeItem(key)
|
|
76
|
+
}
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
// Reload to reinitialize everything from scratch
|
|
79
|
+
window.location.reload()
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
/** Test if a WebSocket URL is reachable by attempting a brief connection. */
|
|
83
83
|
export function testConnection(url: string, timeoutMs = 5000): Promise<boolean> {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
84
|
+
return new Promise((resolve) => {
|
|
85
|
+
const timeout = setTimeout(() => {
|
|
86
|
+
ws.close()
|
|
87
|
+
resolve(false)
|
|
88
|
+
}, timeoutMs)
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
const ws = new WebSocket(url)
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
ws.onopen = () => {
|
|
93
|
+
clearTimeout(timeout)
|
|
94
|
+
ws.close()
|
|
95
|
+
resolve(true)
|
|
96
|
+
}
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
98
|
+
ws.onerror = () => {
|
|
99
|
+
clearTimeout(timeout)
|
|
100
|
+
resolve(false)
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
103
|
}
|
|
@@ -19,20 +19,20 @@ let updateChecked = false
|
|
|
19
19
|
* Silently skips if the updater is not configured (empty endpoints/pubkey).
|
|
20
20
|
*/
|
|
21
21
|
export async function checkForUpdates(): Promise<void> {
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
if (updateChecked) return
|
|
23
|
+
updateChecked = true
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
25
|
+
try {
|
|
26
|
+
const { check } = await import('@tauri-apps/plugin-updater')
|
|
27
|
+
const update = await check()
|
|
28
|
+
if (update) {
|
|
29
|
+
console.log(`Update available: v${update.version}`)
|
|
30
|
+
// Download and install — the app will restart automatically
|
|
31
|
+
await update.downloadAndInstall()
|
|
32
|
+
}
|
|
33
|
+
} catch (err) {
|
|
34
|
+
// Updater not configured or network unavailable — this is fine.
|
|
35
|
+
// The app works fully offline; updates are best-effort.
|
|
36
|
+
console.debug('Update check skipped:', err)
|
|
37
|
+
}
|
|
38
38
|
}
|
|
@@ -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
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "https://raw.githubusercontent.com/
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/tauri-apps/tauri/dev/crates/tauri-config-schema/schema.json",
|
|
3
3
|
"productName": "kora-app",
|
|
4
4
|
"version": "0.0.1",
|
|
5
5
|
"identifier": "com.kora.app",
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"jsx": "react-jsx",
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noUncheckedIndexedAccess": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"outDir": "dist"
|
|
12
|
+
},
|
|
13
|
+
"include": ["src"]
|
|
14
|
+
}
|
|
@@ -3,13 +3,13 @@ import { defineConfig } from 'vite'
|
|
|
3
3
|
|
|
4
4
|
// Tauri apps use native SQLite — no WASM, no OPFS, no cross-origin isolation needed.
|
|
5
5
|
export default defineConfig({
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
plugins: [react()],
|
|
7
|
+
// Prevent Vite from obscuring Rust compilation errors
|
|
8
|
+
clearScreen: false,
|
|
9
|
+
server: {
|
|
10
|
+
// Tauri expects a fixed port; fail if it's not available
|
|
11
|
+
strictPort: true,
|
|
12
|
+
},
|
|
13
|
+
// Environment variables with this prefix are exposed to the app
|
|
14
|
+
envPrefix: ['VITE_', 'TAURI_'],
|
|
15
15
|
})
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# {{projectName}}
|
|
2
|
+
|
|
3
|
+
An offline-first application built with [Kora.js](https://ehoneahobed.github.io/kora/).
|
|
4
|
+
|
|
5
|
+
## Getting Started
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm run dev
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
- **App**: http://localhost:5173
|
|
12
|
+
|
|
13
|
+
## Project Structure
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
src/
|
|
17
|
+
schema.ts # Schema entry point
|
|
18
|
+
main.tsx # App initialization and Kora setup
|
|
19
|
+
App.tsx # Main application component
|
|
20
|
+
modules/
|
|
21
|
+
todos/
|
|
22
|
+
todo.schema.ts # Todo collection definition
|
|
23
|
+
todo.queries.ts # Reusable todo query builders
|
|
24
|
+
todo.mutations.ts # Todo mutation helpers
|
|
25
|
+
useTodos.ts # React hook connecting todos to the UI
|
|
26
|
+
kora-worker.ts # SQLite WASM web worker
|
|
27
|
+
index.css # Styles
|
|
28
|
+
kora.config.ts # Kora configuration
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
In a feature module, `schema` defines data shape, `queries` contain reads only, `mutations` contain
|
|
32
|
+
writes, and `useTodos.ts` is the React binding that exposes todo data and actions to components.
|
|
33
|
+
|
|
34
|
+
## Scripts
|
|
35
|
+
|
|
36
|
+
| Script | Description |
|
|
37
|
+
|--------|-------------|
|
|
38
|
+
| `npm run dev` | Start dev server |
|
|
39
|
+
| `npm run build` | Build for production |
|
|
40
|
+
| `npm run preview` | Preview production build |
|
|
41
|
+
|
|
42
|
+
## Adding Sync
|
|
43
|
+
|
|
44
|
+
To enable real-time sync across devices, update `src/main.tsx`:
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
const app = createApp({
|
|
48
|
+
schema,
|
|
49
|
+
sync: {
|
|
50
|
+
url: import.meta.env.VITE_SYNC_URL || 'ws://localhost:3001',
|
|
51
|
+
},
|
|
52
|
+
// ...
|
|
53
|
+
})
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Then create a `server.ts` and install `@korajs/server`. See the [Sync Configuration guide](https://ehoneahobed.github.io/kora/guide/sync-configuration).
|
|
57
|
+
|
|
58
|
+
## Learn More
|
|
59
|
+
|
|
60
|
+
- [Documentation](https://ehoneahobed.github.io/kora/)
|
|
61
|
+
- [Storage Configuration](https://ehoneahobed.github.io/kora/guide/storage-configuration)
|
|
62
|
+
- [Schema Design](https://ehoneahobed.github.io/kora/guide/schema-design)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>{{projectName}}</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="app"></div>
|
|
10
|
+
<script type="module" src="/src/main.ts"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{projectName}}",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "kora dev",
|
|
8
|
+
"build": "vue-tsc --noEmit && vite build",
|
|
9
|
+
"preview": "vite preview"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"korajs": "{{koraVersion}}",
|
|
13
|
+
"@korajs/vue": "{{koraVersion}}",
|
|
14
|
+
"@korajs/store": "{{koraVersion}}",
|
|
15
|
+
"@sqlite.org/sqlite-wasm": ">=3.51.0-build1",
|
|
16
|
+
"vue": "^3.5.0",
|
|
17
|
+
"yjs": "^13.6.30"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@korajs/cli": "{{koraVersion}}",
|
|
21
|
+
"@vitejs/plugin-vue": "^5.2.0",
|
|
22
|
+
"typescript": "^5.7.0",
|
|
23
|
+
"vite": "^6.0.0",
|
|
24
|
+
"vue-tsc": "^2.2.0"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, ref } from 'vue'
|
|
3
|
+
import { useTodos } from './modules/todos/useTodos'
|
|
4
|
+
|
|
5
|
+
type Filter = 'all' | 'active' | 'completed'
|
|
6
|
+
|
|
7
|
+
const { allTodos, activeTodos, completedTodos, addTodo, toggleTodo, deleteTodo } = useTodos()
|
|
8
|
+
|
|
9
|
+
const filter = ref<Filter>('all')
|
|
10
|
+
const input = ref('')
|
|
11
|
+
|
|
12
|
+
const filteredTodos = computed(() => {
|
|
13
|
+
if (filter.value === 'active') return activeTodos.value
|
|
14
|
+
if (filter.value === 'completed') return completedTodos.value
|
|
15
|
+
return allTodos.value
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
function handleSubmit(): void {
|
|
19
|
+
const title = input.value.trim()
|
|
20
|
+
if (!title) return
|
|
21
|
+
addTodo.mutate({ title })
|
|
22
|
+
input.value = ''
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function clearCompleted(): void {
|
|
26
|
+
for (const todo of completedTodos.value) {
|
|
27
|
+
deleteTodo.mutate(todo.id)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function formatTime(timestamp: number): string {
|
|
32
|
+
const date = new Date(timestamp)
|
|
33
|
+
const now = new Date()
|
|
34
|
+
if (date.toDateString() === now.toDateString()) {
|
|
35
|
+
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
|
|
36
|
+
}
|
|
37
|
+
return date.toLocaleDateString([], { month: 'short', day: 'numeric' })
|
|
38
|
+
}
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<template>
|
|
42
|
+
<div class="app">
|
|
43
|
+
<div class="header">
|
|
44
|
+
<h1>My Tasks</h1>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<div class="stats">
|
|
48
|
+
<div class="stat-card">
|
|
49
|
+
<div class="label">Total</div>
|
|
50
|
+
<div class="value muted">{{ allTodos.length }}</div>
|
|
51
|
+
</div>
|
|
52
|
+
<div class="stat-card">
|
|
53
|
+
<div class="label">Remaining</div>
|
|
54
|
+
<div class="value warning">{{ activeTodos.length }}</div>
|
|
55
|
+
</div>
|
|
56
|
+
<div class="stat-card">
|
|
57
|
+
<div class="label">Done</div>
|
|
58
|
+
<div class="value success">{{ completedTodos.length }}</div>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<form class="add-form" @submit.prevent="handleSubmit">
|
|
63
|
+
<input v-model="input" type="text" placeholder="What needs to be done?" />
|
|
64
|
+
<button type="submit" :disabled="!input.trim()">Add</button>
|
|
65
|
+
</form>
|
|
66
|
+
|
|
67
|
+
<div class="filters">
|
|
68
|
+
<button
|
|
69
|
+
v-for="f in (['all', 'active', 'completed'] as const)"
|
|
70
|
+
:key="f"
|
|
71
|
+
type="button"
|
|
72
|
+
:class="['filter-btn', { active: filter === f }]"
|
|
73
|
+
@click="filter = f"
|
|
74
|
+
>
|
|
75
|
+
{{ f.charAt(0).toUpperCase() + f.slice(1) }}
|
|
76
|
+
<span class="badge">
|
|
77
|
+
{{
|
|
78
|
+
f === 'all'
|
|
79
|
+
? allTodos.length
|
|
80
|
+
: f === 'active'
|
|
81
|
+
? activeTodos.length
|
|
82
|
+
: completedTodos.length
|
|
83
|
+
}}
|
|
84
|
+
</span>
|
|
85
|
+
</button>
|
|
86
|
+
</div>
|
|
87
|
+
|
|
88
|
+
<div class="todo-list">
|
|
89
|
+
<div v-if="filteredTodos.length === 0" class="empty-state">
|
|
90
|
+
<template v-if="filter === 'all'">No tasks yet. Add one above!</template>
|
|
91
|
+
<template v-else-if="filter === 'active'">All caught up! No active tasks.</template>
|
|
92
|
+
<template v-else>No completed tasks yet.</template>
|
|
93
|
+
</div>
|
|
94
|
+
<div v-for="todo in filteredTodos" v-else :key="todo.id" class="todo-item">
|
|
95
|
+
<button
|
|
96
|
+
type="button"
|
|
97
|
+
:class="['toggle', { checked: todo.completed }]"
|
|
98
|
+
@click="toggleTodo.mutate(todo.id, { completed: !todo.completed })"
|
|
99
|
+
>
|
|
100
|
+
{{ todo.completed ? '✓' : '' }}
|
|
101
|
+
</button>
|
|
102
|
+
<span :class="['title', { done: todo.completed }]">{{ String(todo.title) }}</span>
|
|
103
|
+
<span v-if="todo.createdAt" class="time">{{ formatTime(Number(todo.createdAt)) }}</span>
|
|
104
|
+
<button type="button" class="delete-btn" @click="deleteTodo.mutate(todo.id)">×</button>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
|
|
108
|
+
<div v-if="allTodos.length > 0" class="footer">
|
|
109
|
+
<span>{{ activeTodos.length }} item{{ activeTodos.length !== 1 ? 's' : '' }} left</span>
|
|
110
|
+
<button v-if="completedTodos.length > 0" type="button" @click="clearCompleted">
|
|
111
|
+
Clear completed
|
|
112
|
+
</button>
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<p class="branding">Powered by Kora — offline-first</p>
|
|
116
|
+
</div>
|
|
117
|
+
</template>
|