@echovisionlab/geul-common 0.4.0 → 0.6.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.
- package/README.md +23 -0
- package/package.json +4 -2
- package/src/collaboration/artist.ts +12 -14
- package/src/collaboration/campaign.ts +6 -8
- package/src/collaboration/document-layout.ts +6 -8
- package/src/collaboration/document.ts +7 -9
- package/src/collaboration/form.ts +5 -7
- package/src/collaboration/label.ts +9 -11
- package/src/collaboration/map-theme.ts +62 -67
- package/src/collaboration/member-id.ts +2 -2
- package/src/collaboration/metadata-ai.ts +21 -18
- package/src/collaboration/page.ts +2 -2
- package/src/collaboration/post.ts +8 -10
- package/src/collaboration/protocol.ts +609 -0
- package/src/collaboration/release.ts +85 -101
- package/src/collaboration/runtime-events.ts +301 -467
- package/src/collaboration/work.ts +33 -31
- package/src/page/types.ts +4 -6
- package/src/post/types.ts +2 -2
|
@@ -1,191 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
export type RuntimeEntityType =
|
|
4
|
-
| "post"
|
|
5
|
-
| "page"
|
|
6
|
-
| "work"
|
|
7
|
-
| "artist"
|
|
8
|
-
| "label"
|
|
9
|
-
| "release"
|
|
10
|
-
| "series"
|
|
11
|
-
| "form"
|
|
12
|
-
| "program_event"
|
|
13
|
-
| "menu"
|
|
14
|
-
| "site"
|
|
15
|
-
| "site_setting"
|
|
16
|
-
| "email_template"
|
|
17
|
-
| "email_layout"
|
|
18
|
-
| "campaign"
|
|
19
|
-
| "privacy"
|
|
20
|
-
| "terms";
|
|
21
|
-
|
|
22
|
-
export type TranslationLifecycleRuntimeStatus = "failed";
|
|
23
|
-
|
|
24
|
-
export type MediaProcessingRuntimeStatus = "processing" | "ready" | "failed";
|
|
25
|
-
|
|
26
|
-
export type OgGenerationRuntimeEntityType =
|
|
27
|
-
| "post"
|
|
28
|
-
| "page"
|
|
29
|
-
| "work"
|
|
30
|
-
| "artist"
|
|
31
|
-
| "label"
|
|
32
|
-
| "release"
|
|
33
|
-
| "series"
|
|
34
|
-
| "form"
|
|
35
|
-
| "site"
|
|
36
|
-
| "privacy"
|
|
37
|
-
| "terms";
|
|
38
|
-
|
|
39
|
-
export type OgGenerationRuntimeStatus =
|
|
40
|
-
"queued" | "processing" | "ready" | "failed" | "superseded" | "cancelled";
|
|
41
|
-
|
|
42
|
-
export function isOgGenerationRuntimeTerminal(
|
|
43
|
-
status: OgGenerationRuntimeStatus,
|
|
44
|
-
): boolean {
|
|
45
|
-
return (
|
|
46
|
-
status === "ready" ||
|
|
47
|
-
status === "failed" ||
|
|
48
|
-
status === "superseded" ||
|
|
49
|
-
status === "cancelled"
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export type FileIngestRuntimeSource = "upload" | "embed";
|
|
54
|
-
|
|
55
|
-
export type FileIngestRuntimeStage =
|
|
56
|
-
| "uploading"
|
|
57
|
-
| "downloading"
|
|
58
|
-
| "finalized"
|
|
59
|
-
| "attached"
|
|
60
|
-
| "completed"
|
|
61
|
-
| "expired"
|
|
62
|
-
| "failed"
|
|
63
|
-
| "unknown";
|
|
64
|
-
|
|
65
|
-
export interface RuntimeEventEnvelope<K extends string, P> {
|
|
66
|
-
version: 1;
|
|
67
|
-
kind: K;
|
|
68
|
-
entityType: RuntimeEntityType;
|
|
69
|
-
entityId: string;
|
|
70
|
-
locale?: string;
|
|
71
|
-
correlationId?: string;
|
|
72
|
-
sequence?: number;
|
|
73
|
-
timestampMs: number;
|
|
74
|
-
payload: P;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export interface OgGenerationLifecycleRuntimePayload {
|
|
78
|
-
generationId: string;
|
|
79
|
-
runId: string;
|
|
80
|
-
status: OgGenerationRuntimeStatus;
|
|
81
|
-
assetId?: string;
|
|
82
|
-
assetUrl?: string;
|
|
83
|
-
errorCode?: string;
|
|
84
|
-
error?: string;
|
|
85
|
-
replacementGenerationId?: string;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export interface RenderCompleteRuntimePayload {
|
|
89
|
-
contentHash: string;
|
|
90
|
-
success: boolean;
|
|
91
|
-
error?: string;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export interface MediaProcessingRuntimeOutputs {
|
|
95
|
-
spectrogramAssetId?: string;
|
|
96
|
-
thumbnailAssetId?: string;
|
|
97
|
-
hlsGenerationId?: string;
|
|
98
|
-
durationSeconds?: number;
|
|
99
|
-
waveformAssetId?: string;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export interface MediaProcessingLifecycleRuntimePayload {
|
|
103
|
-
fileId: string;
|
|
104
|
-
slotId?: string;
|
|
105
|
-
attemptId?: string;
|
|
106
|
-
status: MediaProcessingRuntimeStatus;
|
|
107
|
-
percentage?: number;
|
|
108
|
-
outputs?: MediaProcessingRuntimeOutputs;
|
|
109
|
-
error?: string;
|
|
110
|
-
trackId?: string;
|
|
111
|
-
releaseId?: string;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
export function isMediaProcessingRuntimeReady(payload: {
|
|
115
|
-
status?: MediaProcessingRuntimeStatus | null;
|
|
116
|
-
}): boolean {
|
|
117
|
-
return payload.status === "ready";
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export interface FileIngestLifecycleRuntimePayload {
|
|
121
|
-
fileId: string;
|
|
122
|
-
uploadId?: string;
|
|
123
|
-
mediaKind?: string;
|
|
124
|
-
slotId?: string;
|
|
125
|
-
attemptId?: string;
|
|
126
|
-
source: FileIngestRuntimeSource;
|
|
127
|
-
stage: FileIngestRuntimeStage;
|
|
128
|
-
progress: number;
|
|
129
|
-
bytesCompleted?: number;
|
|
130
|
-
bytesTotal?: number;
|
|
131
|
-
fileName?: string;
|
|
132
|
-
mimeType?: string;
|
|
133
|
-
fileSize?: number;
|
|
134
|
-
error?: string;
|
|
135
|
-
trackId?: string;
|
|
136
|
-
releaseId?: string;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export interface TranslationLifecycleRuntimePayload {
|
|
140
|
-
jobId: string;
|
|
141
|
-
targetLocale: string;
|
|
142
|
-
status: TranslationLifecycleRuntimeStatus;
|
|
143
|
-
error?: string;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
export interface RuntimeErrorPayload {
|
|
147
|
-
code: string;
|
|
148
|
-
message: string;
|
|
149
|
-
retryable?: boolean;
|
|
150
|
-
source?: "backend" | "collab" | "worker";
|
|
151
|
-
details?: Record<string, string | number | boolean | null>;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
export interface OgGenerationLifecycleRuntimeEvent extends RuntimeEventEnvelope<
|
|
155
|
-
"og.lifecycle",
|
|
156
|
-
OgGenerationLifecycleRuntimePayload
|
|
157
|
-
> {
|
|
158
|
-
entityType: OgGenerationRuntimeEntityType;
|
|
159
|
-
correlationId: string;
|
|
160
|
-
}
|
|
161
|
-
export type RenderCompleteRuntimeEvent = RuntimeEventEnvelope<
|
|
162
|
-
"render.complete",
|
|
163
|
-
RenderCompleteRuntimePayload
|
|
164
|
-
>;
|
|
165
|
-
export type MediaProcessingLifecycleRuntimeEvent = RuntimeEventEnvelope<
|
|
166
|
-
"media.processing.lifecycle",
|
|
167
|
-
MediaProcessingLifecycleRuntimePayload
|
|
168
|
-
>;
|
|
169
|
-
export type FileIngestLifecycleRuntimeEvent = RuntimeEventEnvelope<
|
|
170
|
-
"file.ingest.lifecycle",
|
|
171
|
-
FileIngestLifecycleRuntimePayload
|
|
172
|
-
>;
|
|
173
|
-
export type TranslationLifecycleRuntimeEvent = RuntimeEventEnvelope<
|
|
174
|
-
"translation.lifecycle",
|
|
175
|
-
TranslationLifecycleRuntimePayload
|
|
176
|
-
>;
|
|
177
|
-
export type RuntimeErrorEvent = RuntimeEventEnvelope<
|
|
178
|
-
"runtime.error",
|
|
179
|
-
RuntimeErrorPayload
|
|
180
|
-
>;
|
|
181
|
-
|
|
182
|
-
export type EditorRuntimeEvent =
|
|
183
|
-
| OgGenerationLifecycleRuntimeEvent
|
|
184
|
-
| RenderCompleteRuntimeEvent
|
|
185
|
-
| MediaProcessingLifecycleRuntimeEvent
|
|
186
|
-
| FileIngestLifecycleRuntimeEvent
|
|
187
|
-
| TranslationLifecycleRuntimeEvent
|
|
188
|
-
| RuntimeErrorEvent;
|
|
1
|
+
import * as z from "zod/mini";
|
|
189
2
|
|
|
190
3
|
export const runtimeEntityTypeSchema = z.enum([
|
|
191
4
|
"post",
|
|
@@ -237,311 +50,332 @@ export const ogGenerationRuntimeStatusSchema = z.enum([
|
|
|
237
50
|
]);
|
|
238
51
|
|
|
239
52
|
export const ogGenerationLifecycleRuntimePayloadSchema = z
|
|
240
|
-
.
|
|
241
|
-
generationId: z.string().
|
|
242
|
-
runId: z.string().
|
|
53
|
+
.strictObject({
|
|
54
|
+
generationId: z.string().check(z.minLength(1)),
|
|
55
|
+
runId: z.string().check(z.minLength(1)),
|
|
243
56
|
status: ogGenerationRuntimeStatusSchema,
|
|
244
|
-
assetId: z.string().
|
|
245
|
-
assetUrl: z.string().
|
|
246
|
-
errorCode: z.string().
|
|
247
|
-
error: z.string().
|
|
248
|
-
replacementGenerationId: z.string().
|
|
57
|
+
assetId: z.optional(z.string().check(z.minLength(1))),
|
|
58
|
+
assetUrl: z.optional(z.string().check(z.minLength(1))),
|
|
59
|
+
errorCode: z.optional(z.string().check(z.minLength(1))),
|
|
60
|
+
error: z.optional(z.string().check(z.minLength(1))),
|
|
61
|
+
replacementGenerationId: z.optional(z.string().check(z.minLength(1))),
|
|
249
62
|
})
|
|
250
|
-
.
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
63
|
+
.check(
|
|
64
|
+
z.superRefine((payload, ctx) => {
|
|
65
|
+
if (payload.status === "ready" && !payload.assetId) {
|
|
66
|
+
ctx.addIssue({
|
|
67
|
+
code: "custom",
|
|
68
|
+
path: ["assetId"],
|
|
69
|
+
message: "ready OG lifecycle requires assetId",
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
if (payload.status === "failed" && !payload.error) {
|
|
73
|
+
ctx.addIssue({
|
|
74
|
+
code: "custom",
|
|
75
|
+
path: ["error"],
|
|
76
|
+
message: "failed OG lifecycle requires error",
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (payload.status === "superseded" && !payload.replacementGenerationId) {
|
|
80
|
+
ctx.addIssue({
|
|
81
|
+
code: "custom",
|
|
82
|
+
path: ["replacementGenerationId"],
|
|
83
|
+
message: "superseded OG lifecycle requires replacementGenerationId",
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
if (payload.status !== "ready" && (payload.assetId || payload.assetUrl)) {
|
|
87
|
+
ctx.addIssue({
|
|
88
|
+
code: "custom",
|
|
89
|
+
path: ["assetId"],
|
|
90
|
+
message: "only ready OG lifecycle may include an asset",
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
if (payload.status !== "superseded" && payload.replacementGenerationId) {
|
|
94
|
+
ctx.addIssue({
|
|
95
|
+
code: "custom",
|
|
96
|
+
path: ["replacementGenerationId"],
|
|
97
|
+
message: "only superseded OG lifecycle may include a replacement",
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}),
|
|
101
|
+
);
|
|
288
102
|
|
|
289
|
-
export const mediaProcessingRuntimeOutputsSchema = z
|
|
290
|
-
.
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
})
|
|
297
|
-
.strict();
|
|
103
|
+
export const mediaProcessingRuntimeOutputsSchema = z.strictObject({
|
|
104
|
+
spectrogramAssetId: z.optional(z.string()),
|
|
105
|
+
thumbnailAssetId: z.optional(z.string()),
|
|
106
|
+
hlsGenerationId: z.optional(z.string()),
|
|
107
|
+
durationSeconds: z.optional(z.int().check(z.nonnegative())),
|
|
108
|
+
waveformAssetId: z.optional(z.string()),
|
|
109
|
+
});
|
|
298
110
|
|
|
299
111
|
export const mediaProcessingLifecycleRuntimePayloadSchema = z
|
|
300
|
-
.
|
|
301
|
-
fileId: z.string().
|
|
302
|
-
slotId: z.
|
|
303
|
-
attemptId: z.
|
|
112
|
+
.strictObject({
|
|
113
|
+
fileId: z.string().check(z.minLength(1)),
|
|
114
|
+
slotId: z.optional(z.string()),
|
|
115
|
+
attemptId: z.optional(z.string()),
|
|
304
116
|
status: mediaProcessingRuntimeStatusSchema,
|
|
305
|
-
percentage: z.
|
|
306
|
-
outputs:
|
|
307
|
-
error: z.
|
|
308
|
-
trackId: z.
|
|
309
|
-
releaseId: z.
|
|
117
|
+
percentage: z.optional(z.int().check(z.minimum(0), z.maximum(100))),
|
|
118
|
+
outputs: z.optional(mediaProcessingRuntimeOutputsSchema),
|
|
119
|
+
error: z.optional(z.string()),
|
|
120
|
+
trackId: z.optional(z.string()),
|
|
121
|
+
releaseId: z.optional(z.string()),
|
|
310
122
|
})
|
|
311
|
-
.
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
source: z.enum(["upload", "embed"]),
|
|
369
|
-
stage: z.enum([
|
|
370
|
-
"uploading",
|
|
371
|
-
"downloading",
|
|
372
|
-
"finalized",
|
|
373
|
-
"attached",
|
|
374
|
-
"completed",
|
|
375
|
-
"expired",
|
|
376
|
-
"failed",
|
|
377
|
-
"unknown",
|
|
378
|
-
]),
|
|
379
|
-
progress: z.number().int().min(0).max(100),
|
|
380
|
-
bytesCompleted: z.number().int().nonnegative().optional(),
|
|
381
|
-
bytesTotal: z.number().int().nonnegative().optional(),
|
|
382
|
-
fileName: z.string().optional(),
|
|
383
|
-
mimeType: z.string().optional(),
|
|
384
|
-
fileSize: z.number().int().nonnegative().optional(),
|
|
385
|
-
error: z.string().optional(),
|
|
386
|
-
trackId: z.string().optional(),
|
|
387
|
-
releaseId: z.string().optional(),
|
|
388
|
-
})
|
|
389
|
-
.strict();
|
|
123
|
+
.check(
|
|
124
|
+
z.superRefine((payload, ctx) => {
|
|
125
|
+
if (
|
|
126
|
+
payload.status === "processing" &&
|
|
127
|
+
typeof payload.percentage !== "number"
|
|
128
|
+
) {
|
|
129
|
+
ctx.addIssue({
|
|
130
|
+
code: "custom",
|
|
131
|
+
path: ["percentage"],
|
|
132
|
+
message: "processing media lifecycle requires percentage",
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
if (payload.status === "processing" && payload.outputs) {
|
|
136
|
+
ctx.addIssue({
|
|
137
|
+
code: "custom",
|
|
138
|
+
path: ["outputs"],
|
|
139
|
+
message: "processing media lifecycle must not include ready outputs",
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
if (payload.status === "ready" && !payload.outputs) {
|
|
143
|
+
ctx.addIssue({
|
|
144
|
+
code: "custom",
|
|
145
|
+
path: ["outputs"],
|
|
146
|
+
message: "ready media lifecycle requires outputs",
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
if (
|
|
150
|
+
payload.status === "ready" &&
|
|
151
|
+
typeof payload.percentage === "number"
|
|
152
|
+
) {
|
|
153
|
+
ctx.addIssue({
|
|
154
|
+
code: "custom",
|
|
155
|
+
path: ["percentage"],
|
|
156
|
+
message:
|
|
157
|
+
"ready media lifecycle must not include processing percentage",
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
if (payload.status === "failed" && payload.outputs) {
|
|
161
|
+
ctx.addIssue({
|
|
162
|
+
code: "custom",
|
|
163
|
+
path: ["outputs"],
|
|
164
|
+
message: "failed media lifecycle must not include ready outputs",
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
if (
|
|
168
|
+
payload.status === "failed" &&
|
|
169
|
+
typeof payload.percentage === "number"
|
|
170
|
+
) {
|
|
171
|
+
ctx.addIssue({
|
|
172
|
+
code: "custom",
|
|
173
|
+
path: ["percentage"],
|
|
174
|
+
message:
|
|
175
|
+
"failed media lifecycle must not include processing percentage",
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}),
|
|
179
|
+
);
|
|
390
180
|
|
|
391
|
-
const
|
|
392
|
-
|
|
393
|
-
"
|
|
394
|
-
"
|
|
395
|
-
"
|
|
396
|
-
"
|
|
181
|
+
export const fileIngestRuntimeSourceSchema = z.enum(["upload", "embed"]);
|
|
182
|
+
export const fileIngestRuntimeStageSchema = z.enum([
|
|
183
|
+
"uploading",
|
|
184
|
+
"downloading",
|
|
185
|
+
"finalized",
|
|
186
|
+
"attached",
|
|
187
|
+
"completed",
|
|
188
|
+
"expired",
|
|
189
|
+
"failed",
|
|
190
|
+
"unknown",
|
|
397
191
|
]);
|
|
398
192
|
|
|
399
|
-
const
|
|
400
|
-
.
|
|
193
|
+
export const fileIngestLifecycleRuntimePayloadSchema = z.strictObject({
|
|
194
|
+
fileId: z.string().check(z.minLength(1)),
|
|
195
|
+
uploadId: z.optional(z.string()),
|
|
196
|
+
mediaKind: z.optional(z.string()),
|
|
197
|
+
slotId: z.optional(z.string()),
|
|
198
|
+
attemptId: z.optional(z.string()),
|
|
199
|
+
source: fileIngestRuntimeSourceSchema,
|
|
200
|
+
stage: fileIngestRuntimeStageSchema,
|
|
201
|
+
progress: z.int().check(z.minimum(0), z.maximum(100)),
|
|
202
|
+
bytesCompleted: z.optional(z.int().check(z.nonnegative())),
|
|
203
|
+
bytesTotal: z.optional(z.int().check(z.nonnegative())),
|
|
204
|
+
fileName: z.optional(z.string()),
|
|
205
|
+
mimeType: z.optional(z.string()),
|
|
206
|
+
fileSize: z.optional(z.int().check(z.nonnegative())),
|
|
207
|
+
error: z.optional(z.string()),
|
|
208
|
+
trackId: z.optional(z.string()),
|
|
209
|
+
releaseId: z.optional(z.string()),
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
const localeScopedOgEntityTypes = new Set<
|
|
213
|
+
z.infer<typeof ogGenerationRuntimeEntityTypeSchema>
|
|
214
|
+
>(["post", "page", "form", "privacy", "terms"]);
|
|
215
|
+
|
|
216
|
+
export const ogGenerationLifecycleRuntimeEventSchema = z
|
|
217
|
+
.strictObject({
|
|
401
218
|
version: z.literal(1),
|
|
402
219
|
kind: z.literal("og.lifecycle"),
|
|
403
220
|
entityType: ogGenerationRuntimeEntityTypeSchema,
|
|
404
|
-
entityId: z.string().
|
|
405
|
-
locale: z.string().
|
|
406
|
-
correlationId: z.string().
|
|
407
|
-
sequence: z.
|
|
408
|
-
timestampMs: z.
|
|
221
|
+
entityId: z.string().check(z.minLength(1)),
|
|
222
|
+
locale: z.optional(z.string().check(z.minLength(1))),
|
|
223
|
+
correlationId: z.string().check(z.minLength(1)),
|
|
224
|
+
sequence: z.optional(z.int()),
|
|
225
|
+
timestampMs: z.int(),
|
|
409
226
|
payload: ogGenerationLifecycleRuntimePayloadSchema,
|
|
410
227
|
})
|
|
411
|
-
.
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
228
|
+
.check(
|
|
229
|
+
z.superRefine((event, ctx) => {
|
|
230
|
+
const requiresLocale = localeScopedOgEntityTypes.has(event.entityType);
|
|
231
|
+
if (requiresLocale && !event.locale) {
|
|
232
|
+
ctx.addIssue({
|
|
233
|
+
code: "custom",
|
|
234
|
+
path: ["locale"],
|
|
235
|
+
message: `${event.entityType} OG lifecycle requires a locale target`,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
if (!requiresLocale && event.locale) {
|
|
239
|
+
ctx.addIssue({
|
|
240
|
+
code: "custom",
|
|
241
|
+
path: ["locale"],
|
|
242
|
+
message: `${event.entityType} OG lifecycle requires an entity target`,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
if (event.correlationId !== event.payload.generationId) {
|
|
246
|
+
ctx.addIssue({
|
|
247
|
+
code: "custom",
|
|
248
|
+
path: ["correlationId"],
|
|
249
|
+
message: "OG lifecycle correlationId must equal payload.generationId",
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}),
|
|
253
|
+
);
|
|
436
254
|
|
|
437
|
-
export const
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
255
|
+
export const translationLifecycleRuntimeStatusSchema = z.literal("failed");
|
|
256
|
+
|
|
257
|
+
export const translationLifecycleRuntimePayloadSchema = z.strictObject({
|
|
258
|
+
jobId: z.string().check(z.minLength(1)),
|
|
259
|
+
targetLocale: z.string().check(z.minLength(1)),
|
|
260
|
+
status: translationLifecycleRuntimeStatusSchema,
|
|
261
|
+
error: z.optional(z.string()),
|
|
262
|
+
});
|
|
445
263
|
|
|
446
264
|
export const editorRuntimeEventSchema = z.discriminatedUnion("kind", [
|
|
447
265
|
ogGenerationLifecycleRuntimeEventSchema,
|
|
448
|
-
z
|
|
449
|
-
.
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
.
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
.object({
|
|
482
|
-
version: z.literal(1),
|
|
483
|
-
kind: z.literal("file.ingest.lifecycle"),
|
|
484
|
-
entityType: runtimeEntityTypeSchema,
|
|
485
|
-
entityId: z.string().min(1),
|
|
486
|
-
locale: z.string().optional(),
|
|
487
|
-
correlationId: z.string().optional(),
|
|
488
|
-
sequence: z.number().int().optional(),
|
|
489
|
-
timestampMs: z.number().int(),
|
|
490
|
-
payload: fileIngestLifecycleRuntimePayloadSchema,
|
|
491
|
-
})
|
|
492
|
-
.strict(),
|
|
493
|
-
z
|
|
494
|
-
.object({
|
|
495
|
-
version: z.literal(1),
|
|
496
|
-
kind: z.literal("translation.lifecycle"),
|
|
497
|
-
entityType: runtimeEntityTypeSchema,
|
|
498
|
-
entityId: z.string().min(1),
|
|
499
|
-
locale: z.string().optional(),
|
|
500
|
-
correlationId: z.string().optional(),
|
|
501
|
-
sequence: z.number().int().optional(),
|
|
502
|
-
timestampMs: z.number().int(),
|
|
503
|
-
payload: translationLifecycleRuntimePayloadSchema,
|
|
504
|
-
})
|
|
505
|
-
.strict(),
|
|
506
|
-
z
|
|
507
|
-
.object({
|
|
508
|
-
version: z.literal(1),
|
|
509
|
-
kind: z.literal("runtime.error"),
|
|
510
|
-
entityType: runtimeEntityTypeSchema,
|
|
511
|
-
entityId: z.string().min(1),
|
|
512
|
-
locale: z.string().optional(),
|
|
513
|
-
correlationId: z.string().optional(),
|
|
514
|
-
sequence: z.number().int().optional(),
|
|
515
|
-
timestampMs: z.number().int(),
|
|
516
|
-
payload: z
|
|
517
|
-
.object({
|
|
518
|
-
code: z.string().min(1),
|
|
519
|
-
message: z.string(),
|
|
520
|
-
retryable: z.boolean().optional(),
|
|
521
|
-
source: z.enum(["backend", "collab", "worker"]).optional(),
|
|
522
|
-
details: z
|
|
523
|
-
.record(
|
|
524
|
-
z.string(),
|
|
525
|
-
z.union([z.string(), z.number(), z.boolean(), z.null()]),
|
|
526
|
-
)
|
|
527
|
-
.optional(),
|
|
528
|
-
})
|
|
529
|
-
.strict(),
|
|
530
|
-
})
|
|
531
|
-
.strict(),
|
|
266
|
+
z.strictObject({
|
|
267
|
+
version: z.literal(1),
|
|
268
|
+
kind: z.literal("media.processing.lifecycle"),
|
|
269
|
+
entityType: runtimeEntityTypeSchema,
|
|
270
|
+
entityId: z.string().check(z.minLength(1)),
|
|
271
|
+
locale: z.optional(z.string()),
|
|
272
|
+
correlationId: z.optional(z.string()),
|
|
273
|
+
sequence: z.optional(z.int()),
|
|
274
|
+
timestampMs: z.int(),
|
|
275
|
+
payload: mediaProcessingLifecycleRuntimePayloadSchema,
|
|
276
|
+
}),
|
|
277
|
+
z.strictObject({
|
|
278
|
+
version: z.literal(1),
|
|
279
|
+
kind: z.literal("file.ingest.lifecycle"),
|
|
280
|
+
entityType: runtimeEntityTypeSchema,
|
|
281
|
+
entityId: z.string().check(z.minLength(1)),
|
|
282
|
+
locale: z.optional(z.string()),
|
|
283
|
+
correlationId: z.optional(z.string()),
|
|
284
|
+
sequence: z.optional(z.int()),
|
|
285
|
+
timestampMs: z.int(),
|
|
286
|
+
payload: fileIngestLifecycleRuntimePayloadSchema,
|
|
287
|
+
}),
|
|
288
|
+
z.strictObject({
|
|
289
|
+
version: z.literal(1),
|
|
290
|
+
kind: z.literal("translation.lifecycle"),
|
|
291
|
+
entityType: runtimeEntityTypeSchema,
|
|
292
|
+
entityId: z.string().check(z.minLength(1)),
|
|
293
|
+
locale: z.optional(z.string()),
|
|
294
|
+
correlationId: z.optional(z.string()),
|
|
295
|
+
sequence: z.optional(z.int()),
|
|
296
|
+
timestampMs: z.int(),
|
|
297
|
+
payload: translationLifecycleRuntimePayloadSchema,
|
|
298
|
+
}),
|
|
532
299
|
]);
|
|
533
300
|
|
|
534
301
|
export function parseEditorRuntimeEventMessage(
|
|
535
302
|
payload: string,
|
|
536
303
|
): EditorRuntimeEvent | null {
|
|
537
304
|
try {
|
|
538
|
-
const
|
|
539
|
-
|
|
540
|
-
if (!result.success) {
|
|
541
|
-
return null;
|
|
542
|
-
}
|
|
543
|
-
return result.data as EditorRuntimeEvent;
|
|
305
|
+
const result = editorRuntimeEventSchema.safeParse(JSON.parse(payload));
|
|
306
|
+
return result.success ? result.data : null;
|
|
544
307
|
} catch {
|
|
545
308
|
return null;
|
|
546
309
|
}
|
|
547
310
|
}
|
|
311
|
+
|
|
312
|
+
// ---- Types: inferred from the schemas above, the single definition of every runtime event ----
|
|
313
|
+
|
|
314
|
+
export type RuntimeEntityType = z.infer<typeof runtimeEntityTypeSchema>;
|
|
315
|
+
export type TranslationLifecycleRuntimeStatus = z.infer<
|
|
316
|
+
typeof translationLifecycleRuntimeStatusSchema
|
|
317
|
+
>;
|
|
318
|
+
export type MediaProcessingRuntimeStatus = z.infer<
|
|
319
|
+
typeof mediaProcessingRuntimeStatusSchema
|
|
320
|
+
>;
|
|
321
|
+
export type OgGenerationRuntimeEntityType = z.infer<
|
|
322
|
+
typeof ogGenerationRuntimeEntityTypeSchema
|
|
323
|
+
>;
|
|
324
|
+
export type OgGenerationRuntimeStatus = z.infer<
|
|
325
|
+
typeof ogGenerationRuntimeStatusSchema
|
|
326
|
+
>;
|
|
327
|
+
export type FileIngestRuntimeSource = z.infer<
|
|
328
|
+
typeof fileIngestRuntimeSourceSchema
|
|
329
|
+
>;
|
|
330
|
+
export type FileIngestRuntimeStage = z.infer<
|
|
331
|
+
typeof fileIngestRuntimeStageSchema
|
|
332
|
+
>;
|
|
333
|
+
export type OgGenerationLifecycleRuntimePayload = z.infer<
|
|
334
|
+
typeof ogGenerationLifecycleRuntimePayloadSchema
|
|
335
|
+
>;
|
|
336
|
+
export type MediaProcessingRuntimeOutputs = z.infer<
|
|
337
|
+
typeof mediaProcessingRuntimeOutputsSchema
|
|
338
|
+
>;
|
|
339
|
+
export type MediaProcessingLifecycleRuntimePayload = z.infer<
|
|
340
|
+
typeof mediaProcessingLifecycleRuntimePayloadSchema
|
|
341
|
+
>;
|
|
342
|
+
export type FileIngestLifecycleRuntimePayload = z.infer<
|
|
343
|
+
typeof fileIngestLifecycleRuntimePayloadSchema
|
|
344
|
+
>;
|
|
345
|
+
export type TranslationLifecycleRuntimePayload = z.infer<
|
|
346
|
+
typeof translationLifecycleRuntimePayloadSchema
|
|
347
|
+
>;
|
|
348
|
+
export type EditorRuntimeEvent = z.infer<typeof editorRuntimeEventSchema>;
|
|
349
|
+
export type OgGenerationLifecycleRuntimeEvent = Extract<
|
|
350
|
+
EditorRuntimeEvent,
|
|
351
|
+
{ kind: "og.lifecycle" }
|
|
352
|
+
>;
|
|
353
|
+
export type MediaProcessingLifecycleRuntimeEvent = Extract<
|
|
354
|
+
EditorRuntimeEvent,
|
|
355
|
+
{ kind: "media.processing.lifecycle" }
|
|
356
|
+
>;
|
|
357
|
+
export type FileIngestLifecycleRuntimeEvent = Extract<
|
|
358
|
+
EditorRuntimeEvent,
|
|
359
|
+
{ kind: "file.ingest.lifecycle" }
|
|
360
|
+
>;
|
|
361
|
+
export type TranslationLifecycleRuntimeEvent = Extract<
|
|
362
|
+
EditorRuntimeEvent,
|
|
363
|
+
{ kind: "translation.lifecycle" }
|
|
364
|
+
>;
|
|
365
|
+
|
|
366
|
+
export function isMediaProcessingRuntimeReady(payload: {
|
|
367
|
+
status?: MediaProcessingRuntimeStatus | null;
|
|
368
|
+
}): boolean {
|
|
369
|
+
return payload.status === "ready";
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
export function isOgGenerationRuntimeTerminal(
|
|
373
|
+
status: OgGenerationRuntimeStatus,
|
|
374
|
+
): boolean {
|
|
375
|
+
return (
|
|
376
|
+
status === "ready" ||
|
|
377
|
+
status === "failed" ||
|
|
378
|
+
status === "superseded" ||
|
|
379
|
+
status === "cancelled"
|
|
380
|
+
);
|
|
381
|
+
}
|