@read-frog/api-contract 0.24.0 → 0.26.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.
@@ -0,0 +1,122 @@
1
+ import { z } from "zod";
2
+
3
+ // What the web app reports about keeping its Electric data live. Every field is
4
+ // an enum, so each label the API counts them under has a fixed set of values.
5
+
6
+ /** The shapes the web app syncs, by their names in `@repo/electric-contract`. */
7
+ export const webSyncShapeSchema = z.enum([
8
+ "notebases",
9
+ "notebaseColumns",
10
+ "notebaseRows",
11
+ "cardTemplates",
12
+ "cards",
13
+ "revlogs",
14
+ "mediaAssets",
15
+ ]);
16
+ export type WebSyncShape = z.infer<typeof webSyncShapeSchema>;
17
+
18
+ /** The write whose change the page waited to see come back over Electric. */
19
+ export const webSyncOperationSchema = z.enum([
20
+ // The review session's own writes.
21
+ "review",
22
+ // A review the server had already recorded: it waits for that review's card
23
+ // and revlog, as its own transaction wrote nothing.
24
+ "reviewReplay",
25
+ "undo",
26
+ "bury",
27
+ "suspend",
28
+ "deleteNote",
29
+ "deleteCard",
30
+ // A synced collection's own mutation handlers.
31
+ "insert",
32
+ "update",
33
+ "delete",
34
+ // Other writes that wait for their change.
35
+ "setSleep",
36
+ "srsSettings",
37
+ "cardStatus",
38
+ "createTemplate",
39
+ "updateTemplate",
40
+ ]);
41
+ export type WebSyncOperation = z.infer<typeof webSyncOperationSchema>;
42
+
43
+ /** How the shape that lagged was receiving live changes. */
44
+ export const webSyncTransportSchema = z.enum(["sse", "longPoll"]);
45
+ export type WebSyncTransport = z.infer<typeof webSyncTransportSchema>;
46
+
47
+ /**
48
+ * A write wait is only reported once its first wait ran out: `recovered` when
49
+ * reconnecting the lagging shapes brought the change, `failed` when the page
50
+ * gave up on it.
51
+ */
52
+ export const webSyncWriteOutcomeSchema = z.enum(["recovered", "failed"]);
53
+ export type WebSyncWriteOutcome = z.infer<typeof webSyncWriteOutcomeSchema>;
54
+
55
+ export const webSyncStreamErrorTypeSchema = z.enum([
56
+ // 401: the session ended.
57
+ "unauthorized",
58
+ // 403: the notebase was deleted, or is someone else's.
59
+ "forbidden",
60
+ // 400 and any other 4xx.
61
+ "badRequest",
62
+ "clientError",
63
+ // A response without Electric's headers: a proxy or CORS in the way.
64
+ "missingHeaders",
65
+ // Anything that is not an HTTP status: an unreadable body, a parse error.
66
+ "unexpected",
67
+ ]);
68
+ export type WebSyncStreamErrorType = z.infer<typeof webSyncStreamErrorTypeSchema>;
69
+
70
+ /** `initial` before the shape first loaded, when the page shows the error at once. */
71
+ export const webSyncStreamPhaseSchema = z.enum(["initial", "live"]);
72
+ export type WebSyncStreamPhase = z.infer<typeof webSyncStreamPhaseSchema>;
73
+
74
+ export const webSyncPageSchema = z.enum(["reviewCombined", "reviewNotebase"]);
75
+ export type WebSyncPage = z.infer<typeof webSyncPageSchema>;
76
+
77
+ export const webSyncUnavailableReasonSchema = z.enum([
78
+ // A write's change never came back, even after reconnecting.
79
+ "syncTimeout",
80
+ // A shape stream stopped.
81
+ "streamFailed",
82
+ // The notebase is gone: its shapes answer 403.
83
+ "notebaseGone",
84
+ ]);
85
+ export type WebSyncUnavailableReason = z.infer<typeof webSyncUnavailableReasonSchema>;
86
+
87
+ export const webSyncEventSchema = z.discriminatedUnion("type", [
88
+ z
89
+ .object({
90
+ type: z.literal("writeWait"),
91
+ operation: webSyncOperationSchema,
92
+ outcome: webSyncWriteOutcomeSchema,
93
+ transport: webSyncTransportSchema,
94
+ })
95
+ .strict(),
96
+ z
97
+ .object({
98
+ type: z.literal("streamError"),
99
+ shape: webSyncShapeSchema,
100
+ errorType: webSyncStreamErrorTypeSchema,
101
+ phase: webSyncStreamPhaseSchema,
102
+ })
103
+ .strict(),
104
+ z
105
+ .object({
106
+ type: z.literal("unavailable"),
107
+ page: webSyncPageSchema,
108
+ reason: webSyncUnavailableReasonSchema,
109
+ })
110
+ .strict(),
111
+ ]);
112
+ export type WebSyncEvent = z.infer<typeof webSyncEventSchema>;
113
+
114
+ /** A page sends what happened within a second or so as one batch. */
115
+ export const WEB_SYNC_REPORT_MAX_EVENTS = 20;
116
+
117
+ export const reportWebSyncInputSchema = z
118
+ .object({
119
+ events: z.array(webSyncEventSchema).min(1).max(WEB_SYNC_REPORT_MAX_EVENTS),
120
+ })
121
+ .strict();
122
+ export type ReportWebSyncInput = z.infer<typeof reportWebSyncInputSchema>;