Proposal: `Blob.from()` for creating virtual Blobs with custom backing storage
まだ誰も着手していません。
- 主要言語
- HTML
- スター
- 118
- フォーク
- 52
- 平均マージ
- 9日 16時間
- マージ済み PR(30日)
- 1
説明
I'd like to propose an addition to the Blob API to enable the creation of virtual Blob or File instances backed by custom-defined storage logic. This would allow SDKs and libraries to expose file-like objects without requiring the developer to manage low-level data fetching or streaming themselves.
✨ Proposed API
const virtualBlob = Blob.from({
size: 1024,
async stream(start, end) {
return customStreamOrAsyncIterable(start, end)
}
})
-
size: Total size of the blob (required).
-
stream(start, end): Required method that returns a ReadableStream or AsyncIterable for the requested byte range. it may or may not be async
This API is synchronous to create, but lazy in that no data is fetched until actually needed. The internal Blob machinery would take care of slicing and offsetting, so the developers only need to focus on implement the backing source logic.
🧩 Example Usage with SDK
This enables a clean integration pattern with APIs like Dropbox, Google Drive, or internal systems:
import Client from 'dropbox/sdk.js'
const dropbox = new Client(apiKey)
const fileHandle = await dropbox.getFileHandle(user, path)
const file = fileHandle.openAsFile()
const url = URL.createObjectURL(file)
What dropbox sdk then actually dose:
function openAsFile() {
const blobPart = Blob.from({
size: this.#size,
async stream(start, end) {
// makes a partial request for the requested range
const res = await fetch(url, {
headers: { range: `bytes=${start}-${end}` }
})
return res.body
}
})
return new File([ blobPart ], this.#filename, {
type: this.#type,
lastModified: this.#lastModified
})
}
In this model:
fileHandlecontains only metadata (filename, type, size, lastModified).openAsFile()constructs a File backed by virtual Blob part.- No actual data is fetched until the Blob is consumed — for example, when writing to disk or calling
.arrayBuffer().
✅ Benefits
- Enables SDKs to expose virtual File/Blob objects without requiring developers to build ad-hoc wrappers.
- Avoids early data fetching and defers I/O until absolutely needed.
- Keeps the interface clean, idiomatic, and interoperable with existing Blob consumers.
- Great fit for use cases like remote file systems, zip file introspection, lazy file generation, and more.
🔧 Comparison to Today
Without this feature, developers must manually wrap streams, manage slicing, and emulate Blob behavior — often with duplicated effort and edge-case bugs. This addition would make such patterns first-class citizens in the platform.
🔍 Real-World Problem This Solves
A common pattern on the web is to trigger file downloads using a Blob URL and a programmatically clicked <a> tag:
const blob = new Blob([fileData], { type: 'application/pdf' })
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = 'report.pdf'
a.click()
However, to use this pattern today, you must already have all the file data in memory.
If you're working with a remote file (e.g. from cloud storage or an SDK), you can't delay the download until after the click — because:
Once the click handler ends, isTrusted becomes false.
Any async operation (like fetching the file) that happens after the click ends is now treated as not user-initiated.
Browsers will block the download, thinking it's an automatic or malicious attempt.
⛔️ This effectively means: if you want to allow the user to download a file, you must download the entire file first, even if they never end up clicking “Download.”
With Blob.from(), we could instead return a virtual Blob that doesn't require any data until it's needed:
const blob = Blob.from({
size: 10_000_000,
async stream(start, end) {
return fetchRangeStream(start, end)
}
})
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = 'report.pdf'
a.click()
In this model, the download is triggered immediately within the click event — but data is only fetched as it's needed, safely within the user gesture's trusted scope.
✅ This allows you to:
- Keep memory usage low (no preloading needed).
- Allow user-triggered downloads of remote/virtual files.
- Preserve compatibility with browser download restrictions.
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
まず、Blob、File、slicing、streaming、object URLs に関する既存の File API 定義を確認します。この issue ではファイルもテストも指定されていません。完了には、size と stream(start, end) の契約、lazy fetching の動作、既存の Blob コンシューマーとの互換性を含む、Blob.from() の解決済み仕様が必要です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- javascript
- 領域
- api, web-dev
- issue の種類
- 機能追加
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 32/100