deepspace 0.12.0 → 0.14.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/CHANGELOG.md +162 -0
- package/dist/{chunk-ZJ43EK3N.js → chunk-233GQU2H.js} +492 -365
- package/dist/chunk-233GQU2H.js.map +1 -0
- package/dist/cli.js +536 -172
- package/dist/cli.js.map +1 -1
- package/dist/documentation-client-core.d.ts +2 -2
- package/dist/documentation-client-core.js +1 -1
- package/dist/documentation-default-renderer.cjs +34 -34
- package/dist/documentation-react.d.ts +1 -1
- package/dist/documentation-react.js +1 -1
- package/dist/documentation-runtime.js +10 -10
- package/dist/documentation-server-core.d.ts +2 -2
- package/dist/documentation-server-core.js +1 -1
- package/dist/documentation.js +2 -2
- package/dist/documentation.js.map +1 -1
- package/dist/index.d.ts +28 -3
- package/dist/index.js +93 -8
- package/dist/index.js.map +1 -1
- package/dist/{public-BGRX_Cjd.d.ts → public-BtArwbVM.d.ts} +8 -0
- package/dist/server.d.ts +143 -27
- package/dist/server.js +427 -91
- package/dist/server.js.map +1 -1
- package/dist/worker.d.ts +140 -24
- package/dist/worker.js +432 -91
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-ZJ43EK3N.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -3636,6 +3636,12 @@ declare function toConnectionStatus(queryStatus: string): ConnectionStatus;
|
|
|
3636
3636
|
*
|
|
3637
3637
|
* Provides upload, download, list, and delete for files in R2.
|
|
3638
3638
|
*
|
|
3639
|
+
* Uploads pick their own transport. A small file goes in one request; a large
|
|
3640
|
+
* one is chunked into parts with `Blob.slice`, so peak memory is bounded by
|
|
3641
|
+
* the PART SIZE rather than by the file — a 1 GiB video costs one part, not a
|
|
3642
|
+
* gibibyte — and the file ceiling becomes a product decision rather than a
|
|
3643
|
+
* request-size accident. Callers do nothing differently either way.
|
|
3644
|
+
*
|
|
3639
3645
|
* Two scopes are supported via the `scope` option:
|
|
3640
3646
|
* - `'self'` (default): per-user storage. Reads require auth.
|
|
3641
3647
|
* - `'app'`: app-wide storage. Reads are public — the upload URL works
|
|
@@ -3668,10 +3674,29 @@ interface R2FileInfo {
|
|
|
3668
3674
|
originalName?: string;
|
|
3669
3675
|
uploadedBy?: string;
|
|
3670
3676
|
}
|
|
3677
|
+
/** Told after each part lands, so a long upload can drive a progress bar. */
|
|
3678
|
+
type UploadProgress = (sent: number, total: number) => void;
|
|
3679
|
+
interface UploadOptions {
|
|
3680
|
+
onProgress?: UploadProgress;
|
|
3681
|
+
}
|
|
3671
3682
|
interface UseR2FilesReturn {
|
|
3672
|
-
/**
|
|
3673
|
-
|
|
3674
|
-
|
|
3683
|
+
/**
|
|
3684
|
+
* Upload a File or Blob. Optionally provide a display name.
|
|
3685
|
+
*
|
|
3686
|
+
* A file above the single-request bound is chunked automatically and sent as
|
|
3687
|
+
* parts — nothing to opt into, and nothing held in memory beyond one part.
|
|
3688
|
+
* Pass `onProgress` to follow a large one.
|
|
3689
|
+
*/
|
|
3690
|
+
upload: (file: File | Blob, name?: string, options?: UploadOptions) => Promise<R2UploadResult>;
|
|
3691
|
+
/**
|
|
3692
|
+
* Upload raw base64 data.
|
|
3693
|
+
*
|
|
3694
|
+
* Single-request only: base64 has to be materialized whole to be decoded, so
|
|
3695
|
+
* this path keeps the one-request bound rather than the file ceiling — and
|
|
3696
|
+
* because the request carries the ENCODED string, its real budget is
|
|
3697
|
+
* `MAX_BASE64_UPLOAD_BYTES` (~18.75 MiB decoded), not the full 25 MiB. Send a
|
|
3698
|
+
* Blob through `upload` for anything larger; it chunks.
|
|
3699
|
+
*/
|
|
3675
3700
|
uploadBase64: (base64Data: string, name: string, mimeType?: string) => Promise<R2UploadResult>;
|
|
3676
3701
|
/**
|
|
3677
3702
|
* Delete a file. Accepts an R2FileInfo from `list()` or a raw key string.
|
package/dist/index.js
CHANGED
|
@@ -3521,8 +3521,32 @@ function toConnectionStatus(queryStatus) {
|
|
|
3521
3521
|
import { useCallback as useCallback15, useState as useState13, useMemo as useMemo11 } from "react";
|
|
3522
3522
|
|
|
3523
3523
|
// src/shared/app-files.ts
|
|
3524
|
-
var MAX_APP_FILE_BYTES =
|
|
3524
|
+
var MAX_APP_FILE_BYTES = 1024 * 1024 * 1024;
|
|
3525
|
+
var MAX_UPLOAD_REQUEST_BYTES = 25 * 1024 * 1024;
|
|
3526
|
+
var UPLOAD_PART_BYTES = 20 * 1024 * 1024;
|
|
3527
|
+
var MAX_UPLOAD_PARTS = Math.ceil(MAX_APP_FILE_BYTES / UPLOAD_PART_BYTES);
|
|
3528
|
+
var MAX_BASE64_UPLOAD_BYTES = Math.floor(MAX_UPLOAD_REQUEST_BYTES * 3 / 4);
|
|
3529
|
+
function planUploadParts(totalBytes, partSize) {
|
|
3530
|
+
const parts = [];
|
|
3531
|
+
for (let start = 0; start < totalBytes; start += partSize) {
|
|
3532
|
+
parts.push({
|
|
3533
|
+
partNumber: parts.length + 1,
|
|
3534
|
+
start,
|
|
3535
|
+
end: Math.min(start + partSize, totalBytes)
|
|
3536
|
+
});
|
|
3537
|
+
}
|
|
3538
|
+
return parts;
|
|
3539
|
+
}
|
|
3540
|
+
var APP_STORAGE_LIMIT_BYTES = {
|
|
3541
|
+
test: 0,
|
|
3542
|
+
free: 128 * 1024 * 1024,
|
|
3543
|
+
starter: 512 * 1024 * 1024,
|
|
3544
|
+
premium: 2 * 1024 * 1024 * 1024,
|
|
3545
|
+
admin: 10 * 1024 * 1024 * 1024
|
|
3546
|
+
};
|
|
3547
|
+
var MAX_DEPLOY_ASSET_FILE_BYTES = 25 * 1024 * 1024;
|
|
3525
3548
|
function formatBytes(bytes) {
|
|
3549
|
+
if (bytes >= 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GiB`;
|
|
3526
3550
|
if (bytes >= 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MiB`;
|
|
3527
3551
|
if (bytes >= 1024) return `${Math.round(bytes / 1024)} KiB`;
|
|
3528
3552
|
return `${bytes} B`;
|
|
@@ -3530,8 +3554,8 @@ function formatBytes(bytes) {
|
|
|
3530
3554
|
function encodeKeyPath(key) {
|
|
3531
3555
|
return key.split("/").map(encodeURIComponent).join("/");
|
|
3532
3556
|
}
|
|
3533
|
-
function oversizeMessage(bytes) {
|
|
3534
|
-
return `That file is ${formatBytes(bytes)}; the limit is ${formatBytes(
|
|
3557
|
+
function oversizeMessage(bytes, limit = MAX_APP_FILE_BYTES) {
|
|
3558
|
+
return `That file is ${formatBytes(bytes)}; the limit is ${formatBytes(limit)} per file.`;
|
|
3535
3559
|
}
|
|
3536
3560
|
function describeFilesFailure(status, body) {
|
|
3537
3561
|
const trimmed = body.trim();
|
|
@@ -3543,8 +3567,9 @@ function describeFilesFailure(status, body) {
|
|
|
3543
3567
|
}
|
|
3544
3568
|
}
|
|
3545
3569
|
if (status === 413) {
|
|
3546
|
-
return `The
|
|
3570
|
+
return `The upload is too large. Files are limited to ${formatBytes(MAX_APP_FILE_BYTES)}, and one request may carry ${formatBytes(MAX_UPLOAD_REQUEST_BYTES)} \u2014 a larger request is rejected by the network before the app receives it.`;
|
|
3547
3571
|
}
|
|
3572
|
+
if (status === 411) return "The upload did not declare its length.";
|
|
3548
3573
|
if (status === 401 || status === 403) return "Not authorized to write these files.";
|
|
3549
3574
|
if (status === 415) return "That file type is not accepted.";
|
|
3550
3575
|
if (status >= 500) return `The files service failed (HTTP ${status}). Retry shortly.`;
|
|
@@ -3552,8 +3577,8 @@ function describeFilesFailure(status, body) {
|
|
|
3552
3577
|
}
|
|
3553
3578
|
|
|
3554
3579
|
// src/client/storage/useR2Files.ts
|
|
3555
|
-
function oversize(bytes) {
|
|
3556
|
-
return bytes >
|
|
3580
|
+
function oversize(bytes, limit = MAX_APP_FILE_BYTES) {
|
|
3581
|
+
return bytes > limit ? { success: false, error: oversizeMessage(bytes, limit) } : null;
|
|
3557
3582
|
}
|
|
3558
3583
|
async function readUploadResult(response) {
|
|
3559
3584
|
const text = await response.text();
|
|
@@ -3572,6 +3597,58 @@ function resolveFile(fileOrKey) {
|
|
|
3572
3597
|
}
|
|
3573
3598
|
return { key: fileOrKey.key, name: fileOrKey.originalName };
|
|
3574
3599
|
}
|
|
3600
|
+
async function uploadInParts(file, name, scopeParams, authHeaders, onProgress) {
|
|
3601
|
+
const headers = await authHeaders();
|
|
3602
|
+
const json = { ...headers, "Content-Type": "application/json" };
|
|
3603
|
+
const initResponse = await fetch(`/api/files/multipart?${scopeParams}`, {
|
|
3604
|
+
method: "POST",
|
|
3605
|
+
headers: json,
|
|
3606
|
+
body: JSON.stringify({ name, mimeType: file.type || "application/octet-stream", size: file.size })
|
|
3607
|
+
});
|
|
3608
|
+
if (!initResponse.ok) return await readUploadResult(initResponse);
|
|
3609
|
+
const session = await initResponse.json();
|
|
3610
|
+
if (!Number.isSafeInteger(session.partSize) || session.partSize < 1) {
|
|
3611
|
+
return {
|
|
3612
|
+
success: false,
|
|
3613
|
+
error: `The files service advertised an unusable part size (${session.partSize}).`
|
|
3614
|
+
};
|
|
3615
|
+
}
|
|
3616
|
+
const query = `${scopeParams}&uploadKey=${encodeKeyPath(session.uploadKey)}&uploadId=${encodeURIComponent(session.uploadId)}`;
|
|
3617
|
+
const plan = planUploadParts(file.size, session.partSize);
|
|
3618
|
+
const parts = [];
|
|
3619
|
+
let assembled = false;
|
|
3620
|
+
try {
|
|
3621
|
+
for (const part of plan) {
|
|
3622
|
+
const send = () => fetch(`/api/files/multipart/part?${query}&partNumber=${part.partNumber}`, {
|
|
3623
|
+
method: "PUT",
|
|
3624
|
+
headers,
|
|
3625
|
+
body: file.slice(part.start, part.end)
|
|
3626
|
+
});
|
|
3627
|
+
let response = await send().catch(() => null);
|
|
3628
|
+
if (!response || response.status === 429 || response.status >= 500) {
|
|
3629
|
+
const retried = await send().catch(() => null);
|
|
3630
|
+
if (retried) response = retried;
|
|
3631
|
+
}
|
|
3632
|
+
if (!response) return { success: false, error: "The files service could not be reached." };
|
|
3633
|
+
if (!response.ok) return await readUploadResult(response);
|
|
3634
|
+
parts.push(await response.json());
|
|
3635
|
+
onProgress?.(part.end, file.size);
|
|
3636
|
+
}
|
|
3637
|
+
const completed = await fetch(`/api/files/multipart/complete?${query}`, {
|
|
3638
|
+
method: "POST",
|
|
3639
|
+
headers: json,
|
|
3640
|
+
body: JSON.stringify({ parts })
|
|
3641
|
+
});
|
|
3642
|
+
assembled = completed.ok;
|
|
3643
|
+
return await readUploadResult(completed);
|
|
3644
|
+
} finally {
|
|
3645
|
+
if (!assembled) {
|
|
3646
|
+
await fetch(`/api/files/multipart?${query}`, { method: "DELETE", headers }).catch(
|
|
3647
|
+
() => void 0
|
|
3648
|
+
);
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3651
|
+
}
|
|
3575
3652
|
function useR2Files(options) {
|
|
3576
3653
|
const [isUploading, setIsUploading] = useState13(false);
|
|
3577
3654
|
const scope = options?.scope ?? "self";
|
|
@@ -3588,11 +3665,15 @@ function useR2Files(options) {
|
|
|
3588
3665
|
return {};
|
|
3589
3666
|
}, []);
|
|
3590
3667
|
const upload = useCallback15(
|
|
3591
|
-
async (file, name) => {
|
|
3668
|
+
async (file, name, options2) => {
|
|
3592
3669
|
setIsUploading(true);
|
|
3593
3670
|
try {
|
|
3594
3671
|
const tooBig = oversize(file.size);
|
|
3595
3672
|
if (tooBig) return tooBig;
|
|
3673
|
+
const fileName = name ?? (file instanceof File ? file.name : "upload");
|
|
3674
|
+
if (file.size > UPLOAD_PART_BYTES) {
|
|
3675
|
+
return await uploadInParts(file, fileName, scopeParams, authHeaders, options2?.onProgress);
|
|
3676
|
+
}
|
|
3596
3677
|
const headers = await authHeaders();
|
|
3597
3678
|
const formData = new FormData();
|
|
3598
3679
|
formData.append("file", file);
|
|
@@ -3602,6 +3683,7 @@ function useR2Files(options) {
|
|
|
3602
3683
|
headers,
|
|
3603
3684
|
body: formData
|
|
3604
3685
|
});
|
|
3686
|
+
options2?.onProgress?.(file.size, file.size);
|
|
3605
3687
|
return await readUploadResult(response);
|
|
3606
3688
|
} catch (err) {
|
|
3607
3689
|
return { success: false, error: err instanceof Error ? err.message : "Upload failed" };
|
|
@@ -3615,7 +3697,10 @@ function useR2Files(options) {
|
|
|
3615
3697
|
async (base64Data, name, mimeType) => {
|
|
3616
3698
|
setIsUploading(true);
|
|
3617
3699
|
try {
|
|
3618
|
-
const tooBig = oversize(
|
|
3700
|
+
const tooBig = oversize(
|
|
3701
|
+
Math.floor(base64Data.length * 3 / 4),
|
|
3702
|
+
MAX_BASE64_UPLOAD_BYTES
|
|
3703
|
+
);
|
|
3619
3704
|
if (tooBig) return tooBig;
|
|
3620
3705
|
const headers = await authHeaders();
|
|
3621
3706
|
const response = await fetch(`/api/files/upload?${scopeParams}`, {
|