@prabhask5/stellar-engine 1.1.18 → 1.2.1

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 (95) hide show
  1. package/README.md +448 -321
  2. package/dist/bin/commands.d.ts +14 -0
  3. package/dist/bin/commands.d.ts.map +1 -0
  4. package/dist/bin/commands.js +68 -0
  5. package/dist/bin/commands.js.map +1 -0
  6. package/dist/bin/install-pwa.d.ts +20 -6
  7. package/dist/bin/install-pwa.d.ts.map +1 -1
  8. package/dist/bin/install-pwa.js +111 -184
  9. package/dist/bin/install-pwa.js.map +1 -1
  10. package/dist/config.d.ts +67 -11
  11. package/dist/config.d.ts.map +1 -1
  12. package/dist/config.js +265 -24
  13. package/dist/config.js.map +1 -1
  14. package/dist/crdt/awareness.d.ts +128 -0
  15. package/dist/crdt/awareness.d.ts.map +1 -0
  16. package/dist/crdt/awareness.js +284 -0
  17. package/dist/crdt/awareness.js.map +1 -0
  18. package/dist/crdt/channel.d.ts +165 -0
  19. package/dist/crdt/channel.d.ts.map +1 -0
  20. package/dist/crdt/channel.js +522 -0
  21. package/dist/crdt/channel.js.map +1 -0
  22. package/dist/crdt/config.d.ts +58 -0
  23. package/dist/crdt/config.d.ts.map +1 -0
  24. package/dist/crdt/config.js +123 -0
  25. package/dist/crdt/config.js.map +1 -0
  26. package/dist/crdt/helpers.d.ts +104 -0
  27. package/dist/crdt/helpers.d.ts.map +1 -0
  28. package/dist/crdt/helpers.js +116 -0
  29. package/dist/crdt/helpers.js.map +1 -0
  30. package/dist/crdt/offline.d.ts +58 -0
  31. package/dist/crdt/offline.d.ts.map +1 -0
  32. package/dist/crdt/offline.js +130 -0
  33. package/dist/crdt/offline.js.map +1 -0
  34. package/dist/crdt/persistence.d.ts +65 -0
  35. package/dist/crdt/persistence.d.ts.map +1 -0
  36. package/dist/crdt/persistence.js +171 -0
  37. package/dist/crdt/persistence.js.map +1 -0
  38. package/dist/crdt/provider.d.ts +109 -0
  39. package/dist/crdt/provider.d.ts.map +1 -0
  40. package/dist/crdt/provider.js +543 -0
  41. package/dist/crdt/provider.js.map +1 -0
  42. package/dist/crdt/store.d.ts +111 -0
  43. package/dist/crdt/store.d.ts.map +1 -0
  44. package/dist/crdt/store.js +158 -0
  45. package/dist/crdt/store.js.map +1 -0
  46. package/dist/crdt/types.d.ts +281 -0
  47. package/dist/crdt/types.d.ts.map +1 -0
  48. package/dist/crdt/types.js +26 -0
  49. package/dist/crdt/types.js.map +1 -0
  50. package/dist/database.d.ts +66 -1
  51. package/dist/database.d.ts.map +1 -1
  52. package/dist/database.js +133 -7
  53. package/dist/database.js.map +1 -1
  54. package/dist/diagnostics.d.ts +75 -0
  55. package/dist/diagnostics.d.ts.map +1 -1
  56. package/dist/diagnostics.js +114 -2
  57. package/dist/diagnostics.js.map +1 -1
  58. package/dist/engine.d.ts.map +1 -1
  59. package/dist/engine.js +21 -1
  60. package/dist/engine.js.map +1 -1
  61. package/dist/entries/crdt.d.ts +32 -0
  62. package/dist/entries/crdt.d.ts.map +1 -0
  63. package/dist/entries/crdt.js +52 -0
  64. package/dist/entries/crdt.js.map +1 -0
  65. package/dist/entries/types.d.ts +5 -3
  66. package/dist/entries/types.d.ts.map +1 -1
  67. package/dist/entries/utils.d.ts +1 -0
  68. package/dist/entries/utils.d.ts.map +1 -1
  69. package/dist/entries/utils.js +8 -0
  70. package/dist/entries/utils.js.map +1 -1
  71. package/dist/entries/vite.d.ts +1 -1
  72. package/dist/entries/vite.d.ts.map +1 -1
  73. package/dist/index.d.ts +9 -2
  74. package/dist/index.d.ts.map +1 -1
  75. package/dist/index.js +14 -0
  76. package/dist/index.js.map +1 -1
  77. package/dist/schema.d.ts +150 -0
  78. package/dist/schema.d.ts.map +1 -0
  79. package/dist/schema.js +891 -0
  80. package/dist/schema.js.map +1 -0
  81. package/dist/sw/build/vite-plugin.d.ts +93 -18
  82. package/dist/sw/build/vite-plugin.d.ts.map +1 -1
  83. package/dist/sw/build/vite-plugin.js +356 -22
  84. package/dist/sw/build/vite-plugin.js.map +1 -1
  85. package/dist/types.d.ts +139 -0
  86. package/dist/types.d.ts.map +1 -1
  87. package/package.json +9 -3
  88. package/dist/operations.d.ts +0 -73
  89. package/dist/operations.d.ts.map +0 -1
  90. package/dist/operations.js +0 -227
  91. package/dist/operations.js.map +0 -1
  92. package/dist/reconnectHandler.d.ts +0 -16
  93. package/dist/reconnectHandler.d.ts.map +0 -1
  94. package/dist/reconnectHandler.js +0 -21
  95. package/dist/reconnectHandler.js.map +0 -1
