@syncular/tauri 0.30.5 → 0.30.6

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 CHANGED
@@ -117,8 +117,11 @@ still owns OS secure-store deletion and any key buffers it supplied.
117
117
 
118
118
  Runtime `setHeaders()` is an active-session operation and is rejected during
119
119
  preflight at both the JavaScript and native command boundaries. Supply bootstrap
120
- headers through trusted plugin configuration; rotate them only after successful
121
- activation.
120
+ headers through trusted plugin configuration or `activateSecurity({ headers })`;
121
+ the latter installs the current bearer before the startup round. Rotate them
122
+ with `setHeaders()` only after successful activation. Closed clients reject data
123
+ and control calls with `client.closed` before testing preflight; listener
124
+ registration and local progress reads throw that code. `close()` is idempotent.
122
125
 
123
126
  ## Privacy-safe diagnostics
124
127
 
package/dist/index.js CHANGED
@@ -160,9 +160,7 @@ export class TauriSyncClient {
160
160
  }
161
161
  /** Dispatch a `syncular_command` and unwrap `{result}` / throw on `{error}`. */
162
162
  async #command(method, params) {
163
- if (this.#closed) {
164
- throw new TauriSyncError('client.closed', 'the Tauri sync client is closed');
165
- }
163
+ this.#requireOpen();
166
164
  if (this.#securityLifecycle === 'preflight' &&
167
165
  ![
168
166
  'securityLifecycle',
@@ -185,7 +183,13 @@ export class TauriSyncClient {
185
183
  #throwSecurityPreflight() {
186
184
  throw new TauriSyncError(SECURITY_PREFLIGHT_REQUIRED_CODE, 'the local replica is in security preflight; complete quarantine checks and call activateSecurity before accessing protected data');
187
185
  }
186
+ #requireOpen() {
187
+ if (this.#closed) {
188
+ throw new TauriSyncError('client.closed', 'the Tauri sync client is closed');
189
+ }
190
+ }
188
191
  #requireActive() {
192
+ this.#requireOpen();
189
193
  if (this.#securityLifecycle === 'preflight')
190
194
  this.#throwSecurityPreflight();
191
195
  }
@@ -254,7 +258,8 @@ export class TauriSyncClient {
254
258
  }
255
259
  }
256
260
  // -- SyncClientLike --------------------------------------------------------
