@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,5 +1,5 @@
1
1
  let CHUNK_SIZE_BYTES = 8 * 1024 * 1024;
2
- if (process.env.CHUNK_SIZE_BYTES) {
2
+ if ("process" in globalThis && process.env.CHUNK_SIZE_BYTES) {
3
3
  CHUNK_SIZE_BYTES = Number.parseInt(process.env.CHUNK_SIZE_BYTES, 10);
4
4
  }
5
5
  export {
@@ -0,0 +1,25 @@
1
+ import { CompleteEvent, ProgressEvent, StreamEventSource } from './StreamEventSource.ts';
2
+ declare abstract class BaseEventIterator<T extends CompleteEvent | any> implements AsyncIterable<T> {
3
+ protected eventSource: StreamEventSource;
4
+ protected queue: T[];
5
+ protected index: number;
6
+ protected isComplete: boolean;
7
+ protected resolversNext: PromiseWithResolvers<void>;
8
+ constructor(eventSource: StreamEventSource);
9
+ whenComplete(): Promise<T[]>;
10
+ on: (event: "progress", callback: (event: ProgressEvent) => void) => this;
11
+ protected push(event: T): void;
12
+ protected get queueLength(): number;
13
+ [Symbol.asyncIterator](): AsyncIterator<T>;
14
+ }
15
+ export declare class ProgressIterator extends BaseEventIterator<ProgressEvent | CompleteEvent> {
16
+ constructor(eventSource: StreamEventSource);
17
+ private initializeListeners;
18
+ }
19
+ export declare class CompletionIterator extends BaseEventIterator<CompleteEvent | ProgressEvent> {
20
+ private totalSize;
21
+ private currentProgress;
22
+ constructor(eventSource: StreamEventSource);
23
+ private initializeListeners;
24
+ }
25
+ export {};
@@ -0,0 +1,99 @@
1
+ class BaseEventIterator {
2
+ constructor(eventSource) {
3
+ this.queue = [];
4
+ this.index = 0;
5
+ this.isComplete = false;
6
+ this.resolversNext = Promise.withResolvers();
7
+ this.eventSource = eventSource;
8
+ }
9
+ async whenComplete() {
10
+ for await (const _ of this) {
11
+ }
12
+ return this.queue;
13
+ }
14
+ push(event) {
15
+ this.queue.push(event);
16
+ this.resolversNext.resolve();
17
+ this.resolversNext = Promise.withResolvers();
18
+ }
19
+ get queueLength() {
20
+ return this.queue.length - this.index;
21
+ }
22
+ async *[Symbol.asyncIterator]() {
23
+ try {
24
+ while (!this.isComplete || this.queueLength > 0) {
25
+ if (this.queueLength === 0) {
26
+ await this.resolversNext.promise;
27
+ } else {
28
+ const item = this.queue[this.index];
29
+ if (!item) {
30
+ throw new Error("Queue is corrupted");
31
+ }
32
+ yield item;
33
+ this.index++;
34
+ }
35
+ }
36
+ } finally {
37
+ this.eventSource.close();
38
+ }
39
+ }
40
+ }
41
+ class ProgressIterator extends BaseEventIterator {
42
+ constructor(eventSource) {
43
+ super(eventSource);
44
+ this.initializeListeners();
45
+ }
46
+ initializeListeners() {
47
+ this.eventSource.on("progress", (event) => {
48
+ this.push(event);
49
+ });
50
+ this.eventSource.on("complete", (event) => {
51
+ this.isComplete = true;
52
+ this.push(event);
53
+ });
54
+ this.eventSource.on("error", (error) => {
55
+ this.eventSource.close();
56
+ this.resolversNext.reject(error);
57
+ });
58
+ }
59
+ }
60
+ class CompletionIterator extends BaseEventIterator {
61
+ constructor(eventSource) {
62
+ super(eventSource);
63
+ this.totalSize = 0;
64
+ this.currentProgress = 0;
65
+ this.initializeListeners();
66
+ }
67
+ initializeListeners() {
68
+ this.eventSource.on("size", (event) => {
69
+ this.totalSize = event.data.size;
70
+ this.push({
71
+ type: "progress",
72
+ data: {
73
+ progress: 0
74
+ }
75
+ });
76
+ });
77
+ this.eventSource.on("completion", (event) => {
78
+ this.currentProgress += Number(event.data.count);
79
+ this.push({
80
+ type: "progress",
81
+ data: {
82
+ progress: this.currentProgress / this.totalSize
83
+ }
84
+ });
85
+ });
86
+ this.eventSource.on("complete", (event) => {
87
+ this.isComplete = true;
88
+ this.push(event);
89
+ });
90
+ this.eventSource.on("error", (error) => {
91
+ this.eventSource.close();
92
+ this.resolversNext.reject(error);
93
+ });
94
+ }
95
+ }
96
+ export {
97
+ CompletionIterator,
98
+ ProgressIterator
99
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,50 @@
1
+ type EventCallback<T> = (event: T) => void;
2
+ export type StreamEventSourceEventMap = {
3
+ progress: ProgressEvent;
4
+ complete: CompleteEvent;
5
+ size: SizeEvent;
6
+ completion: CompletionEvent;
7
+ message: {
8
+ id: string | undefined;
9
+ data: string;
10
+ };
11
+ end: [];
12
+ error: Error;
13
+ };
14
+ export type ProgressEvent = {
15
+ type: "progress";
16
+ data: {
17
+ progress: number;
18
+ };
19
+ };
20
+ export type CompleteEvent = {
21
+ type: "complete";
22
+ data: object;
23
+ };
24
+ export type SizeEvent = {
25
+ type: "size";
26
+ data: {
27
+ size: number;
28
+ };
29
+ };
30
+ export type CompletionEvent = {
31
+ type: "completion";
32
+ data: {
33
+ count: number;
34
+ };
35
+ };
36
+ export declare class StreamEventSource {
37
+ private stream;
38
+ private activeReader;
39
+ private decoder;
40
+ private parser;
41
+ private listeners;
42
+ constructor(stream: ReadableStream);
43
+ on<K extends keyof StreamEventSourceEventMap>(event: K, callback: EventCallback<StreamEventSourceEventMap[K]>): this;
44
+ off<K extends keyof StreamEventSourceEventMap>(event: K, callback: EventCallback<StreamEventSourceEventMap[K]>): this;
45
+ protected emit<K extends keyof StreamEventSourceEventMap>(event: K, data: StreamEventSourceEventMap[K]): void;
46
+ whenClosed(): Promise<void>;
47
+ private startReading;
48
+ close(): void;
49
+ }
50
+ export {};
@@ -0,0 +1,130 @@
1
+ import debug from "debug";
2
+ import { createParser } from "eventsource-parser";
3
+ const log = debug("ef:StreamEventSource");
4
+ class StreamEventSource {
5
+ constructor(stream) {
6
+ this.activeReader = null;
7
+ this.decoder = new TextDecoder();
8
+ this.listeners = {};
9
+ if (!stream) {
10
+ console.error("StreamEventSource: Stream is null or undefined");
11
+ throw new Error("Stream is required");
12
+ }
13
+ this.stream = stream;
14
+ this.parser = createParser({
15
+ onError: (err) => {
16
+ console.error("StreamEventSource: Parser error:", err);
17
+ this.emit("error", err);
18
+ },
19
+ onEvent: (event) => {
20
+ if (event.event) {
21
+ switch (event.event) {
22
+ case "size":
23
+ this.emit("size", {
24
+ type: "size",
25
+ data: JSON.parse(event.data)
26
+ });
27
+ break;
28
+ case "completion":
29
+ this.emit("completion", {
30
+ type: "completion",
31
+ data: JSON.parse(event.data)
32
+ });
33
+ break;
34
+ case "progress":
35
+ this.emit("progress", {
36
+ type: "progress",
37
+ data: JSON.parse(event.data)
38
+ });
39
+ break;
40
+ case "complete":
41
+ this.emit("complete", {
42
+ type: "complete",
43
+ data: JSON.parse(event.data)
44
+ });
45
+ break;
46
+ case "error":
47
+ log("StreamEventSource: Error event", event.data);
48
+ this.emit("error", new Error(event.data));
49
+ break;
50
+ default:
51
+ this.emit(
52
+ "error",
53
+ new Error(`Unknown event: ${event.event} data: ${event.data}`)
54
+ );
55
+ }
56
+ } else {
57
+ this.emit("message", {
58
+ id: event.id,
59
+ data: event.data
60
+ });
61
+ }
62
+ }
63
+ });
64
+ this.startReading().catch((error) => {
65
+ console.error("StreamEventSource: Error in startReading:", error);
66
+ this.emit("error", error);
67
+ });
68
+ }
69
+ on(event, callback) {
70
+ if (!this.listeners[event]) {
71
+ this.listeners[event] = [];
72
+ }
73
+ this.listeners[event]?.push(callback);
74
+ return this;
75
+ }
76
+ off(event, callback) {
77
+ const listeners = this.listeners[event];
78
+ if (listeners) {
79
+ const index = listeners.indexOf(callback);
80
+ if (index !== -1) {
81
+ listeners.splice(index, 1);
82
+ }
83
+ }
84
+ return this;
85
+ }
86
+ emit(event, data) {
87
+ for (const callback of this.listeners[event] ?? []) {
88
+ callback(data);
89
+ }
90
+ }
91
+ whenClosed() {
92
+ return new Promise((resolve) => {
93
+ this.on("end", () => resolve());
94
+ });
95
+ }
96
+ async startReading() {
97
+ try {
98
+ this.activeReader = this.stream.getReader();
99
+ while (true) {
100
+ const { done, value } = await this.activeReader.read();
101
+ if (done) break;
102
+ const chunk = this.decoder.decode(value);
103
+ if (!value) {
104
+ throw new Error("Chunk is null");
105
+ }
106
+ this.parser.feed(chunk);
107
+ }
108
+ this.activeReader.releaseLock();
109
+ this.activeReader = null;
110
+ this.emit("end", []);
111
+ } catch (error) {
112
+ console.error("StreamEventSource: Error reading stream:", error);
113
+ if (error instanceof Error) {
114
+ this.emit("error", error);
115
+ } else {
116
+ this.emit("error", new Error(String(error)));
117
+ }
118
+ }
119
+ }
120
+ close() {
121
+ if (this.activeReader) {
122
+ this.activeReader.releaseLock();
123
+ this.activeReader = null;
124
+ }
125
+ this.parser.reset();
126
+ }
127
+ }
128
+ export {
129
+ StreamEventSource
130
+ };
@@ -0,0 +1 @@
1
+ export {};
package/dist/client.d.ts CHANGED
@@ -1,6 +1,9 @@
1
- import { RequestInit } from 'node-fetch';
1
+ import { StreamEventSource } from './StreamEventSource.ts';
2
2
  export declare class Client {
3
3
  #private;
4
- constructor(token: string, efHost?: string);
5
- authenticatedFetch: (path: string, init?: RequestInit) => Promise<import('node-fetch').Response>;
4
+ constructor(token?: string, efHost?: string);
5
+ authenticatedEventSource: (path: string, init?: RequestInit) => Promise<StreamEventSource>;
6
+ authenticatedFetch: (path: string, init?: RequestInit & {
7
+ duplex?: "half";
8
+ }) => Promise<Response>;
6
9
  }
package/dist/client.js CHANGED
@@ -1,20 +1,32 @@
1
1
  import debug from "debug";
2
- import fetch from "node-fetch";
2
+ import { StreamEventSource } from "./StreamEventSource.js";
3
3
  const log = debug("ef:api:client");
4
4
  class Client {
5
5
  constructor(token, efHost = "https://editframe.dev") {
6
+ this.authenticatedEventSource = async (path, init = {}) => {
7
+ const response = await this.authenticatedFetch(path, init);
8
+ if (response.body === null) {
9
+ throw new Error("Could not create event source. Response body is null.");
10
+ }
11
+ return new StreamEventSource(response.body);
12
+ };
6
13
  this.authenticatedFetch = async (path, init = {}) => {
7
14
  init.headers ||= {};
8
15
  const url = new URL(path, this.#efHost);
9
16
  log(
10
17
  "Authenticated fetch",
11
18
  { url: url.toString(), init },
12
- "(Token will be added as Bearer token)"
19
+ this.#token ? "(Token will be added as Bearer token)" : "(Using session cookie)"
13
20
  );
21
+ if (this.#token) {
22
+ Object.assign(init.headers, {
23
+ Authorization: `Bearer ${this.#token}`
24
+ });
25
+ }
14
26
  Object.assign(init.headers, {
15
- Authorization: `Bearer ${this.#token}`,
16
27
  "Content-Type": "application/json"
17
28
  });
29
+ init.credentials = "include";
18
30
  const response = await fetch(url, init);
19
31
  log("Authenticated fetch response", response.status, response.statusText);
20
32
  return response;
@@ -22,9 +34,11 @@ class Client {
22
34
  log("Creating client with efHost", { efHost, tokenIsSet: !!token });
23
35
  this.#token = token;
24
36
  this.#efHost = efHost;
25
- const { apiKey, apiSecret } = token.match(/^(?<apiSecret>ef_[^_]+)_(?<apiKey>.+)$/)?.groups ?? {};
26
- if (!apiKey || !apiSecret) {
27
- throw new Error("Invalid token format. Must look like: ef_{}_{}");
37
+ if (token) {
38
+ const { apiKey, apiSecret } = token.match(/^(?<apiSecret>ef_[^_]+)_(?<apiKey>.+)$/)?.groups ?? {};
39
+ if (!apiKey || !apiSecret) {
40
+ throw new Error("Invalid token format. Must look like: ef_{}_{}");
41
+ }
28
42
  }
29
43
  }
30
44
  #token;
package/dist/index.d.ts CHANGED
@@ -1,8 +1,10 @@
1
- export { createCaptionFile, CreateCaptionFilePayload, type CreateCaptionFileResult, uploadCaptionFile, } from './resources/caption-file.ts';
2
- export { createImageFile, CreateImageFilePayload, type CreateImageFileResult, uploadImageFile, } from './resources/image-file.ts';
3
- export { createISOBMFFFile, CreateISOBMFFFilePayload, type CreateISOBMFFFileResult, uploadFragmentIndex, } from './resources/isobmff-file.ts';
1
+ export { createCaptionFile, CreateCaptionFilePayload, type CreateCaptionFileResult, uploadCaptionFile, type LookupCaptionFileByMd5Result, lookupCaptionFileByMd5, } from './resources/caption-file.ts';
2
+ export { createImageFile, CreateImageFilePayload, type CreateImageFileResult, uploadImageFile, type LookupImageFileByMd5Result, lookupImageFileByMd5, } from './resources/image-file.ts';
3
+ export { createISOBMFFFile, CreateISOBMFFFilePayload, type CreateISOBMFFFileResult, uploadFragmentIndex, type LookupISOBMFFFileByMd5Result, lookupISOBMFFFileByMd5, type GetISOBMFFFileTranscriptionResult, getISOBMFFFileTranscription, } from './resources/isobmff-file.ts';
4
4
  export { createISOBMFFTrack, CreateISOBMFFTrackPayload, type CreateISOBMFFTrackResult, uploadISOBMFFTrack, } from './resources/isobmff-track.ts';
5
- export { createRender, CreateRenderPayload, type CreateRenderResult, uploadRender, } from './resources/renders.ts';
5
+ export { createRender, CreateRenderPayload, type CreateRenderResult, uploadRender, type LookupRenderByMd5Result, lookupRenderByMd5, } from './resources/renders.ts';
6
+ export { createTranscription, CreateTranscriptionPayload, type CreateTranscriptionResult, getTranscriptionInfo, getTranscriptionProgress, type TranscriptionInfoResult, } from './resources/transcriptions.ts';
6
7
  export { createURLToken, type URLTokenResult, } from './resources/url-token.ts';
7
- export { createUnprocessedFile, CreateUnprocessedFilePayload, type CreateUnprocessedFileResult, updateUnprocessedFile, UpdateUnprocessedFilePayload, type UpdateUnprocessedFileResult, uploadUnprocessedFile, processAVFile, processAVFileBuffer, processImageFile, processImageFileBuffer, } from './resources/unprocessed-file.ts';
8
+ export { createUnprocessedFile, CreateUnprocessedFilePayload, type CreateUnprocessedFileResult, uploadUnprocessedFile, type LookupUnprocessedFileByMd5Result, lookupUnprocessedFileByMd5, processIsobmffFile, type ProcessIsobmffFileResult, } from './resources/unprocessed-file.ts';
9
+ export { getIsobmffProcessInfo, getIsobmffProcessProgress, type IsobmffProcessInfoResult, } from './resources/process-isobmff.ts';
8
10
  export { Client } from './client.ts';
package/dist/index.js CHANGED
@@ -1,10 +1,12 @@
1
- import { CreateCaptionFilePayload, createCaptionFile, uploadCaptionFile } from "./resources/caption-file.js";
2
- import { CreateImageFilePayload, createImageFile, uploadImageFile } from "./resources/image-file.js";
3
- import { CreateISOBMFFFilePayload, createISOBMFFFile, uploadFragmentIndex } from "./resources/isobmff-file.js";
1
+ import { CreateCaptionFilePayload, createCaptionFile, lookupCaptionFileByMd5, uploadCaptionFile } from "./resources/caption-file.js";
2
+ import { CreateImageFilePayload, createImageFile, lookupImageFileByMd5, uploadImageFile } from "./resources/image-file.js";
3
+ import { CreateISOBMFFFilePayload, createISOBMFFFile, getISOBMFFFileTranscription, lookupISOBMFFFileByMd5, uploadFragmentIndex } from "./resources/isobmff-file.js";
4
4
  import { CreateISOBMFFTrackPayload, createISOBMFFTrack, uploadISOBMFFTrack } from "./resources/isobmff-track.js";
5
- import { CreateRenderPayload, createRender, uploadRender } from "./resources/renders.js";
5
+ import { CreateRenderPayload, createRender, lookupRenderByMd5, uploadRender } from "./resources/renders.js";
6
+ import { CreateTranscriptionPayload, createTranscription, getTranscriptionInfo, getTranscriptionProgress } from "./resources/transcriptions.js";
6
7
  import { createURLToken } from "./resources/url-token.js";
7
- import { CreateUnprocessedFilePayload, UpdateUnprocessedFilePayload, createUnprocessedFile, processAVFile, processAVFileBuffer, processImageFile, processImageFileBuffer, updateUnprocessedFile, uploadUnprocessedFile } from "./resources/unprocessed-file.js";
8
+ import { CreateUnprocessedFilePayload, createUnprocessedFile, lookupUnprocessedFileByMd5, processIsobmffFile, uploadUnprocessedFile } from "./resources/unprocessed-file.js";
9
+ import { getIsobmffProcessInfo, getIsobmffProcessProgress } from "./resources/process-isobmff.js";
8
10
  import { Client } from "./client.js";
9
11
  export {
10
12
  Client,
@@ -13,20 +15,27 @@ export {
13
15
  CreateISOBMFFTrackPayload,
14
16
  CreateImageFilePayload,
15
17
  CreateRenderPayload,
18
+ CreateTranscriptionPayload,
16
19
  CreateUnprocessedFilePayload,
17
- UpdateUnprocessedFilePayload,
18
20
  createCaptionFile,
19
21
  createISOBMFFFile,
20
22
  createISOBMFFTrack,
21
23
  createImageFile,
22
24
  createRender,
25
+ createTranscription,
23
26
  createURLToken,
24
27
  createUnprocessedFile,
25
- processAVFile,
26
- processAVFileBuffer,
27
- processImageFile,
28
- processImageFileBuffer,
29
- updateUnprocessedFile,
28
+ getISOBMFFFileTranscription,
29
+ getIsobmffProcessInfo,
30
+ getIsobmffProcessProgress,
31
+ getTranscriptionInfo,
32
+ getTranscriptionProgress,
33
+ lookupCaptionFileByMd5,
34
+ lookupISOBMFFFileByMd5,
35
+ lookupImageFileByMd5,
36
+ lookupRenderByMd5,
37
+ lookupUnprocessedFileByMd5,
38
+ processIsobmffFile,
30
39
  uploadCaptionFile,
31
40
  uploadFragmentIndex,
32
41
  uploadISOBMFFTrack,
@@ -1,2 +1 @@
1
- import { Readable } from 'node:stream';
2
- export declare const readableFromBuffers: (...buffers: Buffer[]) => Readable;
1
+ export declare const webReadableFromBuffers: (...buffers: Buffer[]) => ReadableStream<any>;
@@ -1,4 +1,3 @@
1
- import { Readable } from 'node:stream';
2
1
  import { z } from 'zod';
3
2
  import { Client } from '../client.ts';
4
3
  export declare const CreateCaptionFilePayload: z.ZodObject<{
@@ -18,7 +17,11 @@ export interface CreateCaptionFileResult {
18
17
  complete: boolean | null;
19
18
  id: string;
20
19
  md5: string;
21
- asset_id: string;
20
+ }
21
+ export interface LookupCaptionFileByMd5Result {
22
+ complete: boolean | null;
23
+ id: string;
24
+ md5: string;
22
25
  }
23
26
  /**
24
27
  * Create a caption file
@@ -38,4 +41,5 @@ export interface CreateCaptionFileResult {
38
41
  * @beta
39
42
  */
40
43
  export declare const createCaptionFile: (client: Client, payload: z.infer<typeof CreateCaptionFilePayload>) => Promise<CreateCaptionFileResult>;
41
- export declare const uploadCaptionFile: (client: Client, fileId: string, fileStream: Readable, fileSize: number) => Promise<unknown>;
44
+ export declare const uploadCaptionFile: (client: Client, fileId: string, fileStream: ReadableStream, fileSize: number) => Promise<any>;
45
+ export declare const lookupCaptionFileByMd5: (client: Client, md5: string) => Promise<LookupCaptionFileByMd5Result | null>;
@@ -1,5 +1,5 @@
1
- import { z } from "zod";
2
1
  import debug from "debug";
2
+ import { z } from "zod";
3
3
  const log = debug("ef:api:caption-file");
4
4
  const MAX_CAPTION_SIZE = 1024 * 1024 * 2;
5
5
  const CreateCaptionFilePayload = z.object({
@@ -37,7 +37,8 @@ const uploadCaptionFile = async (client, fileId, fileStream, fileSize) => {
37
37
  `/api/v1/caption_files/${fileId}/upload`,
38
38
  {
39
39
  method: "POST",
40
- body: fileStream
40
+ body: fileStream,
41
+ duplex: "half"
41
42
  }
42
43
  );
43
44
  log("Caption file uploaded", response);
@@ -48,8 +49,27 @@ const uploadCaptionFile = async (client, fileId, fileStream, fileSize) => {
48
49
  `Failed to upload caption ${response.status} ${response.statusText}`
49
50
  );
50
51
  };
52
+ const lookupCaptionFileByMd5 = async (client, md5) => {
53
+ const response = await client.authenticatedFetch(
54
+ `/api/v1/caption_files/md5/${md5}`,
55
+ {
56
+ method: "GET"
57
+ }
58
+ );
59
+ log("Caption file lookup", response);
60
+ if (response.ok) {
61
+ return await response.json();
62
+ }
63
+ if (response.status === 404) {
64
+ return null;
65
+ }
66
+ throw new Error(
67
+ `Failed to lookup caption by md5 ${md5} ${response.status} ${response.statusText}`
68
+ );
69
+ };
51
70
  export {
52
71
  CreateCaptionFilePayload,
53
72
  createCaptionFile,
73
+ lookupCaptionFileByMd5,
54
74
  uploadCaptionFile
55
75
  };
@@ -1,4 +1,3 @@
1
- import { Readable } from 'node:stream';
2
1
  import { z } from 'zod';
3
2
  import { Client } from '../client.ts';
4
3
  export declare const CreateImageFilePayload: z.ZodObject<{
@@ -27,7 +26,12 @@ export interface CreateImageFileResult {
27
26
  complete: boolean | null;
28
27
  id: string;
29
28
  md5: string;
30
- asset_id: string;
29
+ }
30
+ export interface LookupImageFileByMd5Result {
31
+ complete: boolean | null;
32
+ id: string;
33
+ md5: string;
31
34
  }
32
35
  export declare const createImageFile: (client: Client, payload: z.infer<typeof CreateImageFilePayload>) => Promise<CreateImageFileResult>;
33
- export declare const uploadImageFile: (client: Client, fileId: string, fileStream: Readable, fileSize: number) => import('../uploadChunks.ts').IteratorWithPromise<import('../uploadChunks.ts').UploadChunkEvent>;
36
+ export declare const uploadImageFile: (client: Client, fileId: string, fileStream: ReadableStream, fileSize: number) => import('../uploadChunks.ts').IteratorWithPromise<import('../uploadChunks.ts').UploadChunkEvent>;
37
+ export declare const lookupImageFileByMd5: (client: Client, md5: string) => Promise<LookupImageFileByMd5Result | null>;
@@ -35,8 +35,27 @@ const uploadImageFile = (client, fileId, fileStream, fileSize) => {
35
35
  maxSize: MAX_IMAGE_SIZE
36
36
  });
37
37
  };
38
+ const lookupImageFileByMd5 = async (client, md5) => {
39
+ const response = await client.authenticatedFetch(
40
+ `/api/v1/image_files/md5/${md5}`,
41
+ {
42
+ method: "GET"
43
+ }
44
+ );
45
+ log("Image file lookup", response);
46
+ if (response.ok) {
47
+ return await response.json();
48
+ }
49
+ if (response.status === 404) {
50
+ return null;
51
+ }
52
+ throw new Error(
53
+ `Failed to lookup image by md5 ${md5} ${response.status} ${response.statusText}`
54
+ );
55
+ };
38
56
  export {
39
57
  CreateImageFilePayload,
40
58
  createImageFile,
59
+ lookupImageFileByMd5,
41
60
  uploadImageFile
42
61
  };
@@ -1,4 +1,3 @@
1
- import { Readable } from 'node:stream';
2
1
  import { z } from 'zod';
3
2
  import { Client } from '../client.ts';
4
3
  export declare const CreateISOBMFFFilePayload: z.ZodObject<{
@@ -16,7 +15,21 @@ export interface CreateISOBMFFFileResult {
16
15
  filename: string;
17
16
  id: string;
18
17
  md5: string;
19
- asset_id: string;
18
+ }
19
+ export interface LookupISOBMFFFileByMd5Result {
20
+ fragment_index_complete: boolean;
21
+ filename: string;
22
+ id: string;
23
+ md5: string;
24
+ }
25
+ export interface GetISOBMFFFileTranscriptionResult {
26
+ id: string;
27
+ work_slice_ms: number;
28
+ isobmff_track: {
29
+ duration_ms: number;
30
+ };
20
31
  }
21
32
  export declare const createISOBMFFFile: (client: Client, payload: z.infer<typeof CreateISOBMFFFilePayload>) => Promise<CreateISOBMFFFileResult>;
22
- export declare const uploadFragmentIndex: (client: Client, fileId: string, fileStream: Readable, fileSize: number) => Promise<unknown>;
33
+ export declare const uploadFragmentIndex: (client: Client, fileId: string, fileStream: ReadableStream, fileSize: number) => Promise<any>;
34
+ export declare const lookupISOBMFFFileByMd5: (client: Client, md5: string) => Promise<LookupISOBMFFFileByMd5Result | null>;
35
+ export declare const getISOBMFFFileTranscription: (client: Client, id: string) => Promise<GetISOBMFFFileTranscriptionResult | null>;
@@ -1,5 +1,5 @@
1
- import { z } from "zod";
2
1
  import debug from "debug";
2
+ import { z } from "zod";
3
3
  const log = debug("ef:api:isobmff-file");
4
4
  const FILE_SIZE_LIMIT = 1024 * 1024 * 2;
5
5
  const CreateISOBMFFFilePayload = z.object({
@@ -29,7 +29,8 @@ const uploadFragmentIndex = async (client, fileId, fileStream, fileSize) => {
29
29
  `/api/v1/isobmff_files/${fileId}/index/upload`,
30
30
  {
31
31
  method: "POST",
32
- body: fileStream
32
+ body: fileStream,
33
+ duplex: "half"
33
34
  }
34
35
  );
35
36
  log("Fragment index uploaded", response);
@@ -40,8 +41,42 @@ const uploadFragmentIndex = async (client, fileId, fileStream, fileSize) => {
40
41
  `Failed to create fragment index ${response.status} ${response.statusText}`
41
42
  );
42
43
  };
44
+ const lookupISOBMFFFileByMd5 = async (client, md5) => {
45
+ const response = await client.authenticatedFetch(
46
+ `/api/v1/isobmff_files/md5/${md5}`,
47
+ {
48
+ method: "GET"
49
+ }
50
+ );
51
+ log("ISOBMFF file lookup", response);
52
+ if (response.ok) {
53
+ return await response.json();
54
+ }
55
+ if (response.status === 404) {
56
+ return null;
57
+ }
58
+ throw new Error(
59
+ `Failed to lookup isobmff file by md5 ${md5} ${response.status} ${response.statusText}`
60
+ );
61
+ };
62
+ const getISOBMFFFileTranscription = async (client, id) => {
63
+ const response = await client.authenticatedFetch(
64
+ `/api/v1/isobmff_files/${id}/transcription`
65
+ );
66
+ if (response.ok) {
67
+ return await response.json();
68
+ }
69
+ if (response.status === 404) {
70
+ return null;
71
+ }
72
+ throw new Error(
73
+ `Failed to get isobmff file transcription ${id} ${response.status} ${response.statusText}`
74
+ );
75
+ };
43
76
  export {
44
77
  CreateISOBMFFFilePayload,
45
78
  createISOBMFFFile,
79
+ getISOBMFFFileTranscription,
80
+ lookupISOBMFFFileByMd5,
46
81
  uploadFragmentIndex
47
82
  };