package/dist/config.d.ts CHANGED
@@ -23,37 +23,67 @@
23
23
  import type { SupabaseClient } from '@supabase/supabase-js';
24
24
  import type { Session } from '@supabase/supabase-js';
25
25
  import type Dexie from 'dexie';
26
- import type { SingleUserGateType } from './types';
26
+ import type { SingleUserGateType, SchemaDefinition, AuthConfig } from './types';
27
+ import type { CRDTConfig } from './crdt/types';
27
28
  import type { DemoConfig } from './demo';
28
29
  import { type DatabaseConfig } from './database';
29
30
  /**
30
31
  * Top-level configuration for the sync engine.
31
32
  *
32
- * Passed to {@link initEngine} at app startup. All fields except `tables`
33
- * and `prefix` have sensible defaults.
33
+ * Passed to {@link initEngine} at app startup. Supports two configuration modes:
34
+ *
35
+ * 1. **Schema-driven** (recommended) — Provide a `schema` object. The engine
36
+ * auto-generates `tables`, Dexie stores, versioning, and database naming.
37
+ * 2. **Manual** (backward compat) — Provide explicit `tables` and `database`.
38
+ *
39
+ * The two modes are mutually exclusive (`schema` vs `tables` + `database`).
34
40
  *
35
41
  * @example
42
+ * // Schema-driven (new, recommended):
43
+ * initEngine({
44
+ * prefix: 'myapp',
45
+ * schema: {
46
+ * goals: 'goal_list_id, order',
47
+ * focus_settings: { singleton: true },
48
+ * },
49
+ * });
50
+ *
51
+ * // Manual (backward compat):
36
52
  * initEngine({
37
53
  * prefix: 'myapp',
38
- * tables: [
39
- * { supabaseName: 'goals', columns: 'id,title,target,current_value,...' },
40
- * ],
41
- * database: { name: 'myapp-db', versions: [{ version: 1, stores: { goals: 'id,user_id' } }] },
42
- * syncDebounceMs: 1000,
54
+ * tables: [...],
55
+ * database: { name: 'myapp-db', versions: [...] },
43
56
  * });
44
57
  */
