@prabhask5/stellar-engine 1.2.1 → 1.2.2
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/README.md +129 -134
- package/dist/auth/resolveAuthState.js +3 -16
- package/dist/auth/resolveAuthState.js.map +1 -1
- package/dist/auth/singleUser.d.ts.map +1 -1
- package/dist/auth/singleUser.js +2 -3
- package/dist/auth/singleUser.js.map +1 -1
- package/dist/config.d.ts +18 -29
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +13 -20
- package/dist/config.js.map +1 -1
- package/dist/database.d.ts +3 -18
- package/dist/database.d.ts.map +1 -1
- package/dist/database.js +5 -22
- package/dist/database.js.map +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +8 -11
- package/dist/engine.js.map +1 -1
- package/dist/sw/sw.js +0 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
# @prabhask5/stellar-engine [](https://www.npmjs.com/package/@prabhask5/stellar-engine) [](https://supabase.com)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A plug-and-play, offline-first sync engine for **Supabase + Dexie.js** applications. All reads come from IndexedDB, all writes land locally first, and a background sync loop ships changes to Supabase -- so your app stays fast and functional regardless of network state. Optional **SvelteKit** integrations are included for teams building with Svelte 5, but the core engine works with any framework or vanilla JS.
|
|
4
4
|
|
|
5
5
|
## Documentation
|
|
6
6
|
|
|
7
|
-
- [API Reference](./API_REFERENCE.md) -- full signatures, parameters, and usage examples for every public export
|
|
8
7
|
- [Architecture](./ARCHITECTURE.md) -- internal design, data flow, and module responsibilities
|
|
9
|
-
- [
|
|
10
|
-
frameworks used in stellar-engine
|
|
8
|
+
- [API Reference](./API_REFERENCE.md) -- full signatures, parameters, and usage examples for every public export
|
|
9
|
+
- [Frameworks](./FRAMEWORKS.md) -- more reading on frameworks used in stellar-engine
|
|
11
10
|
|
|
12
11
|
## Features
|
|
13
12
|
|
|
14
|
-
- **Schema-driven configuration** -- declare tables once
|
|
13
|
+
- **Schema-driven configuration** -- declare tables once in a simple object; the engine auto-generates Dexie stores, database versioning, TypeScript interfaces, and Supabase SQL
|
|
15
14
|
- **Intent-based sync operations** -- operations preserve intent (`increment`, `set`, `create`, `delete`) instead of final state, enabling smarter coalescing and conflict handling
|
|
16
15
|
- **6-step operation coalescing** -- 50 rapid writes are compressed into 1 outbound operation, dramatically reducing sync traffic
|
|
17
16
|
- **Three-tier conflict resolution** -- field-level auto-merge for non-overlapping changes, different-field merge, and same-field resolution (`local_pending` > `delete_wins` > `last_write_wins` with device ID tiebreaker)
|
|
18
17
|
- **Offline authentication** -- SHA-256 credential caching and offline session tokens let users sign in and work without connectivity; sessions reconcile automatically on reconnect
|
|
19
18
|
- **Single-user PIN/password auth** -- simplified gate backed by real Supabase email/password auth; PIN is padded to meet minimum length and verified server-side
|
|
20
|
-
- **Device verification** -- email OTP for untrusted devices with
|
|
19
|
+
- **Device verification** -- email OTP for untrusted devices with configurable trust duration
|
|
21
20
|
- **Realtime subscriptions** -- Supabase Realtime WebSocket push with echo suppression and deduplication against polling
|
|
22
21
|
- **Tombstone management** -- soft deletes with configurable garbage collection
|
|
23
22
|
- **Egress optimization** -- column-level selects, operation coalescing, push-only mode when realtime is healthy, cursor-based pulls
|
|
@@ -28,6 +27,7 @@ frameworks used in stellar-engine
|
|
|
28
27
|
- **Svelte actions** -- `remoteChangeAnimation`, `trackEditing`, `triggerLocalAnimation` for declarative UI behavior
|
|
29
28
|
- **SQL generation** -- auto-generate `CREATE TABLE` statements, RLS policies, and migrations from your schema config
|
|
30
29
|
- **TypeScript generation** -- auto-generate interfaces from schema
|
|
30
|
+
- **Migration generation** -- auto-generate `ALTER TABLE` rename and column rename SQL from `renamedFrom` / `renamedColumns` hints
|
|
31
31
|
- **Diagnostics** -- comprehensive runtime diagnostics covering sync, queue, realtime, conflicts, egress, and network
|
|
32
32
|
- **Debug utilities** -- opt-in debug logging and `window` debug utilities for browser console inspection
|
|
33
33
|
- **SvelteKit integration** (optional) -- layout helpers, server handlers, email confirmation, service worker lifecycle, and auth hydration
|
|
@@ -50,92 +50,73 @@ frameworks used in stellar-engine
|
|
|
50
50
|
// npm install @prabhask5/stellar-engine
|
|
51
51
|
|
|
52
52
|
// ─── 1. Initialize the engine ──────────────────────────────────────
|
|
53
|
-
// Call once at app startup (e.g., root layout, main entry point)
|
|
53
|
+
// Call once at app startup (e.g., root layout, main entry point).
|
|
54
|
+
// Schema-driven: declare tables once, engine handles everything else.
|
|
54
55
|
|
|
55
|
-
import {
|
|
56
|
-
initEngine,
|
|
57
|
-
startSyncEngine,
|
|
58
|
-
supabase,
|
|
59
|
-
getDb,
|
|
60
|
-
resetDatabase,
|
|
61
|
-
validateSupabaseCredentials,
|
|
62
|
-
validateSchema,
|
|
63
|
-
} from '@prabhask5/stellar-engine';
|
|
56
|
+
import { initEngine, startSyncEngine, getDb, resetDatabase } from '@prabhask5/stellar-engine';
|
|
64
57
|
import { initConfig } from '@prabhask5/stellar-engine/config';
|
|
65
58
|
import { resolveAuthState } from '@prabhask5/stellar-engine/auth';
|
|
66
59
|
|
|
67
60
|
initEngine({
|
|
68
61
|
prefix: 'myapp',
|
|
69
|
-
|
|
70
|
-
// Schema-driven: declare tables once, engine handles the rest
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
supabaseName: 'tasks',
|
|
82
|
-
columns: 'id, title, project_id, count, sort_order, created_at, updated_at, is_deleted, user_id',
|
|
83
|
-
ownershipFilter: 'user_id',
|
|
84
|
-
mergeFields: ['count'], // Numeric merge: concurrent increments add up
|
|
62
|
+
|
|
63
|
+
// Schema-driven: declare tables once, engine handles the rest.
|
|
64
|
+
// System indexes (id, user_id, created_at, updated_at, deleted, _version)
|
|
65
|
+
// are auto-appended to every table. Database name auto-derived as `${prefix}DB`.
|
|
66
|
+
schema: {
|
|
67
|
+
projects: 'order', // String shorthand = indexes only
|
|
68
|
+
tasks: 'project_id, order', // Comma-separated Dexie indexes
|
|
69
|
+
focus_settings: { singleton: true }, // Object form for full control
|
|
70
|
+
goals: {
|
|
71
|
+
indexes: 'goal_list_id, order',
|
|
72
|
+
numericMergeFields: ['current_value'], // Additive merge on conflicts
|
|
73
|
+
excludeFromConflict: ['device_id'], // Skip these in conflict diffing
|
|
85
74
|
},
|
|
86
|
-
],
|
|
87
|
-
|
|
88
|
-
// Declarative database versioning -- system tables (syncQueue, conflictHistory,
|
|
89
|
-
// offlineCredentials, offlineSession, singleUserConfig) are auto-merged
|
|
90
|
-
database: {
|
|
91
|
-
name: 'MyAppDB',
|
|
92
|
-
versions: [
|
|
93
|
-
{
|
|
94
|
-
version: 1,
|
|
95
|
-
stores: {
|
|
96
|
-
projects: 'id, user_id, updated_at',
|
|
97
|
-
tasks: 'id, project_id, user_id, updated_at',
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
],
|
|
101
75
|
},
|
|
102
76
|
|
|
103
|
-
// Auth
|
|
77
|
+
// Auth: flat format with sensible defaults (all fields optional).
|
|
78
|
+
// No nested `singleUser` key needed -- engine normalizes internally.
|
|
104
79
|
auth: {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
80
|
+
gateType: 'code', // 'code' | 'password' (default: 'code')
|
|
81
|
+
codeLength: 6, // 4 | 6 (default: 6)
|
|
82
|
+
emailConfirmation: true, // default: true
|
|
83
|
+
deviceVerification: true, // default: true
|
|
84
|
+
profileExtractor: (meta) => ({ firstName: meta.first_name }),
|
|
85
|
+
profileToMetadata: (p) => ({ first_name: p.firstName }),
|
|
109
86
|
},
|
|
110
87
|
|
|
111
|
-
//
|
|
88
|
+
// Optional CRDT collaborative editing
|
|
89
|
+
crdt: true, // or { persistIntervalMs: 60000, maxOfflineDocuments: 50 }
|
|
90
|
+
|
|
91
|
+
// Optional demo mode
|
|
112
92
|
demo: {
|
|
113
93
|
seedData: async (db) => {
|
|
114
94
|
await db.table('projects').bulkPut([
|
|
115
|
-
{ id: 'demo-1', name: 'Sample Project',
|
|
95
|
+
{ id: 'demo-1', name: 'Sample Project', order: 1 },
|
|
116
96
|
]);
|
|
117
97
|
},
|
|
118
|
-
mockProfile: { email: 'demo@
|
|
98
|
+
mockProfile: { email: 'demo@test.com', firstName: 'Demo', lastName: 'User' },
|
|
119
99
|
},
|
|
120
100
|
|
|
121
|
-
//
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
},
|
|
101
|
+
// Tuning (all optional with defaults)
|
|
102
|
+
syncDebounceMs: 2000, // Default: 2000
|
|
103
|
+
syncIntervalMs: 900000, // Default: 900000 (15 min)
|
|
104
|
+
tombstoneMaxAgeDays: 7, // Default: 7
|
|
126
105
|
});
|
|
127
106
|
|
|
128
107
|
// ─── 2. Resolve auth and start the engine ──────────────────────────
|
|
108
|
+
// The engine fetches runtime config (Supabase URL + anon key) from
|
|
109
|
+
// your /api/config endpoint -- no need to pass a supabase client.
|
|
129
110
|
|
|
130
111
|
await initConfig();
|
|
131
112
|
const auth = await resolveAuthState();
|
|
132
113
|
|
|
133
114
|
if (!auth.singleUserSetUp) {
|
|
134
115
|
// First-time setup flow
|
|
135
|
-
//
|
|
116
|
+
// -> call setupSingleUser(code, profile, email) from your UI
|
|
136
117
|
} else if (auth.authMode === 'none') {
|
|
137
118
|
// Locked -- show unlock screen
|
|
138
|
-
//
|
|
119
|
+
// -> call unlockSingleUser(code) from your UI
|
|
139
120
|
} else {
|
|
140
121
|
// Authenticated -- start syncing
|
|
141
122
|
await startSyncEngine();
|
|
@@ -160,10 +141,10 @@ const projectId = generateId();
|
|
|
160
141
|
await engineCreate('projects', {
|
|
161
142
|
id: projectId,
|
|
162
143
|
name: 'New Project',
|
|
163
|
-
|
|
144
|
+
order: 1,
|
|
164
145
|
created_at: now(),
|
|
165
146
|
updated_at: now(),
|
|
166
|
-
|
|
147
|
+
deleted: false,
|
|
167
148
|
user_id: 'current-user-id',
|
|
168
149
|
});
|
|
169
150
|
|
|
@@ -177,7 +158,7 @@ await engineUpdate('tasks', taskId, {
|
|
|
177
158
|
await engineDelete('tasks', taskId);
|
|
178
159
|
|
|
179
160
|
// Increment (intent-preserved -- concurrent increments merge correctly)
|
|
180
|
-
await engineIncrement('
|
|
161
|
+
await engineIncrement('goals', goalId, 'current_value', 1);
|
|
181
162
|
|
|
182
163
|
// Query all rows from local IndexedDB
|
|
183
164
|
const projects = await queryAll('projects');
|
|
@@ -186,20 +167,19 @@ const projects = await queryAll('projects');
|
|
|
186
167
|
const project = await queryOne('projects', projectId);
|
|
187
168
|
|
|
188
169
|
// Get or create (atomic upsert)
|
|
189
|
-
const { record, created } = await engineGetOrCreate('
|
|
190
|
-
id:
|
|
191
|
-
|
|
192
|
-
sort_order: 0,
|
|
170
|
+
const { record, created } = await engineGetOrCreate('focus_settings', settingsId, {
|
|
171
|
+
id: settingsId,
|
|
172
|
+
theme: 'dark',
|
|
193
173
|
created_at: now(),
|
|
194
174
|
updated_at: now(),
|
|
195
|
-
|
|
175
|
+
deleted: false,
|
|
196
176
|
user_id: 'current-user-id',
|
|
197
177
|
});
|
|
198
178
|
|
|
199
179
|
// Batch writes (multiple operations in one sync push)
|
|
200
180
|
await engineBatchWrite([
|
|
201
|
-
{ type: 'create', table: 'tasks', data: { id: generateId(), title: 'Task 1', project_id: projectId,
|
|
202
|
-
{ type: 'create', table: 'tasks', data: { id: generateId(), title: 'Task 2', project_id: projectId,
|
|
181
|
+
{ type: 'create', table: 'tasks', data: { id: generateId(), title: 'Task 1', project_id: projectId, order: 1, created_at: now(), updated_at: now(), deleted: false, user_id: 'uid' } },
|
|
182
|
+
{ type: 'create', table: 'tasks', data: { id: generateId(), title: 'Task 2', project_id: projectId, order: 2, created_at: now(), updated_at: now(), deleted: false, user_id: 'uid' } },
|
|
203
183
|
{ type: 'update', table: 'projects', id: projectId, data: { updated_at: now() } },
|
|
204
184
|
]);
|
|
205
185
|
|
|
@@ -209,8 +189,8 @@ import { createCollectionStore, createDetailStore } from '@prabhask5/stellar-eng
|
|
|
209
189
|
|
|
210
190
|
// Collection store -- live-updating list from IndexedDB
|
|
211
191
|
const projectsStore = createCollectionStore('projects', {
|
|
212
|
-
filter: (p) => !p.
|
|
213
|
-
sort: (a, b) => a.
|
|
192
|
+
filter: (p) => !p.deleted,
|
|
193
|
+
sort: (a, b) => a.order - b.order,
|
|
214
194
|
});
|
|
215
195
|
// Subscribe: projectsStore.subscribe(items => { ... })
|
|
216
196
|
|
|
@@ -218,7 +198,7 @@ const projectsStore = createCollectionStore('projects', {
|
|
|
218
198
|
const projectDetail = createDetailStore('projects', projectId);
|
|
219
199
|
// Subscribe: projectDetail.subscribe(record => { ... })
|
|
220
200
|
|
|
221
|
-
// ─── 5. Reactive stores
|
|
201
|
+
// ─── 5. Reactive stores ────────────────────────────────────────────
|
|
222
202
|
|
|
223
203
|
import {
|
|
224
204
|
syncStatusStore,
|
|
@@ -228,12 +208,27 @@ import {
|
|
|
228
208
|
onSyncComplete,
|
|
229
209
|
} from '@prabhask5/stellar-engine/stores';
|
|
230
210
|
|
|
211
|
+
// $syncStatusStore -- current SyncStatus, last sync time, errors
|
|
212
|
+
// $authState -- { mode, session, offlineProfile, isLoading, authKickedMessage }
|
|
213
|
+
// $isOnline -- reactive boolean reflecting network state
|
|
214
|
+
// remoteChangesStore -- tracks entities recently changed by remote peers
|
|
215
|
+
|
|
231
216
|
// Listen for sync completions
|
|
232
217
|
onSyncComplete(() => {
|
|
233
218
|
console.log('Sync cycle finished');
|
|
234
219
|
});
|
|
235
220
|
|
|
236
|
-
// ─── 6.
|
|
221
|
+
// ─── 6. Svelte actions ─────────────────────────────────────────────
|
|
222
|
+
|
|
223
|
+
import { remoteChangeAnimation, trackEditing } from '@prabhask5/stellar-engine/actions';
|
|
224
|
+
|
|
225
|
+
// use:remoteChangeAnimation={{ table: 'tasks', id: task.id }}
|
|
226
|
+
// Animates elements when remote changes arrive for that entity.
|
|
227
|
+
|
|
228
|
+
// use:trackEditing={{ table: 'tasks', id: task.id }}
|
|
229
|
+
// Signals the engine a field is being actively edited (suppresses incoming overwrites).
|
|
230
|
+
|
|
231
|
+
// ─── 7. CRDT collaborative editing ────────────────────────────────
|
|
237
232
|
|
|
238
233
|
import {
|
|
239
234
|
openDocument,
|
|
@@ -255,6 +250,9 @@ const provider = await openDocument('doc-1', 'page-1', {
|
|
|
255
250
|
const { content, meta } = createBlockDocument(provider.doc);
|
|
256
251
|
meta.set('title', 'My Page');
|
|
257
252
|
|
|
253
|
+
// Shared text for simpler use cases
|
|
254
|
+
const text = createSharedText(provider.doc);
|
|
255
|
+
|
|
258
256
|
// Track collaborator cursors and presence
|
|
259
257
|
const unsub = onCollaboratorsChange('doc-1', (collaborators) => {
|
|
260
258
|
// Update avatar list, cursor positions, etc.
|
|
@@ -262,52 +260,55 @@ const unsub = onCollaboratorsChange('doc-1', (collaborators) => {
|
|
|
262
260
|
|
|
263
261
|
await closeDocument('doc-1');
|
|
264
262
|
|
|
265
|
-
// ───
|
|
263
|
+
// ─── 8. Demo mode ──────────────────────────────────────────────────
|
|
264
|
+
|
|
265
|
+
import { setDemoMode, isDemoMode } from '@prabhask5/stellar-engine';
|
|
266
266
|
|
|
267
|
-
|
|
267
|
+
// Check if demo mode is active
|
|
268
|
+
if (isDemoMode()) {
|
|
269
|
+
// In demo mode:
|
|
270
|
+
// - Uses '${prefix}DB_demo' IndexedDB (real DB never opened)
|
|
271
|
+
// - Zero Supabase network requests
|
|
272
|
+
// - authMode === 'demo', protected routes work with mock data
|
|
273
|
+
// - seedData callback runs on each page load
|
|
274
|
+
}
|
|
268
275
|
|
|
269
|
-
// Toggle demo mode (requires full page reload)
|
|
276
|
+
// Toggle demo mode from your UI (requires full page reload)
|
|
270
277
|
setDemoMode(true);
|
|
271
278
|
window.location.href = '/';
|
|
272
279
|
|
|
273
|
-
//
|
|
274
|
-
// - Uses '${name}_demo' IndexedDB (real DB never opened)
|
|
275
|
-
// - Zero Supabase network requests
|
|
276
|
-
// - authMode === 'demo', protected routes work with mock data
|
|
277
|
-
// - seedData callback runs on each page load
|
|
280
|
+
// ─── 9. SQL and TypeScript generation ──────────────────────────────
|
|
278
281
|
|
|
279
|
-
|
|
282
|
+
import { generateSupabaseSQL, generateTypeScript } from '@prabhask5/stellar-engine/utils';
|
|
283
|
+
import { getEngineConfig } from '@prabhask5/stellar-engine';
|
|
280
284
|
|
|
281
|
-
|
|
282
|
-
setDebugMode,
|
|
283
|
-
isDebugMode,
|
|
284
|
-
getSyncDiagnostics,
|
|
285
|
-
getQueueDiagnostics,
|
|
286
|
-
getRealtimeDiagnostics,
|
|
287
|
-
getConflictDiagnostics,
|
|
288
|
-
getEgressDiagnostics,
|
|
289
|
-
getNetworkDiagnostics,
|
|
290
|
-
} from '@prabhask5/stellar-engine/utils';
|
|
285
|
+
const config = getEngineConfig();
|
|
291
286
|
|
|
292
|
-
|
|
287
|
+
// Auto-generate Supabase SQL (CREATE TABLE + RLS policies) from schema
|
|
288
|
+
const sql = generateSupabaseSQL(config.schema!);
|
|
293
289
|
|
|
294
|
-
//
|
|
295
|
-
const
|
|
296
|
-
const queueInfo = getQueueDiagnostics();
|
|
297
|
-
const egressInfo = getEgressDiagnostics();
|
|
290
|
+
// Auto-generate TypeScript interfaces from schema
|
|
291
|
+
const ts = generateTypeScript(config.schema!);
|
|
298
292
|
|
|
299
|
-
// ───
|
|
293
|
+
// ─── 10. Diagnostics and debug ─────────────────────────────────────
|
|
300
294
|
|
|
301
|
-
import {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
295
|
+
import { setDebugMode, isDebugMode } from '@prabhask5/stellar-engine/utils';
|
|
296
|
+
import { getDiagnostics } from '@prabhask5/stellar-engine';
|
|
297
|
+
|
|
298
|
+
setDebugMode(true);
|
|
299
|
+
|
|
300
|
+
// Comprehensive runtime diagnostics
|
|
301
|
+
const diagnostics = await getDiagnostics();
|
|
302
|
+
// diagnostics.sync -- sync cycle statistics and recent cycle details
|
|
303
|
+
// diagnostics.queue -- pending operation queue state
|
|
304
|
+
// diagnostics.realtime -- realtime connection state and health
|
|
305
|
+
// diagnostics.conflict -- conflict resolution history and stats
|
|
306
|
+
// diagnostics.egress -- data transfer from Supabase (bytes, per-table breakdown)
|
|
307
|
+
// diagnostics.network -- network state and connectivity info
|
|
308
|
+
|
|
309
|
+
// When debug mode is enabled, utilities are exposed on `window`:
|
|
310
|
+
// window.__myappSyncStats(), window.__myappEgress(), window.__myappTombstones()
|
|
311
|
+
// window.__myappSync.forceFullSync()
|
|
311
312
|
```
|
|
312
313
|
|
|
313
314
|
## Commands
|
|
@@ -346,7 +347,7 @@ Generates **34+ files** for a production-ready SvelteKit 2 + Svelte 5 project:
|
|
|
346
347
|
|
|
347
348
|
| Export | Description |
|
|
348
349
|
|---|---|
|
|
349
|
-
| `initEngine(config)` | Initialize the engine with
|
|
350
|
+
| `initEngine(config)` | Initialize the engine with schema, auth, and optional CRDT/demo config |
|
|
350
351
|
| `startSyncEngine()` | Start the sync loop, realtime subscriptions, and event listeners |
|
|
351
352
|
| `stopSyncEngine()` | Tear down sync loop and subscriptions cleanly |
|
|
352
353
|
| `runFullSync()` | Run a complete pull-then-push cycle |
|
|
@@ -359,12 +360,11 @@ Generates **34+ files** for a production-ready SvelteKit 2 + Svelte 5 project:
|
|
|
359
360
|
|
|
360
361
|
| Export | Description |
|
|
361
362
|
|---|---|
|
|
362
|
-
| `supabase` | The configured `SupabaseClient` instance |
|
|
363
363
|
| `getDb()` | Get the Dexie database instance |
|
|
364
364
|
| `resetDatabase()` | Drop and recreate the local IndexedDB database |
|
|
365
365
|
| `clearLocalCache()` | Wipe all local application data |
|
|
366
366
|
| `clearPendingSyncQueue()` | Drop all pending outbound operations |
|
|
367
|
-
| `getSupabaseAsync()` | Async getter that waits for initialization |
|
|
367
|
+
| `getSupabaseAsync()` | Async getter that waits for Supabase client initialization |
|
|
368
368
|
| `resetSupabaseClient()` | Tear down and reinitialize the Supabase client |
|
|
369
369
|
|
|
370
370
|
### CRUD and Query Operations
|
|
@@ -465,7 +465,7 @@ Generates **34+ files** for a production-ready SvelteKit 2 + Svelte 5 project:
|
|
|
465
465
|
|
|
466
466
|
| Export | Description |
|
|
467
467
|
|---|---|
|
|
468
|
-
| `initConfig()` | Initialize runtime configuration |
|
|
468
|
+
| `initConfig()` | Initialize runtime configuration (fetches Supabase credentials from `/api/config`) |
|
|
469
469
|
| `getConfig()` | Get current config |
|
|
470
470
|
| `setConfig(config)` | Update runtime config |
|
|
471
471
|
| `waitForConfig()` | Async getter that waits for config initialization |
|
|
@@ -477,12 +477,7 @@ Generates **34+ files** for a production-ready SvelteKit 2 + Svelte 5 project:
|
|
|
477
477
|
|
|
478
478
|
| Export | Description |
|
|
479
479
|
|---|---|
|
|
480
|
-
| `
|
|
481
|
-
| `getQueueDiagnostics()` | Pending operation queue state |
|
|
482
|
-
| `getRealtimeDiagnostics()` | Realtime connection state and health |
|
|
483
|
-
| `getConflictDiagnostics()` | Conflict resolution history and stats |
|
|
484
|
-
| `getEgressDiagnostics()` | Data transfer from Supabase (bytes, per-table breakdown) |
|
|
485
|
-
| `getNetworkDiagnostics()` | Network state and connectivity info |
|
|
480
|
+
| `getDiagnostics()` | Comprehensive runtime diagnostics (sync, queue, realtime, conflict, egress, network) |
|
|
486
481
|
| `setDebugMode(enabled)` | Enable/disable debug logging |
|
|
487
482
|
| `isDebugMode()` | Check if debug mode is active |
|
|
488
483
|
| `debugLog` / `debugWarn` / `debugError` | Prefixed console helpers (gated by debug mode) |
|
|
@@ -503,9 +498,9 @@ When debug mode is enabled, the engine exposes utilities on `window` using your
|
|
|
503
498
|
|
|
504
499
|
| Export | Description |
|
|
505
500
|
|---|---|
|
|
506
|
-
| `
|
|
507
|
-
| `
|
|
508
|
-
| `
|
|
501
|
+
| `generateSupabaseSQL(schema)` | Generate `CREATE TABLE` statements and RLS policies from schema |
|
|
502
|
+
| `generateTypeScript(schema)` | Generate TypeScript interfaces from schema |
|
|
503
|
+
| `generateMigrationSQL(oldSchema, newSchema)` | Generate `ALTER TABLE` migration SQL for schema changes |
|
|
509
504
|
|
|
510
505
|
### Svelte Actions
|
|
511
506
|
|
|
@@ -516,17 +511,17 @@ When debug mode is enabled, the engine exposes utilities on `window` using your
|
|
|
516
511
|
| `triggerLocalAnimation` | Programmatically trigger the local-change animation on a node |
|
|
517
512
|
| `truncateTooltip` | Action that shows a tooltip with full text when content is truncated |
|
|
518
513
|
|
|
519
|
-
### Svelte Components
|
|
514
|
+
### Svelte Components (Optional - SvelteKit)
|
|
520
515
|
|
|
521
516
|
| Export | Description |
|
|
522
517
|
|---|---|
|
|
523
|
-
| `@prabhask5/stellar-engine/components/SyncStatus` | Animated sync-state indicator with tooltip and PWA refresh
|
|
524
|
-
| `@prabhask5/stellar-engine/components/DeferredChangesBanner` | Cross-device data conflict notification with
|
|
518
|
+
| `@prabhask5/stellar-engine/components/SyncStatus` | Animated sync-state indicator with tooltip and PWA refresh |
|
|
519
|
+
| `@prabhask5/stellar-engine/components/DeferredChangesBanner` | Cross-device data conflict notification with diff preview |
|
|
525
520
|
| `@prabhask5/stellar-engine/components/DemoBanner` | Demo mode indicator banner |
|
|
526
521
|
|
|
527
|
-
### SvelteKit Helpers (
|
|
522
|
+
### SvelteKit Helpers (Optional - SvelteKit)
|
|
528
523
|
|
|
529
|
-
These require `svelte ^5.0.0` as
|
|
524
|
+
These require `svelte ^5.0.0` and `@sveltejs/kit` as peer dependencies.
|
|
530
525
|
|
|
531
526
|
| Export | Description |
|
|
532
527
|
|---|---|
|
|
@@ -553,7 +548,7 @@ These require `svelte ^5.0.0` as a peer dependency.
|
|
|
553
548
|
|
|
554
549
|
All TypeScript types are available from `@prabhask5/stellar-engine/types`:
|
|
555
550
|
|
|
556
|
-
`Session`, `SyncEngineConfig`, `TableConfig`, `BatchOperation`, `SingleUserConfig`, `DemoConfig`, `SyncStatus`, `
|
|
551
|
+
`Session`, `SyncEngineConfig`, `TableConfig`, `AuthConfig`, `SchemaDefinition`, `SchemaTableConfig`, `FieldType`, `BatchOperation`, `SingleUserConfig`, `DemoConfig`, `SyncStatus`, `AuthMode`, `CRDTConfig`, and more.
|
|
557
552
|
|
|
558
553
|
## Subpath exports
|
|
559
554
|
|
|
@@ -561,7 +556,7 @@ Import only what you need:
|
|
|
561
556
|
|
|
562
557
|
| Subpath | Contents |
|
|
563
558
|
|---|---|
|
|
564
|
-
| `@prabhask5/stellar-engine` | Core: `initEngine`, `startSyncEngine`, `runFullSync`, `
|
|
559
|
+
| `@prabhask5/stellar-engine` | Core: `initEngine`, `startSyncEngine`, `runFullSync`, `getDb`, `resetDatabase`, `getDiagnostics`, CRUD, auth, stores, and all re-exports |
|
|
565
560
|
| `@prabhask5/stellar-engine/data` | CRUD + query operations + helpers |
|
|
566
561
|
| `@prabhask5/stellar-engine/auth` | All auth functions |
|
|
567
562
|
| `@prabhask5/stellar-engine/stores` | Reactive stores + store factories + event subscriptions |
|
|
@@ -580,7 +575,7 @@ Import only what you need:
|
|
|
580
575
|
|
|
581
576
|
stellar-engine includes a built-in demo mode that provides a completely isolated sandbox. When active:
|
|
582
577
|
|
|
583
|
-
- **Separate database** -- uses `${
|
|
578
|
+
- **Separate database** -- uses `${prefix}DB_demo` IndexedDB; the real database is never opened
|
|
584
579
|
- **No Supabase** -- zero network requests to the backend
|
|
585
580
|
- **Mock auth** -- `authMode === 'demo'`; protected routes work with mock data only
|
|
586
581
|
- **Auto-seeded** -- your `seedData(db)` callback populates the demo database on each page load
|
|
@@ -588,13 +583,13 @@ stellar-engine includes a built-in demo mode that provides a completely isolated
|
|
|
588
583
|
|
|
589
584
|
```ts
|
|
590
585
|
import type { DemoConfig } from '@prabhask5/stellar-engine';
|
|
591
|
-
import { setDemoMode } from '@prabhask5/stellar-engine';
|
|
586
|
+
import { setDemoMode, isDemoMode } from '@prabhask5/stellar-engine';
|
|
592
587
|
|
|
593
588
|
// Define demo config in initEngine
|
|
594
589
|
const demoConfig: DemoConfig = {
|
|
595
590
|
seedData: async (db) => {
|
|
596
591
|
await db.table('projects').bulkPut([
|
|
597
|
-
{ id: 'demo-1', name: 'Sample Project',
|
|
592
|
+
{ id: 'demo-1', name: 'Sample Project', order: 1 },
|
|
598
593
|
]);
|
|
599
594
|
},
|
|
600
595
|
mockProfile: { email: 'demo@example.com', firstName: 'Demo', lastName: 'User' },
|
|
@@ -149,27 +149,14 @@ async function resolveSingleUserAuthState() {
|
|
|
149
149
|
return { session: null, authMode: 'none', offlineProfile: null, singleUserSetUp: false };
|
|
150
150
|
}
|
|
151
151
|
if (!config.email) {
|
|
152
|
-
/*
|
|
153
|
-
go through the new setup flow (email + PIN). Old anonymous data will not
|
|
154
|
-
be accessible under ownership-based RLS anyway.
|
|
155
|
-
Nuke all legacy auth artifacts so the user gets a clean slate. */
|
|
156
|
-
debugLog('[Auth] Legacy config without email detected, clearing old auth state');
|
|
157
|
-
try {
|
|
158
|
-
await db.table('singleUserConfig').delete('config');
|
|
159
|
-
await db.table('offlineCredentials').delete('current_user');
|
|
160
|
-
await db.table('offlineSession').delete('current_session');
|
|
161
|
-
}
|
|
162
|
-
catch (e) {
|
|
163
|
-
debugWarn('[Auth] Failed to clear legacy auth state:', e);
|
|
164
|
-
}
|
|
152
|
+
/* Config without email is invalid — user needs to go through setup. */
|
|
165
153
|
return { session: null, authMode: 'none', offlineProfile: null, singleUserSetUp: false };
|
|
166
154
|
}
|
|
167
155
|
/* codeLength migration: if the engine config specifies a different PIN length
|
|
168
156
|
than what is stored locally, the user must re-setup. This handles the case
|
|
169
|
-
where the app developer changes the codeLength in their engine config.
|
|
170
|
-
Existing configs from before codeLength was stored default to 4. */
|
|
157
|
+
where the app developer changes the codeLength in their engine config. */
|
|
171
158
|
const expectedCodeLength = getEngineConfig().auth?.singleUser?.codeLength;
|
|
172
|
-
const storedCodeLength = config.codeLength
|
|
159
|
+
const storedCodeLength = config.codeLength;
|
|
173
160
|
if (expectedCodeLength && storedCodeLength !== expectedCodeLength) {
|
|
174
161
|
debugLog('[Auth] codeLength mismatch detected:', storedCodeLength, '→', expectedCodeLength);
|
|
175
162
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveAuthState.js","sourceRoot":"","sources":["../../src/auth/resolveAuthState.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"resolveAuthState.js","sourceRoot":"","sources":["../../src/auth/resolveAuthState.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"singleUser.d.ts","sourceRoot":"","sources":["../../src/auth/singleUser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAwCjD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG1C;AA6CD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO1D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC;IACjD,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,yEAAyE;IACzE,QAAQ,EAAE,gBAAgB,CAAC,UAAU,CAAC,CAAC;IACvC,kEAAkE;IAClE,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACnB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,IAAI,CAAC,CAUR;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,oBAAoB,EAAE,OAAO,CAAA;CAAE,CAAC,CAiIlE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CA2DjF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC,
|
|
1
|
+
{"version":3,"file":"singleUser.d.ts","sourceRoot":"","sources":["../../src/auth/singleUser.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/singleUser.js
CHANGED
|
@@ -564,9 +564,8 @@ export async function unlockSingleUser(gate) {
|
|
|
564
564
|
return { error: null };
|
|
565
565
|
}
|
|
566
566
|
else {
|
|
567
|
-
// --- OFFLINE UNLOCK
|
|
568
|
-
/* Fall back to local hash verification when offline
|
|
569
|
-
config has no email (legacy accounts before email was required) */
|
|
567
|
+
// --- OFFLINE UNLOCK ---
|
|
568
|
+
/* Fall back to local hash verification when offline */
|
|
570
569
|
const inputHash = await hashValue(gate);
|
|
571
570
|
if (config.gateHash && inputHash !== config.gateHash) {
|
|
572
571
|
return { error: 'Incorrect code' };
|