create-syncular-app 0.1.2 → 0.2.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 (64) hide show
  1. package/README.md +70 -27
  2. package/dist/cli.d.ts +11 -0
  3. package/dist/cli.js +131 -179
  4. package/dist/constants.d.ts +40 -0
  5. package/dist/constants.js +46 -0
  6. package/dist/index.d.ts +3 -0
  7. package/dist/index.js +3 -0
  8. package/dist/scaffold.d.ts +44 -0
  9. package/dist/scaffold.js +106 -0
  10. package/package.json +22 -15
  11. package/src/cli.ts +174 -0
  12. package/src/constants.ts +53 -0
  13. package/src/index.ts +3 -0
  14. package/src/scaffold.ts +161 -0
  15. package/template/minimal/README.md +45 -0
  16. package/template/minimal/gitignore +5 -0
  17. package/template/minimal/migrations/0001_initial/up.sql +9 -0
  18. package/template/minimal/package.json +22 -0
  19. package/template/minimal/src/clients.ts +54 -0
  20. package/template/minimal/src/make-client.ts +26 -0
  21. package/template/minimal/src/server.ts +39 -0
  22. package/template/minimal/src/smoke.test.ts +70 -0
  23. package/template/minimal/src/syncular.generated.ts +66 -0
  24. package/template/minimal/syncular.ir.json +66 -0
  25. package/template/minimal/syncular.json +17 -0
  26. package/template/minimal/tsconfig.json +16 -0
  27. package/template/web/README.md +63 -0
  28. package/template/web/gitignore +5 -0
  29. package/template/web/migrations/0001_initial/up.sql +11 -0
  30. package/template/web/package.json +22 -0
  31. package/template/web/src/frontend/index.html +37 -0
  32. package/template/web/src/frontend/main.ts +191 -0
  33. package/template/web/src/frontend/worker.ts +9 -0
  34. package/template/web/src/server.ts +183 -0
  35. package/template/web/src/smoke.test.ts +91 -0
  36. package/template/web/src/syncular.generated.ts +74 -0
  37. package/template/web/syncular.ir.json +76 -0
  38. package/template/web/syncular.json +17 -0
  39. package/template/web/tsconfig.json +16 -0
  40. package/template/README.md +0 -122
  41. package/template/_gitignore +0 -5
  42. package/template/generated/kotlin/SyncularApp.kt +0 -1005
  43. package/template/generated/rust/diesel_tables.rs +0 -142
  44. package/template/generated/rust/migrations.rs +0 -32
  45. package/template/generated/rust/schema.rs +0 -15
  46. package/template/generated/rust/syncular.rs +0 -926
  47. package/template/generated/swift/SyncularApp.swift +0 -1191
  48. package/template/generated/syncular.codegen.json +0 -19
  49. package/template/index.html +0 -13
  50. package/template/migrations/0001_initial/down.sql +0 -1
  51. package/template/migrations/0001_initial/up.sql +0 -8
  52. package/template/package.json +0 -33
  53. package/template/scripts/dev.ts +0 -42
  54. package/template/src/app.tsx +0 -231
  55. package/template/src/client/syncular.ts +0 -61
  56. package/template/src/generated/syncular.generated.ts +0 -769
  57. package/template/src/generated/syncular.server.generated.ts +0 -512
  58. package/template/src/main.tsx +0 -5
  59. package/template/src/server/sync-server.ts +0 -129
  60. package/template/src/styles.css +0 -233
  61. package/template/syncular.app.ts +0 -23
  62. package/template/syncular.schema.json +0 -145
  63. package/template/tsconfig.json +0 -18
  64. package/template/vite.config.ts +0 -9
