@syncular/tauri 0.22.0 → 0.24.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.
- package/dist/index.d.ts +13 -1
- package/dist/index.js +33 -1
- package/package.json +3 -3
- package/src/index.ts +63 -0
package/dist/index.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ import type { ClientSnapshotMethods, PromiseMethods } from '@syncular/client';
|
|
|
28
28
|
* `invoke`/`listen` either from its ESM entry points, from the ambient
|
|
29
29
|
* `window.__TAURI__`, or via injected doubles (tests).
|
|
30
30
|
*/
|
|
31
|
-
import type { ClientChangeListener, ClientDiagnosticsListener, ClientDiagnosticsRequest, ClientDiagnosticsSnapshot, CommitOutcome, CommitOutcomeQuery, ConflictRecord, EncryptionKeyringConfig, InvalidationListener, LocalDataPurgeInput, LocalDataPurgeResult, LocalDataRebootstrapInput, LocalDataRebootstrapResult, MutationInput, PresencePeer, QueryReadSpec, QuerySnapshot, RejectionRecord, ResolveCommitOutcomeInput, SecurityLifecycle, SqlRow, SqlValue, SyncStatusSnapshot, WindowBase, WindowState } from '@syncular/client';
|
|
31
|
+
import type { ClientChangeListener, ClientDiagnosticsListener, ClientDiagnosticsRequest, ClientDiagnosticsSnapshot, CommitOutcome, CommitOutcomeQuery, ConflictRecord, EncryptionKeyringConfig, InvalidationListener, LocalDataPurgeInput, LocalDataPurgeResult, LocalDataRebootstrapInput, LocalDataRebootstrapResult, MutationInput, PresencePeer, PreviousVersionAudit, PreviousVersionReadSpec, PreviousVersionSnapshot, QueryReadSpec, QuerySnapshot, RejectionRecord, ResolveCommitOutcomeInput, SecurityLifecycle, SqlRow, SqlValue, SyncClientConfig, SyncStatusSnapshot, WindowBase, WindowState } from '@syncular/client';
|
|
32
32
|
/** One event pushed on `syncular://event` (the derived client-observable set). */
|
|
33
33
|
interface SyncularEvent {
|
|
34
34
|
readonly type: string;
|
|
@@ -62,6 +62,12 @@ export interface TauriSyncClientConfig {
|
|
|
62
62
|
readonly encryption?: EncryptionKeyringConfig;
|
|
63
63
|
/** Open the native replica behind the fail-closed security gate. */
|
|
64
64
|
readonly securityPreflight?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* RFC 0005 previous-version context, forwarded to the native `create`. The
|
|
67
|
+
* Rust create handler must read this key to enable capture; while it does
|
|
68
|
+
* not, the native core treats the feature as off (default-off).
|
|
69
|
+
*/
|
|
70
|
+
readonly previousVersionContext?: SyncClientConfig['previousVersionContext'];
|
|
65
71
|
/**
|
|
66
72
|
* The Tauri primitives. Omit in a real Tauri webview to auto-resolve from
|
|
67
73
|
* `@tauri-apps/api` (peer dep) or the ambient `window.__TAURI__`; inject in
|
|
@@ -114,6 +120,12 @@ export declare class TauriSyncClient implements PromiseMethods<ClientSnapshotMet
|
|
|
114
120
|
}): Promise<string>;
|
|
115
121
|
purgeLocalData(input: LocalDataPurgeInput): Promise<LocalDataPurgeResult>;
|
|
116
122
|
rebootstrapLocalData(input: LocalDataRebootstrapInput): Promise<LocalDataRebootstrapResult>;
|
|
123
|
+
previousVersionSnapshot(spec: PreviousVersionReadSpec): Promise<PreviousVersionSnapshot>;
|
|
124
|
+
previousVersionAudit(): Promise<PreviousVersionAudit | undefined>;
|
|
125
|
+
previousVersionDiscard(): Promise<{
|
|
126
|
+
present: boolean;
|
|
127
|
+
discarded: boolean;
|
|
128
|
+
}>;
|
|
117
129
|
/**
|
|
118
130
|
* Replace the native transport's request headers at runtime — the auth
|
|
119
131
|
* rotation path. Pass the FULL header set (it replaces,
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { ProgressEmitter, } from '@syncular/client';
|
|
|
2
2
|
// -- Types the bridge speaks (structurally the web-client's) -----------------
|
|
3
3
|
// Most imports stay type-only; the stable preflight error code is shared at
|
|
4
4
|
// runtime so every host surfaces byte-identical policy evidence.
|
|
5
|
-
import { decodeLocalDataRebootstrapResult, SECURITY_PREFLIGHT_REQUIRED_CODE, withClientDiagnosticsHost, } from '@syncular/client';
|
|
5
|
+
import { decodeLocalDataRebootstrapResult, decodePreviousVersionAuditResult, decodePreviousVersionDiscardResult, decodePreviousVersionSnapshot, SECURITY_PREFLIGHT_REQUIRED_CODE, withClientDiagnosticsHost, } from '@syncular/client';
|
|
6
6
|
/** The plugin's Tauri event name — mirror of `tauri-plugin-syncular`. */
|
|
7
7
|
export const SYNCULAR_EVENT = 'syncular://event';
|
|
8
8
|
const PLUGIN = 'plugin:syncular|';
|
|
@@ -94,6 +94,25 @@ function decodeRow(row) {
|
|
|
94
94
|
}
|
|
95
95
|
return out;
|
|
96
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Decode the JSON cell envelopes in an RFC 0005 snapshot reply's rows before
|
|
99
|
+
* the strict bridge decoder sees them; a malformed reply is passed through
|
|
100
|
+
* untouched so `decodePreviousVersionSnapshot` rejects it.
|
|
101
|
+
*/
|
|
102
|
+
function decodeSnapshotRows(value) {
|
|
103
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
104
|
+
return value;
|
|
105
|
+
}
|
|
106
|
+
const source = value;
|
|
107
|
+
if (!Array.isArray(source.rows))
|
|
108
|
+
return value;
|
|
109
|
+
return {
|
|
110
|
+
...source,
|
|
111
|
+
rows: source.rows.map((row) => row !== null && typeof row === 'object' && !Array.isArray(row)
|
|
112
|
+
? decodeRow(row)
|
|
113
|
+
: row),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
97
116
|
/** Resolve the Tauri primitives from the ambient environment when not injected. */
|
|
98
117
|
async function resolveTauri(injected) {
|
|
99
118
|
if (injected !== undefined)
|
|
@@ -150,6 +169,7 @@ export class TauriSyncClient {
|
|
|
150
169
|
'beginSecurityPreflight',
|
|
151
170
|
'activateSecurity',
|
|
152
171
|
'purgeLocalData',
|
|
172
|
+
'previousVersionDiscard',
|
|
153
173
|
'localRevision',
|
|
154
174
|
'statusSnapshot',
|
|
155
175
|
'shutdown',
|
|
@@ -390,6 +410,15 @@ export class TauriSyncClient {
|
|
|
390
410
|
async rebootstrapLocalData(input) {
|
|
391
411
|
return decodeLocalDataRebootstrapResult(await this.#command('rebootstrapLocalData', { input }));
|
|
392
412
|
}
|
|
413
|
+
async previousVersionSnapshot(spec) {
|
|
414
|
+
return decodePreviousVersionSnapshot(decodeSnapshotRows(await this.#command('previousVersionSnapshot', { spec })));
|
|
415
|
+
}
|
|
416
|
+
async previousVersionAudit() {
|
|
417
|
+
return decodePreviousVersionAuditResult(await this.#command('previousVersionAudit', {}));
|
|
418
|
+
}
|
|
419
|
+
async previousVersionDiscard() {
|
|
420
|
+
return decodePreviousVersionDiscardResult(await this.#command('previousVersionDiscard', {}));
|
|
421
|
+
}
|
|
393
422
|
/**
|
|
394
423
|
* Replace the native transport's request headers at runtime — the auth
|
|
395
424
|
* rotation path. Pass the FULL header set (it replaces,
|
|
@@ -683,6 +712,9 @@ export async function createTauriSyncClient(config) {
|
|
|
683
712
|
...(config.securityPreflight !== undefined
|
|
684
713
|
? { securityPreflight: config.securityPreflight }
|
|
685
714
|
: {}),
|
|
715
|
+
...(config.previousVersionContext !== undefined
|
|
716
|
+
? { previousVersionContext: config.previousVersionContext }
|
|
717
|
+
: {}),
|
|
686
718
|
},
|
|
687
719
|
},
|
|
688
720
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@syncular/tauri",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
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.
|
|
51
|
+
"@syncular/client": "0.24.0"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"@tauri-apps/api": ">=2.0.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@syncular/react": "0.
|
|
57
|
+
"@syncular/react": "0.24.0"
|
|
58
58
|
}
|
|
59
59
|
}
|
package/src/index.ts
CHANGED
|
@@ -51,6 +51,9 @@ import type {
|
|
|
51
51
|
LocalDataRebootstrapResult,
|
|
52
52
|
MutationInput,
|
|
53
53
|
PresencePeer,
|
|
54
|
+
PreviousVersionAudit,
|
|
55
|
+
PreviousVersionReadSpec,
|
|
56
|
+
PreviousVersionSnapshot,
|
|
54
57
|
QueryReadSpec,
|
|
55
58
|
QuerySnapshot,
|
|
56
59
|
RejectionRecord,
|
|
@@ -58,6 +61,7 @@ import type {
|
|
|
58
61
|
SecurityLifecycle,
|
|
59
62
|
SqlRow,
|
|
60
63
|
SqlValue,
|
|
64
|
+
SyncClientConfig,
|
|
61
65
|
SyncStatusSnapshot,
|
|
62
66
|
WindowBase,
|
|
63
67
|
WindowState,
|
|
@@ -67,6 +71,9 @@ import type {
|
|
|
67
71
|
// runtime so every host surfaces byte-identical policy evidence.
|
|
68
72
|
import {
|
|
69
73
|
decodeLocalDataRebootstrapResult,
|
|
74
|
+
decodePreviousVersionAuditResult,
|
|
75
|
+
decodePreviousVersionDiscardResult,
|
|
76
|
+
decodePreviousVersionSnapshot,
|
|
70
77
|
SECURITY_PREFLIGHT_REQUIRED_CODE,
|
|
71
78
|
withClientDiagnosticsHost,
|
|
72
79
|
} from '@syncular/client';
|
|
@@ -116,6 +123,12 @@ export interface TauriSyncClientConfig {
|
|
|
116
123
|
readonly encryption?: EncryptionKeyringConfig;
|
|
117
124
|
/** Open the native replica behind the fail-closed security gate. */
|
|
118
125
|
readonly securityPreflight?: boolean;
|
|
126
|
+
/**
|
|
127
|
+
* RFC 0005 previous-version context, forwarded to the native `create`. The
|
|
128
|
+
* Rust create handler must read this key to enable capture; while it does
|
|
129
|
+
* not, the native core treats the feature as off (default-off).
|
|
130
|
+
*/
|
|
131
|
+
readonly previousVersionContext?: SyncClientConfig['previousVersionContext'];
|
|
119
132
|
/**
|
|
120
133
|
* The Tauri primitives. Omit in a real Tauri webview to auto-resolve from
|
|
121
134
|
* `@tauri-apps/api` (peer dep) or the ambient `window.__TAURI__`; inject in
|
|
@@ -225,6 +238,27 @@ function decodeRow(row: Record<string, unknown>): SqlRow {
|
|
|
225
238
|
return out;
|
|
226
239
|
}
|
|
227
240
|
|
|
241
|
+
/**
|
|
242
|
+
* Decode the JSON cell envelopes in an RFC 0005 snapshot reply's rows before
|
|
243
|
+
* the strict bridge decoder sees them; a malformed reply is passed through
|
|
244
|
+
* untouched so `decodePreviousVersionSnapshot` rejects it.
|
|
245
|
+
*/
|
|
246
|
+
function decodeSnapshotRows(value: unknown): unknown {
|
|
247
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
248
|
+
return value;
|
|
249
|
+
}
|
|
250
|
+
const source = value as Record<string, unknown>;
|
|
251
|
+
if (!Array.isArray(source.rows)) return value;
|
|
252
|
+
return {
|
|
253
|
+
...source,
|
|
254
|
+
rows: source.rows.map((row) =>
|
|
255
|
+
row !== null && typeof row === 'object' && !Array.isArray(row)
|
|
256
|
+
? decodeRow(row as Record<string, unknown>)
|
|
257
|
+
: row,
|
|
258
|
+
),
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
228
262
|
/** Resolve the Tauri primitives from the ambient environment when not injected. */
|
|
229
263
|
async function resolveTauri(injected: TauriApi | undefined): Promise<TauriApi> {
|
|
230
264
|
if (injected !== undefined) return injected;
|
|
@@ -301,6 +335,7 @@ export class TauriSyncClient implements PromiseMethods<ClientSnapshotMethods> {
|
|
|
301
335
|
'beginSecurityPreflight',
|
|
302
336
|
'activateSecurity',
|
|
303
337
|
'purgeLocalData',
|
|
338
|
+
'previousVersionDiscard',
|
|
304
339
|
'localRevision',
|
|
305
340
|
'statusSnapshot',
|
|
306
341
|
'shutdown',
|
|
@@ -602,6 +637,31 @@ export class TauriSyncClient implements PromiseMethods<ClientSnapshotMethods> {
|
|
|
602
637
|
);
|
|
603
638
|
}
|
|
604
639
|
|
|
640
|
+
async previousVersionSnapshot(
|
|
641
|
+
spec: PreviousVersionReadSpec,
|
|
642
|
+
): Promise<PreviousVersionSnapshot> {
|
|
643
|
+
return decodePreviousVersionSnapshot(
|
|
644
|
+
decodeSnapshotRows(
|
|
645
|
+
await this.#command('previousVersionSnapshot', { spec }),
|
|
646
|
+
),
|
|
647
|
+
);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
async previousVersionAudit(): Promise<PreviousVersionAudit | undefined> {
|
|
651
|
+
return decodePreviousVersionAuditResult(
|
|
652
|
+
await this.#command('previousVersionAudit', {}),
|
|
653
|
+
);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
async previousVersionDiscard(): Promise<{
|
|
657
|
+
present: boolean;
|
|
658
|
+
discarded: boolean;
|
|
659
|
+
}> {
|
|
660
|
+
return decodePreviousVersionDiscardResult(
|
|
661
|
+
await this.#command('previousVersionDiscard', {}),
|
|
662
|
+
);
|
|
663
|
+
}
|
|
664
|
+
|
|
605
665
|
/**
|
|
606
666
|
* Replace the native transport's request headers at runtime — the auth
|
|
607
667
|
* rotation path. Pass the FULL header set (it replaces,
|
|
@@ -985,6 +1045,9 @@ export async function createTauriSyncClient(
|
|
|
985
1045
|
...(config.securityPreflight !== undefined
|
|
986
1046
|
? { securityPreflight: config.securityPreflight }
|
|
987
1047
|
: {}),
|
|
1048
|
+
...(config.previousVersionContext !== undefined
|
|
1049
|
+
? { previousVersionContext: config.previousVersionContext }
|
|
1050
|
+
: {}),
|
|
988
1051
|
},
|
|
989
1052
|
},
|
|
990
1053
|
});
|