45
58
  export interface SyncEngineConfig {
46
- /** Per-table sync configuration (required). */
59
+ /** Per-table sync configuration. Auto-populated when using `schema`. */
47
60
  tables: TableConfig[];
48
61
  /** Application prefix — used for localStorage keys, debug logging, etc. */
49
62
  prefix: string;
63
+ /**
64
+ * Declarative schema definition — replaces both `tables` and `database`.
65
+ *
66
+ * Each key is a Supabase table name (snake_case). Values are either a string
67
+ * of Dexie indexes or a {@link SchemaTableConfig} object for full control.
68
+ * Mutually exclusive with `tables` + `database`.
69
+ *
70
+ * @see {@link SchemaDefinition} for the full type definition
71
+ */
72
+ schema?: SchemaDefinition;
73
+ /**
74
+ * Override the auto-generated database name when using `schema`.
75
+ *
76
+ * By default, the database is named `${prefix}DB` (e.g., `stellarDB`).
77
+ * Use this to keep an existing database name for data continuity.
78
+ */
79
+ databaseName?: string;
50
80
  /** Provide a pre-created Dexie instance (backward compat). Mutually exclusive with `database`. */
51
81
  db?: Dexie;
52
82
  /** Provide a pre-created Supabase client (backward compat). Engine creates one internally if not provided. */
53
83
  supabase?: SupabaseClient;
54
84
  /** Engine creates and owns the Dexie instance when this is provided. */
55
85
  database?: DatabaseConfig;
56
- /** Authentication configuration. */
86
+ /** Authentication configuration (nested/internal form). */
57
87
  auth?: {
58
88
  /** Single-user mode gate configuration. */
59
89
  singleUser?: {
@@ -104,6 +134,18 @@ export interface SyncEngineConfig {
104
134
  * @see {@link DemoConfig} for the configuration shape
105
135
  */
106
136
  demo?: DemoConfig;
137
+ /**
138
+ * CRDT collaborative editing configuration.
139
+ *
140
+ * When provided, enables the CRDT subsystem — creates IndexedDB tables for
141
+ * CRDT document storage and allows use of the `@prabhask5/stellar-engine/crdt` API.
142
+ * When omitted, no CRDT tables are created and CRDT imports will throw.
143
+ *
144
+ * Pass `true` as shorthand for `{}` (all defaults).
145
+ *
146
+ * @see {@link CRDTConfig} for available configuration options
147
+ */
148
+ crdt?: CRDTConfig | true;
107
149
  }
108
150
  /**
109
151
  * Per-table sync configuration.
@@ -154,7 +196,21 @@ export interface TableConfig {
154
196
  * database: { name: 'myapp-db', versions: [...] },
155
197
  * });
156
198
  */
157
- export declare function initEngine(config: SyncEngineConfig): void;
199
+ /**
200
+ * Input type for {@link initEngine}.
201
+ *
202
+ * Differs from {@link SyncEngineConfig} in two ways:
203
+ * - `tables` is optional (auto-generated when `schema` is provided)
204
+ * - `auth` accepts either the flat {@link AuthConfig} or the nested internal form
205
+ *
206
+ * The flat auth form is detected by the absence of a `singleUser` key and is
207
+ * normalized to the nested structure before being stored on the config singleton.
208
+ */
209
+ export type InitEngineInput = Omit<SyncEngineConfig, 'tables' | 'auth'> & {
210
+ tables?: TableConfig[];
211
+ auth?: AuthConfig | SyncEngineConfig['auth'];
212
+ };
213
+ export declare function initEngine(config: InitEngineInput): void;
158
214
  /**
159
215
  * Wait for the database to be fully opened and upgraded.
160
216
  *
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/config.js CHANGED
@@ -25,7 +25,8 @@ import { _setDeviceIdPrefix } from './deviceId';
25
25
  import { _setClientPrefix } from './supabase/client';
26
26
  import { _setConfigPrefix } from './runtime/runtimeConfig';
27
27
  import { registerDemoConfig, _setDemoPrefix, isDemoMode } from './demo';
28
- import { createDatabase, _setManagedDb } from './database';
28
+ import { createDatabase, _setManagedDb, SYSTEM_INDEXES, computeSchemaVersion } from './database';
29
+ import { _initCRDT } from './crdt/config';
29
30
  import { snakeToCamel } from './utils';
30
31
  // =============================================================================
31
32
  // Module State
@@ -34,28 +35,32 @@ import { snakeToCamel } from './utils';
34
35
  let engineConfig = null;
35
36
  /** Promise that resolves when the database is fully opened and upgraded. */
36
37
  let _dbReady = null;
37
- // =============================================================================
38
- // Initialization
39
- // =============================================================================
40
- /**
41
- * Initialize the sync engine with the provided configuration.
42
- *
43
- * Must be called once at app startup, before any other engine function.
44
- * Propagates the `prefix` to all internal modules (debug, deviceId,
45
- * Supabase client, runtime config) and creates or registers the Dexie
46
- * database instance.
47
- *
48
- * @param config - The full engine configuration object.
49
- *
50
- * @example
51
- * // In your app's root layout or entry point:
52
- * initEngine({
53
- * prefix: 'myapp',
54
- * tables: [...],
55
- * database: { name: 'myapp-db', versions: [...] },
56
- * });
57
- */
58
38
  export function initEngine(config) {
39
+ /* Normalize `crdt: true` shorthand to `crdt: {}`. */
40
+ if (config.crdt === true) {
41
+ config.crdt = {};
42
+ }
43
+ /* Normalize flat auth config to the nested structure used internally. */
44
+ if (config.auth) {
45
+ config.auth = normalizeAuthConfig(config.auth);
46
+ }
47
+ /*
48
+ * Schema-driven mode: auto-generate `tables` and `database` from the
49
+ * declarative schema definition.
50
+ */
51
+ if (config.schema) {
52
+ if (config.tables || config.database) {
53
+ throw new Error('initEngine: `schema` is mutually exclusive with `tables` and `database`. ' +
54
+ 'Use either the schema-driven API or the manual API, not both.');
55
+ }
56
+ config.tables = generateTablesFromSchema(config.schema);
57
+ config.database = generateDatabaseFromSchema(config.schema, config.prefix, config.databaseName, !!config.crdt);
58
+ }
59
+ /* Validate that tables are configured (either manually or via schema). */
60
+ if (!config.tables || config.tables.length === 0) {
61
+ throw new Error('initEngine: No tables configured. Provide either `schema` or `tables`.');
62
+ }
63
+ /* At this point tables is guaranteed to be populated — safe to cast. */
59
64
  engineConfig = config;
60
65
  /* Propagate prefix to all internal modules that use localStorage keys. */
61
66
  if (config.prefix) {
@@ -69,13 +74,18 @@ export function initEngine(config) {
69
74
  if (config.demo) {
70
75
  registerDemoConfig(config.demo);
71
76
  }
77
+ /* Initialize CRDT subsystem if configured. */
78
+ if (config.crdt) {
79
+ _initCRDT(config.crdt, config.prefix);
80
+ }
72
81
  /* If demo mode is active, switch to a separate sandboxed database. */
73
82
  if (isDemoMode() && config.database) {
74
83
  config.database = { ...config.database, name: config.database.name + '_demo' };
75
84
  }
76
- /* Handle database creation — either managed or provided. */
85
+ /* Handle database creation — either managed or provided.
86
+ * Pass crdtEnabled flag so CRDT IndexedDB tables are conditionally included. */
77
87
  if (config.database) {
78
- _dbReady = createDatabase(config.database).then((db) => {
88
+ _dbReady = createDatabase(config.database, !!config.crdt).then((db) => {
79
89
  /* Store on config for backward compat (engine.ts reads config.db). */
80
90
  config.db = db;
81
91
  });
@@ -158,4 +168,235 @@ export function getTableColumns(supabaseName) {
158
168
  }
159
169
  return table.columns;
160
170
  }
171
+ // =============================================================================
172
+ // Schema → Config Generation
173
+ // =============================================================================
174
+ /**
175
+ * Generate `TableConfig[]` from a declarative {@link SchemaDefinition}.
176
+ *
177
+ * Each schema key becomes a `TableConfig` with:
178
+ * - `supabaseName` = the schema key (snake_case)
179
+ * - `columns` = `'*'` (SELECT all by default — no egress micro-optimization)
180
+ * - `ownershipFilter` = `'user_id'` (default, since RLS always filters by user)
181
+ * - `isSingleton`, `excludeFromConflict`, `numericMergeFields`, `onRemoteChange`
182
+ * from the object form (if provided)
183
+ *
184
+ * @param schema - The declarative schema definition.
185
+ * @returns An array of `TableConfig` objects ready for engine consumption.
186
+ *
187
+ * @example
188
+ * generateTablesFromSchema({
189
+ * goals: 'goal_list_id, order',
190
+ * focus_settings: { singleton: true },
191
+ * });
192
+ * // → [
193
+ * // { supabaseName: 'goals', columns: '*', ownershipFilter: 'user_id' },
194
+ * // { supabaseName: 'focus_settings', columns: '*', ownershipFilter: 'user_id', isSingleton: true },
195
+ * // ]
196
+ */
197
+ function generateTablesFromSchema(schema) {
198
+ const tables = [];
199
+ for (const [tableName, definition] of Object.entries(schema)) {
200
+ /* String form is sugar for { indexes: theString }. */
201
+ const config = typeof definition === 'string' ? { indexes: definition } : definition;
202
+ const tableConfig = {
203
+ supabaseName: tableName,
204
+ columns: config.columns || '*',
205
+ ownershipFilter: config.ownership || 'user_id'
206
+ };
207
+ if (config.singleton)
208
+ tableConfig.isSingleton = true;
209
+ if (config.excludeFromConflict)
210
+ tableConfig.excludeFromConflict = config.excludeFromConflict;
211
+ if (config.numericMergeFields)
212
+ tableConfig.numericMergeFields = config.numericMergeFields;
213
+ if (config.onRemoteChange)
214
+ tableConfig.onRemoteChange = config.onRemoteChange;
215
+ tables.push(tableConfig);
216
+ }
217
+ return tables;
218
+ }
219
+ /**
220
+ * Generate a `DatabaseConfig` from a declarative {@link SchemaDefinition}.
221
+ *
222
+ * Builds the Dexie store schema for each table by combining the app-specific
223
+ * indexes from the schema with the {@link SYSTEM_INDEXES} constant. Uses
224
+ * {@link computeSchemaVersion} for automatic version management.
225
+ *
226
+ * @param schema - The declarative schema definition.
227
+ * @param prefix - Application prefix for database naming and versioning.
228
+ * @param databaseName - Optional override for the database name.
229
+ * @param crdtEnabled - Whether the CRDT subsystem is enabled.
230
+ * @returns A `DatabaseConfig` ready for `createDatabase()`.
231
+ *
232
+ * @example
233
+ * generateDatabaseFromSchema(
234
+ * { goals: 'goal_list_id, order' },
235
+ * 'stellar',
236
+ * undefined,
237
+ * false
238
+ * );
239
+ * // → {
240
+ * // name: 'stellarDB',
241
+ * // versions: [{ version: 1, stores: { goals: 'id, user_id, ..., goal_list_id, order' } }]
242
+ * // }
243
+ */
244
+ function generateDatabaseFromSchema(schema, prefix, databaseName, crdtEnabled = false) {
245
+ const stores = {};
246
+ for (const [tableName, definition] of Object.entries(schema)) {
247
+ const config = typeof definition === 'string' ? { indexes: definition } : definition;
248
+ /* Determine the Dexie table name (camelCase by default, or explicit override). */
249
+ const dexieName = config.dexieName || snakeToCamel(tableName);
250
+ /* Merge system indexes with app-specific indexes. */
251
+ const appIndexes = (config.indexes || '').trim();
252
+ stores[dexieName] = appIndexes ? `${SYSTEM_INDEXES}, ${appIndexes}` : SYSTEM_INDEXES;
253
+ }
254
+ /* Compute auto-version based on the merged store schema.
255
+ * The CRDT flag affects the schema hash because CRDT system tables are merged
256
+ * by buildDexie() — if CRDT is toggled, the version should bump. */
257
+ const hashInput = crdtEnabled ? { ...stores, __crdt: 'enabled' } : stores;
258
+ const result = computeSchemaVersion(prefix, hashInput);
259
+ /*
260
+ * Build the versions array. When an upgrade is detected, declare BOTH
261
+ * the previous version and the current version so Dexie has a proper
262
+ * upgrade path (v(N-1) → vN). This avoids the UpgradeError that occurs
263
+ * when only the new version is declared and the browser already has the
264
+ * old version's IndexedDB schema.
265
+ *
266
+ * Dexie handles additive changes (new tables, new indexes) natively.
267
+ * For the previous version we use its original stores so Dexie can diff
268
+ * and apply the structural changes.
269
+ */
270
+ const versions = [];
271
+ if (result.previousStores && result.previousVersion) {
272
+ versions.push({ version: result.previousVersion, stores: result.previousStores });
273
+ }
274
+ /*
275
+ * Generate an upgrade callback when any table declares `renamedFrom`.
276
+ * The callback copies data from the old Dexie table to the new one,
277
+ * applying any `renamedColumns` transformations along the way.
278
+ */
279
+ const upgradeCallback = buildRenameUpgradeCallback(schema);
280
+ if (upgradeCallback) {
281
+ versions.push({ version: result.version, stores, upgrade: upgradeCallback });
282
+ }
283
+ else {
284
+ versions.push({ version: result.version, stores });
285
+ }
286
+ return {
287
+ name: databaseName || `${prefix}DB`,
288
+ versions
289
+ };
290
+ }
291
+ /**
292
+ * Build a Dexie upgrade callback that handles table renames.
293
+ *
294
+ * When a table declares `renamedFrom`, the callback copies all rows from
295
+ * the old table name to the new one, applying any `renamedColumns` field
296
+ * name transformations. Dexie's schema diff handles creating the new table
297
+ * and removing the old one — this callback only handles data migration.
298
+ *
299
+ * @param schema - The declarative schema definition.
300
+ * @returns An upgrade function, or `null` if no renames are declared.
301
+ * @internal
302
+ */
303
+ function buildRenameUpgradeCallback(schema) {
304
+ /* Collect all rename operations. */
305
+ const renames = [];
306
+ for (const [tableName, definition] of Object.entries(schema)) {
307
+ const config = typeof definition === 'string' ? { indexes: definition } : definition;
308
+ if (!config.renamedFrom)
309
+ continue;
310
+ const oldDexie = config.dexieName ? config.dexieName : snakeToCamel(config.renamedFrom);
311
+ const newDexie = config.dexieName || snakeToCamel(tableName);
312
+ /* Only generate a callback if the Dexie name actually changed. */
313
+ if (oldDexie !== newDexie) {
314
+ renames.push({
315
+ oldDexie,
316
+ newDexie,
317
+ columnMap: config.renamedColumns
318
+ });
319
+ }
320
+ }
321
+ if (renames.length === 0)
322
+ return null;
323
+ return async (tx) => {
324
+ for (const { oldDexie, newDexie, columnMap } of renames) {
325
+ try {
326
+ const oldTable = tx.table(oldDexie);
327
+ const newTable = tx.table(newDexie);
328
+ const rows = await oldTable.toArray();
329
+ for (const row of rows) {
330
+ /* Apply column renames if specified. */
331
+ if (columnMap) {
332
+ for (const [newCol, oldCol] of Object.entries(columnMap)) {
333
+ if (oldCol in row) {
334
+ row[newCol] = row[oldCol];
335
+ delete row[oldCol];
336
+ }
337
+ }
338
+ }
339
+ await newTable.put(row);
340
+ }
341
+ /* Clear the old table — Dexie's schema diff will remove it. */
342
+ await oldTable.clear();
343
+ }
344
+ catch {
345
+ /* Old table may not exist (e.g., fresh install) — skip silently. */
346
+ }
347
+ }
348
+ };
349
+ }
350
+ /**
351
+ * Normalize an auth config to the internal nested structure.
352
+ *
353
+ * Detects whether the config is in the new flat form ({@link AuthConfig}) or
354
+ * the legacy nested form (has a `singleUser` key). Flat form is converted to
355
+ * nested; nested form is passed through unchanged.
356
+ *
357
+ * @param auth - The auth config (flat or nested).
358
+ * @returns The normalized nested auth config.
359
+ * @internal
360
+ */
361
+ function normalizeAuthConfig(auth) {
362
+ if (!auth)
363
+ return auth;
364
+ /* Detect legacy nested form by the presence of `singleUser` key. */
365
+ if ('singleUser' in auth) {
366
+ return auth;
367
+ }
368
+ /* Flat form (AuthConfig) → convert to nested structure. */
369
+ const flat = auth;
370
+ const nested = {};
371
+ /* Map flat singleUser fields to nested singleUser object. */
372
+ const gateType = flat.gateType || 'code';
373
+ const codeLength = flat.codeLength || 6;
374
+ nested.singleUser = {
375
+ gateType,
376
+ ...(gateType === 'code' ? { codeLength } : {})
377
+ };
378
+ /* Map flat boolean flags to nested object structures. */
379
+ const emailConfirmation = flat.emailConfirmation !== undefined ? flat.emailConfirmation : true;
380
+ nested.emailConfirmation = { enabled: emailConfirmation };
381
+ const deviceVerification = flat.deviceVerification !== undefined ? flat.deviceVerification : true;
382
+ nested.deviceVerification = {
383
+ enabled: deviceVerification,
384
+ trustDurationDays: flat.trustDurationDays || 90
385
+ };
386
+ /* Pass through remaining fields with defaults. */
387
+ nested.confirmRedirectPath = flat.confirmRedirectPath || '/confirm';
388
+ nested.enableOfflineAuth =
389
+ flat.enableOfflineAuth !== undefined ? flat.enableOfflineAuth : true;
390
+ if (flat.sessionValidationIntervalMs !== undefined) {
391
+ nested.sessionValidationIntervalMs =
392
+ flat.sessionValidationIntervalMs;
393
+ }
394
+ if (flat.profileExtractor) {
395
+ nested.profileExtractor = flat.profileExtractor;
396
+ }
397
+ if (flat.profileToMetadata) {
398
+ nested.profileToMetadata = flat.profileToMetadata;
399
+ }
400
+ return nested;
401
+ }
161
402
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * @fileoverview CRDT Presence / Awareness Management
3
+ *
4
+ * Bridges Supabase Presence ↔ local presence state for collaborative cursor
5
+ * and user tracking. Each open document has its own set of collaborators.
6
+ *
7
+ * Responsibilities:
8
+ * - Tracking local cursor/selection state per document
9
+ * - Debouncing cursor updates to avoid flooding the Presence channel
10
+ * - Maintaining a list of active collaborators per document
11
+ * - Providing subscription-based notifications for collaborator changes
12
+ * - Deterministic color assignment from userId hash
13
+ *
14
+ * The Supabase Presence integration is handled through the same Realtime
15
+ * channel used for Broadcast. Presence state is tracked separately from
16
+ * Yjs document updates — they use different Supabase Realtime features
17
+ * (Presence vs Broadcast) on the same channel.
18
+ *
19
+ * @see {@link ./types.ts} for {@link UserPresenceState}
20
+ * @see {@link ./channel.ts} for the underlying Broadcast channel
21
+ * @see {@link ./provider.ts} for the lifecycle orchestrator
22
+ */
23
+ import type { UserPresenceState } from './types';
24
+ /**
25
+ * Assign a deterministic color to a user based on their userId.
26
+ *
27
+ * Uses a simple hash of the userId to index into the 12-color palette.
28
+ * The same userId always gets the same color, so collaborators appear
29
+ * consistent across sessions and devices.
30
+ *
31
+ * @param userId - The user's UUID.
32
+ * @returns A hex color string from the palette.
33
+ */
34
+ export declare function assignColor(userId: string): string;
35
+ /**
36
+ * Initialize presence tracking for a document.
37
+ *
38
+ * Called by the provider when a document is opened. Sets up the collaborator
39
+ * map and announces the local user's presence.
40
+ *
41
+ * @param documentId - The document to join.
42
+ * @param isConnected - Whether the Broadcast channel is connected.
43
+ * @param initialPresence - The local user's initial presence info.
44
+ * @internal
45
+ */
46
+ export declare function joinPresence(documentId: string, isConnected: boolean, initialPresence: {
47
+ name: string;
48
+ avatarUrl?: string;
49
+ }): void;
50
+ /**
51
+ * Leave presence tracking for a document.
52
+ *
53
+ * Called by the provider when a document is closed. Cleans up the collaborator
54
+ * map and notifies listeners.
55
+ *
56
+ * @param documentId - The document to leave.
57
+ * @internal
58
+ */
59
+ export declare function leavePresence(documentId: string): void;
60
+ /**
61
+ * Handle a remote user joining the document.
62
+ *
63
+ * Called when a Supabase Presence `join` event is received.
64
+ *
65
+ * @param documentId - The document.
66
+ * @param presence - The remote user's presence state.
67
+ * @internal
68
+ */
69
+ export declare function handlePresenceJoin(documentId: string, presence: UserPresenceState): void;
70
+ /**
71
+ * Handle a remote user leaving the document.
72
+ *
73
+ * @param documentId - The document.
74
+ * @param userId - The user's UUID.
75
+ * @param deviceId - The user's device ID.
76
+ * @internal
77
+ */
78
+ export declare function handlePresenceLeave(documentId: string, userId: string, deviceId: string): void;
79
+ /**
80
+ * Update the local user's cursor and selection in a document.
81
+ *
82
+ * Debounced to `cursorDebounceMs` (default 50ms) to avoid flooding the
83
+ * Presence channel with rapid cursor movements.
84
+ *
85
+ * @param documentId - The document to update cursor for.
86
+ * @param cursor - Editor-specific cursor position (opaque to the engine).
87
+ * @param selection - Editor-specific selection range (opaque to the engine).
88
+ *
89
+ * @example
90
+ * // In your editor's cursor change handler:
91
+ * editor.on('selectionUpdate', ({ editor }) => {
92
+ * updateCursor('doc-1', editor.state.selection.anchor, editor.state.selection);
93
+ * });
94
+ */
95
+ export declare function updateCursor(documentId: string, cursor: unknown, selection?: unknown): void;
96
+ /**
97
+ * Get the current list of collaborators for a document.
98
+ *
99
+ * Excludes the local user (they don't need to see their own cursor).
100
+ *
101
+ * @param documentId - The document to get collaborators for.
102
+ * @returns Array of presence states for remote collaborators.
103
+ *
104
+ * @example
105
+ * const collaborators = getCollaborators('doc-1');
106
+ * // [{ userId: '...', name: 'Alice', color: '#E57373', cursor: {...} }]
107
+ */
108
+ export declare function getCollaborators(documentId: string): UserPresenceState[];
109
+ /**
110
+ * Subscribe to collaborator changes for a document.
111
+ *
112
+ * The callback is invoked whenever a collaborator joins, leaves, or updates
113
+ * their cursor position. The callback receives the current list of remote
114
+ * collaborators (excluding the local user).
115
+ *
116
+ * @param documentId - The document to subscribe to.
117
+ * @param callback - Called with the updated collaborator list.
118
+ * @returns An unsubscribe function.
119
+ *
120
+ * @example
121
+ * const unsub = onCollaboratorsChange('doc-1', (collaborators) => {
122
+ * avatarList = collaborators.map(c => ({ name: c.name, color: c.color }));
123
+ * });
124
+ * // Later:
125
+ * unsub();
126
+ */
127
+ export declare function onCollaboratorsChange(documentId: string, callback: (collaborators: UserPresenceState[]) => void): () => void;
128
+ //# sourceMappingURL=awareness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"awareness.d.ts","sourceRoot":"","sources":["../../src/crdt/awareness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAKH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AA6CjD;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAMlD;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,OAAO,EACpB,eAAe,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACpD,IAAI,CAQN;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAItD;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAcxF;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAY9F;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,OAAO,GAAG,IAAI,CAgC3F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAmBxE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,CAAC,aAAa,EAAE,iBAAiB,EAAE,KAAK,IAAI,GACrD,MAAM,IAAI,CAcZ"}