@@ -1,233 +0,0 @@
1
- :root {
2
- color: #17211f;
3
- background: #eef2ef;
4
- font-family:
5
- Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
6
- "Segoe UI", sans-serif;
7
- font-synthesis: none;
8
- text-rendering: optimizeLegibility;
9
- }
10
-
11
- * {
12
- box-sizing: border-box;
13
- }
14
-
15
- body {
16
- margin: 0;
17
- min-width: 320px;
18
- min-height: 100vh;
19
- }
20
-
21
- button,
22
- input {
23
- font: inherit;
24
- }
25
-
26
- .app-shell {
27
- max-width: 640px;
28
- min-height: 100vh;
29
- margin: 0 auto;
30
- padding: 32px 18px;
31
- }
32
-
33
- .topbar {
34
- margin-bottom: 20px;
35
- }
36
-
37
- .eyebrow {
38
- margin: 0 0 5px;
39
- color: #65706d;
40
- font-size: 0.76rem;
41
- font-weight: 700;
42
- text-transform: uppercase;
43
- }
44
-
45
- h1,
46
- h2 {
47
- margin: 0;
48
- }
49
-
50
- h1 {
51
- font-size: clamp(1.8rem, 4vw, 2.6rem);
52
- line-height: 1.05;
53
- }
54
-
55
- h2 {
56
- font-size: 1.22rem;
57
- }
58
-
59
- .client-pane {
60
- padding: 18px;
61
- border: 1px solid #d2ddd8;
62
- border-top: 5px solid #2f8f83;
63
- border-radius: 8px;
64
- background: #fbfdfb;
65
- box-shadow: 0 18px 40px rgb(24 42 36 / 8%);
66
- }
67
-
68
- .pane-header {
69
- display: flex;
70
- align-items: center;
71
- justify-content: space-between;
72
- gap: 12px;
73
- margin-bottom: 18px;
74
- }
75
-
76
- .status-badge {
77
- display: inline-flex;
78
- align-items: center;
79
- gap: 7px;
80
- min-width: 88px;
81
- justify-content: center;
82
- padding: 7px 9px;
83
- border-radius: 999px;
84
- color: #21302c;
85
- background: #ecf3ef;
86
- font-size: 0.82rem;
87
- font-weight: 700;
88
- }
89
-
90
- .status-dot {
91
- width: 8px;
92
- height: 8px;
93
- border-radius: 50%;
94
- background: #77837e;
95
- }
96
-
97
- .status-badge.ready .status-dot {
98
- background: #2f8f83;
99
- }
100
-
101
- .status-badge.syncing .status-dot {
102
- background: #c59724;
103
- }
104
-
105
- .status-badge.offline .status-dot {
106
- background: #5f6f79;
107
- }
108
-
109
- .status-badge.attention .status-dot {
110
- background: #b7791f;
111
- }
112
-
113
- .status-badge.error .status-dot {
114
- background: #c54646;
115
- }
116
-
117
- .add-row {
118
- display: grid;
119
- grid-template-columns: minmax(0, 1fr) 42px;
120
- gap: 8px;
121
- margin-bottom: 14px;
122
- }
123
-
124
- .add-row input {
125
- min-width: 0;
126
- height: 42px;
127
- padding: 0 12px;
128
- border: 1px solid #cbd6d1;
129
- border-radius: 8px;
130
- background: #fff;
131
- color: #17211f;
132
- }
133
-
134
- .add-row input:focus {
135
- border-color: #2f8f83;
136
- outline: 3px solid rgb(47 143 131 / 18%);
137
- }
138
-
139
- .add-row button {
140
- display: inline-flex;
141
- align-items: center;
142
- justify-content: center;
143
- border: 0;
144
- border-radius: 8px;
145
- color: #fff;
146
- background: #17211f;
147
- font-size: 1.2rem;
148
- cursor: pointer;
149
- }
150
-
151
- .task-list {
152
- display: grid;
153
- gap: 8px;
154
- }
155
-
156
- .task-row {
157
- display: grid;
158
- grid-template-columns: 34px minmax(0, 1fr) 34px;
159
- align-items: center;
160
- gap: 8px;
161
- min-height: 44px;
162
- padding: 6px;
163
- border: 1px solid #dde5e1;
164
- border-radius: 8px;
165
- background: #fff;
166
- }
167
-
168
- .task-row span {
169
- min-width: 0;
170
- overflow-wrap: anywhere;
171
- font-size: 0.95rem;
172
- }
173
-
174
- .task-row span.done {
175
- color: #7b8581;
176
- text-decoration: line-through;
177
- }
178
-
179
- .icon-button {
180
- display: inline-flex;
181
- align-items: center;
182
- justify-content: center;
183
- width: 32px;
184
- height: 32px;
185
- border: 0;
186
- border-radius: 8px;
187
- color: #1f3a35;
188
- background: #e4efeb;
189
- cursor: pointer;
190
- }
191
-
192
- .icon-button.muted {
193
- color: #5d6763;
194
- background: transparent;
195
- }
196
-
197
- .icon-button:hover,
198
- .add-row button:hover {
199
- filter: brightness(0.94);
200
- }
201
-
202
- .empty-state,
203
- .error-line,
204
- .offline-line {
205
- margin: 12px 0 0;
206
- padding: 12px;
207
- border-radius: 8px;
208
- font-size: 0.9rem;
209
- }
210
-
211
- .empty-state {
212
- color: #68736f;
213
- background: #f2f6f4;
214
- }
215
-
216
- .error-line {
217
- color: #8f2727;
218
- background: #fff1f1;
219
- overflow-wrap: anywhere;
220
- }
221
-
222
- .offline-line {
223
- color: #45545b;
224
- background: #eef4f6;
225
- overflow-wrap: anywhere;
226
- }
227
-
228
- .pane-footnote {
229
- margin: 14px 0 0;
230
- color: #68736f;
231
- font-size: 0.82rem;
232
- font-weight: 600;
233
- }
@@ -1,23 +0,0 @@
1
- import { defineSyncularClient, scope, syncedTable } from '@syncular/typegen';
2
-
3
- /**
4
- * Syncular app contract.
5
- *
6
- * The schema lives in migrations/*.sql; this file describes how the synced
7
- * tables map to subscriptions and scopes. After changing either, run
8
- * `bun run codegen` (or `npx syncular generate`) to refresh the generated
9
- * modules under src/generated/.
10
- */
11
- export const app = defineSyncularClient({
12
- typescriptOutputPath: 'src/generated/syncular.generated.ts',
13
- typescriptServerOutputPath: 'src/generated/syncular.server.generated.ts',
14
- tables: {
15
- tasks: syncedTable({
16
- table: 'tasks',
17
- subscriptionId: 'sub-tasks',
18
- scopes: [scope('user_id', { source: 'actorId', required: true })],
19
- serverVersion: 'server_version',
20
- sqliteWithoutRowid: true,
21
- }),
22
- },
23
- });
@@ -1,145 +0,0 @@
1
- {
2
- "$schema": "https://syncular.dev/schemas/syncular.schema.v1.json",
3
- "contractVersion": 1,
4
- "appSchemaVersion": 1,
5
- "clientSchemaSupport": {
6
- "current": 1,
7
- "minSupported": 1,
8
- "supported": [
9
- 1
10
- ]
11
- },
12
- "migrations": [
13
- {
14
- "version": "0001",
15
- "schemaVersion": 1,
16
- "name": "initial"
17
- }
18
- ],
19
- "tables": [
20
- {
21
- "name": "tasks",
22
- "primaryKeyColumn": "id",
23
- "serverVersionColumn": "server_version",
24
- "softDeleteColumn": null,
25
- "columns": [
26
- {
27
- "name": "id",
28
- "sqlType": "TEXT",
29
- "typeFamily": "text",
30
- "appType": "string",
31
- "nullable": false,
32
- "notnullRequired": false,
33
- "primaryKey": true,
34
- "hasDefault": false,
35
- "defaultSql": null,
36
- "serverVersion": false,
37
- "softDelete": false,
38
- "blobRef": false,
39
- "scope": null
40
- },
41
- {
42
- "name": "title",
43
- "sqlType": "TEXT",
44
- "typeFamily": "text",
45
- "appType": "string",
46
- "nullable": false,
47
- "notnullRequired": true,
48
- "primaryKey": false,
49
- "hasDefault": false,
50
- "defaultSql": null,
51
- "serverVersion": false,
52
- "softDelete": false,
53
- "blobRef": false,
54
- "scope": null
55
- },
56
- {
57
- "name": "completed",
58
- "sqlType": "INTEGER",
59
- "typeFamily": "integer",
60
- "appType": "integer",
61
- "nullable": false,
62
- "notnullRequired": true,
63
- "primaryKey": false,
64
- "hasDefault": true,
65
- "defaultSql": "0",
66
- "serverVersion": false,
67
- "softDelete": false,
68
- "blobRef": false,
69
- "scope": null
70
- },
71
- {
72
- "name": "user_id",
73
- "sqlType": "TEXT",
74
- "typeFamily": "text",
75
- "appType": "string",
76
- "nullable": false,
77
- "notnullRequired": true,
78
- "primaryKey": false,
79
- "hasDefault": false,
80
- "defaultSql": null,
81
- "serverVersion": false,
82
- "softDelete": false,
83
- "blobRef": false,
84
- "scope": "user_id"
85
- },
86
- {
87
- "name": "created_at",
88
- "sqlType": "BIGINT",
89
- "typeFamily": "integer",
90
- "appType": "integer",
91
- "nullable": false,
92
- "notnullRequired": true,
93
- "primaryKey": false,
94
- "hasDefault": true,
95
- "defaultSql": "0",
96
- "serverVersion": false,
97
- "softDelete": false,
98
- "blobRef": false,
99
- "scope": null
100
- },
101
- {
102
- "name": "server_version",
103
- "sqlType": "BIGINT",
104
- "typeFamily": "integer",
105
- "appType": "integer",
106
- "nullable": false,
107
- "notnullRequired": true,
108
- "primaryKey": false,
109
- "hasDefault": true,
110
- "defaultSql": "0",
111
- "serverVersion": true,
112
- "softDelete": false,
113
- "blobRef": false,
114
- "scope": null
115
- }
116
- ],
117
- "blobColumns": [],
118
- "crdtYjsFields": [],
119
- "encryptedFields": [],
120
- "scopes": [
121
- {
122
- "name": "user_id",
123
- "column": "user_id",
124
- "source": "actorId",
125
- "required": true
126
- }
127
- ],
128
- "subscription": {
129
- "id": "sub-tasks",
130
- "params": {}
131
- },
132
- "sqliteWithoutRowid": true
133
- }
134
- ],
135
- "localBaseSchema": {
136
- "tableSetupSql": [
137
- "CREATE TABLE IF NOT EXISTS \"tasks\" (\n \"id\" TEXT PRIMARY KEY,\n \"title\" TEXT NOT NULL,\n \"completed\" INTEGER NOT NULL DEFAULT 0,\n \"user_id\" TEXT NOT NULL,\n \"created_at\" INTEGER NOT NULL DEFAULT 0,\n \"server_version\" INTEGER NOT NULL DEFAULT 0\n) WITHOUT ROWID"
138
- ]
139
- },
140
- "localDerivedSchema": {
141
- "indexes": [],
142
- "readModelSetupSql": [],
143
- "readModelRebuildSql": []
144
- }
145
- }
@@ -1,18 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "ESNext",
5
- "moduleResolution": "Bundler",
6
- "lib": ["ES2024", "DOM", "DOM.Iterable"],
7
- "jsx": "react-jsx",
8
- "strict": true,
9
- "skipLibCheck": true,
10
- "esModuleInterop": true,
11
- "resolveJsonModule": true,
12
- "isolatedModules": true,
13
- "forceConsistentCasingInFileNames": true,
14
- "noEmit": true,
15
- "types": ["bun", "vite/client"]
16
- },
17
- "include": ["src", "scripts", "syncular.app.ts", "vite.config.ts"]
18
- }
@@ -1,9 +0,0 @@
1
- import { defineConfig } from 'vite';
2
-
3
- export default defineConfig({
4
- server: {
5
- host: '127.0.0.1',
6
- port: 5173,
7
- strictPort: false,
8
- },
9
- });