@pylonsync/sync 0.3.189 → 0.3.193
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/package.json +1 -1
- package/src/ids.ts +60 -0
- package/src/index.ts +165 -716
- package/src/local-store.ts +309 -0
- package/src/mutation-queue.ts +153 -0
- package/src/transport.ts +205 -0
- package/src/types.ts +136 -0
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";
|