@sudobility/screenwriter_types 0.1.1
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/CLAUDE.md +50 -0
- package/README.md +34 -0
- package/dist/account/index.d.ts +440 -0
- package/dist/account/index.js +274 -0
- package/dist/admin/index.d.ts +95 -0
- package/dist/admin/index.js +20 -0
- package/dist/ai/index.d.ts +564 -0
- package/dist/ai/index.js +179 -0
- package/dist/api/envelope.d.ts +33 -0
- package/dist/api/envelope.js +140 -0
- package/dist/api/pagination.d.ts +7 -0
- package/dist/api/pagination.js +9 -0
- package/dist/api/routes.d.ts +273 -0
- package/dist/api/routes.js +306 -0
- package/dist/assets/index.d.ts +722 -0
- package/dist/assets/index.js +452 -0
- package/dist/collab/index.d.ts +214 -0
- package/dist/collab/index.js +211 -0
- package/dist/commands/index.d.ts +92 -0
- package/dist/commands/index.js +20 -0
- package/dist/credits/index.d.ts +26 -0
- package/dist/credits/index.js +7 -0
- package/dist/formats/index.d.ts +87 -0
- package/dist/formats/index.js +26 -0
- package/dist/ids/index.d.ts +2 -0
- package/dist/ids/index.js +2 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +33 -0
- package/dist/io/index.d.ts +395 -0
- package/dist/io/index.js +161 -0
- package/dist/jobs/index.d.ts +278 -0
- package/dist/jobs/index.js +138 -0
- package/dist/keys/index.d.ts +53 -0
- package/dist/keys/index.js +22 -0
- package/dist/lifecycle/index.d.ts +263 -0
- package/dist/lifecycle/index.js +148 -0
- package/dist/me/index.d.ts +35 -0
- package/dist/me/index.js +18 -0
- package/dist/packets/index.d.ts +887 -0
- package/dist/packets/index.js +312 -0
- package/dist/projects/index.d.ts +201 -0
- package/dist/projects/index.js +75 -0
- package/dist/public/index.d.ts +95 -0
- package/dist/public/index.js +25 -0
- package/dist/reads/index.d.ts +387 -0
- package/dist/reads/index.js +118 -0
- package/dist/reports/index.d.ts +168 -0
- package/dist/reports/index.js +466 -0
- package/dist/sharing/index.d.ts +256 -0
- package/dist/sharing/index.js +91 -0
- package/dist/sync/codec.d.ts +7 -0
- package/dist/sync/codec.js +91 -0
- package/dist/sync/index.d.ts +382 -0
- package/dist/sync/index.js +262 -0
- package/dist/sync/permissions.d.ts +22 -0
- package/dist/sync/permissions.js +11 -0
- package/dist/templates/index.d.ts +1699 -0
- package/dist/templates/index.js +70 -0
- package/dist/tenancy/index.d.ts +116 -0
- package/dist/tenancy/index.js +102 -0
- package/dist/test/index.d.ts +8 -0
- package/dist/test/index.js +88 -0
- package/dist/versions/index.d.ts +335 -0
- package/dist/versions/index.js +107 -0
- package/package.json +62 -0
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/** Spec 03 §2. Subprotocol string is `fadewright-sync.v1`. */
|
|
3
|
+
export declare const SYNC_PROTOCOL_VERSION = 1;
|
|
4
|
+
export declare const SYNC_SUBPROTOCOL = "fadewright-sync.v1";
|
|
5
|
+
export declare const SYNC_PATH = "/api/v1/sync";
|
|
6
|
+
export declare const SYNC_HEARTBEAT_MS = 25000;
|
|
7
|
+
export declare const SYNC_MAX_FRAME_BYTES = 1048576;
|
|
8
|
+
export declare const SYNC_AUTH_TIMEOUT_MS = 5000;
|
|
9
|
+
/** Numeric message-type codes (spec 03 §2.3). Frame = channelId, messageType, payload. */
|
|
10
|
+
export declare const SYNC_MESSAGE_TYPES: {
|
|
11
|
+
readonly auth: 0;
|
|
12
|
+
readonly authOk: 1;
|
|
13
|
+
readonly authError: 2;
|
|
14
|
+
readonly reauth: 3;
|
|
15
|
+
readonly ping: 4;
|
|
16
|
+
readonly pong: 4;
|
|
17
|
+
readonly subscribe: 10;
|
|
18
|
+
readonly subscribed: 11;
|
|
19
|
+
readonly subscribeError: 12;
|
|
20
|
+
readonly unsubscribe: 13;
|
|
21
|
+
readonly syncStep1: 20;
|
|
22
|
+
readonly syncStep2: 21;
|
|
23
|
+
readonly update: 22;
|
|
24
|
+
readonly ack: 23;
|
|
25
|
+
readonly reject: 24;
|
|
26
|
+
readonly awareness: 30;
|
|
27
|
+
readonly epochChanged: 40;
|
|
28
|
+
readonly roleChanged: 41;
|
|
29
|
+
readonly documentDeleted: 42;
|
|
30
|
+
readonly normalized: 43;
|
|
31
|
+
readonly serverShutdown: 50;
|
|
32
|
+
};
|
|
33
|
+
export type SyncMessageName = keyof typeof SYNC_MESSAGE_TYPES;
|
|
34
|
+
/** Close codes (spec 03 §2.6). */
|
|
35
|
+
export declare const SYNC_CLOSE_CODES: {
|
|
36
|
+
readonly NORMAL: 1000;
|
|
37
|
+
readonly GOING_AWAY: 1001;
|
|
38
|
+
readonly MALFORMED_FRAME: 4400;
|
|
39
|
+
readonly AUTH_TIMEOUT_OR_INVALID: 4401;
|
|
40
|
+
readonly ACCOUNT_DISABLED_OR_DEVICE_REVOKED: 4403;
|
|
41
|
+
readonly PROTOCOL_UNSUPPORTED: 4406;
|
|
42
|
+
readonly HEARTBEAT_TIMEOUT: 4408;
|
|
43
|
+
/** Document epoch changed (snapshot open / version restore): resubscribe at the new epoch. */
|
|
44
|
+
readonly EPOCH_CHANGED: 4409;
|
|
45
|
+
readonly FRAME_TOO_LARGE: 4413;
|
|
46
|
+
readonly RATE_LIMITED: 4429;
|
|
47
|
+
};
|
|
48
|
+
export type SyncCloseCode = (typeof SYNC_CLOSE_CODES)[keyof typeof SYNC_CLOSE_CODES];
|
|
49
|
+
export declare const SYNC_AUTH_SCHEMES: readonly ["firebase", "apikey", "link"];
|
|
50
|
+
export declare const SYNC_AUTH_ERROR_CODES: readonly ["UNAUTHENTICATED", "ACCOUNT_DISABLED", "DEVICE_REVOKED", "LINK_EXPIRED", "CLIENT_TOO_OLD", "SERVER_TOO_OLD"];
|
|
51
|
+
export declare const SYNC_SUBSCRIBE_ERROR_CODES: readonly ["NOT_FOUND", "FORBIDDEN", "DOCUMENT_DELETED", "EPOCH_MISMATCH", "DOCUMENT_LOCKED", "CLIENT_TOO_OLD"];
|
|
52
|
+
export declare const SYNC_REJECT_CODES: readonly ["FORBIDDEN", "EPOCH_MISMATCH", "UPDATE_INVALID", "PAYLOAD_TOO_LARGE", "SCHEMA_VIOLATION"];
|
|
53
|
+
export declare const SYNC_SUBSCRIBE_MODES: readonly ["edit", "view"];
|
|
54
|
+
export declare const SYNC_EPOCH_REASONS: readonly ["snapshot-open", "import-over", "version-restore", "schema-migration"];
|
|
55
|
+
export declare const authPayloadSchema: z.ZodObject<{
|
|
56
|
+
scheme: z.ZodEnum<{
|
|
57
|
+
link: "link";
|
|
58
|
+
firebase: "firebase";
|
|
59
|
+
apikey: "apikey";
|
|
60
|
+
}>;
|
|
61
|
+
token: z.ZodString;
|
|
62
|
+
deviceId: z.ZodString;
|
|
63
|
+
installId: z.ZodString;
|
|
64
|
+
clientVersion: z.ZodString;
|
|
65
|
+
schemaVersion: z.ZodNumber;
|
|
66
|
+
unlockToken: z.ZodOptional<z.ZodString>;
|
|
67
|
+
}, z.core.$strip>;
|
|
68
|
+
export declare const authOkPayloadSchema: z.ZodObject<{
|
|
69
|
+
userId: z.ZodString;
|
|
70
|
+
sessionId: z.ZodString;
|
|
71
|
+
serverSchemaVersion: z.ZodNumber;
|
|
72
|
+
heartbeatMs: z.ZodNumber;
|
|
73
|
+
maxFrameBytes: z.ZodNumber;
|
|
74
|
+
}, z.core.$strip>;
|
|
75
|
+
export declare const authErrorPayloadSchema: z.ZodObject<{
|
|
76
|
+
code: z.ZodEnum<{
|
|
77
|
+
CLIENT_TOO_OLD: "CLIENT_TOO_OLD";
|
|
78
|
+
DEVICE_REVOKED: "DEVICE_REVOKED";
|
|
79
|
+
UNAUTHENTICATED: "UNAUTHENTICATED";
|
|
80
|
+
ACCOUNT_DISABLED: "ACCOUNT_DISABLED";
|
|
81
|
+
LINK_EXPIRED: "LINK_EXPIRED";
|
|
82
|
+
SERVER_TOO_OLD: "SERVER_TOO_OLD";
|
|
83
|
+
}>;
|
|
84
|
+
message: z.ZodString;
|
|
85
|
+
}, z.core.$strip>;
|
|
86
|
+
export declare const reauthPayloadSchema: z.ZodObject<{
|
|
87
|
+
token: z.ZodString;
|
|
88
|
+
}, z.core.$strip>;
|
|
89
|
+
export declare const pingPayloadSchema: z.ZodObject<{
|
|
90
|
+
t: z.ZodNumber;
|
|
91
|
+
}, z.core.$strip>;
|
|
92
|
+
export declare const subscribePayloadSchema: z.ZodObject<{
|
|
93
|
+
channelId: z.ZodNumber;
|
|
94
|
+
documentId: z.ZodString;
|
|
95
|
+
epoch: z.ZodNumber;
|
|
96
|
+
stateVector: z.ZodOptional<z.ZodString>;
|
|
97
|
+
mode: z.ZodEnum<{
|
|
98
|
+
view: "view";
|
|
99
|
+
edit: "edit";
|
|
100
|
+
}>;
|
|
101
|
+
snapshotId: z.ZodOptional<z.ZodString>;
|
|
102
|
+
}, z.core.$strip>;
|
|
103
|
+
export declare const subscribedPayloadSchema: z.ZodObject<{
|
|
104
|
+
documentId: z.ZodString;
|
|
105
|
+
role: z.ZodEnum<{
|
|
106
|
+
owner: "owner";
|
|
107
|
+
admin: "admin";
|
|
108
|
+
writer: "writer";
|
|
109
|
+
commenter: "commenter";
|
|
110
|
+
viewer: "viewer";
|
|
111
|
+
none: "none";
|
|
112
|
+
}>;
|
|
113
|
+
epoch: z.ZodNumber;
|
|
114
|
+
markPermissions: z.ZodUnknown;
|
|
115
|
+
schemaVersion: z.ZodNumber;
|
|
116
|
+
}, z.core.$strip>;
|
|
117
|
+
export declare const subscribeErrorPayloadSchema: z.ZodObject<{
|
|
118
|
+
code: z.ZodEnum<{
|
|
119
|
+
FORBIDDEN: "FORBIDDEN";
|
|
120
|
+
NOT_FOUND: "NOT_FOUND";
|
|
121
|
+
EPOCH_MISMATCH: "EPOCH_MISMATCH";
|
|
122
|
+
DOCUMENT_LOCKED: "DOCUMENT_LOCKED";
|
|
123
|
+
CLIENT_TOO_OLD: "CLIENT_TOO_OLD";
|
|
124
|
+
DOCUMENT_DELETED: "DOCUMENT_DELETED";
|
|
125
|
+
}>;
|
|
126
|
+
detail: z.ZodOptional<z.ZodUnknown>;
|
|
127
|
+
}, z.core.$strip>;
|
|
128
|
+
export declare const unsubscribePayloadSchema: z.ZodObject<{
|
|
129
|
+
channelId: z.ZodNumber;
|
|
130
|
+
}, z.core.$strip>;
|
|
131
|
+
export declare const ackPayloadSchema: z.ZodObject<{
|
|
132
|
+
clientSeq: z.ZodNumber;
|
|
133
|
+
serverSeq: z.ZodNumber;
|
|
134
|
+
}, z.core.$strip>;
|
|
135
|
+
export declare const rejectPayloadSchema: z.ZodObject<{
|
|
136
|
+
clientSeq: z.ZodNumber;
|
|
137
|
+
code: z.ZodEnum<{
|
|
138
|
+
FORBIDDEN: "FORBIDDEN";
|
|
139
|
+
EPOCH_MISMATCH: "EPOCH_MISMATCH";
|
|
140
|
+
PAYLOAD_TOO_LARGE: "PAYLOAD_TOO_LARGE";
|
|
141
|
+
UPDATE_INVALID: "UPDATE_INVALID";
|
|
142
|
+
SCHEMA_VIOLATION: "SCHEMA_VIOLATION";
|
|
143
|
+
}>;
|
|
144
|
+
detail: z.ZodOptional<z.ZodUnknown>;
|
|
145
|
+
}, z.core.$strip>;
|
|
146
|
+
export declare const epochChangedPayloadSchema: z.ZodObject<{
|
|
147
|
+
newEpoch: z.ZodNumber;
|
|
148
|
+
reason: z.ZodEnum<{
|
|
149
|
+
"snapshot-open": "snapshot-open";
|
|
150
|
+
"import-over": "import-over";
|
|
151
|
+
"version-restore": "version-restore";
|
|
152
|
+
"schema-migration": "schema-migration";
|
|
153
|
+
}>;
|
|
154
|
+
byUserId: z.ZodString;
|
|
155
|
+
snapshotId: z.ZodOptional<z.ZodString>;
|
|
156
|
+
}, z.core.$strip>;
|
|
157
|
+
export declare const roleChangedPayloadSchema: z.ZodObject<{
|
|
158
|
+
role: z.ZodEnum<{
|
|
159
|
+
owner: "owner";
|
|
160
|
+
admin: "admin";
|
|
161
|
+
writer: "writer";
|
|
162
|
+
commenter: "commenter";
|
|
163
|
+
viewer: "viewer";
|
|
164
|
+
none: "none";
|
|
165
|
+
}>;
|
|
166
|
+
markPermissions: z.ZodUnknown;
|
|
167
|
+
}, z.core.$strip>;
|
|
168
|
+
export declare const documentDeletedPayloadSchema: z.ZodObject<{
|
|
169
|
+
byUserId: z.ZodString;
|
|
170
|
+
recoverableUntil: z.ZodString;
|
|
171
|
+
}, z.core.$strip>;
|
|
172
|
+
export declare const normalizedPayloadSchema: z.ZodObject<{
|
|
173
|
+
serverSeq: z.ZodNumber;
|
|
174
|
+
contentHashes: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
175
|
+
}, z.core.$strip>;
|
|
176
|
+
export declare const serverShutdownPayloadSchema: z.ZodObject<{
|
|
177
|
+
reconnectAfterMs: z.ZodNumber;
|
|
178
|
+
}, z.core.$strip>;
|
|
179
|
+
export declare const syncFrameSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
180
|
+
channelId: z.ZodLiteral<0>;
|
|
181
|
+
type: z.ZodLiteral<"auth">;
|
|
182
|
+
payload: z.ZodObject<{
|
|
183
|
+
scheme: z.ZodEnum<{
|
|
184
|
+
link: "link";
|
|
185
|
+
firebase: "firebase";
|
|
186
|
+
apikey: "apikey";
|
|
187
|
+
}>;
|
|
188
|
+
token: z.ZodString;
|
|
189
|
+
deviceId: z.ZodString;
|
|
190
|
+
installId: z.ZodString;
|
|
191
|
+
clientVersion: z.ZodString;
|
|
192
|
+
schemaVersion: z.ZodNumber;
|
|
193
|
+
unlockToken: z.ZodOptional<z.ZodString>;
|
|
194
|
+
}, z.core.$strip>;
|
|
195
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
196
|
+
channelId: z.ZodLiteral<0>;
|
|
197
|
+
type: z.ZodLiteral<"authOk">;
|
|
198
|
+
payload: z.ZodObject<{
|
|
199
|
+
userId: z.ZodString;
|
|
200
|
+
sessionId: z.ZodString;
|
|
201
|
+
serverSchemaVersion: z.ZodNumber;
|
|
202
|
+
heartbeatMs: z.ZodNumber;
|
|
203
|
+
maxFrameBytes: z.ZodNumber;
|
|
204
|
+
}, z.core.$strip>;
|
|
205
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
206
|
+
channelId: z.ZodLiteral<0>;
|
|
207
|
+
type: z.ZodLiteral<"authError">;
|
|
208
|
+
payload: z.ZodObject<{
|
|
209
|
+
code: z.ZodEnum<{
|
|
210
|
+
CLIENT_TOO_OLD: "CLIENT_TOO_OLD";
|
|
211
|
+
DEVICE_REVOKED: "DEVICE_REVOKED";
|
|
212
|
+
UNAUTHENTICATED: "UNAUTHENTICATED";
|
|
213
|
+
ACCOUNT_DISABLED: "ACCOUNT_DISABLED";
|
|
214
|
+
LINK_EXPIRED: "LINK_EXPIRED";
|
|
215
|
+
SERVER_TOO_OLD: "SERVER_TOO_OLD";
|
|
216
|
+
}>;
|
|
217
|
+
message: z.ZodString;
|
|
218
|
+
}, z.core.$strip>;
|
|
219
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
220
|
+
channelId: z.ZodLiteral<0>;
|
|
221
|
+
type: z.ZodLiteral<"reauth">;
|
|
222
|
+
payload: z.ZodObject<{
|
|
223
|
+
token: z.ZodString;
|
|
224
|
+
}, z.core.$strip>;
|
|
225
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
226
|
+
channelId: z.ZodLiteral<0>;
|
|
227
|
+
type: z.ZodLiteral<"ping">;
|
|
228
|
+
payload: z.ZodObject<{
|
|
229
|
+
t: z.ZodNumber;
|
|
230
|
+
}, z.core.$strip>;
|
|
231
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
232
|
+
channelId: z.ZodLiteral<0>;
|
|
233
|
+
type: z.ZodLiteral<"pong">;
|
|
234
|
+
payload: z.ZodObject<{
|
|
235
|
+
t: z.ZodNumber;
|
|
236
|
+
}, z.core.$strip>;
|
|
237
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
238
|
+
channelId: z.ZodLiteral<0>;
|
|
239
|
+
type: z.ZodLiteral<"subscribe">;
|
|
240
|
+
payload: z.ZodObject<{
|
|
241
|
+
channelId: z.ZodNumber;
|
|
242
|
+
documentId: z.ZodString;
|
|
243
|
+
epoch: z.ZodNumber;
|
|
244
|
+
stateVector: z.ZodOptional<z.ZodString>;
|
|
245
|
+
mode: z.ZodEnum<{
|
|
246
|
+
view: "view";
|
|
247
|
+
edit: "edit";
|
|
248
|
+
}>;
|
|
249
|
+
snapshotId: z.ZodOptional<z.ZodString>;
|
|
250
|
+
}, z.core.$strip>;
|
|
251
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
252
|
+
channelId: z.ZodNumber;
|
|
253
|
+
type: z.ZodLiteral<"subscribed">;
|
|
254
|
+
payload: z.ZodObject<{
|
|
255
|
+
documentId: z.ZodString;
|
|
256
|
+
role: z.ZodEnum<{
|
|
257
|
+
owner: "owner";
|
|
258
|
+
admin: "admin";
|
|
259
|
+
writer: "writer";
|
|
260
|
+
commenter: "commenter";
|
|
261
|
+
viewer: "viewer";
|
|
262
|
+
none: "none";
|
|
263
|
+
}>;
|
|
264
|
+
epoch: z.ZodNumber;
|
|
265
|
+
markPermissions: z.ZodUnknown;
|
|
266
|
+
schemaVersion: z.ZodNumber;
|
|
267
|
+
}, z.core.$strip>;
|
|
268
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
269
|
+
channelId: z.ZodNumber;
|
|
270
|
+
type: z.ZodLiteral<"subscribeError">;
|
|
271
|
+
payload: z.ZodObject<{
|
|
272
|
+
code: z.ZodEnum<{
|
|
273
|
+
FORBIDDEN: "FORBIDDEN";
|
|
274
|
+
NOT_FOUND: "NOT_FOUND";
|
|
275
|
+
EPOCH_MISMATCH: "EPOCH_MISMATCH";
|
|
276
|
+
DOCUMENT_LOCKED: "DOCUMENT_LOCKED";
|
|
277
|
+
CLIENT_TOO_OLD: "CLIENT_TOO_OLD";
|
|
278
|
+
DOCUMENT_DELETED: "DOCUMENT_DELETED";
|
|
279
|
+
}>;
|
|
280
|
+
detail: z.ZodOptional<z.ZodUnknown>;
|
|
281
|
+
}, z.core.$strip>;
|
|
282
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
283
|
+
channelId: z.ZodLiteral<0>;
|
|
284
|
+
type: z.ZodLiteral<"unsubscribe">;
|
|
285
|
+
payload: z.ZodObject<{
|
|
286
|
+
channelId: z.ZodNumber;
|
|
287
|
+
}, z.core.$strip>;
|
|
288
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
289
|
+
channelId: z.ZodNumber;
|
|
290
|
+
type: z.ZodLiteral<"syncStep1">;
|
|
291
|
+
payload: z.ZodInstanceOf<Uint8Array<ArrayBuffer>>;
|
|
292
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
293
|
+
channelId: z.ZodNumber;
|
|
294
|
+
type: z.ZodLiteral<"syncStep2">;
|
|
295
|
+
payload: z.ZodInstanceOf<Uint8Array<ArrayBuffer>>;
|
|
296
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
297
|
+
channelId: z.ZodNumber;
|
|
298
|
+
type: z.ZodLiteral<"update">;
|
|
299
|
+
payload: z.ZodObject<{
|
|
300
|
+
epoch: z.ZodNumber;
|
|
301
|
+
clientSeq: z.ZodNumber;
|
|
302
|
+
update: z.ZodInstanceOf<Uint8Array<ArrayBuffer>>;
|
|
303
|
+
}, z.core.$strip>;
|
|
304
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
305
|
+
channelId: z.ZodNumber;
|
|
306
|
+
type: z.ZodLiteral<"ack">;
|
|
307
|
+
payload: z.ZodObject<{
|
|
308
|
+
clientSeq: z.ZodNumber;
|
|
309
|
+
serverSeq: z.ZodNumber;
|
|
310
|
+
}, z.core.$strip>;
|
|
311
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
312
|
+
channelId: z.ZodNumber;
|
|
313
|
+
type: z.ZodLiteral<"reject">;
|
|
314
|
+
payload: z.ZodObject<{
|
|
315
|
+
clientSeq: z.ZodNumber;
|
|
316
|
+
code: z.ZodEnum<{
|
|
317
|
+
FORBIDDEN: "FORBIDDEN";
|
|
318
|
+
EPOCH_MISMATCH: "EPOCH_MISMATCH";
|
|
319
|
+
PAYLOAD_TOO_LARGE: "PAYLOAD_TOO_LARGE";
|
|
320
|
+
UPDATE_INVALID: "UPDATE_INVALID";
|
|
321
|
+
SCHEMA_VIOLATION: "SCHEMA_VIOLATION";
|
|
322
|
+
}>;
|
|
323
|
+
detail: z.ZodOptional<z.ZodUnknown>;
|
|
324
|
+
}, z.core.$strip>;
|
|
325
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
326
|
+
channelId: z.ZodNumber;
|
|
327
|
+
type: z.ZodLiteral<"awareness">;
|
|
328
|
+
payload: z.ZodInstanceOf<Uint8Array<ArrayBuffer>>;
|
|
329
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
330
|
+
channelId: z.ZodNumber;
|
|
331
|
+
type: z.ZodLiteral<"epochChanged">;
|
|
332
|
+
payload: z.ZodObject<{
|
|
333
|
+
newEpoch: z.ZodNumber;
|
|
334
|
+
reason: z.ZodEnum<{
|
|
335
|
+
"snapshot-open": "snapshot-open";
|
|
336
|
+
"import-over": "import-over";
|
|
337
|
+
"version-restore": "version-restore";
|
|
338
|
+
"schema-migration": "schema-migration";
|
|
339
|
+
}>;
|
|
340
|
+
byUserId: z.ZodString;
|
|
341
|
+
snapshotId: z.ZodOptional<z.ZodString>;
|
|
342
|
+
}, z.core.$strip>;
|
|
343
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
344
|
+
channelId: z.ZodNumber;
|
|
345
|
+
type: z.ZodLiteral<"roleChanged">;
|
|
346
|
+
payload: z.ZodObject<{
|
|
347
|
+
role: z.ZodEnum<{
|
|
348
|
+
owner: "owner";
|
|
349
|
+
admin: "admin";
|
|
350
|
+
writer: "writer";
|
|
351
|
+
commenter: "commenter";
|
|
352
|
+
viewer: "viewer";
|
|
353
|
+
none: "none";
|
|
354
|
+
}>;
|
|
355
|
+
markPermissions: z.ZodUnknown;
|
|
356
|
+
}, z.core.$strip>;
|
|
357
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
358
|
+
channelId: z.ZodNumber;
|
|
359
|
+
type: z.ZodLiteral<"documentDeleted">;
|
|
360
|
+
payload: z.ZodObject<{
|
|
361
|
+
byUserId: z.ZodString;
|
|
362
|
+
recoverableUntil: z.ZodString;
|
|
363
|
+
}, z.core.$strip>;
|
|
364
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
365
|
+
channelId: z.ZodNumber;
|
|
366
|
+
type: z.ZodLiteral<"normalized">;
|
|
367
|
+
payload: z.ZodObject<{
|
|
368
|
+
serverSeq: z.ZodNumber;
|
|
369
|
+
contentHashes: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
370
|
+
}, z.core.$strip>;
|
|
371
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
372
|
+
channelId: z.ZodLiteral<0>;
|
|
373
|
+
type: z.ZodLiteral<"serverShutdown">;
|
|
374
|
+
payload: z.ZodObject<{
|
|
375
|
+
reconnectAfterMs: z.ZodNumber;
|
|
376
|
+
}, z.core.$strip>;
|
|
377
|
+
}, z.core.$strip>], "type">;
|
|
378
|
+
export type SyncFrame = z.infer<typeof syncFrameSchema>;
|
|
379
|
+
export type SyncFrameOf<T extends SyncFrame['type']> = Extract<SyncFrame, {
|
|
380
|
+
type: T;
|
|
381
|
+
}>;
|
|
382
|
+
export * from './permissions.js';
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/** Spec 03 §2. Subprotocol string is `fadewright-sync.v1`. */
|
|
3
|
+
export const SYNC_PROTOCOL_VERSION = 1;
|
|
4
|
+
export const SYNC_SUBPROTOCOL = 'fadewright-sync.v1';
|
|
5
|
+
export const SYNC_PATH = '/api/v1/sync';
|
|
6
|
+
export const SYNC_HEARTBEAT_MS = 25_000;
|
|
7
|
+
export const SYNC_MAX_FRAME_BYTES = 1_048_576;
|
|
8
|
+
export const SYNC_AUTH_TIMEOUT_MS = 5_000;
|
|
9
|
+
/** Numeric message-type codes (spec 03 §2.3). Frame = channelId, messageType, payload. */
|
|
10
|
+
export const SYNC_MESSAGE_TYPES = {
|
|
11
|
+
auth: 0,
|
|
12
|
+
authOk: 1,
|
|
13
|
+
authError: 2,
|
|
14
|
+
reauth: 3,
|
|
15
|
+
ping: 4,
|
|
16
|
+
pong: 4,
|
|
17
|
+
subscribe: 10,
|
|
18
|
+
subscribed: 11,
|
|
19
|
+
subscribeError: 12,
|
|
20
|
+
unsubscribe: 13,
|
|
21
|
+
syncStep1: 20,
|
|
22
|
+
syncStep2: 21,
|
|
23
|
+
update: 22,
|
|
24
|
+
ack: 23,
|
|
25
|
+
reject: 24,
|
|
26
|
+
awareness: 30,
|
|
27
|
+
epochChanged: 40,
|
|
28
|
+
roleChanged: 41,
|
|
29
|
+
documentDeleted: 42,
|
|
30
|
+
normalized: 43,
|
|
31
|
+
serverShutdown: 50,
|
|
32
|
+
};
|
|
33
|
+
/** Close codes (spec 03 §2.6). */
|
|
34
|
+
export const SYNC_CLOSE_CODES = {
|
|
35
|
+
NORMAL: 1000,
|
|
36
|
+
GOING_AWAY: 1001,
|
|
37
|
+
MALFORMED_FRAME: 4400,
|
|
38
|
+
AUTH_TIMEOUT_OR_INVALID: 4401,
|
|
39
|
+
ACCOUNT_DISABLED_OR_DEVICE_REVOKED: 4403,
|
|
40
|
+
PROTOCOL_UNSUPPORTED: 4406,
|
|
41
|
+
HEARTBEAT_TIMEOUT: 4408,
|
|
42
|
+
/** Document epoch changed (snapshot open / version restore): resubscribe at the new epoch. */
|
|
43
|
+
EPOCH_CHANGED: 4409,
|
|
44
|
+
FRAME_TOO_LARGE: 4413,
|
|
45
|
+
RATE_LIMITED: 4429,
|
|
46
|
+
};
|
|
47
|
+
// ─── Vocabularies ───────────────────────────────────────────────────────────
|
|
48
|
+
export const SYNC_AUTH_SCHEMES = ['firebase', 'apikey', 'link'];
|
|
49
|
+
export const SYNC_AUTH_ERROR_CODES = [
|
|
50
|
+
'UNAUTHENTICATED',
|
|
51
|
+
'ACCOUNT_DISABLED',
|
|
52
|
+
'DEVICE_REVOKED',
|
|
53
|
+
'LINK_EXPIRED',
|
|
54
|
+
'CLIENT_TOO_OLD',
|
|
55
|
+
'SERVER_TOO_OLD',
|
|
56
|
+
];
|
|
57
|
+
export const SYNC_SUBSCRIBE_ERROR_CODES = [
|
|
58
|
+
'NOT_FOUND',
|
|
59
|
+
'FORBIDDEN',
|
|
60
|
+
'DOCUMENT_DELETED',
|
|
61
|
+
'EPOCH_MISMATCH',
|
|
62
|
+
'DOCUMENT_LOCKED',
|
|
63
|
+
'CLIENT_TOO_OLD',
|
|
64
|
+
];
|
|
65
|
+
export const SYNC_REJECT_CODES = [
|
|
66
|
+
'FORBIDDEN',
|
|
67
|
+
'EPOCH_MISMATCH',
|
|
68
|
+
'UPDATE_INVALID',
|
|
69
|
+
'PAYLOAD_TOO_LARGE',
|
|
70
|
+
'SCHEMA_VIOLATION',
|
|
71
|
+
];
|
|
72
|
+
export const SYNC_SUBSCRIBE_MODES = ['edit', 'view'];
|
|
73
|
+
export const SYNC_EPOCH_REASONS = [
|
|
74
|
+
'snapshot-open',
|
|
75
|
+
'import-over',
|
|
76
|
+
'version-restore',
|
|
77
|
+
'schema-migration',
|
|
78
|
+
];
|
|
79
|
+
const roleOrNone = z.enum([
|
|
80
|
+
'owner',
|
|
81
|
+
'admin',
|
|
82
|
+
'writer',
|
|
83
|
+
'commenter',
|
|
84
|
+
'viewer',
|
|
85
|
+
'none',
|
|
86
|
+
]);
|
|
87
|
+
const bytes = z.instanceof(Uint8Array);
|
|
88
|
+
const uint = z.number().int().min(0);
|
|
89
|
+
// ─── Payload schemas (JSON UTF-8 payloads) ──────────────────────────────────
|
|
90
|
+
export const authPayloadSchema = z.object({
|
|
91
|
+
scheme: z.enum(SYNC_AUTH_SCHEMES),
|
|
92
|
+
token: z.string(),
|
|
93
|
+
deviceId: z.string(),
|
|
94
|
+
installId: z.string(),
|
|
95
|
+
clientVersion: z.string(),
|
|
96
|
+
schemaVersion: uint,
|
|
97
|
+
/** Unlock-session token (`POST /documents/:did/unlock-session`) for opening locked documents. */
|
|
98
|
+
unlockToken: z.string().optional(),
|
|
99
|
+
});
|
|
100
|
+
export const authOkPayloadSchema = z.object({
|
|
101
|
+
userId: z.string(),
|
|
102
|
+
sessionId: z.string(),
|
|
103
|
+
serverSchemaVersion: uint,
|
|
104
|
+
heartbeatMs: uint,
|
|
105
|
+
maxFrameBytes: uint,
|
|
106
|
+
});
|
|
107
|
+
export const authErrorPayloadSchema = z.object({
|
|
108
|
+
code: z.enum(SYNC_AUTH_ERROR_CODES),
|
|
109
|
+
message: z.string(),
|
|
110
|
+
});
|
|
111
|
+
export const reauthPayloadSchema = z.object({ token: z.string() });
|
|
112
|
+
export const pingPayloadSchema = z.object({ t: z.number() });
|
|
113
|
+
export const subscribePayloadSchema = z.object({
|
|
114
|
+
channelId: uint.min(1),
|
|
115
|
+
documentId: z.string(),
|
|
116
|
+
epoch: uint,
|
|
117
|
+
/** base64 state vector */
|
|
118
|
+
stateVector: z.string().optional(),
|
|
119
|
+
mode: z.enum(SYNC_SUBSCRIBE_MODES),
|
|
120
|
+
snapshotId: z.string().optional(),
|
|
121
|
+
});
|
|
122
|
+
export const subscribedPayloadSchema = z.object({
|
|
123
|
+
documentId: z.string(),
|
|
124
|
+
role: roleOrNone,
|
|
125
|
+
epoch: uint,
|
|
126
|
+
markPermissions: z.unknown(),
|
|
127
|
+
schemaVersion: uint,
|
|
128
|
+
});
|
|
129
|
+
export const subscribeErrorPayloadSchema = z.object({
|
|
130
|
+
code: z.enum(SYNC_SUBSCRIBE_ERROR_CODES),
|
|
131
|
+
detail: z.unknown().optional(),
|
|
132
|
+
});
|
|
133
|
+
export const unsubscribePayloadSchema = z.object({ channelId: uint.min(1) });
|
|
134
|
+
export const ackPayloadSchema = z.object({
|
|
135
|
+
clientSeq: uint,
|
|
136
|
+
serverSeq: uint,
|
|
137
|
+
});
|
|
138
|
+
export const rejectPayloadSchema = z.object({
|
|
139
|
+
clientSeq: uint,
|
|
140
|
+
code: z.enum(SYNC_REJECT_CODES),
|
|
141
|
+
detail: z.unknown().optional(),
|
|
142
|
+
});
|
|
143
|
+
export const epochChangedPayloadSchema = z.object({
|
|
144
|
+
newEpoch: uint,
|
|
145
|
+
reason: z.enum(SYNC_EPOCH_REASONS),
|
|
146
|
+
byUserId: z.string(),
|
|
147
|
+
snapshotId: z.string().optional(),
|
|
148
|
+
});
|
|
149
|
+
export const roleChangedPayloadSchema = z.object({
|
|
150
|
+
role: roleOrNone,
|
|
151
|
+
markPermissions: z.unknown(),
|
|
152
|
+
});
|
|
153
|
+
export const documentDeletedPayloadSchema = z.object({
|
|
154
|
+
byUserId: z.string(),
|
|
155
|
+
recoverableUntil: z.string(),
|
|
156
|
+
});
|
|
157
|
+
export const normalizedPayloadSchema = z.object({
|
|
158
|
+
serverSeq: uint,
|
|
159
|
+
contentHashes: z.record(z.string(), z.string()),
|
|
160
|
+
});
|
|
161
|
+
export const serverShutdownPayloadSchema = z.object({
|
|
162
|
+
reconnectAfterMs: uint,
|
|
163
|
+
});
|
|
164
|
+
// ─── Frame schemas: decoded `{channelId, type, payload}` ────────────────────
|
|
165
|
+
const ctl = z.literal(0);
|
|
166
|
+
const chan = uint.min(1);
|
|
167
|
+
export const syncFrameSchema = z.discriminatedUnion('type', [
|
|
168
|
+
z.object({
|
|
169
|
+
channelId: ctl,
|
|
170
|
+
type: z.literal('auth'),
|
|
171
|
+
payload: authPayloadSchema,
|
|
172
|
+
}),
|
|
173
|
+
z.object({
|
|
174
|
+
channelId: ctl,
|
|
175
|
+
type: z.literal('authOk'),
|
|
176
|
+
payload: authOkPayloadSchema,
|
|
177
|
+
}),
|
|
178
|
+
z.object({
|
|
179
|
+
channelId: ctl,
|
|
180
|
+
type: z.literal('authError'),
|
|
181
|
+
payload: authErrorPayloadSchema,
|
|
182
|
+
}),
|
|
183
|
+
z.object({
|
|
184
|
+
channelId: ctl,
|
|
185
|
+
type: z.literal('reauth'),
|
|
186
|
+
payload: reauthPayloadSchema,
|
|
187
|
+
}),
|
|
188
|
+
z.object({
|
|
189
|
+
channelId: ctl,
|
|
190
|
+
type: z.literal('ping'),
|
|
191
|
+
payload: pingPayloadSchema,
|
|
192
|
+
}),
|
|
193
|
+
z.object({
|
|
194
|
+
channelId: ctl,
|
|
195
|
+
type: z.literal('pong'),
|
|
196
|
+
payload: pingPayloadSchema,
|
|
197
|
+
}),
|
|
198
|
+
z.object({
|
|
199
|
+
channelId: ctl,
|
|
200
|
+
type: z.literal('subscribe'),
|
|
201
|
+
payload: subscribePayloadSchema,
|
|
202
|
+
}),
|
|
203
|
+
z.object({
|
|
204
|
+
channelId: chan,
|
|
205
|
+
type: z.literal('subscribed'),
|
|
206
|
+
payload: subscribedPayloadSchema,
|
|
207
|
+
}),
|
|
208
|
+
z.object({
|
|
209
|
+
channelId: chan,
|
|
210
|
+
type: z.literal('subscribeError'),
|
|
211
|
+
payload: subscribeErrorPayloadSchema,
|
|
212
|
+
}),
|
|
213
|
+
z.object({
|
|
214
|
+
channelId: ctl,
|
|
215
|
+
type: z.literal('unsubscribe'),
|
|
216
|
+
payload: unsubscribePayloadSchema,
|
|
217
|
+
}),
|
|
218
|
+
z.object({ channelId: chan, type: z.literal('syncStep1'), payload: bytes }),
|
|
219
|
+
z.object({ channelId: chan, type: z.literal('syncStep2'), payload: bytes }),
|
|
220
|
+
z.object({
|
|
221
|
+
channelId: chan,
|
|
222
|
+
type: z.literal('update'),
|
|
223
|
+
payload: z.object({ epoch: uint, clientSeq: uint, update: bytes }),
|
|
224
|
+
}),
|
|
225
|
+
z.object({
|
|
226
|
+
channelId: chan,
|
|
227
|
+
type: z.literal('ack'),
|
|
228
|
+
payload: ackPayloadSchema,
|
|
229
|
+
}),
|
|
230
|
+
z.object({
|
|
231
|
+
channelId: chan,
|
|
232
|
+
type: z.literal('reject'),
|
|
233
|
+
payload: rejectPayloadSchema,
|
|
234
|
+
}),
|
|
235
|
+
z.object({ channelId: chan, type: z.literal('awareness'), payload: bytes }),
|
|
236
|
+
z.object({
|
|
237
|
+
channelId: chan,
|
|
238
|
+
type: z.literal('epochChanged'),
|
|
239
|
+
payload: epochChangedPayloadSchema,
|
|
240
|
+
}),
|
|
241
|
+
z.object({
|
|
242
|
+
channelId: chan,
|
|
243
|
+
type: z.literal('roleChanged'),
|
|
244
|
+
payload: roleChangedPayloadSchema,
|
|
245
|
+
}),
|
|
246
|
+
z.object({
|
|
247
|
+
channelId: chan,
|
|
248
|
+
type: z.literal('documentDeleted'),
|
|
249
|
+
payload: documentDeletedPayloadSchema,
|
|
250
|
+
}),
|
|
251
|
+
z.object({
|
|
252
|
+
channelId: chan,
|
|
253
|
+
type: z.literal('normalized'),
|
|
254
|
+
payload: normalizedPayloadSchema,
|
|
255
|
+
}),
|
|
256
|
+
z.object({
|
|
257
|
+
channelId: ctl,
|
|
258
|
+
type: z.literal('serverShutdown'),
|
|
259
|
+
payload: serverShutdownPayloadSchema,
|
|
260
|
+
}),
|
|
261
|
+
]);
|
|
262
|
+
export * from './permissions.js';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spec 03 §3.2 write matrix as data, projected from spec 05's role matrix onto Y.Doc keys.
|
|
3
|
+
* The server checks inbound updates against it; `markPermissionsFor` is what `subscribed` and
|
|
4
|
+
* `roleChanged` send so a client can disable UI instead of being rejected.
|
|
5
|
+
*/
|
|
6
|
+
import type { Role } from '../tenancy/index.js';
|
|
7
|
+
/** Top-level Y.Doc keys a commenter may change (notes and replies, R6). */
|
|
8
|
+
export declare const COMMENTER_WRITABLE_KEYS: readonly string[];
|
|
9
|
+
/** Inline marks a commenter may add or remove inside element text: note anchors `n:<NoteId>` and the highlighter. */
|
|
10
|
+
export declare const isCommenterMark: (name: string) => boolean;
|
|
11
|
+
/** What a role may produce (courtesy for the UI; the server check is the authority). */
|
|
12
|
+
export interface MarkPermissions {
|
|
13
|
+
/** Text, attributes, structure, tags, revisions, settings: everything an owner/admin/writer writes. */
|
|
14
|
+
edit: boolean;
|
|
15
|
+
/** Notes and replies (`notes` + `n:` marks). */
|
|
16
|
+
comment: boolean;
|
|
17
|
+
/** Highlighter (`hl` marks). */
|
|
18
|
+
highlight: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare function markPermissionsFor(role: Role | 'none'): MarkPermissions;
|
|
21
|
+
/** Roles that may send `update` frames at all (a commenter's are filtered by the matrix). */
|
|
22
|
+
export declare const canSendUpdates: (role: Role) => boolean;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Top-level Y.Doc keys a commenter may change (notes and replies, R6). */
|
|
2
|
+
export const COMMENTER_WRITABLE_KEYS = ['notes'];
|
|
3
|
+
/** Inline marks a commenter may add or remove inside element text: note anchors `n:<NoteId>` and the highlighter. */
|
|
4
|
+
export const isCommenterMark = (name) => name === 'hl' || name.startsWith('n:');
|
|
5
|
+
export function markPermissionsFor(role) {
|
|
6
|
+
const edit = role === 'owner' || role === 'admin' || role === 'writer';
|
|
7
|
+
const comment = edit || role === 'commenter';
|
|
8
|
+
return { edit, comment, highlight: comment };
|
|
9
|
+
}
|
|
10
|
+
/** Roles that may send `update` frames at all (a commenter's are filtered by the matrix). */
|
|
11
|
+
export const canSendUpdates = (role) => role !== 'viewer';
|