@devultur/convex 1.5.0 → 1.5.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/README.md +24 -3
- package/dist/chunk-BDEO67OT.js +110 -0
- package/dist/component/http.js +2 -2
- package/dist/component/library.d.ts +2 -2
- package/dist/component/library.js +3 -3
- package/dist/component/lock.js +3 -3
- package/dist/component/mediaClient.js +1 -1
- package/dist/component/metadata.js +2 -2
- package/dist/component/public.js +9 -9
- package/dist/component/uploads.js +6 -6
- package/dist/component/workerErrors.d.ts +1 -1
- package/dist/component/workerErrors.js +1 -1
- package/dist/hooks-uqpBd5UF.d.ts +171 -0
- package/dist/index.d.ts +53 -16
- package/dist/index.js +1 -0
- package/dist/react/hooks.d.ts +6 -0
- package/dist/react/hooks.js +23 -0
- package/dist/react.d.ts +123 -277
- package/dist/react.js +784 -829
- package/docs/guides/object-lock.md +517 -0
- package/docs/guides/plugins.md +205 -0
- package/docs/guides/self-host.md +523 -0
- package/docs/guides/video-player.md +105 -0
- package/package.json +10 -5
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
DevulturApiContext,
|
|
4
|
+
DevulturContext,
|
|
5
|
+
DevulturProgressContext,
|
|
6
|
+
useDevultur,
|
|
7
|
+
useDevulturApi,
|
|
8
|
+
useDevulturOptional,
|
|
9
|
+
useDevulturProgress,
|
|
10
|
+
useMediaUrl,
|
|
11
|
+
useVideoProps
|
|
12
|
+
} from "../chunk-BDEO67OT.js";
|
|
13
|
+
export {
|
|
14
|
+
DevulturApiContext,
|
|
15
|
+
DevulturContext,
|
|
16
|
+
DevulturProgressContext,
|
|
17
|
+
useDevultur,
|
|
18
|
+
useDevulturApi,
|
|
19
|
+
useDevulturOptional,
|
|
20
|
+
useDevulturProgress,
|
|
21
|
+
useMediaUrl,
|
|
22
|
+
useVideoProps
|
|
23
|
+
};
|
package/dist/react.d.ts
CHANGED
|
@@ -1,134 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { V as VideoProps, a as ViewerTokenAction, b as ViewerTokenArgs, D as DevulturApi } from './hooks-uqpBd5UF.js';
|
|
3
|
+
export { c as DevulturApiContext, d as DevulturContext, e as DevulturContextValue, f as DevulturProgressContext, g as DevulturProgressContextValue, T as TokenStatus, U as UploadOptions, h as UploadedMedia, i as ViewerTokenResult, u as useDevultur, j as useDevulturApi, k as useDevulturOptional, l as useDevulturProgress, m as useMediaUrl, n as useVideoProps } from './hooks-uqpBd5UF.js';
|
|
4
|
+
import { BakeOutputFormat, MediaUploadState, MediaUploadError } from '@devultur/react';
|
|
4
5
|
export { MediaUploadError, MediaUploadState, UploadProgress } from '@devultur/react';
|
|
5
|
-
import {
|
|
6
|
-
import { Value } from 'convex/values';
|
|
7
|
-
import { A as AttachmentLabels, M as MediaLibraryLabels, P as PreviewLabels, a as MediaPickerLabels, b as MediaFetchError } from './preview-labels-C2nUUY_f.js';
|
|
6
|
+
import { A as AttachmentLabels, b as MediaFetchError, M as MediaLibraryLabels, P as PreviewLabels, a as MediaPickerLabels } from './preview-labels-C2nUUY_f.js';
|
|
8
7
|
export { c as AttachmentKind, d as MediaFetchErrorCode, e as defaultAttachmentLabels, f as defaultMediaLibraryLabels, g as defaultMediaPickerLabels, h as defaultPreviewLabels, i as formatDuration, j as formatFileSize } from './preview-labels-C2nUUY_f.js';
|
|
8
|
+
import { Visibility, DevulturMedia, MediaUrlOptions, MediaStatusValue, ProcessingPhase, FailureReason } from '@devultur/core';
|
|
9
9
|
import { M as MediaRecord } from './types-C0ruHUcu.js';
|
|
10
10
|
import { P as PdfjsLoader } from './pdf-render-BwJGagvz.js';
|
|
11
11
|
export { a as PdfjsModule } from './pdf-render-BwJGagvz.js';
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
type ViewerTokenResult = {
|
|
15
|
-
token: string;
|
|
16
|
-
expiresIn: number;
|
|
17
|
-
} | string;
|
|
18
|
-
/** Extra arguments sent with `sessionSecret` to the viewer token action. */
|
|
19
|
-
type ViewerTokenArgs = Record<string, Value>;
|
|
20
|
-
/**
|
|
21
|
-
* Where the viewer token for the current `tokenArgs` stands: not requested yet, being issued (no token yet), held, or
|
|
22
|
-
* failed (the action threw or returned no token). A renewal in flight, or one that failed, keeps `"ready"`.
|
|
23
|
-
*/
|
|
24
|
-
type TokenStatus = "idle" | "loading" | "ready" | "error";
|
|
25
|
-
|
|
26
|
-
/** Transform/delivery options for media URLs (without `token`, which the context injects). */
|
|
27
|
-
type MediaRenderOptions = Omit<MediaUrlOptions, "token">;
|
|
28
|
-
/**
|
|
29
|
-
* The viewer token action: the component's `issueViewerToken` (as `defineDevulturFunctions` or `exposeApi` export it,
|
|
30
|
-
* where `sessionSecret` is optional) or an app's own, which may require it. The providers always send it.
|
|
31
|
-
*/
|
|
32
|
-
type ViewerTokenAction = FunctionReference<"action", "public", {
|
|
33
|
-
sessionSecret?: string;
|
|
34
|
-
}>;
|
|
35
|
-
interface MediaSession {
|
|
36
|
-
token: string | null;
|
|
37
|
-
/** Where the viewer token stands; `"error"` makes private previews fail fast with `token_unavailable`. */
|
|
38
|
-
tokenStatus: TokenStatus;
|
|
39
|
-
/** Why the last issuance failed (the action threw or returned no token), while `tokenStatus` is `"error"`. */
|
|
40
|
-
tokenError: Error | null;
|
|
41
|
-
/** Issues the viewer token again (after a failure, for example). Resolves to the new token, or `null`. */
|
|
42
|
-
retryToken: () => Promise<string | null>;
|
|
43
|
-
/**
|
|
44
|
-
* Asks for the viewer token where it's issued lazily (`<DevulturViewerProvider lazyToken>`): the first private media
|
|
45
|
-
* shown calls it, and so must code that reads `token` itself. A no-op once asked, and where the token is issued
|
|
46
|
-
* right away (the default).
|
|
47
|
-
*/
|
|
48
|
-
requestToken: () => void;
|
|
49
|
-
baseUrl: string | null;
|
|
50
|
-
/** Browser session secret → sent in `${SESSION_HEADER}` on every private delivery. */
|
|
51
|
-
sessionSecret: string;
|
|
52
|
-
/** Delivery URL from a reference (non-hook → usable in handlers and `.map`). Token-transparent. */
|
|
53
|
-
url: (media: DevulturMedia, options?: MediaRenderOptions) => string;
|
|
54
|
-
/** Downloads a video's subtitle text for a locale (auth-transparent). */
|
|
55
|
-
getCaptionsText: (media: DevulturMedia, locale: string) => Promise<string>;
|
|
56
|
-
/**
|
|
57
|
-
* Re-issues the viewer token (new session fingerprint with the current UA/IP) and updates the context.
|
|
58
|
-
* Single-flight: concurrent calls share the same issuance. Returns the new token (or null if it
|
|
59
|
-
* failed). The render uses it to transparently recover from a 401 `session_mismatch`.
|
|
60
|
-
*/
|
|
61
|
-
reissueToken: () => Promise<string | null>;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
type AnyAction = FunctionReference<"action">;
|
|
65
|
-
type AnyMutation = FunctionReference<"mutation">;
|
|
66
|
-
type AnyQuery = FunctionReference<"query">;
|
|
67
|
-
interface DevulturApi {
|
|
68
|
-
issueViewerToken: AnyAction;
|
|
69
|
-
createUploadUrl: AnyAction;
|
|
70
|
-
/** Records an upload in the component after its PUT, so it shows in `listMedia`. Optional (uploads still work). */
|
|
71
|
-
confirmUpload?: AnyAction;
|
|
72
|
-
deleteMedia: AnyAction;
|
|
73
|
-
/** Deletes the full folder of a video (raw/hls/thumbnails/captions). Required to delete videos. */
|
|
74
|
-
deleteVideo?: AnyAction;
|
|
75
|
-
/** Requests the transcode of an uploaded video. Required by `useMediaUpload` for auto-process. */
|
|
76
|
-
processVideo?: AnyAction;
|
|
77
|
-
getMedia?: AnyQuery;
|
|
78
|
-
/** The library, newest first. Required by `useMediaLibrary` and `<MediaLibrary>`. */
|
|
79
|
-
listMediaPage?: AnyQuery;
|
|
80
|
-
/** The library matching a search. Required by `useMediaLibrary` and `<MediaLibrary>` to search. */
|
|
81
|
-
searchMedia?: AnyQuery;
|
|
82
|
-
saveProgress?: AnyMutation;
|
|
83
|
-
loadProgress?: AnyQuery;
|
|
84
|
-
markComplete?: AnyMutation;
|
|
85
|
-
resetProgress?: AnyMutation;
|
|
86
|
-
}
|
|
87
|
-
interface UploadOptions {
|
|
88
|
-
/**
|
|
89
|
-
* Visibility override for this resource. Omitted → `config.upload.visibility` on your server, else the Worker's
|
|
90
|
-
* default by type. Your guard can still rewrite it.
|
|
91
|
-
*/
|
|
92
|
-
visibility?: Visibility;
|
|
93
|
-
/** Progress of the PUT: bytes sent, total bytes and their fraction (0 to 1). */
|
|
94
|
-
onProgress?: (progress: UploadProgress) => void;
|
|
95
|
-
/** Aborts the PUT → `upload()` rejects with an `AbortError`. */
|
|
96
|
-
signal?: AbortSignal;
|
|
97
|
-
/** A PDF's page count to record with it, a hint (`countPdfPages` from `@devultur/convex/pdfjs` counts it). */
|
|
98
|
-
pageCount?: number;
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* The reference `upload()` resolves to: a `DevulturMedia` whose `key` is always set (the uploaded object's key; a
|
|
102
|
-
* video's raw file, what `processVideo` takes). It stores as-is in a `dv.media()` field.
|
|
103
|
-
*/
|
|
104
|
-
type UploadedMedia = DevulturMedia & {
|
|
105
|
-
readonly key: string;
|
|
106
|
-
};
|
|
107
|
-
/**
|
|
108
|
-
* What `useDevultur()` returns. Under a `<DevulturViewerProvider>`, `uploadUrl`, `upload` and `deleteMedia` throw a
|
|
109
|
-
* `DevulturCapabilityError` (`capability_unavailable`).
|
|
110
|
-
*/
|
|
111
|
-
interface DevulturContextValue extends MediaSession {
|
|
112
|
-
uploadUrl: (file: File) => Promise<{
|
|
113
|
-
url: string;
|
|
114
|
-
key: string;
|
|
115
|
-
}>;
|
|
116
|
-
/** Uploads a file (reporting progress), records it in the component, and returns the reference ready to save. */
|
|
117
|
-
upload: (file: File, options?: UploadOptions) => Promise<UploadedMedia>;
|
|
118
|
-
/** Deletes a media by reference: video → full folder; image/file → the object. */
|
|
119
|
-
deleteMedia: (media: DevulturMedia) => void;
|
|
120
|
-
}
|
|
121
|
-
declare function useDevultur(): DevulturContextValue;
|
|
122
|
-
/**
|
|
123
|
-
* `useDevultur()` for components that also render outside a provider: the same value under `<DevulturProvider>` or
|
|
124
|
-
* `<DevulturViewerProvider>`, and `null` outside both instead of throwing.
|
|
125
|
-
*/
|
|
126
|
-
declare function useDevulturOptional(): DevulturContextValue | null;
|
|
127
|
-
/**
|
|
128
|
-
* The `api` passed to `<DevulturProvider>`: your app's exported Devultur functions. Under a `<DevulturViewerProvider>`
|
|
129
|
-
* it throws a `DevulturCapabilityError`.
|
|
130
|
-
*/
|
|
131
|
-
declare function useDevulturApi(): DevulturApi;
|
|
12
|
+
import 'convex/server';
|
|
13
|
+
import 'convex/values';
|
|
132
14
|
|
|
133
15
|
/** What `useDevultur()` can do only under a `<DevulturProvider>` given the matching actions. */
|
|
134
16
|
type DevulturCapability = "upload" | "uploadUrl" | "deleteMedia" | "api";
|
|
@@ -234,6 +116,27 @@ interface AttachmentCardProps extends Omit<React.HTMLAttributes<HTMLElement>, "c
|
|
|
234
116
|
*/
|
|
235
117
|
declare function AttachmentCard({ media, contentType, onOpen, preview, headingLevel, locale, labels, ...articleProps }: AttachmentCardProps): React.JSX.Element | null;
|
|
236
118
|
|
|
119
|
+
interface DownloadLinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, "href" | "download" | "media"> {
|
|
120
|
+
media: DevulturMedia | null | undefined;
|
|
121
|
+
/** Name it downloads as. Without this it uses the upload's original name. */
|
|
122
|
+
filename?: string;
|
|
123
|
+
/**
|
|
124
|
+
* A private download that failed: `token_unavailable` right away when the viewer token couldn't be issued
|
|
125
|
+
* (`useDevultur().retryToken()` tries again), `http_error` when the delivery refused it.
|
|
126
|
+
*/
|
|
127
|
+
onDownloadError?: (error: MediaFetchError) => void;
|
|
128
|
+
children: React.ReactNode;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* `<a>` that downloads a media with its original name (token-transparent). The worker serves it with
|
|
132
|
+
* `Content-Disposition: attachment`, so a click downloads the file instead of opening it in a tab.
|
|
133
|
+
*
|
|
134
|
+
* Private: an `<a download>` NAVIGATES, and a navigation can't send `${SESSION_HEADER}` → with session
|
|
135
|
+
* binding the gate gives a 401. So, for private media, we intercept the click, blob-fetch with the header
|
|
136
|
+
* (like private `<Image>`) and trigger the download from the object URL. Public keeps native navigation.
|
|
137
|
+
*/
|
|
138
|
+
declare function DownloadLink({ media, filename, onDownloadError, children, ...anchorProps }: DownloadLinkProps): React.JSX.Element | null;
|
|
139
|
+
|
|
237
140
|
/** An explicit `srcSet` is passed through to the `<img>` as is, and wins over the one `widths` builds. */
|
|
238
141
|
interface ImageProps extends Omit<React.ImgHTMLAttributes<HTMLImageElement>, "src" | "width" | "height"> {
|
|
239
142
|
/** Typed reference. `null`/`undefined` → renders `fallback` (or `externalFallback`). Its `alt` is the default `alt`. */
|
|
@@ -275,6 +178,68 @@ interface ImageProps extends Omit<React.ImgHTMLAttributes<HTMLImageElement>, "sr
|
|
|
275
178
|
*/
|
|
276
179
|
declare function Image({ media, width, height, fit, format, quality, widths, sizes, fallback, externalFallback, render, alt, onLoadError, ...imgProps }: ImageProps): React.JSX.Element;
|
|
277
180
|
|
|
181
|
+
interface MediaStatusReturn {
|
|
182
|
+
status: MediaStatusValue;
|
|
183
|
+
/** Typed progress: `phase` is the pipeline step (no `as any`). */
|
|
184
|
+
progress: {
|
|
185
|
+
current: number;
|
|
186
|
+
total: number;
|
|
187
|
+
percent: number;
|
|
188
|
+
phase?: ProcessingPhase;
|
|
189
|
+
} | null;
|
|
190
|
+
error: string | null;
|
|
191
|
+
/** Categorized failure reason (null if it didn't fail). */
|
|
192
|
+
failureReason: FailureReason | null;
|
|
193
|
+
/** Whether the failure is retriable (null if it didn't fail). */
|
|
194
|
+
retriable: boolean | null;
|
|
195
|
+
isQueued: boolean;
|
|
196
|
+
isTranscoding: boolean;
|
|
197
|
+
isCaptioning: boolean;
|
|
198
|
+
isReady: boolean;
|
|
199
|
+
isFailed: boolean;
|
|
200
|
+
playlistUrl: string | null;
|
|
201
|
+
thumbnailKey: string | null;
|
|
202
|
+
captionLocales: string[];
|
|
203
|
+
duration: number | null;
|
|
204
|
+
isLoading: boolean;
|
|
205
|
+
}
|
|
206
|
+
declare function useDevulturMedia(key: string | null | undefined): MediaStatusReturn;
|
|
207
|
+
interface CaptionTrack {
|
|
208
|
+
locale: string;
|
|
209
|
+
label: string;
|
|
210
|
+
src: string;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* A video's pipeline state as a **discriminated union** on `phase`: the render is an exhaustive
|
|
214
|
+
* `switch` (no boolean ordering or `as any`), and adding a new phase is a compile error until it's
|
|
215
|
+
* handled. `processing` carries typed `step`/`percent`; `ready` carries the ref + props ready for
|
|
216
|
+
* `<VideoPlayer>` (token-transparent); `failed` carries a categorized `reason` + `retriable`.
|
|
217
|
+
*/
|
|
218
|
+
type VideoState = {
|
|
219
|
+
phase: "idle";
|
|
220
|
+
} | {
|
|
221
|
+
phase: "queued";
|
|
222
|
+
} | {
|
|
223
|
+
phase: "processing";
|
|
224
|
+
step: ProcessingPhase;
|
|
225
|
+
percent: number;
|
|
226
|
+
} | {
|
|
227
|
+
phase: "ready";
|
|
228
|
+
media: DevulturMedia;
|
|
229
|
+
playlist: string;
|
|
230
|
+
duration: number;
|
|
231
|
+
captions: CaptionTrack[];
|
|
232
|
+
playerProps: VideoProps;
|
|
233
|
+
} | {
|
|
234
|
+
phase: "failed";
|
|
235
|
+
reason: FailureReason;
|
|
236
|
+
message: string;
|
|
237
|
+
retriable: boolean;
|
|
238
|
+
};
|
|
239
|
+
declare function useVideoState(media: DevulturMedia | null | undefined, options?: {
|
|
240
|
+
locales?: string[];
|
|
241
|
+
}): VideoState;
|
|
242
|
+
|
|
278
243
|
/** What `renderItem` gets besides the record. */
|
|
279
244
|
interface MediaLibraryItemState {
|
|
280
245
|
/** The record's reference (`mediaFromRecord`), `null` for a record without a visibility. */
|
|
@@ -657,6 +622,38 @@ interface MediaLibraryState {
|
|
|
657
622
|
*/
|
|
658
623
|
declare function useMediaLibrary(options?: UseMediaLibraryOptions): MediaLibraryState;
|
|
659
624
|
|
|
625
|
+
interface UseMediaUploadOptions {
|
|
626
|
+
/** Resource visibility. Omitted → `config.upload.visibility`, else the Worker's default by type. Your guard can rewrite it. */
|
|
627
|
+
visibility?: Visibility;
|
|
628
|
+
/** Fires ONCE, at the persistence point (PUT done + transcode requested). */
|
|
629
|
+
onComplete?: (media: DevulturMedia) => void;
|
|
630
|
+
onError?: (error: MediaUploadError) => void;
|
|
631
|
+
/** Deletes this old video/asset after a successful PUT (best-effort). */
|
|
632
|
+
replaces?: DevulturMedia | null;
|
|
633
|
+
/** Auto-request the transcode for videos. Default `true`; `false` = upload the raw file unprocessed. */
|
|
634
|
+
process?: boolean;
|
|
635
|
+
/** Caption locales to request when transcoding. */
|
|
636
|
+
locales?: string[];
|
|
637
|
+
}
|
|
638
|
+
interface UseMediaUploadReturn {
|
|
639
|
+
/** Triggers the upload; resolves with the `DevulturMedia` at the persistence point, or `null` if cancelled/failed. */
|
|
640
|
+
upload: (file: File) => Promise<DevulturMedia | null>;
|
|
641
|
+
/** The reactive state machine for the full cycle. */
|
|
642
|
+
state: MediaUploadState;
|
|
643
|
+
/** Aborts the in-progress PUT (`uploading` phase). */
|
|
644
|
+
cancel: () => void;
|
|
645
|
+
/** Returns to `idle` and clears everything. */
|
|
646
|
+
reset: () => void;
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* Unified upload primitive: hides the seam between the (imperative) upload and the (reactive)
|
|
650
|
+
* transcode behind ONE state machine. The consumer calls `upload(file)`, persists the ref in
|
|
651
|
+
* `onComplete`, and renders a `switch` over `state.phase`. Video triggers the transcode on its own;
|
|
652
|
+
* image/file go straight to `ready`. Requires `createUploadUrl` + `getMedia` in the provider (and
|
|
653
|
+
* `processVideo` for video).
|
|
654
|
+
*/
|
|
655
|
+
declare function useMediaUpload(options?: UseMediaUploadOptions): UseMediaUploadReturn;
|
|
656
|
+
|
|
660
657
|
interface DevulturViewerProviderProps {
|
|
661
658
|
/** Media worker base (e.g. `https://media.your-domain.com`). */
|
|
662
659
|
baseUrl: string;
|
|
@@ -694,15 +691,6 @@ interface DevulturViewerProviderProps {
|
|
|
694
691
|
*/
|
|
695
692
|
declare function DevulturViewerProvider({ issueViewerToken, ...props }: DevulturViewerProviderProps): React.JSX.Element;
|
|
696
693
|
|
|
697
|
-
interface ProgressContextValue {
|
|
698
|
-
save: (videoId: string, position: number) => Promise<void>;
|
|
699
|
-
load: (videoId: string) => Promise<{
|
|
700
|
-
lastPosition: number;
|
|
701
|
-
completedAt: Date | null;
|
|
702
|
-
} | null>;
|
|
703
|
-
markComplete: (videoId: string) => Promise<void>;
|
|
704
|
-
reset: (videoId: string) => Promise<void>;
|
|
705
|
-
}
|
|
706
694
|
interface DevulturProviderProps {
|
|
707
695
|
api: DevulturApi;
|
|
708
696
|
/** Media worker base (e.g. `https://media.your-domain.com`). Required for `useMediaUrl`. */
|
|
@@ -722,147 +710,5 @@ interface DevulturProviderProps {
|
|
|
722
710
|
children: React.ReactNode;
|
|
723
711
|
}
|
|
724
712
|
declare function DevulturProvider({ api, baseUrl, tokenArgs, issueViewerToken, children }: DevulturProviderProps): React.JSX.Element;
|
|
725
|
-
declare function useDevulturProgress(): ProgressContextValue;
|
|
726
|
-
/**
|
|
727
|
-
* Ready-to-use delivery URL for a key, with the context's viewer token already injected. The consumer
|
|
728
|
-
* never touches the token or the query — it only declares what it wants (download, resize, etc.).
|
|
729
|
-
*
|
|
730
|
-
* @example
|
|
731
|
-
* <img src={useMediaUrl(key)} />
|
|
732
|
-
* <a href={useMediaUrl(key, { download: true })} download>Download</a>
|
|
733
|
-
* <img src={useMediaUrl(key, { width: 512, format: "webp" })} />
|
|
734
|
-
*/
|
|
735
|
-
declare function useMediaUrl(key: string | null | undefined, options?: MediaRenderOptions): string | null;
|
|
736
|
-
interface VideoProps {
|
|
737
|
-
src: string;
|
|
738
|
-
token: string | undefined;
|
|
739
|
-
captions: {
|
|
740
|
-
locale: string;
|
|
741
|
-
label: string;
|
|
742
|
-
src: string;
|
|
743
|
-
}[];
|
|
744
|
-
/** Session secret → `<VideoPlayer>` sends it in `${SESSION_HEADER}` on hls.js/captions requests. */
|
|
745
|
-
sessionSecret?: string;
|
|
746
|
-
}
|
|
747
|
-
/**
|
|
748
|
-
* Token-transparent props for `<VideoPlayer>` from a video reference: builds the HLS playlist `src`,
|
|
749
|
-
* the viewer `token` (only if private), and the `captions` for the requested locales.
|
|
750
|
-
* The consumer just does `<VideoPlayer {...useVideoProps(lesson.video, { locales })} />`.
|
|
751
|
-
*/
|
|
752
|
-
declare function useVideoProps(media: DevulturMedia | null | undefined, options?: {
|
|
753
|
-
locales?: string[];
|
|
754
|
-
}): VideoProps | null;
|
|
755
|
-
interface DownloadLinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, "href" | "download" | "media"> {
|
|
756
|
-
media: DevulturMedia | null | undefined;
|
|
757
|
-
/** Name it downloads as. Without this it uses the upload's original name. */
|
|
758
|
-
filename?: string;
|
|
759
|
-
/**
|
|
760
|
-
* A private download that failed: `token_unavailable` right away when the viewer token couldn't be issued
|
|
761
|
-
* (`useDevultur().retryToken()` tries again), `http_error` when the delivery refused it.
|
|
762
|
-
*/
|
|
763
|
-
onDownloadError?: (error: MediaFetchError) => void;
|
|
764
|
-
children: React.ReactNode;
|
|
765
|
-
}
|
|
766
|
-
/**
|
|
767
|
-
* `<a>` that downloads a media with its original name (token-transparent). The worker serves it with
|
|
768
|
-
* `Content-Disposition: attachment`, so a click downloads the file instead of opening it in a tab.
|
|
769
|
-
*
|
|
770
|
-
* Private: an `<a download>` NAVIGATES, and a navigation can't send `${SESSION_HEADER}` → with session
|
|
771
|
-
* binding the gate gives a 401. So, for private media, we intercept the click, blob-fetch with the header
|
|
772
|
-
* (like private `<Image>`) and trigger the download from the object URL. Public keeps native navigation.
|
|
773
|
-
*/
|
|
774
|
-
declare function DownloadLink({ media, filename, onDownloadError, children, ...anchorProps }: DownloadLinkProps): React.JSX.Element | null;
|
|
775
|
-
interface MediaStatusReturn {
|
|
776
|
-
status: MediaStatusValue;
|
|
777
|
-
/** Typed progress: `phase` is the pipeline step (no `as any`). */
|
|
778
|
-
progress: {
|
|
779
|
-
current: number;
|
|
780
|
-
total: number;
|
|
781
|
-
percent: number;
|
|
782
|
-
phase?: ProcessingPhase;
|
|
783
|
-
} | null;
|
|
784
|
-
error: string | null;
|
|
785
|
-
/** Categorized failure reason (null if it didn't fail). */
|
|
786
|
-
failureReason: FailureReason | null;
|
|
787
|
-
/** Whether the failure is retriable (null if it didn't fail). */
|
|
788
|
-
retriable: boolean | null;
|
|
789
|
-
isQueued: boolean;
|
|
790
|
-
isTranscoding: boolean;
|
|
791
|
-
isCaptioning: boolean;
|
|
792
|
-
isReady: boolean;
|
|
793
|
-
isFailed: boolean;
|
|
794
|
-
playlistUrl: string | null;
|
|
795
|
-
thumbnailKey: string | null;
|
|
796
|
-
captionLocales: string[];
|
|
797
|
-
duration: number | null;
|
|
798
|
-
isLoading: boolean;
|
|
799
|
-
}
|
|
800
|
-
declare function useDevulturMedia(key: string | null | undefined): MediaStatusReturn;
|
|
801
|
-
interface CaptionTrack {
|
|
802
|
-
locale: string;
|
|
803
|
-
label: string;
|
|
804
|
-
src: string;
|
|
805
|
-
}
|
|
806
|
-
/**
|
|
807
|
-
* A video's pipeline state as a **discriminated union** on `phase`: the render is an exhaustive
|
|
808
|
-
* `switch` (no boolean ordering or `as any`), and adding a new phase is a compile error until it's
|
|
809
|
-
* handled. `processing` carries typed `step`/`percent`; `ready` carries the ref + props ready for
|
|
810
|
-
* `<VideoPlayer>` (token-transparent); `failed` carries a categorized `reason` + `retriable`.
|
|
811
|
-
*/
|
|
812
|
-
type VideoState = {
|
|
813
|
-
phase: "idle";
|
|
814
|
-
} | {
|
|
815
|
-
phase: "queued";
|
|
816
|
-
} | {
|
|
817
|
-
phase: "processing";
|
|
818
|
-
step: ProcessingPhase;
|
|
819
|
-
percent: number;
|
|
820
|
-
} | {
|
|
821
|
-
phase: "ready";
|
|
822
|
-
media: DevulturMedia;
|
|
823
|
-
playlist: string;
|
|
824
|
-
duration: number;
|
|
825
|
-
captions: CaptionTrack[];
|
|
826
|
-
playerProps: VideoProps;
|
|
827
|
-
} | {
|
|
828
|
-
phase: "failed";
|
|
829
|
-
reason: FailureReason;
|
|
830
|
-
message: string;
|
|
831
|
-
retriable: boolean;
|
|
832
|
-
};
|
|
833
|
-
declare function useVideoState(media: DevulturMedia | null | undefined, options?: {
|
|
834
|
-
locales?: string[];
|
|
835
|
-
}): VideoState;
|
|
836
|
-
interface UseMediaUploadOptions {
|
|
837
|
-
/** Resource visibility. Omitted → `config.upload.visibility`, else the Worker's default by type. Your guard can rewrite it. */
|
|
838
|
-
visibility?: Visibility;
|
|
839
|
-
/** Fires ONCE, at the persistence point (PUT done + transcode requested). */
|
|
840
|
-
onComplete?: (media: DevulturMedia) => void;
|
|
841
|
-
onError?: (error: MediaUploadError) => void;
|
|
842
|
-
/** Deletes this old video/asset after a successful PUT (best-effort). */
|
|
843
|
-
replaces?: DevulturMedia | null;
|
|
844
|
-
/** Auto-request the transcode for videos. Default `true`; `false` = upload the raw file unprocessed. */
|
|
845
|
-
process?: boolean;
|
|
846
|
-
/** Caption locales to request when transcoding. */
|
|
847
|
-
locales?: string[];
|
|
848
|
-
}
|
|
849
|
-
interface UseMediaUploadReturn {
|
|
850
|
-
/** Triggers the upload; resolves with the `DevulturMedia` at the persistence point, or `null` if cancelled/failed. */
|
|
851
|
-
upload: (file: File) => Promise<DevulturMedia | null>;
|
|
852
|
-
/** The reactive state machine for the full cycle. */
|
|
853
|
-
state: MediaUploadState;
|
|
854
|
-
/** Aborts the in-progress PUT (`uploading` phase). */
|
|
855
|
-
cancel: () => void;
|
|
856
|
-
/** Returns to `idle` and clears everything. */
|
|
857
|
-
reset: () => void;
|
|
858
|
-
}
|
|
859
|
-
/**
|
|
860
|
-
* Unified upload primitive: hides the seam between the (imperative) upload and the (reactive)
|
|
861
|
-
* transcode behind ONE state machine. The consumer calls `upload(file)`, persists the ref in
|
|
862
|
-
* `onComplete`, and renders a `switch` over `state.phase`. Video triggers the transcode on its own;
|
|
863
|
-
* image/file go straight to `ready`. Requires `createUploadUrl` + `getMedia` in the provider (and
|
|
864
|
-
* `processVideo` for video).
|
|
865
|
-
*/
|
|
866
|
-
declare function useMediaUpload(options?: UseMediaUploadOptions): UseMediaUploadReturn;
|
|
867
713
|
|
|
868
|
-
export { AttachmentCard, type AttachmentCardProps, AttachmentLabels, type CaptionTrack, CropUpload, type CropUploadLabels, type CropUploadProps, type CropUploadRenderProps,
|
|
714
|
+
export { AttachmentCard, type AttachmentCardProps, AttachmentLabels, type CaptionTrack, CropUpload, type CropUploadLabels, type CropUploadProps, type CropUploadRenderProps, DevulturApi, type DevulturCapability, DevulturCapabilityError, DevulturProvider, DevulturViewerProvider, type DevulturViewerProviderProps, DocumentLink, type DocumentLinkProps, DownloadLink, type DownloadLinkProps, Image, type ImageProps, MediaFetchError, MediaLibrary, type MediaLibraryItemState, MediaLibraryLabels, type MediaLibraryPart, type MediaLibraryProps, type MediaLibraryState, type MediaLibraryStatus, type MediaObjectUrl, MediaPicker, MediaPickerLabels, type MediaPickerLibraryProps, type MediaPickerProps, type MediaPickerSelectionProps, type MediaPickerState, type MediaPickerUpload$1 as MediaPickerUpload, type MediaPickerUploadProps, type MediaPickerUploads, type MediaStatusReturn, type PdfPreviewConfig, PdfPreviewProvider, PdfThumbnail, type PdfThumbnailProps, PdfjsLoader, Preview, type PreviewKind, PreviewLabels, type PreviewProps, type UseMediaLibraryOptions, type UseMediaObjectUrlOptions, type UseMediaUploadOptions, type UseMediaUploadReturn, VideoProps, type VideoState, ViewerTokenArgs, matchesAccept, useDevulturMedia, useMediaLibrary, useMediaObjectUrl, useMediaPicker, useMediaUpload, useVideoState };
|