@syncular/tauri 0.30.15 → 0.30.16
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 +12 -5
- package/dist/authority.d.ts +10 -0
- package/dist/authority.js +26 -0
- package/dist/index.d.ts +9 -2
- package/dist/index.js +12 -27
- package/package.json +12 -4
- package/src/authority.ts +51 -0
- package/src/index.ts +28 -28
package/README.md
CHANGED
|
@@ -154,7 +154,8 @@ available. The native database opens and migrates, but query/snapshot, mutation,
|
|
|
154
154
|
subscription, sync, realtime, presence, blob, and automatic retry work fails
|
|
155
155
|
with `client.security_preflight_required`. Status, local revision, lifecycle,
|
|
156
156
|
and `purgeLocalData` remain available. A creation-time `defineAuthorityReads`
|
|
157
|
-
policy
|
|
157
|
+
policy on `createTauriAuthoritySyncClient` enables the read-only
|
|
158
|
+
`authoritySnapshot()` described below.
|
|
158
159
|
|
|
159
160
|
```ts
|
|
160
161
|
const client = await createTauriSyncClient({
|
|
@@ -184,16 +185,17 @@ registration and local progress reads throw that code. `close()` is idempotent.
|
|
|
184
185
|
## Authority evidence before activation
|
|
185
186
|
|
|
186
187
|
Declare authority reads at client creation with `defineAuthorityReads` from
|
|
187
|
-
`@syncular/client`. Each table declares plain columns, including
|
|
188
|
-
key and scope columns, and concrete scope selectors. These selectors remain
|
|
188
|
+
`@syncular/client/authority`. Each table declares plain columns, including
|
|
189
|
+
its primary key and scope columns, and concrete scope selectors. These selectors remain
|
|
189
190
|
fixed for that client. A declaration cannot include encrypted, bytes, blob,
|
|
190
191
|
CRDT or internal columns. Choose only authority fields; clinical fields and
|
|
191
192
|
credentials do not belong in this policy.
|
|
192
193
|
|
|
193
194
|
```ts
|
|
194
|
-
import { defineAuthorityReads } from '@syncular/client';
|
|
195
|
+
import { defineAuthorityReads } from '@syncular/client/authority';
|
|
196
|
+
import { createTauriAuthoritySyncClient } from '@syncular/tauri/authority';
|
|
195
197
|
|
|
196
|
-
const client = await
|
|
198
|
+
const client = await createTauriAuthoritySyncClient({
|
|
197
199
|
schema,
|
|
198
200
|
securityPreflight: true,
|
|
199
201
|
transportEnabled: false,
|
|
@@ -206,6 +208,11 @@ const client = await createTauriSyncClient({
|
|
|
206
208
|
const evidence = await client.authoritySnapshot();
|
|
207
209
|
```
|
|
208
210
|
|
|
211
|
+
Use `createTauriAuthoritySyncClient` for the bridge that exposes
|
|
212
|
+
`authoritySnapshot()`. The ordinary `createTauriSyncClient` class does not
|
|
213
|
+
contain that method or its reply decoder. Upgrade 0.30.15 callers to these
|
|
214
|
+
explicit subpaths; the snapshot and native security checks keep their semantics.
|
|
215
|
+
|
|
209
216
|
The native application must also set an independent ceiling at plugin creation:
|
|
210
217
|
|
|
211
218
|
```rust
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AuthorityReadPolicy, AuthoritySnapshot } from '@syncular/client/authority';
|
|
2
|
+
import { TauriSyncClient, type TauriSyncClientConfig } from './index.js';
|
|
3
|
+
/** Explicit native bridge with the zero-argument preflight authority read. */
|
|
4
|
+
export declare class TauriAuthoritySyncClient extends TauriSyncClient {
|
|
5
|
+
authoritySnapshot(): Promise<AuthoritySnapshot>;
|
|
6
|
+
}
|
|
7
|
+
/** Construct an authority-enabled bridge; Rust still enforces its independent ceiling. */
|
|
8
|
+
export declare function createTauriAuthoritySyncClient(config: TauriSyncClientConfig & {
|
|
9
|
+
readonly authorityReads: AuthorityReadPolicy;
|
|
10
|
+
}): Promise<TauriAuthoritySyncClient>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createTauriSyncClient, decodeRow, TauriSyncClient, TauriSyncError, } from './index.js';
|
|
2
|
+
/** Explicit native bridge with the zero-argument preflight authority read. */
|
|
3
|
+
export class TauriAuthoritySyncClient extends TauriSyncClient {
|
|
4
|
+
async authoritySnapshot() {
|
|
5
|
+
this.requireOpen();
|
|
6
|
+
if (arguments.length)
|
|
7
|
+
throw new TauriSyncError('client.authority_read_forbidden', 'authoritySnapshot accepts no arguments');
|
|
8
|
+
const result = (await this.command('authoritySnapshot', {}));
|
|
9
|
+
this.requireOpen();
|
|
10
|
+
return {
|
|
11
|
+
...result,
|
|
12
|
+
revision: BigInt(result.revision),
|
|
13
|
+
tables: result.tables.map((table) => ({
|
|
14
|
+
...table,
|
|
15
|
+
rows: table.rows.map((row) => ({
|
|
16
|
+
...row,
|
|
17
|
+
values: decodeRow(row.values),
|
|
18
|
+
})),
|
|
19
|
+
})),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** Construct an authority-enabled bridge; Rust still enforces its independent ceiling. */
|
|
24
|
+
export function createTauriAuthoritySyncClient(config) {
|
|
25
|
+
return createTauriSyncClient(config, (...args) => new TauriAuthoritySyncClient(...args));
|
|
26
|
+
}
|
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 { AuthorityReadPolicy,
|
|
31
|
+
import type { AuthorityReadPolicy, 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;
|
|
@@ -97,6 +97,8 @@ export interface TauriSyncClientConfig {
|
|
|
97
97
|
export type BytesEnvelope = {
|
|
98
98
|
readonly $bytes: string;
|
|
99
99
|
};
|
|
100
|
+
/** @internal Shared native row codec. */
|
|
101
|
+
export declare function decodeRow(row: Record<string, unknown>): SqlRow;
|
|
100
102
|
/**
|
|
101
103
|
* The webview-side proxy implementing `SyncClientLike` over the plugin. Every
|
|
102
104
|
* snapshot method returns a promise from an IPC round trip. React hooks accept
|
|
@@ -106,6 +108,10 @@ export declare class TauriSyncClient implements PromiseMethods<ClientSnapshotMet
|
|
|
106
108
|
#private;
|
|
107
109
|
/** @internal — use {@link createTauriSyncClient}. */
|
|
108
110
|
constructor(tauri: TauriApi, unlisten: () => void, securityLifecycle?: SecurityLifecycle);
|
|
111
|
+
/** @internal Shared command gate for explicit bridge extensions. */
|
|
112
|
+
protected command(method: string, params: Record<string, unknown>): Promise<unknown>;
|
|
113
|
+
/** @internal Recheck local close after an extension's asynchronous reply. */
|
|
114
|
+
protected requireOpen(): void;
|
|
109
115
|
/** @internal — fan an incoming plugin event out to the local listeners. */
|
|
110
116
|
__dispatchEvent(event: SyncularEvent): void;
|
|
111
117
|
securityLifecycle(): Promise<SecurityLifecycle>;
|
|
@@ -128,7 +134,6 @@ export declare class TauriSyncClient implements PromiseMethods<ClientSnapshotMet
|
|
|
128
134
|
onDiagnostics(listener: ClientDiagnosticsListener): () => void;
|
|
129
135
|
onPresence(listener: (scopeKey: string) => void): () => void;
|
|
130
136
|
query(sql: string, params?: readonly SqlValue[]): Promise<SqlRow[]>;
|
|
131
|
-
authoritySnapshot(): Promise<AuthoritySnapshot>;
|
|
132
137
|
querySnapshot<Row = SqlRow>(spec: QueryReadSpec): Promise<QuerySnapshot<Row>>;
|
|
133
138
|
localRevision(): Promise<bigint>;
|
|
134
139
|
statusSnapshot(): Promise<SyncStatusSnapshot>;
|
|
@@ -204,4 +209,6 @@ export declare class TauriSyncError extends Error {
|
|
|
204
209
|
* React `<SyncProvider client={…}>`.
|
|
205
210
|
*/
|
|
206
211
|
export declare function createTauriSyncClient(config: TauriSyncClientConfig): Promise<TauriSyncClient>;
|
|
212
|
+
/** @internal Explicit bridge extension used by the authority entry. */
|
|
213
|
+
export declare function createTauriSyncClient<Client extends TauriSyncClient>(config: TauriSyncClientConfig, createClient: (...args: ConstructorParameters<typeof TauriSyncClient>) => Client): Promise<Client>;
|
|
207
214
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -82,7 +82,8 @@ function decodeCell(value) {
|
|
|
82
82
|
// string (SQLite json columns arrive as text already; this is defensive).
|
|
83
83
|
return JSON.stringify(value);
|
|
84
84
|
}
|
|
85
|
-
|
|
85
|
+
/** @internal Shared native row codec. */
|
|
86
|
+
export function decodeRow(row) {
|
|
86
87
|
const out = {};
|
|
87
88
|
for (const [key, value] of Object.entries(row)) {
|
|
88
89
|
// Reserved `_sync_*` columns stay engine-internal (parity with the
|
|
@@ -190,6 +191,14 @@ export class TauriSyncClient {
|
|
|
190
191
|
throw new TauriSyncError('client.closed', 'the Tauri sync client is closed');
|
|
191
192
|
}
|
|
192
193
|
}
|
|
194
|
+
/** @internal Shared command gate for explicit bridge extensions. */
|
|
195
|
+
command(method, params) {
|
|
196
|
+
return this.#command(method, params);
|
|
197
|
+
}
|
|
198
|
+
/** @internal Recheck local close after an extension's asynchronous reply. */
|
|
199
|
+
requireOpen() {
|
|
200
|
+
this.#requireOpen();
|
|
201
|
+
}
|
|
193
202
|
#requireActive() {
|
|
194
203
|
this.#requireOpen();
|
|
195
204
|
if (this.#securityLifecycle === 'preflight')
|
|
@@ -365,24 +374,6 @@ export class TauriSyncClient {
|
|
|
365
374
|
const rows = reply.result.rows ?? [];
|
|
366
375
|
return rows.map((r) => decodeRow(r));
|
|
367
376
|
}
|
|
368
|
-
async authoritySnapshot() {
|
|
369
|
-
this.#requireOpen();
|
|
370
|
-
if (arguments.length)
|
|
371
|
-
throw new TauriSyncError('client.authority_read_forbidden', 'authoritySnapshot accepts no arguments');
|
|
372
|
-
const result = (await this.#command('authoritySnapshot', {}));
|
|
373
|
-
this.#requireOpen();
|
|
374
|
-
return {
|
|
375
|
-
...result,
|
|
376
|
-
revision: BigInt(result.revision),
|
|
377
|
-
tables: result.tables.map((table) => ({
|
|
378
|
-
...table,
|
|
379
|
-
rows: table.rows.map((row) => ({
|
|
380
|
-
...row,
|
|
381
|
-
values: decodeRow(row.values),
|
|
382
|
-
})),
|
|
383
|
-
})),
|
|
384
|
-
};
|
|
385
|
-
}
|
|
386
377
|
async querySnapshot(spec) {
|
|
387
378
|
this.#requireActive();
|
|
388
379
|
const reply = await this.#tauri.invoke(`${PLUGIN}syncular_query_snapshot`, {
|
|
@@ -720,13 +711,7 @@ function encodeMutation(mutation) {
|
|
|
720
711
|
}
|
|
721
712
|
return { ...mutation, values };
|
|
722
713
|
}
|
|
723
|
-
|
|
724
|
-
* Construct the bridge and issue the native `create` (opening/attaching the
|
|
725
|
-
* file DB on the Rust side per the plugin config). Returns a ready
|
|
726
|
-
* `TauriSyncClient` that satisfies `SyncClientLike` — pass it straight to the
|
|
727
|
-
* React `<SyncProvider client={…}>`.
|
|
728
|
-
*/
|
|
729
|
-
export async function createTauriSyncClient(config) {
|
|
714
|
+
export async function createTauriSyncClient(config, createClient = (...args) => new TauriSyncClient(...args)) {
|
|
730
715
|
const tauri = await resolveTauri(config.tauri);
|
|
731
716
|
// Wire the event stream BEFORE create, so no early change batch is missed.
|
|
732
717
|
const clientRef = {
|
|
@@ -739,7 +724,7 @@ export async function createTauriSyncClient(config) {
|
|
|
739
724
|
unlisten();
|
|
740
725
|
throw new TauriSyncError('sync.invalid_request', 'securityPreflight and encryption are mutually exclusive; install keys with activateSecurity after preflight');
|
|
741
726
|
}
|
|
742
|
-
const client =
|
|
727
|
+
const client = createClient(tauri, unlisten, config.securityPreflight === true ? 'preflight' : 'active');
|
|
743
728
|
clientRef.client = client;
|
|
744
729
|
// The native side owns every path (plugin config); the JS side names a
|
|
745
730
|
// database and supplies the schema, clientId, and limits.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@syncular/tauri",
|
|
3
|
-
"version": "0.30.
|
|
3
|
+
"version": "0.30.16",
|
|
4
4
|
"description": "Tauri integration for the Syncular client",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Benjamin Kniffler",
|
|
@@ -33,6 +33,14 @@
|
|
|
33
33
|
"types": "./dist/index.d.ts",
|
|
34
34
|
"default": "./dist/index.js"
|
|
35
35
|
}
|
|
36
|
+
},
|
|
37
|
+
"./authority": {
|
|
38
|
+
"bun": "./src/authority.ts",
|
|
39
|
+
"browser": "./dist/authority.js",
|
|
40
|
+
"import": {
|
|
41
|
+
"types": "./dist/authority.d.ts",
|
|
42
|
+
"default": "./dist/authority.js"
|
|
43
|
+
}
|
|
36
44
|
}
|
|
37
45
|
},
|
|
38
46
|
"files": [
|
|
@@ -48,13 +56,13 @@
|
|
|
48
56
|
"test": "bun test"
|
|
49
57
|
},
|
|
50
58
|
"dependencies": {
|
|
51
|
-
"@syncular/client": "0.30.
|
|
59
|
+
"@syncular/client": "0.30.16"
|
|
52
60
|
},
|
|
53
61
|
"peerDependencies": {
|
|
54
62
|
"@tauri-apps/api": ">=2.0.0"
|
|
55
63
|
},
|
|
56
64
|
"devDependencies": {
|
|
57
|
-
"@syncular/react": "0.30.
|
|
58
|
-
"@syncular/server": "0.30.
|
|
65
|
+
"@syncular/react": "0.30.16",
|
|
66
|
+
"@syncular/server": "0.30.16"
|
|
59
67
|
}
|
|
60
68
|
}
|
package/src/authority.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AuthorityReadPolicy,
|
|
3
|
+
AuthoritySnapshot,
|
|
4
|
+
} from '@syncular/client/authority';
|
|
5
|
+
import {
|
|
6
|
+
createTauriSyncClient,
|
|
7
|
+
decodeRow,
|
|
8
|
+
TauriSyncClient,
|
|
9
|
+
TauriSyncError,
|
|
10
|
+
type TauriSyncClientConfig,
|
|
11
|
+
} from './index';
|
|
12
|
+
|
|
13
|
+
/** Explicit native bridge with the zero-argument preflight authority read. */
|
|
14
|
+
export class TauriAuthoritySyncClient extends TauriSyncClient {
|
|
15
|
+
async authoritySnapshot(): Promise<AuthoritySnapshot> {
|
|
16
|
+
this.requireOpen();
|
|
17
|
+
if (arguments.length)
|
|
18
|
+
throw new TauriSyncError(
|
|
19
|
+
'client.authority_read_forbidden',
|
|
20
|
+
'authoritySnapshot accepts no arguments',
|
|
21
|
+
);
|
|
22
|
+
const result = (await this.command('authoritySnapshot', {})) as Omit<
|
|
23
|
+
AuthoritySnapshot,
|
|
24
|
+
'revision'
|
|
25
|
+
> & { revision: string };
|
|
26
|
+
this.requireOpen();
|
|
27
|
+
return {
|
|
28
|
+
...result,
|
|
29
|
+
revision: BigInt(result.revision),
|
|
30
|
+
tables: result.tables.map((table) => ({
|
|
31
|
+
...table,
|
|
32
|
+
rows: table.rows.map((row) => ({
|
|
33
|
+
...row,
|
|
34
|
+
values: decodeRow(row.values),
|
|
35
|
+
})),
|
|
36
|
+
})),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Construct an authority-enabled bridge; Rust still enforces its independent ceiling. */
|
|
42
|
+
export function createTauriAuthoritySyncClient(
|
|
43
|
+
config: TauriSyncClientConfig & {
|
|
44
|
+
readonly authorityReads: AuthorityReadPolicy;
|
|
45
|
+
},
|
|
46
|
+
): Promise<TauriAuthoritySyncClient> {
|
|
47
|
+
return createTauriSyncClient(
|
|
48
|
+
config,
|
|
49
|
+
(...args) => new TauriAuthoritySyncClient(...args),
|
|
50
|
+
);
|
|
51
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -35,7 +35,6 @@ import type { ClientSnapshotMethods, PromiseMethods } from '@syncular/client';
|
|
|
35
35
|
|
|
36
36
|
import type {
|
|
37
37
|
AuthorityReadPolicy,
|
|
38
|
-
AuthoritySnapshot,
|
|
39
38
|
ClientChangeBatch,
|
|
40
39
|
ClientChangeListener,
|
|
41
40
|
ClientDiagnosticsListener,
|
|
@@ -250,7 +249,8 @@ function decodeCell(value: unknown): SqlValue {
|
|
|
250
249
|
return JSON.stringify(value);
|
|
251
250
|
}
|
|
252
251
|
|
|
253
|
-
|
|
252
|
+
/** @internal Shared native row codec. */
|
|
253
|
+
export function decodeRow(row: Record<string, unknown>): SqlRow {
|
|
254
254
|
const out: SqlRow = {};
|
|
255
255
|
for (const [key, value] of Object.entries(row)) {
|
|
256
256
|
// Reserved `_sync_*` columns stay engine-internal (parity with the
|
|
@@ -394,6 +394,19 @@ export class TauriSyncClient implements PromiseMethods<ClientSnapshotMethods> {
|
|
|
394
394
|
}
|
|
395
395
|
}
|
|
396
396
|
|
|
397
|
+
/** @internal Shared command gate for explicit bridge extensions. */
|
|
398
|
+
protected command(
|
|
399
|
+
method: string,
|
|
400
|
+
params: Record<string, unknown>,
|
|
401
|
+
): Promise<unknown> {
|
|
402
|
+
return this.#command(method, params);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/** @internal Recheck local close after an extension's asynchronous reply. */
|
|
406
|
+
protected requireOpen(): void {
|
|
407
|
+
this.#requireOpen();
|
|
408
|
+
}
|
|
409
|
+
|
|
397
410
|
#requireActive(): void {
|
|
398
411
|
this.#requireOpen();
|
|
399
412
|
if (this.#securityLifecycle === 'preflight') this.#throwSecurityPreflight();
|
|
@@ -593,31 +606,6 @@ export class TauriSyncClient implements PromiseMethods<ClientSnapshotMethods> {
|
|
|
593
606
|
return rows.map((r) => decodeRow(r as Record<string, unknown>));
|
|
594
607
|
}
|
|
595
608
|
|
|
596
|
-
async authoritySnapshot(): Promise<AuthoritySnapshot> {
|
|
597
|
-
this.#requireOpen();
|
|
598
|
-
if (arguments.length)
|
|
599
|
-
throw new TauriSyncError(
|
|
600
|
-
'client.authority_read_forbidden',
|
|
601
|
-
'authoritySnapshot accepts no arguments',
|
|
602
|
-
);
|
|
603
|
-
const result = (await this.#command('authoritySnapshot', {})) as Omit<
|
|
604
|
-
AuthoritySnapshot,
|
|
605
|
-
'revision'
|
|
606
|
-
> & { revision: string };
|
|
607
|
-
this.#requireOpen();
|
|
608
|
-
return {
|
|
609
|
-
...result,
|
|
610
|
-
revision: BigInt(result.revision),
|
|
611
|
-
tables: result.tables.map((table) => ({
|
|
612
|
-
...table,
|
|
613
|
-
rows: table.rows.map((row) => ({
|
|
614
|
-
...row,
|
|
615
|
-
values: decodeRow(row.values),
|
|
616
|
-
})),
|
|
617
|
-
})),
|
|
618
|
-
};
|
|
619
|
-
}
|
|
620
|
-
|
|
621
609
|
async querySnapshot<Row = SqlRow>(
|
|
622
610
|
spec: QueryReadSpec,
|
|
623
611
|
): Promise<QuerySnapshot<Row>> {
|
|
@@ -1097,8 +1085,20 @@ function encodeMutation(mutation: MutationInput): unknown {
|
|
|
1097
1085
|
* `TauriSyncClient` that satisfies `SyncClientLike` — pass it straight to the
|
|
1098
1086
|
* React `<SyncProvider client={…}>`.
|
|
1099
1087
|
*/
|
|
1088
|
+
export function createTauriSyncClient(
|
|
1089
|
+
config: TauriSyncClientConfig,
|
|
1090
|
+
): Promise<TauriSyncClient>;
|
|
1091
|
+
/** @internal Explicit bridge extension used by the authority entry. */
|
|
1092
|
+
export function createTauriSyncClient<Client extends TauriSyncClient>(
|
|
1093
|
+
config: TauriSyncClientConfig,
|
|
1094
|
+
createClient: (
|
|
1095
|
+
...args: ConstructorParameters<typeof TauriSyncClient>
|
|
1096
|
+
) => Client,
|
|
1097
|
+
): Promise<Client>;
|
|
1100
1098
|
export async function createTauriSyncClient(
|
|
1101
1099
|
config: TauriSyncClientConfig,
|
|
1100
|
+
createClient = (...args: ConstructorParameters<typeof TauriSyncClient>) =>
|
|
1101
|
+
new TauriSyncClient(...args),
|
|
1102
1102
|
): Promise<TauriSyncClient> {
|
|
1103
1103
|
const tauri = await resolveTauri(config.tauri);
|
|
1104
1104
|
|
|
@@ -1121,7 +1121,7 @@ export async function createTauriSyncClient(
|
|
|
1121
1121
|
);
|
|
1122
1122
|
}
|
|
1123
1123
|
|
|
1124
|
-
const client =
|
|
1124
|
+
const client = createClient(
|
|
1125
1125
|
tauri,
|
|
1126
1126
|
unlisten,
|
|
1127
1127
|
config.securityPreflight === true ? 'preflight' : 'active',
|