@syncular/react 0.15.14 → 0.15.15
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 +21 -0
- package/dist/client.d.ts +9 -1
- package/dist/client.js +3 -0
- package/package.json +5 -5
- package/src/client.ts +15 -0
package/README.md
CHANGED
|
@@ -101,6 +101,27 @@ const clientResource = createSyncClientResource(() => createClient());
|
|
|
101
101
|
Call `await clientResource.dispose()` from the application's real lifecycle
|
|
102
102
|
owner, not from a StrictMode-sensitive child effect.
|
|
103
103
|
|
|
104
|
+
If the application requires authentication or signed quarantine processing
|
|
105
|
+
before protected data is visible, complete the concrete client's security
|
|
106
|
+
preflight before returning it from the resource factory. Do not mount the
|
|
107
|
+
ordinary provider tree while `securityLifecycle` is `preflight`: reactive store
|
|
108
|
+
startup intentionally touches protected status/outcome/query surfaces.
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
const clientResource = createSyncClientResource(async () => {
|
|
112
|
+
const client = await createClient({ securityPreflight: true });
|
|
113
|
+
await applyValidatedLocalPurge(client);
|
|
114
|
+
await client.activateSecurity({ encryption: acceptedKeyring });
|
|
115
|
+
return client;
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The normalized client exposes `securityLifecycle()`,
|
|
120
|
+
`beginSecurityPreflight()`, and keyless `activateSecurity()` for host-agnostic
|
|
121
|
+
coordination. Key-bearing activation stays on each concrete client type because
|
|
122
|
+
direct TypeScript uses an `EncryptionConfig`, while Worker/Tauri/React Native
|
|
123
|
+
use the portable keyring.
|
|
124
|
+
|
|
104
125
|
Use `renderBoundary` as the canonical application guard across browser and
|
|
105
126
|
native hosts. It covers resource startup/errors, migration, client upgrade,
|
|
106
127
|
server-behind, incompatible-schema, and unreachable-leader states. The
|
package/dist/client.d.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* value → read it) and wraps every result in `Promise.resolve`, so a hook
|
|
12
12
|
* never has to care which core it holds.
|
|
13
13
|
*/
|
|
14
|
-
import type { ClientChangeListener, CommitOutcome, CommitOutcomeQuery, ConflictRecord, InvalidationListener, LeadershipState, LeaseState, LocalDataPurgeInput, LocalDataPurgeResult, MutationInput, PresencePeer, QueryReadSpec, QuerySnapshot, RejectionRecord, ResolveCommitOutcomeInput, SchemaFloor, SqlRow, SqlValue, SyncStatusSnapshot, WindowBase, WindowState } from '@syncular/client';
|
|
14
|
+
import type { ClientChangeListener, CommitOutcome, CommitOutcomeQuery, ConflictRecord, InvalidationListener, LeadershipState, LeaseState, LocalDataPurgeInput, LocalDataPurgeResult, MutationInput, PresencePeer, QueryReadSpec, QuerySnapshot, RejectionRecord, ResolveCommitOutcomeInput, SchemaFloor, SecurityLifecycle, SqlRow, SqlValue, SyncStatusSnapshot, WindowBase, WindowState } from '@syncular/client';
|
|
15
15
|
/**
|
|
16
16
|
* The structural union of `SyncClient` and `SyncClientHandle`. Members that
|
|
17
17
|
* diverge are typed as "value or method, sync or promise"; {@link normalizeClient}
|
|
@@ -25,6 +25,10 @@ export interface SyncClientLike {
|
|
|
25
25
|
onPresence(listener: (scopeKey: string) => void): () => void;
|
|
26
26
|
onLeadershipChange?(listener: (state: LeadershipState) => void): () => void;
|
|
27
27
|
leadershipSnapshot?(): LeadershipState | undefined;
|
|
28
|
+
securityLifecycle: SecurityLifecycle | (() => SecurityLifecycle | Promise<SecurityLifecycle>);
|
|
29
|
+
beginSecurityPreflight(): void | Promise<void>;
|
|
30
|
+
/** Key-bearing activation remains available on each concrete host type. */
|
|
31
|
+
activateSecurity(): void | Promise<void>;
|
|
28
32
|
query(sql: string, params?: readonly SqlValue[]): SqlRow[] | Promise<SqlRow[]>;
|
|
29
33
|
mutate(mutations: readonly MutationInput[]): string | Promise<string>;
|
|
30
34
|
patch(table: string, rowId: string, partial: Readonly<Record<string, unknown>>, options?: {
|
|
@@ -58,6 +62,10 @@ export interface NormalizedClient {
|
|
|
58
62
|
onPresence(listener: (scopeKey: string) => void): () => void;
|
|
59
63
|
onLeadershipChange(listener: (state: LeadershipState) => void): () => void;
|
|
60
64
|
leadershipSnapshot(): LeadershipState | undefined;
|
|
65
|
+
securityLifecycle(): Promise<SecurityLifecycle>;
|
|
66
|
+
beginSecurityPreflight(): Promise<void>;
|
|
67
|
+
/** Key-bearing activation remains available on each concrete host type. */
|
|
68
|
+
activateSecurity(): Promise<void>;
|
|
61
69
|
query(sql: string, params?: readonly SqlValue[]): Promise<SqlRow[]>;
|
|
62
70
|
mutate(mutations: readonly MutationInput[]): Promise<string>;
|
|
63
71
|
patch(table: string, rowId: string, partial: Readonly<Record<string, unknown>>, options?: {
|
package/dist/client.js
CHANGED
|
@@ -20,6 +20,9 @@ export function normalizeClient(client) {
|
|
|
20
20
|
onPresence: (listener) => client.onPresence(listener),
|
|
21
21
|
onLeadershipChange: (listener) => client.onLeadershipChange?.(listener) ?? (() => { }),
|
|
22
22
|
leadershipSnapshot: () => client.leadershipSnapshot?.(),
|
|
23
|
+
securityLifecycle: () => resolveMember(client, 'securityLifecycle'),
|
|
24
|
+
beginSecurityPreflight: () => Promise.resolve(client.beginSecurityPreflight()),
|
|
25
|
+
activateSecurity: () => Promise.resolve(client.activateSecurity()),
|
|
23
26
|
query: (sql, params) => Promise.resolve(client.query(sql, params)),
|
|
24
27
|
mutate: (mutations) => Promise.resolve(client.mutate(mutations)),
|
|
25
28
|
patch: (table, rowId, partial, options) => Promise.resolve(client.patch(table, rowId, partial, options)),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@syncular/react",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.15",
|
|
4
4
|
"description": "React hooks for Syncular offline-first sync",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Benjamin Kniffler",
|
|
@@ -48,15 +48,15 @@
|
|
|
48
48
|
"test": "bun test --preload ./test/setup.ts"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@syncular/client": "0.15.
|
|
51
|
+
"@syncular/client": "0.15.15"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"react": ">=18.0.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@happy-dom/global-registrator": "^
|
|
58
|
-
"@syncular/core": "0.15.
|
|
59
|
-
"@syncular/server": "0.15.
|
|
57
|
+
"@happy-dom/global-registrator": "^20.0.0",
|
|
58
|
+
"@syncular/core": "0.15.15",
|
|
59
|
+
"@syncular/server": "0.15.15",
|
|
60
60
|
"@testing-library/react": "^16.1.0",
|
|
61
61
|
"@types/react": "^18.3.0",
|
|
62
62
|
"react": "^18.3.1",
|
package/src/client.ts
CHANGED
|
@@ -28,6 +28,7 @@ import type {
|
|
|
28
28
|
RejectionRecord,
|
|
29
29
|
ResolveCommitOutcomeInput,
|
|
30
30
|
SchemaFloor,
|
|
31
|
+
SecurityLifecycle,
|
|
31
32
|
SqlRow,
|
|
32
33
|
SqlValue,
|
|
33
34
|
SyncStatusSnapshot,
|
|
@@ -48,6 +49,12 @@ export interface SyncClientLike {
|
|
|
48
49
|
onPresence(listener: (scopeKey: string) => void): () => void;
|
|
49
50
|
onLeadershipChange?(listener: (state: LeadershipState) => void): () => void;
|
|
50
51
|
leadershipSnapshot?(): LeadershipState | undefined;
|
|
52
|
+
securityLifecycle:
|
|
53
|
+
| SecurityLifecycle
|
|
54
|
+
| (() => SecurityLifecycle | Promise<SecurityLifecycle>);
|
|
55
|
+
beginSecurityPreflight(): void | Promise<void>;
|
|
56
|
+
/** Key-bearing activation remains available on each concrete host type. */
|
|
57
|
+
activateSecurity(): void | Promise<void>;
|
|
51
58
|
query(
|
|
52
59
|
sql: string,
|
|
53
60
|
params?: readonly SqlValue[],
|
|
@@ -130,6 +137,10 @@ export interface NormalizedClient {
|
|
|
130
137
|
onPresence(listener: (scopeKey: string) => void): () => void;
|
|
131
138
|
onLeadershipChange(listener: (state: LeadershipState) => void): () => void;
|
|
132
139
|
leadershipSnapshot(): LeadershipState | undefined;
|
|
140
|
+
securityLifecycle(): Promise<SecurityLifecycle>;
|
|
141
|
+
beginSecurityPreflight(): Promise<void>;
|
|
142
|
+
/** Key-bearing activation remains available on each concrete host type. */
|
|
143
|
+
activateSecurity(): Promise<void>;
|
|
133
144
|
query(sql: string, params?: readonly SqlValue[]): Promise<SqlRow[]>;
|
|
134
145
|
mutate(mutations: readonly MutationInput[]): Promise<string>;
|
|
135
146
|
patch(
|
|
@@ -173,6 +184,10 @@ export function normalizeClient(client: SyncClientLike): NormalizedClient {
|
|
|
173
184
|
onLeadershipChange: (listener) =>
|
|
174
185
|
client.onLeadershipChange?.(listener) ?? (() => {}),
|
|
175
186
|
leadershipSnapshot: () => client.leadershipSnapshot?.(),
|
|
187
|
+
securityLifecycle: () => resolveMember(client, 'securityLifecycle'),
|
|
188
|
+
beginSecurityPreflight: () =>
|
|
189
|
+
Promise.resolve(client.beginSecurityPreflight()),
|
|
190
|
+
activateSecurity: () => Promise.resolve(client.activateSecurity()),
|
|
176
191
|
query: (sql, params) => Promise.resolve(client.query(sql, params)),
|
|
177
192
|
mutate: (mutations) => Promise.resolve(client.mutate(mutations)),
|
|
178
193
|
patch: (table, rowId, partial, options) =>
|