@editframe/api 0.11.0-beta.9 → 0.12.0-beta.2

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.
Files changed (51) hide show
  1. package/dist/CHUNK_SIZE_BYTES.js +1 -1
  2. package/dist/ProgressIterator.d.ts +25 -0
  3. package/dist/ProgressIterator.js +99 -0
  4. package/dist/ProgressIterator.test.d.ts +1 -0
  5. package/dist/StreamEventSource.d.ts +50 -0
  6. package/dist/StreamEventSource.js +130 -0
  7. package/dist/StreamEventSource.test.d.ts +1 -0
  8. package/dist/client.d.ts +6 -3
  9. package/dist/client.js +20 -6
  10. package/dist/index.d.ts +7 -5
  11. package/dist/index.js +20 -11
  12. package/dist/readableFromBuffers.d.ts +1 -2
  13. package/dist/resources/caption-file.d.ts +7 -3
  14. package/dist/resources/caption-file.js +22 -2
  15. package/dist/resources/image-file.d.ts +7 -3
  16. package/dist/resources/image-file.js +19 -0
  17. package/dist/resources/isobmff-file.d.ts +16 -3
  18. package/dist/resources/isobmff-file.js +37 -2
  19. package/dist/resources/isobmff-track.d.ts +5 -7
  20. package/dist/resources/isobmff-track.js +44 -1
  21. package/dist/resources/process-isobmff.d.ts +12 -0
  22. package/dist/resources/process-isobmff.js +22 -0
  23. package/dist/resources/process-isobmff.test.d.ts +1 -0
  24. package/dist/resources/renders.d.ts +10 -5
  25. package/dist/resources/renders.js +21 -2
  26. package/dist/resources/transcriptions.d.ts +24 -0
  27. package/dist/resources/transcriptions.js +45 -0
  28. package/dist/resources/transcriptions.test.d.ts +1 -0
  29. package/dist/resources/unprocessed-file.d.ts +12 -53
  30. package/dist/resources/unprocessed-file.js +31 -130
  31. package/dist/streamChunker.d.ts +1 -2
  32. package/dist/streamChunker.js +20 -9
  33. package/dist/uploadChunks.d.ts +1 -2
  34. package/dist/uploadChunks.js +1 -4
  35. package/package.json +3 -2
  36. package/src/resources/caption-file.test.ts +57 -6
  37. package/src/resources/caption-file.ts +34 -5
  38. package/src/resources/image-file.test.ts +56 -5
  39. package/src/resources/image-file.ts +32 -4
  40. package/src/resources/isobmff-file.test.ts +57 -6
  41. package/src/resources/isobmff-file.ts +64 -5
  42. package/src/resources/isobmff-track.test.ts +3 -3
  43. package/src/resources/isobmff-track.ts +50 -5
  44. package/src/resources/process-isobmff.test.ts +62 -0
  45. package/src/resources/process-isobmff.ts +33 -0
  46. package/src/resources/renders.test.ts +51 -6
  47. package/src/resources/renders.ts +34 -5
  48. package/src/resources/transcriptions.test.ts +49 -0
  49. package/src/resources/transcriptions.ts +64 -0
  50. package/src/resources/unprocessed-file.test.ts +19 -430
  51. package/src/resources/unprocessed-file.ts +45 -161
@@ -1,69 +1,37 @@
1
- import { createReadStream } from "node:fs";
2
- import { stat } from "node:fs/promises";
3
- import { basename } from "node:path";
4
- import { Readable } from "node:stream";
5
-
6
1
  import debug from "debug";
7
2
  import { z } from "zod";
8
3
 
9
- import { md5Buffer, md5FilePath } from "@editframe/assets";
10
-
11
4
  import type { Client } from "../client.ts";
12
- import {
13
- type IteratorWithPromise,
14
- type UploadChunkEvent,
15
- uploadChunks,
16
- } from "../uploadChunks.ts";
5
+ import { uploadChunks } from "../uploadChunks.ts";
17
6
 
18
7
  const log = debug("ef:api:unprocessed-file");
19
8
 
