@pylonsync/sync 0.3.189 → 0.3.192

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/src/types.ts ADDED
@@ -0,0 +1,136 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Wire + public types for the sync package. Pure type-only file —
3
+ // no runtime imports.
4
+ // ---------------------------------------------------------------------------
5
+
6
+ export interface ChangeEvent {
7
+ seq: number;
8
+ entity: string;
9
+ row_id: string;
10
+ kind: "insert" | "update" | "delete";
11
+ data?: Record<string, unknown>;
12
+ timestamp: string;
13
+ }
14
+
15
+ export interface SyncCursor {
16
+ last_seq: number;
17
+ }
18
+
19
+ export interface PullResponse {
20
+ changes: ChangeEvent[];
21
+ cursor: SyncCursor;
22
+ has_more: boolean;
23
+ }
24
+
25
+ /**
26
+ * Server-resolved auth/session state. Shape mirrors what `/api/auth/me`
27
+ * returns (which is `AuthContext` from the Rust side, with camelCase
28
+ * normalization on the way out).
29
+ *
30
+ * `userId=null` means anonymous. `tenantId=null` means the user hasn't
31
+ * selected an org yet (or the backend is single-tenant).
32
+ */
33
+ export interface ResolvedSession {
34
+ userId: string | null;
35
+ tenantId: string | null;
36
+ isAdmin: boolean;
37
+ roles: string[];
38
+ }
39
+
40
+ /**
41
+ * Per-op result on /api/sync/push. Formal shape:
42
+ *
43
+ * { op_id, row_id, entity, kind, status, seq?, error? }
44
+ *
45
+ * Status semantics:
46
+ * - `applied` — first-time write committed at `seq`.
47
+ * - `replayed` — same op_id arrived again after a confirmed apply;
48
+ * `seq` is the cached value of the original write so
49
+ * the client can adopt it on its optimistic ghost
50
+ * without waiting for the WS rebroadcast.
51
+ * - `pending` — a concurrent push carrying this op_id is still
52
+ * in flight on the server. No `seq` yet; the
53
+ * client should retry after a short backoff.
54
+ * - `error` — the write was attempted and rejected; `error`
55
+ * carries the server's code + message.
56
+ *
57
+ * Legacy `deduped` is treated as `replayed` for compatibility — older
58
+ * servers (≤ 0.3.190) returned `deduped` for both InFlight and
59
+ * Replayed cases.
60
+ */
61
+ export interface PushOpResult {
62
+ op_id?: string | null;
63
+ entity?: string;
64
+ row_id?: string;
65
+ kind?: "insert" | "update" | "delete";
66
+ status: "applied" | "replayed" | "pending" | "error" | "deduped";
67
+ seq?: number;
68
+ error?: { code: string; message: string } | string;
69
+ }
70
+
71
+ export interface PushResponse {
72
+ applied: number;
73
+ deduped: number;
74
+ errors: string[];
75
+ results?: PushOpResult[];
76
+ cursor: SyncCursor;
77
+ }
78
+
79
+ export interface ClientChange {
80
+ entity: string;
81
+ row_id: string;
82
+ kind: "insert" | "update" | "delete";
83
+ data?: Record<string, unknown>;
84
+ /**
85
+ * Client-minted idempotency key. The server tracks recently-seen op_ids
86
+ * and returns a no-op success for replays. Supply this on every retry of
87
+ * the same logical mutation — the `MutationQueue` does so automatically.
88
+ */
89
+ op_id?: string;
90
+ }
91
+
92
+ /**
93
+ * Reactive subscription spec — what the server needs to replay a
94
+ * subscription if the client reconnects. Cached client-side so the
95
+ * `ws.onopen` reconnect sweep can re-register every active sub
96
+ * without the React hooks having to know about reconnect lifecycle.
97
+ */
98
+ export interface ReactiveSpec {
99
+ fn_name: string;
100
+ args: unknown;
101
+ }
102
+
103
+ /**
104
+ * Push message routed to a reactive subscription handler. `result`
105
+ * fires on initial run + every time the server's re-run produces a
106
+ * value whose hash differs from the last push. `error` fires when
107
+ * the server can't execute the handler (function not registered,
108
+ * reactive runtime unavailable, runtime error in user code).
109
+ */
110
+ export type ReactiveMessage =
111
+ | { kind: "result"; result: unknown }
112
+ | { kind: "error"; code: string; message: string };
113
+
114
+ export type Row = Record<string, unknown>;
115
+
116
+ export type TransportType = "websocket" | "sse" | "poll";
117
+
118
+ /**
119
+ * Coarse connection state for UI consumers.
120
+ *
121
+ * - `connecting` — engine is starting up; first WS handshake hasn't
122
+ * completed yet. Apps typically render their initial
123
+ * skeleton during this state.
124
+ * - `connected` — WS is open and we've stayed open long enough to
125
+ * consider it stable (5s on the wire). Live queries
126
+ * are receiving real-time updates.
127
+ * - `reconnecting` — WS dropped (network blip, autostop) and the
128
+ * engine is backing off + retrying.
129
+ * - `offline` — engine has been stopped via `engine.stop()` or
130
+ * was never started. No retries pending.
131
+ */
132
+ export type SyncConnectionStatus =
133
+ | "connecting"
134
+ | "connected"
135
+ | "reconnecting"
136
+ | "offline";