@editframe/api 0.12.0-beta.2 → 0.12.0-beta.21

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 (111) hide show
  1. package/dist/ProgressIterator.d.ts +1 -1
  2. package/dist/ProgressIterator.js +14 -2
  3. package/dist/StreamEventSource.d.ts +2 -3
  4. package/dist/StreamEventSource.js +0 -2
  5. package/dist/client.d.ts +1 -1
  6. package/dist/index.d.ts +13 -10
  7. package/dist/index.js +5 -3
  8. package/dist/node.d.ts +6 -0
  9. package/dist/node.js +92 -0
  10. package/dist/resources/caption-file.d.ts +32 -4
  11. package/dist/resources/caption-file.js +9 -0
  12. package/dist/resources/image-file.d.ts +35 -11
  13. package/dist/resources/image-file.js +22 -4
  14. package/dist/resources/isobmff-file.d.ts +37 -4
  15. package/dist/resources/isobmff-file.js +20 -0
  16. package/dist/resources/isobmff-track.d.ts +277 -13
  17. package/dist/resources/isobmff-track.js +20 -18
  18. package/dist/resources/process-isobmff.d.ts +2 -2
  19. package/dist/resources/renders.d.ts +9 -8
  20. package/dist/resources/transcriptions.d.ts +4 -3
  21. package/dist/resources/unprocessed-file.d.ts +9 -8
  22. package/dist/resources/unprocessed-file.js +8 -8
  23. package/dist/resources/url-token.d.ts +1 -1
  24. package/dist/uploadChunks.d.ts +4 -1
  25. package/dist/utils/assertTypesMatch.d.ts +3 -0
  26. package/dist/utils/createReadableStreamFromReadable.d.ts +4 -0
  27. package/dist/utils/createReadableStreamFromReadable.js +82 -0
  28. package/docs/packages/api/docs/.nojekyll +1 -0
  29. package/docs/packages/api/docs/assets/highlight.css +71 -0
  30. package/docs/packages/api/docs/assets/icons.js +18 -0
  31. package/docs/packages/api/docs/assets/icons.svg +1 -0
  32. package/docs/packages/api/docs/assets/main.js +60 -0
  33. package/docs/packages/api/docs/assets/navigation.js +1 -0
  34. package/docs/packages/api/docs/assets/search.js +1 -0
  35. package/docs/packages/api/docs/assets/style.css +1493 -0
  36. package/docs/packages/api/docs/classes/Client.html +4 -0
  37. package/docs/packages/api/docs/functions/createCaptionFile.html +8 -0
  38. package/docs/packages/api/docs/functions/createISOBMFFFile.html +1 -0
  39. package/docs/packages/api/docs/functions/createISOBMFFTrack.html +1 -0
  40. package/docs/packages/api/docs/functions/createImageFile.html +1 -0
  41. package/docs/packages/api/docs/functions/createRender.html +1 -0
  42. package/docs/packages/api/docs/functions/createTranscription.html +1 -0
  43. package/docs/packages/api/docs/functions/createURLToken.html +1 -0
  44. package/docs/packages/api/docs/functions/createUnprocessedFile.html +1 -0
  45. package/docs/packages/api/docs/functions/getISOBMFFFileTranscription.html +1 -0
  46. package/docs/packages/api/docs/functions/getIsobmffProcessInfo.html +1 -0
  47. package/docs/packages/api/docs/functions/getIsobmffProcessProgress.html +1 -0
  48. package/docs/packages/api/docs/functions/getTranscriptionInfo.html +1 -0
  49. package/docs/packages/api/docs/functions/getTranscriptionProgress.html +1 -0
  50. package/docs/packages/api/docs/functions/lookupCaptionFileByMd5.html +1 -0
  51. package/docs/packages/api/docs/functions/lookupISOBMFFFileByMd5.html +1 -0
  52. package/docs/packages/api/docs/functions/lookupImageFileByMd5.html +1 -0
  53. package/docs/packages/api/docs/functions/lookupRenderByMd5.html +1 -0
  54. package/docs/packages/api/docs/functions/lookupUnprocessedFileByMd5.html +1 -0
  55. package/docs/packages/api/docs/functions/processIsobmffFile.html +1 -0
  56. package/docs/packages/api/docs/functions/transcribeISOBMFFFile.html +1 -0
  57. package/docs/packages/api/docs/functions/uploadCaptionFile.html +1 -0
  58. package/docs/packages/api/docs/functions/uploadFragmentIndex.html +1 -0
  59. package/docs/packages/api/docs/functions/uploadISOBMFFTrack.html +1 -0
  60. package/docs/packages/api/docs/functions/uploadImageFile.html +1 -0
  61. package/docs/packages/api/docs/functions/uploadRender.html +1 -0
  62. package/docs/packages/api/docs/functions/uploadUnprocessedReadableStream.html +1 -0
  63. package/docs/packages/api/docs/index.html +39 -0
  64. package/docs/packages/api/docs/interfaces/CreateCaptionFileResult.html +4 -0
  65. package/docs/packages/api/docs/interfaces/CreateISOBMFFFileResult.html +5 -0
  66. package/docs/packages/api/docs/interfaces/CreateISOBMFFTrackResult.html +6 -0
  67. package/docs/packages/api/docs/interfaces/CreateImageFileResult.html +5 -0
  68. package/docs/packages/api/docs/interfaces/CreateRenderResult.html +4 -0
  69. package/docs/packages/api/docs/interfaces/CreateTranscriptionResult.html +3 -0
  70. package/docs/packages/api/docs/interfaces/CreateUnprocessedFileResult.html +6 -0
  71. package/docs/packages/api/docs/interfaces/GetISOBMFFFileTranscriptionResult.html +4 -0
  72. package/docs/packages/api/docs/interfaces/IsobmffProcessInfoResult.html +7 -0
  73. package/docs/packages/api/docs/interfaces/LookupCaptionFileByMd5Result.html +4 -0
  74. package/docs/packages/api/docs/interfaces/LookupISOBMFFFileByMd5Result.html +5 -0
  75. package/docs/packages/api/docs/interfaces/LookupImageFileByMd5Result.html +5 -0
  76. package/docs/packages/api/docs/interfaces/LookupRenderByMd5Result.html +4 -0
  77. package/docs/packages/api/docs/interfaces/LookupUnprocessedFileByMd5Result.html +6 -0
  78. package/docs/packages/api/docs/interfaces/ProcessIsobmffFileResult.html +2 -0
  79. package/docs/packages/api/docs/interfaces/TranscribeISOBMFFFileResult.html +4 -0
  80. package/docs/packages/api/docs/interfaces/TranscriptionInfoResult.html +3 -0
  81. package/docs/packages/api/docs/interfaces/URLTokenResult.html +2 -0
  82. package/docs/packages/api/docs/modules.html +54 -0
  83. package/docs/packages/api/docs/variables/CreateCaptionFilePayload.html +1 -0
  84. package/docs/packages/api/docs/variables/CreateISOBMFFFilePayload.html +1 -0
  85. package/docs/packages/api/docs/variables/CreateISOBMFFTrackPayload.html +1 -0
  86. package/docs/packages/api/docs/variables/CreateImageFilePayload.html +1 -0
  87. package/docs/packages/api/docs/variables/CreateRenderPayload.html +1 -0
  88. package/docs/packages/api/docs/variables/CreateTranscriptionPayload.html +1 -0
  89. package/docs/packages/api/docs/variables/CreateUnprocessedFilePayload.html +1 -0
  90. package/docs/packages/api/docs/variables/TranscribeISOBMFFFilePayload.html +1 -0
  91. package/package.json +12 -4
  92. package/src/resources/caption-file.test.ts +3 -3
  93. package/src/resources/caption-file.ts +31 -2
  94. package/src/resources/image-file.test.ts +6 -9
  95. package/src/resources/image-file.ts +32 -8
  96. package/src/resources/isobmff-file.test.ts +3 -3
  97. package/src/resources/isobmff-file.ts +58 -2
  98. package/src/resources/isobmff-track.test.ts +4 -4
  99. package/src/resources/isobmff-track.ts +33 -21
  100. package/src/resources/process-isobmff.test.ts +3 -3
  101. package/src/resources/process-isobmff.ts +2 -2
  102. package/src/resources/renders.test.ts +3 -3
  103. package/src/resources/renders.ts +3 -2
  104. package/src/resources/transcriptions.test.ts +2 -2
  105. package/src/resources/transcriptions.ts +7 -3
  106. package/src/resources/unprocessed-file.test.ts +8 -10
  107. package/src/resources/unprocessed-file.ts +21 -16
  108. package/src/resources/url-token.test.ts +3 -3
  109. package/src/resources/url-token.ts +1 -1
  110. package/src/utils/assertTypesMatch.ts +10 -0
  111. package/src/utils/createReadableStreamFromReadable.ts +117 -0