20
- const FileProcessor = z.union([
21
- z.literal("isobmff"),
22
- z.literal("image"),
23
- z.literal("captions"),
24
- z.string(),
25
- ]);
26
-
27
- const FileProcessors = z.array(FileProcessor).refine(
28
- (value) => {
29
- return new Set(value).size === value.length;
30
- },
31
- {
32
- message: "Processors list must not include duplicates",
33
- },
34
- );
35
-
36
9
  const MAX_FILE_SIZE = 1024 * 1024 * 1024; // 1GiB
37
10
 
38
11
  export const CreateUnprocessedFilePayload = z.object({
39
12
  md5: z.string(),
40
13
  filename: z.string(),
41
- processes: FileProcessors.optional(),
42
14
  byte_size: z.number().int().max(MAX_FILE_SIZE),
43
15
  });
44
16
 
45
- export const UpdateUnprocessedFilePayload = z.object({
46
- processes: FileProcessors.optional(),
47
- });
17
+ export const UpdateUnprocessedFilePayload = z.object({});
48
18
 
49
- export interface CreateUnprocessedFileResult {
19
+ interface UnprocessedFile {
50
20
  byte_size: number;
51
21
  next_byte: number;
52
22
  complete: boolean;
53
23
  id: string;
54
24
  md5: string;
55
- processes: z.infer<typeof FileProcessors> & string[];
56
- asset_id: string;
57
25
  }
58
26
 
59
- export interface UpdateUnprocessedFileResult {
60
- byte_size?: number;
61
- next_byte: number;
62
- complete: boolean;
27
+ export interface CreateUnprocessedFileResult extends UnprocessedFile {}
28
+
29
+ export interface LookupUnprocessedFileByMd5Result extends UnprocessedFile {}
30
+
31
+ export interface UpdateUnprocessedFileResult extends UnprocessedFile {}
32
+
33
+ export interface ProcessIsobmffFileResult {
63
34
  id: string;
64
- md5: string;
65
- processes: z.infer<typeof FileProcessors>;
66
- asset_id: string;
67
35
  }
68
36
 
69
37
  export const createUnprocessedFile = async (
@@ -96,36 +64,10 @@ export const createUnprocessedFile = async (
96
64
  );
97
65
  };
98
66
 
99
- export const updateUnprocessedFile = async (
100
- client: Client,
101
- fileId: string,
102
- payload: Partial<z.infer<typeof UpdateUnprocessedFilePayload>>,
103
- ) => {
104
- log("Updating unprocessed file", fileId, payload);
105
- UpdateUnprocessedFilePayload.parse(payload);
106
- const response = await client.authenticatedFetch(
107
- `/api/v1/unprocessed_files/${fileId}`,
108
- {
109
- method: "POST",
110
- body: JSON.stringify(payload),
111
- },
112
- );
113
-
114
- log("Unprocessed file updated", response);
115
-
116
- if (response.ok) {
117
- return (await response.json()) as UpdateUnprocessedFileResult;
118
- }
119
-
120
- throw new Error(
121
- `Failed to update unprocessed file ${response.status} ${response.statusText}`,
122
- );
123
- };
124
-
125
67
  export const uploadUnprocessedFile = (
126
68
  client: Client,
127
69
  fileId: string,
128
- fileStream: Readable,
70
+ fileStream: ReadableStream,
129
71
  fileSize: number,
130
72
  ) => {
131
73
  log("Uploading unprocessed file", fileId);
@@ -138,104 +80,46 @@ export const uploadUnprocessedFile = (
138
80
  });
139
81
  };
140
82
 
141
- const processResource = (
83
+ export const lookupUnprocessedFileByMd5 = async (
142
84
  client: Client,
143
- filename: string,
144
85
  md5: string,
145
- byteSize: number,
146
- processor: z.infer<typeof FileProcessor>,
147
- doUpload: (id: string) => IteratorWithPromise<UploadChunkEvent>,
148
- ) => {
149
- log("Processing", { filename, md5, byteSize, processor });
86
+ ): Promise<LookupUnprocessedFileByMd5Result | null> => {
87
+ const response = await client.authenticatedFetch(
88
+ `/api/v1/unprocessed_files/md5/${md5}`,
89
+ {
90
+ method: "GET",
91
+ },
92
+ );
150
93
 
151
- const createFilePromise = createUnprocessedFile(client, {
152
- md5: md5,
153
- processes: [],
154
- filename,
155
- byte_size: byteSize,
156
- });
94
+ if (response.ok) {
95
+ return (await response.json()) as LookupUnprocessedFileByMd5Result;
96
+ }
157
97
 
158
- return {
159
- async *progress() {
160
- const unprocessedFile = await createFilePromise;
161
- if (unprocessedFile.complete) {
162
- yield { type: "progress", progress: 0 };
163
- yield { type: "progress", progress: 1 };
164
- }
165
- yield* doUpload(unprocessedFile.id);
166
- },
167
- file: async () => {
168
- const unprocessedFile = await createFilePromise;
169
- if (unprocessedFile.complete) {
170
- return unprocessedFile;
171
- }
172
- await doUpload(unprocessedFile.id).whenUploaded();
173
- const fileInformation = await updateUnprocessedFile(
174
- client,
175
- unprocessedFile.id,
176
- {
177
- processes: [processor],
178
- },
179
- );
180
- log("File processed", fileInformation);
181
- return fileInformation;
182
- },
183
- };
184
- };
98
+ if (response.status === 404) {
99
+ return null;
100
+ }
185
101
 
186
- const buildBufferProcessor = (processor: z.infer<typeof FileProcessor>) => {
187
- return (client: Client, buffer: Buffer, filename = "buffer") => {
188
- log(`Processing file buffer: ${processor}`, filename);
189
- const md5 = md5Buffer(buffer);
190
-
191
- return processResource(
192
- client,
193
- filename,
194
- md5,
195
- buffer.byteLength,
196
- processor,
197
- (id: string) => {
198
- const readStream = new Readable({
199
- read() {
200
- readStream.push(buffer);
201
- readStream.push(null);
202
- },
203
- });
204
-
205
- return uploadUnprocessedFile(client, id, readStream, buffer.byteLength);
206
- },
207
- );
208
- };
102
+ throw new Error(
103
+ `Failed to lookup unprocessed file by md5 ${md5} ${response.status} ${response.statusText}`,
104
+ );
209
105
  };
210
106
 
211
- const buildFileProcessor = (processor: z.infer<typeof FileProcessor>) => {
212
- return (client: Client, filePath: string) => {
213
- const processPromise = async () => {
214
- const [md5, { size: byteSize }] = await Promise.all([
215
- md5FilePath(filePath),
216
- stat(filePath),
217
- ]);
218
- return processResource(
219
- client,
220
- basename(filePath),
221
- md5,
222
- byteSize,
223
- processor,
224
- (id: string) => {
225
- const readStream = createReadStream(filePath);
226
- return uploadUnprocessedFile(client, id, readStream, byteSize);
227
- },
228
- );
229
- };
230
- return {
231
- progress: async () => (await processPromise()).progress(),
232
- file: async () => (await processPromise()).file(),
233
- };
234
- };
235
- };
107
+ export const processIsobmffFile = async (
108
+ client: Client,
109
+ unprocessedFileId: LookupUnprocessedFileByMd5Result["id"],
110
+ ) => {
111
+ const response = await client.authenticatedFetch(
112
+ `/api/v1/unprocessed_files/${unprocessedFileId}/isobmff`,
113
+ {
114
+ method: "POST",
115
+ },
116
+ );
236
117
 
237
- export const processAVFileBuffer = buildBufferProcessor("isobmff");
238
- export const processAVFile = buildFileProcessor("isobmff");
118
+ if (response.ok) {
119
+ return (await response.json()) as ProcessIsobmffFileResult;
120
+ }
239
121
 
240
- export const processImageFileBuffer = buildBufferProcessor("image");
241
- export const processImageFile = buildFileProcessor("image");
122
+ throw new Error(
123
+ `Failed to process isobmff file ${response.status} ${response.statusText}`,
124
+ );
125
+ };