Skip to content

Commit 3046b71

Browse files
committed
Better sync question
1 parent a8f3baf commit 3046b71

10 files changed

Lines changed: 775 additions & 1126 deletions

File tree

CONVENTIONS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ When retrieving typed values from stores:
348348
const username = settingsStore.getValue('username') as string;
349349

350350
// Use nullish coalescing for optional values
351-
const points = store.getCell('strokes', id, 'points') as string ?? '[]';
351+
const points = (store.getCell('strokes', id, 'points') as string) ?? '[]';
352352
```
353353

354354
### Unused Parameters

README.md

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ This will prompt you with questions to configure your new TinyBase app:
2222
- **Framework** - React or Vanilla JS
2323
- **App type** - Todo app, Chat app, Drawing app, or Tic-tac-toe game
2424
- **Store schemas** - TypeScript type safety for stores (TypeScript only)
25-
- **Synchronization** - Enable real-time sync between clients
26-
- **Server code** - Include Node.js or Cloudflare Durable Objects server
25+
- **Synchronization** - None, remote demo server, local Node server, or local Durable Objects server
2726
- **Prettier** - Include Prettier for code formatting
2827
- **ESLint** - Include ESLint for code linting
2928

@@ -146,44 +145,44 @@ Schemas define:
146145

147146
### Synchronization
148147

149-
**Enabled** (default):
148+
Choose from four synchronization options:
150149

151-
- Real-time sync between browser tabs
152-
- WebSocket-based synchronization
153-
- Connects to demo server by default (wss://vite.tinybase.org)
154-
- MergeableStore for conflict-free replication
155-
- Automatic reconnection handling
156-
157-
**Disabled**:
150+
**None**:
158151

159152
- Local-only data storage
160153
- No network dependencies
161154
- Simpler architecture
162155
- Still uses MergeableStore for consistency
163156

164-
### Server Code
157+
**Via remote demo server (stateless)** (default):
165158

166-
When synchronization is enabled, you can include server code:
159+
- Real-time sync between browser tabs
160+
- WebSocket-based synchronization
161+
- Connects to demo server (wss://vite.tinybase.org)
162+
- MergeableStore for conflict-free replication
163+
- Automatic reconnection handling
164+
- Great for prototyping
165+
- No local server management needed
167166

168-
**Node.js Server** (port 8043):
167+
**Via local node server (stateless)** (port 8043):
169168

169+
- Real-time sync with local Node.js server
170170
- WebSocket server using `ws` library
171171
- TinyBase server synchronizer
172172
- Runs with `npm run dev` in server directory
173+
- Stateless - no data persistence
173174
- Easy to deploy to any Node.js host
175+
- Full control over server code
174176

175-
**Cloudflare Durable Objects** (port 8787):
177+
**Via local DurableObjects server (stateful)** (port 8787):
176178

179+
- Real-time sync with Cloudflare Durable Objects
177180
- Serverless WebSocket server
178181
- Edge computing with Durable Objects
182+
- Stateful - data persists in Durable Objects storage
179183
- Global distribution
180184
- Runs locally with Wrangler
181-
182-
**No Server**:
183-
184-
- Connects to public demo server
185-
- Great for prototyping
186-
- No local server management needed
185+
- Designed for production deployment
187186

188187
### Prettier & ESLint
189188

screenshots/chat.png

-434 Bytes
Loading

screenshots/drawing.png

6 Bytes
Loading

src/cli.ts

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -73,28 +73,19 @@ const config = {
7373
initial: false,
7474
},
7575
{
76-
type: 'confirm' as const,
77-
name: 'sync',
78-
message: 'Enable synchronization?',
79-
initial: true,
80-
},
81-
{
82-
type: (prev: unknown, answers: Record<string, unknown>) =>
83-
answers.sync ? ('confirm' as const) : null,
84-
name: 'server',
85-
message: 'Add code for server?',
86-
initial: false,
87-
},
88-
{
89-
type: (prev: unknown, answers: Record<string, unknown>) =>
90-
answers.server ? ('select' as const) : null,
91-
name: 'serverType',
92-
message: 'Server type:',
76+
type: 'select' as const,
77+
name: 'syncType',
78+
message: 'Synchronization:',
9379
choices: [
94-
{title: 'Node', value: 'node'},
95-
{title: 'Durable Objects', value: 'durable-objects'},
80+
{title: 'None', value: 'none'},
81+
{title: 'Via remote demo server (stateless)', value: 'remote'},
82+
{title: 'Via local node server (stateless)', value: 'node'},
83+
{
84+
title: 'Via local DurableObjects server (stateful)',
85+
value: 'durable-objects',
86+
},
9687
],
97-
initial: 0,
88+
initial: 1,
9889
},
9990
{
10091
type: 'confirm' as const,
@@ -110,7 +101,9 @@ const config = {
110101
},
111102
{
112103
type: (prev: unknown, answers: Record<string, unknown>) =>
113-
!answers.server ? ('confirm' as const) : null,
104+
answers.syncType !== 'node' && answers.syncType !== 'durable-objects'
105+
? ('confirm' as const)
106+
: null,
114107
name: 'installAndRun',
115108
message: 'Install dependencies and start dev server?',
116109
initial: true,
@@ -126,15 +119,19 @@ const config = {
126119
prettier,
127120
eslint,
128121
schemas,
129-
sync,
130-
server,
131-
serverType,
122+
syncType,
132123
installAndRun,
133124
} = answers;
134125
const typescript = language === 'typescript';
135126
const javascript = !typescript;
136127
const react = framework === 'react';
137128
const ext = typescript ? (react ? 'tsx' : 'ts') : react ? 'jsx' : 'js';
129+
const normalizedSyncType = syncType || 'remote';
130+
const sync = normalizedSyncType !== 'none';
131+
const server =
132+
normalizedSyncType === 'node' || normalizedSyncType === 'durable-objects';
133+
const serverType =
134+
normalizedSyncType === 'durable-objects' ? 'durable-objects' : 'node';
138135

139136
return {
140137
projectName,
@@ -144,9 +141,10 @@ const config = {
144141
prettier,
145142
eslint,
146143
schemas: typescript && (schemas === true || schemas === 'true'),
147-
sync: sync === true || sync === 'true',
148-
server: server === true || server === 'true',
149-
serverType: serverType || 'node',
144+
syncType: normalizedSyncType,
145+
sync,
146+
server,
147+
serverType,
150148
installAndRun: installAndRun === true || installAndRun === 'true',
151149
typescript,
152150
javascript,
@@ -202,7 +200,8 @@ const config = {
202200
workingDirectory: 'client',
203201

204202
onSuccess: (projectName: string, context: Record<string, unknown>) => {
205-
const server = context.server as boolean;
203+
const syncType = context.syncType as string;
204+
const server = syncType === 'node' || syncType === 'durable-objects';
206205
const pm = detectPackageManager();
207206

208207
console.log(`Next steps:`);

templates/README.md.hbs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ A TinyBase app built with {{#if typescript}}TypeScript{{else}}JavaScript{{/if}}
99

1010
## Getting Started
1111

12-
Alongside this file, you will see a directory called `client` (and optionally
13-
one called `server` if you included server code).
12+
Alongside this file, you will see a directory called `client`{{#if server}} (and optionally
13+
one called `server` for your {{#if (eq syncType "node")}}local Node.js server{{else if (eq syncType "durable-objects")}}local Cloudflare Durable Objects server{{/if}}){{/if}}.
1414

1515
To start the web client with Vite, run the following commands:
1616

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
{{#if server}}
2-
{{#if (eq serverType "node")}}
3-
export const SERVER = 'ws://localhost:8043';
4-
{{else}}
5-
export const SERVER = 'ws://localhost:8787';
6-
{{/if}}
1+
{{#if (eq syncType "node")}}
2+
export const SERVER = 'ws://localhost:8043';
3+
{{else if (eq syncType "durable-objects")}}
4+
export const SERVER = 'ws://localhost:8787';
75
{{else}}
86
export const SERVER = 'wss://vite.tinybase.org';
97
{{/if}}

0 commit comments

Comments
 (0)