@@ -2,11 +2,11 @@ import { describe, expect, test } from "vitest";
2
2
  import {
3
3
  getIsobmffProcessInfo,
4
4
  getIsobmffProcessProgress,
5
- } from "./process-isobmff.ts";
5
+ } from "./process-isobmff.js";
6
6
 
7
- import { useMSW } from "TEST/useMSW.ts";
7
+ import { useMSW } from "TEST/useMSW.js";
8
8
  import { http, HttpResponse } from "msw";
9
- import { Client } from "../client.ts";
9
+ import { Client } from "../client.js";
10
10
 
11
11
  const client = new Client("ef_TEST_TOKEN", "http://localhost");
12
12
 
@@ -1,5 +1,5 @@
1
- import { ProgressIterator } from "../ProgressIterator.ts";
2
- import type { Client } from "../client.ts";
1
+ import { ProgressIterator } from "../ProgressIterator.js";
2
+ import type { Client } from "../client.js";
3
3
 
4
4
  export interface IsobmffProcessInfoResult {
5
5
  id: string;
@@ -2,9 +2,9 @@ import { http, HttpResponse } from "msw";
2
2
  import { setupServer } from "msw/node";
3
3
  import { afterAll, afterEach, beforeAll, describe, expect, test } from "vitest";
4
4
 
5
- import { Client } from "../client.ts";
6
- import { webReadableFromBuffers } from "../readableFromBuffers.ts";
7
- import { createRender, lookupRenderByMd5, uploadRender } from "./renders.ts";
5
+ import { Client } from "../client.js";
6
+ import { webReadableFromBuffers } from "../readableFromBuffers.js";
7
+ import { createRender, lookupRenderByMd5, uploadRender } from "./renders.js";
8
8
 
9
9
  const server = setupServer();
10
10
  const client = new Client("ef_TEST_TOKEN", "http://localhost");
@@ -1,7 +1,7 @@
1
1
  import debug from "debug";
2
2
  import { z } from "zod";
3
3
 
4
- import type { Client } from "../client.ts";
4
+ import type { Client } from "../client.js";
5
5
 
6
6
  const log = debug("ef:api:renders");
7
7
  const FILE_SIZE_LIMIT = 1024 * 1024 * 16; // 16MiB
@@ -16,6 +16,7 @@ export const CreateRenderPayload = z.object({
16
16
  strategy: z.enum(["v1", "v2"]),
17
17
  });
18
18
 
19
+ export type CreateRenderPayload = z.infer<typeof CreateRenderPayload>;
19
20
  export interface CreateRenderResult {
20
21
  id: string;
21
22
  md5: string;
@@ -30,7 +31,7 @@ export interface LookupRenderByMd5Result {
30
31
 
31
32
  export const createRender = async (
32
33
  client: Client,
33
- payload: z.infer<typeof CreateRenderPayload>,
34
+ payload: CreateRenderPayload,
34
35
  ) => {
35
36
  log("Creating render", payload);
36
37
  const response = await client.authenticatedFetch("/api/v1/renders", {
@@ -2,8 +2,8 @@ import { http, HttpResponse } from "msw";
2
2
  import { setupServer } from "msw/node";
3
3
  import { afterAll, afterEach, beforeAll, describe, expect, test } from "vitest";
4
4
 
5
- import { Client } from "../client.ts";
6
- import { createTranscription } from "./transcriptions.ts";
5
+ import { Client } from "../client.js";
6
+ import { createTranscription } from "./transcriptions.js";
7
7
 
8
8
  const server = setupServer();
9
9
  const client = new Client("ef_TEST_TOKEN", "http://localhost");
@@ -1,8 +1,8 @@
1
1
  import debug from "debug";
2
2
  import { z } from "zod";
3
3
 
4
- import { CompletionIterator } from "../ProgressIterator.ts";
5
- import type { Client } from "../client.ts";
4
+ import { CompletionIterator } from "../ProgressIterator.js";
5
+ import type { Client } from "../client.js";
6
6
 
7
7
  const log = debug("ef:api:transcriptions");
8
8
 
@@ -11,6 +11,10 @@ export const CreateTranscriptionPayload = z.object({
11
11
  track_id: z.number().int(),
12
12
  });
13
13
 
14
+ export type CreateTranscriptionPayload = z.infer<
15
+ typeof CreateTranscriptionPayload
16
+ >;
17
+
14
18
  export interface CreateTranscriptionResult {
15
19
  id: string;
16
20
  status: "complete" | "created" | "failed" | "pending" | "transcribing";
@@ -23,7 +27,7 @@ export interface TranscriptionInfoResult {
23
27
 
24
28
  export const createTranscription = async (
25
29
  client: Client,
26
- payload: z.infer<typeof CreateTranscriptionPayload>,
30
+ payload: CreateTranscriptionPayload,
27
31
  ) => {
28
32
  log("Creating transcription", payload);
29
33
  const response = await client.authenticatedFetch("/api/v1/transcriptions", {
@@ -3,13 +3,13 @@ import { setupServer } from "msw/node";
3
3
  import { afterAll, afterEach, beforeAll, describe, expect, test } from "vitest";
4
4
  import { ZodError } from "zod";
5
5
 
6
- import { Client } from "../client.ts";
7
- import { webReadableFromBuffers } from "../readableFromBuffers.ts";
6
+ import { Client } from "../client.js";
7
+ import { webReadableFromBuffers } from "../readableFromBuffers.js";
8
8
  import {
9
9
  createUnprocessedFile,
10
10
  lookupUnprocessedFileByMd5,
11
- uploadUnprocessedFile,
12
- } from "./unprocessed-file.ts";
11
+ uploadUnprocessedReadableStream,
12
+ } from "./unprocessed-file.js";
13
13
 
14
14
  const server = setupServer();
15
15
  const client = new Client("ef_TEST_TOKEN", "http://localhost");
@@ -96,11 +96,10 @@ describe("Unprocessed File", () => {
96
96
  );
97
97
 
98
98
  await expect(
99
- uploadUnprocessedFile(
99
+ uploadUnprocessedReadableStream(
100
100
  client,
101
- "test-file",
101
+ { id: "test-file", byte_size: 4 },
102
102
  webReadableFromBuffers(Buffer.from("test")),
103
- 4,
104
103
  ).whenUploaded(),
105
104
  ).rejects.toThrowError(
106
105
  "Failed to upload chunk 0 for /api/v1/unprocessed_files/test-file/upload 500 Internal Server Error",
@@ -117,11 +116,10 @@ describe("Unprocessed File", () => {
117
116
  );
118
117
 
119
118
  await expect(
120
- uploadUnprocessedFile(
119
+ uploadUnprocessedReadableStream(
121
120
  client,
122
- "test-file",
121
+ { id: "test-file", byte_size: 4 },
123
122
  webReadableFromBuffers(Buffer.from("test")),
124
- 4,
125
123
  ).whenUploaded(),
126
124
  ).resolves.toEqual([
127
125
  { type: "progress", progress: 0 },
@@ -1,8 +1,8 @@
1
1
  import debug from "debug";
2
2
  import { z } from "zod";
3
3
 
4
- import type { Client } from "../client.ts";
5
- import { uploadChunks } from "../uploadChunks.ts";
4
+ import type { Client } from "../client.js";
5
+ import { uploadChunks } from "../uploadChunks.js";
6
6
 
7
7
  const log = debug("ef:api:unprocessed-file");
8
8
 
@@ -16,7 +16,11 @@ export const CreateUnprocessedFilePayload = z.object({
16
16
 
17
17
  export const UpdateUnprocessedFilePayload = z.object({});
18
18
 
19
- interface UnprocessedFile {
19
+ export type CreateUnprocessedFilePayload = z.infer<
20
+ typeof CreateUnprocessedFilePayload
21
+ >;
22
+
23
+ export interface UnprocessedFile {
20
24
  byte_size: number;
21
25
  next_byte: number;
22
26
  complete: boolean;
@@ -24,6 +28,11 @@ interface UnprocessedFile {
24
28
  md5: string;
25
29
  }
26
30
 
31
+ export type UnprocessedFileUploadDetails = Pick<
32
+ UnprocessedFile,
33
+ "id" | "byte_size"
34
+ >;
35
+
27
36
  export interface CreateUnprocessedFileResult extends UnprocessedFile {}
28
37
 
29
38
  export interface LookupUnprocessedFileByMd5Result extends UnprocessedFile {}
@@ -36,7 +45,7 @@ export interface ProcessIsobmffFileResult {
36
45
 
37
46
  export const createUnprocessedFile = async (
38
47
  client: Client,
39
- payload: z.infer<typeof CreateUnprocessedFilePayload>,
48
+ payload: CreateUnprocessedFilePayload,
40
49
  ) => {
41
50
  log("Creating an unprocessed file", payload);
42
51
  CreateUnprocessedFilePayload.parse(payload);
@@ -64,17 +73,16 @@ export const createUnprocessedFile = async (
64
73
  );
65
74
  };
66
75
 
67
- export const uploadUnprocessedFile = (
76
+ export const uploadUnprocessedReadableStream = (
68
77
  client: Client,
69
- fileId: string,
78
+ uploadDetails: UnprocessedFileUploadDetails,
70
79
  fileStream: ReadableStream,
71
- fileSize: number,
72
80
  ) => {
73
- log("Uploading unprocessed file", fileId);
81
+ log("Uploading unprocessed file", uploadDetails.id);
74
82
 
75
83
  return uploadChunks(client, {
76
- url: `/api/v1/unprocessed_files/${fileId}/upload`,
77
- fileSize,
84
+ url: `/api/v1/unprocessed_files/${uploadDetails.id}/upload`,
85
+ fileSize: uploadDetails.byte_size,
78
86
  fileStream,
79
87
  maxSize: MAX_FILE_SIZE,
80
88
  });
@@ -104,12 +112,9 @@ export const lookupUnprocessedFileByMd5 = async (
104
112
  );
105
113
  };
106
114
 
107
- export const processIsobmffFile = async (
108
- client: Client,
109
- unprocessedFileId: LookupUnprocessedFileByMd5Result["id"],
110
- ) => {
115
+ export const processIsobmffFile = async (client: Client, id: string) => {
111
116
  const response = await client.authenticatedFetch(
112
- `/api/v1/unprocessed_files/${unprocessedFileId}/isobmff`,
117
+ `/api/v1/unprocessed_files/${id}/isobmff`,
113
118
  {
114
119
  method: "POST",
115
120
  },
@@ -120,6 +125,6 @@ export const processIsobmffFile = async (
120
125
  }
121
126
 
122
127
  throw new Error(
123
- `Failed to process isobmff file ${response.status} ${response.statusText}`,
128
+ `Failed to process isobmff file ${id} ${response.status} ${response.statusText}`,
124
129
  );
125
130
  };
@@ -1,9 +1,9 @@
1
- import { afterAll, afterEach, beforeAll, describe, expect, test } from "vitest";
2
1
  import { http, HttpResponse } from "msw";
3
2
  import { setupServer } from "msw/node";
3
+ import { afterAll, afterEach, beforeAll, describe, expect, test } from "vitest";
4
4
 
5
- import { Client } from "../client.ts";
6
- import { createURLToken } from "./url-token.ts";
5
+ import { Client } from "../client.js";
6
+ import { createURLToken } from "./url-token.js";
7
7
 
8
8
  const server = setupServer();
9
9
  const client = new Client("ef_TEST_TOKEN", "http://localhost");
@@ -1,6 +1,6 @@
1
1
  import debug from "debug";
2
2
 
3
- import type { Client } from "../client.ts";
3
+ import type { Client } from "../client.js";
4
4
 
5
5
  const log = debug("ef:api:url-token");
6
6
 
@@ -0,0 +1,10 @@
1
+ // Type helper that will cause a compilation error
2
+ type Equals<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y
3
+ ? 1
4
+ : 2
5
+ ? true
6
+ : false;
7
+ // Force error with const assertion
8
+ export const assertTypesMatch = <T, U>(
9
+ value: Equals<T, U> extends true ? true : never,
10
+ ) => value;
@@ -0,0 +1,117 @@
1
+ import { type Readable, Stream } from "node:stream";
2
+
3
+ export const createReadableStreamFromReadable = (
4
+ source: Readable & { readableHighWaterMark?: number },
5
+ ) => {
6
+ const pump = new StreamPump(source);
7
+ const stream = new ReadableStream(pump, pump);
8
+ return stream;
9
+ };
10
+
11
+ class StreamPump {
12
+ public highWaterMark: number;
13
+ public accumalatedSize: number;
14
+ private stream: Stream & {
15
+ readableHighWaterMark?: number;
16
+ readable?: boolean;
17
+ resume?: () => void;
18
+ pause?: () => void;
19
+ destroy?: (error?: Error) => void;
20
+ };
21
+ private controller?: ReadableStreamController<Uint8Array>;
22
+
23
+ constructor(
24
+ stream: Stream & {
25
+ readableHighWaterMark?: number;
26
+ readable?: boolean;
27
+ resume?: () => void;
28
+ pause?: () => void;
29
+ destroy?: (error?: Error) => void;
30
+ },
31
+ ) {
32
+ this.highWaterMark =
33
+ stream.readableHighWaterMark ||
34
+ new Stream.Readable().readableHighWaterMark;
35
+ this.accumalatedSize = 0;
36
+ this.stream = stream;
37
+ this.enqueue = this.enqueue.bind(this);
38
+ this.error = this.error.bind(this);
39
+ this.close = this.close.bind(this);
40
+ }
41
+
42
+ size(chunk: Uint8Array) {
43
+ return chunk?.byteLength || 0;
44
+ }
45
+
46
+ start(controller: ReadableStreamController<Uint8Array>) {
47
+ this.controller = controller;
48
+ this.stream.on("data", this.enqueue);
49
+ this.stream.once("error", this.error);
50
+ this.stream.once("end", this.close);
51
+ this.stream.once("close", this.close);
52
+ }
53
+
54
+ pull() {
55
+ this.resume();
56
+ }
57
+
58
+ cancel(reason?: Error) {
59
+ if (this.stream.destroy) {
60
+ this.stream.destroy(reason);
61
+ }
62
+
63
+ this.stream.off("data", this.enqueue);
64
+ this.stream.off("error", this.error);
65
+ this.stream.off("end", this.close);
66
+ this.stream.off("close", this.close);
67
+ }
68
+
69
+ enqueue(chunk: Uint8Array | string) {
70
+ if (this.controller) {
71
+ try {
72
+ const bytes = chunk instanceof Uint8Array ? chunk : Buffer.from(chunk);
73
+
74
+ const available = (this.controller.desiredSize || 0) - bytes.byteLength;
75
+ this.controller.enqueue(bytes);
76
+ if (available <= 0) {
77
+ this.pause();
78
+ }
79
+ } catch (error: any) {
80
+ this.controller.error(
81
+ new Error(
82
+ "Could not create Buffer, chunk must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object",
83
+ ),
84
+ );
85
+ this.cancel();
86
+ }
87
+ }
88
+ }
89
+
90
+ pause() {
91
+ if (this.stream.pause) {
92
+ this.stream.pause();
93
+ }
94
+ }
95
+
96
+ resume() {
97
+ if (this.stream.readable && this.stream.resume) {
98
+ this.stream.resume();
99
+ }
100
+ }
101
+
102
+ close() {
103
+ if (this.controller) {
104
+ this.controller.close();
105
+ // biome-ignore lint/performance/noDelete: infrequent use
106
+ delete this.controller;
107
+ }
108
+ }
109
+
110
+ error(error: Error) {
111
+ if (this.controller) {
112
+ this.controller.error(error);
113
+ // biome-ignore lint/performance/noDelete: infrequent use
114
+ delete this.controller;
115
+ }
116
+ }
117
+ }