257
- securityLifecycle() {
261
+ async securityLifecycle() {
262
+ this.#requireOpen();
258
263
  return Promise.resolve(this.#securityLifecycle);
259
264
  }
260
265
  beginSecurityPreflight() {
@@ -284,6 +289,7 @@ export class TauriSyncClient {
284
289
  * credentials (the direct `setHeaders` path stays refused while gated).
285
290
  */
286
291
  async activateSecurity(options = {}) {
292
+ this.#requireOpen();
287
293
  if (this.#securityLifecycle === 'active') {
288
294
  throw new TauriSyncError('sync.invalid_request', 'activateSecurity requires the client to be in security preflight');
289
295
  }
@@ -297,20 +303,25 @@ export class TauriSyncClient {
297
303
  this.#securityLifecycle = 'active';
298
304
  }
299
305
  onInvalidate(listener) {
306
+ this.#requireOpen();
300
307
  this.#invalidationListeners.add(listener);
301
308
  return () => this.#invalidationListeners.delete(listener);
302
309
  }
303
310
  onProgress(listener) {
311
+ this.#requireOpen();
304
312
  return this.#progress.on(listener);
305
313
  }
306
314
  progressSnapshot() {
315
+ this.#requireOpen();
307
316
  return this.#progress.snapshot();
308
317
  }
309
318
  onChange(listener) {
319
+ this.#requireOpen();
310
320
  this.#changeListeners.add(listener);
311
321
  return () => this.#changeListeners.delete(listener);
312
322
  }
313
323
  onDiagnostics(listener) {
324
+ this.#requireOpen();
314
325
  this.#diagnosticsListeners.add(listener);
315
326
  this.#enableDiagnosticsPush();
316
327
  return () => this.#diagnosticsListeners.delete(listener);
@@ -339,6 +350,7 @@ export class TauriSyncClient {
339
350
  });
340
351
  }
341
352
  onPresence(listener) {
353
+ this.#requireOpen();
342
354
  this.#presenceListeners.add(listener);
343
355
  return () => this.#presenceListeners.delete(listener);
344
356
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@syncular/tauri",
3
- "version": "0.30.5",
3
+ "version": "0.30.6",
4
4
  "description": "Tauri integration for the Syncular client",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Benjamin Kniffler",
@@ -48,12 +48,12 @@
48
48
  "test": "bun test"
49
49
  },
50
50
  "dependencies": {
51
- "@syncular/client": "0.30.5"
51
+ "@syncular/client": "0.30.6"
52
52
  },
53
53
  "peerDependencies": {
54
54
  "@tauri-apps/api": ">=2.0.0"
55
55
  },
56
56
  "devDependencies": {
57
- "@syncular/react": "0.30.5"
57
+ "@syncular/react": "0.30.6"
58
58
  }
59
59
  }
package/src/index.ts CHANGED
@@ -335,12 +335,7 @@ export class TauriSyncClient implements PromiseMethods<ClientSnapshotMethods> {
335
335
  method: string,
336
336
  params: Record<string, unknown>,
337
337
  ): Promise<unknown> {
338
- if (this.#closed) {
339
- throw new TauriSyncError(
340
- 'client.closed',
341
- 'the Tauri sync client is closed',
342
- );
343
- }
338
+ this.#requireOpen();
344
339
  if (
345
340
  this.#securityLifecycle === 'preflight' &&
346
341
  ![
@@ -373,7 +368,17 @@ export class TauriSyncClient implements PromiseMethods<ClientSnapshotMethods> {
373
368
  );
374
369
  }
375
370
 
371
+ #requireOpen(): void {
372
+ if (this.#closed) {
373
+ throw new TauriSyncError(
374
+ 'client.closed',
375
+ 'the Tauri sync client is closed',
376
+ );
377
+ }
378
+ }
379
+
376
380
  #requireActive(): void {
381
+ this.#requireOpen();
377
382
  if (this.#securityLifecycle === 'preflight') this.#throwSecurityPreflight();
378
383
  }
379
384
 
@@ -438,7 +443,8 @@ export class TauriSyncClient implements PromiseMethods<ClientSnapshotMethods> {
438
443
 
439
444
  // -- SyncClientLike --------------------------------------------------------
440
445
 
441
- securityLifecycle(): Promise<SecurityLifecycle> {
446
+ async securityLifecycle(): Promise<SecurityLifecycle> {
447
+ this.#requireOpen();
442
448
  return Promise.resolve(this.#securityLifecycle);
443
449
  }
444
450
 
@@ -479,6 +485,7 @@ export class TauriSyncClient implements PromiseMethods<ClientSnapshotMethods> {
479
485
  readonly headers?: Readonly<Record<string, string>>;
480
486
  } = {},
481
487
  ): Promise<void> {
488
+ this.#requireOpen();
482
489
  if (this.#securityLifecycle === 'active') {
483
490
  throw new TauriSyncError(
484
491
  'sync.invalid_request',
@@ -496,23 +503,28 @@ export class TauriSyncClient implements PromiseMethods<ClientSnapshotMethods> {
496
503
  }
497
504
 
498
505
  onInvalidate(listener: InvalidationListener): () => void {
506
+ this.#requireOpen();
499
507
  this.#invalidationListeners.add(listener);
500
508
  return () => this.#invalidationListeners.delete(listener);
501
509
  }
502
510
 
503
511
  onProgress(listener: SyncProgressListener): () => void {
512
+ this.#requireOpen();
504
513
  return this.#progress.on(listener);
505
514
  }
506
515
  progressSnapshot(): SyncProgress | undefined {
516
+ this.#requireOpen();
507
517
  return this.#progress.snapshot();
508
518
  }
509
519
 
510
520
  onChange(listener: ClientChangeListener): () => void {
521
+ this.#requireOpen();
511
522
  this.#changeListeners.add(listener);
512
523
  return () => this.#changeListeners.delete(listener);
513
524
  }
514
525
 
515
526
  onDiagnostics(listener: ClientDiagnosticsListener): () => void {
527
+ this.#requireOpen();
516
528
  this.#diagnosticsListeners.add(listener);
517
529
  this.#enableDiagnosticsPush();
518
530
  return () => this.#diagnosticsListeners.delete(listener);
@@ -542,6 +554,7 @@ export class TauriSyncClient implements PromiseMethods<ClientSnapshotMethods> {
542
554
  }
543
555
 
544
556
  onPresence(listener: (scopeKey: string) => void): () => void {
557
+ this.#requireOpen();
545
558
  this.#presenceListeners.add(listener);
546
559
  return () => this.#presenceListeners.delete(listener);
547
560
  }