@muhkoo/connect 0.10.9-alpha.0 → 0.10.10-alpha.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/dist/browser/index.js +38 -20
- package/dist/browser/index.js.map +1 -1
- package/dist/connect.d.ts +13 -0
- package/dist/server/index.js +38 -20
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
package/dist/browser/index.js
CHANGED
|
@@ -4120,31 +4120,37 @@ class FileStorage {
|
|
|
4120
4120
|
*/
|
|
4121
4121
|
async writeFileToShards(input) {
|
|
4122
4122
|
await this.codec.ready(this.rsWasmModule);
|
|
4123
|
-
const data = await toUint8Array(input.data);
|
|
4124
4123
|
const fileId = input.fileId ?? generateId();
|
|
4125
4124
|
const createdAt = Date.now();
|
|
4126
4125
|
const chunks = [];
|
|
4127
|
-
|
|
4126
|
+
// Read the source per-chunk so the peak memory footprint stays at
|
|
4127
|
+
// ~chunkSize even for multi-GB files. A Blob/File is sliced lazily (only
|
|
4128
|
+
// the current chunk's bytes are materialized) — reading the whole thing
|
|
4129
|
+
// up front would blow past the browser's ~2GB ArrayBuffer cap and throw
|
|
4130
|
+
// "the file could not be read". A caller that already has the bytes in a
|
|
4131
|
+
// Uint8Array just gets zero-copy subarray views.
|
|
4132
|
+
const asBytes = input.data instanceof Uint8Array ? input.data : null;
|
|
4133
|
+
const size = asBytes ? asBytes.length : input.data.size;
|
|
4134
|
+
const readChunk = async (start, end) => asBytes ? asBytes.subarray(start, end)
|
|
4135
|
+
: new Uint8Array(await input.data.slice(start, end).arrayBuffer());
|
|
4136
|
+
const totalChunks = Math.max(1, Math.ceil(size / this.chunkSize));
|
|
4128
4137
|
input.onProgress?.(0, totalChunks);
|
|
4129
|
-
//
|
|
4130
|
-
|
|
4131
|
-
// Within a chunk, the shard uploads are parallelized up to
|
|
4132
|
-
// `this.concurrency`.
|
|
4133
|
-
for (let chunkIndex = 0; chunkIndex * this.chunkSize < Math.max(1, data.length); chunkIndex++) {
|
|
4138
|
+
// Within a chunk, the shard uploads are parallelized up to `this.concurrency`.
|
|
4139
|
+
for (let chunkIndex = 0; chunkIndex * this.chunkSize < Math.max(1, size); chunkIndex++) {
|
|
4134
4140
|
const start = chunkIndex * this.chunkSize;
|
|
4135
|
-
const end = Math.min(start + this.chunkSize,
|
|
4136
|
-
const plaintext =
|
|
4141
|
+
const end = Math.min(start + this.chunkSize, size);
|
|
4142
|
+
const plaintext = await readChunk(start, end);
|
|
4137
4143
|
chunks.push(await this.writeChunk(plaintext, chunkIndex));
|
|
4138
4144
|
input.onProgress?.(chunks.length, totalChunks);
|
|
4139
4145
|
// Stop after one iteration if the file is empty — we still emit a
|
|
4140
4146
|
// single zero-length chunk so the manifest has a stable shape.
|
|
4141
|
-
if (
|
|
4147
|
+
if (size === 0)
|
|
4142
4148
|
break;
|
|
4143
4149
|
}
|
|
4144
4150
|
const manifest = {
|
|
4145
4151
|
id: fileId,
|
|
4146
4152
|
name: input.metadata.name,
|
|
4147
|
-
size
|
|
4153
|
+
size,
|
|
4148
4154
|
type: input.metadata.type,
|
|
4149
4155
|
path: input.metadata.path,
|
|
4150
4156
|
lastModified: input.metadata.lastModified ?? createdAt,
|
|
@@ -4180,6 +4186,19 @@ class FileStorage {
|
|
|
4180
4186
|
}
|
|
4181
4187
|
return { data: out, stat: manifestToStat(manifest) };
|
|
4182
4188
|
}
|
|
4189
|
+
/**
|
|
4190
|
+
* Streaming inverse of {@link writeFileToShards}: yields each chunk's
|
|
4191
|
+
* decrypted plaintext in order WITHOUT concatenating. Peak memory stays at
|
|
4192
|
+
* ~one chunk, so multi-GB files (which overflow a single `Uint8Array`) can be
|
|
4193
|
+
* piped straight to a file/socket. Same shard sourcing (cache → peers →
|
|
4194
|
+
* origin) and per-chunk auth as {@link readFileFromShards}.
|
|
4195
|
+
*/
|
|
4196
|
+
async *readChunksFromShards(manifest) {
|
|
4197
|
+
await this.codec.ready(this.rsWasmModule);
|
|
4198
|
+
for (const chunkManifest of [...manifest.chunks].sort((a, b) => a.chunkIndex - b.chunkIndex)) {
|
|
4199
|
+
yield await this.readChunk(chunkManifest);
|
|
4200
|
+
}
|
|
4201
|
+
}
|
|
4183
4202
|
// -------------------------------------------------------------------------
|
|
4184
4203
|
// Space-backed convenience wrappers — encrypt + upload + write manifest.
|
|
4185
4204
|
// Require a `SharedSpaceClient` to have been provided at construction.
|
|
@@ -4313,14 +4332,6 @@ class FileStorage {
|
|
|
4313
4332
|
await Promise.all(workers);
|
|
4314
4333
|
}
|
|
4315
4334
|
}
|
|
4316
|
-
/** Normalize `data` to a flat `Uint8Array`. */
|
|
4317
|
-
async function toUint8Array(data) {
|
|
4318
|
-
if (data instanceof Uint8Array)
|
|
4319
|
-
return data;
|
|
4320
|
-
// Blob covers File too (File extends Blob in every runtime we target).
|
|
4321
|
-
const ab = await data.arrayBuffer();
|
|
4322
|
-
return new Uint8Array(ab);
|
|
4323
|
-
}
|
|
4324
4335
|
|
|
4325
4336
|
/**
|
|
4326
4337
|
* HTTP client for the gated file-manifest store on a SharedSpace
|
|
@@ -5057,7 +5068,7 @@ function base64UrlDecode(s) {
|
|
|
5057
5068
|
* expect (and isn't serving a stale cached bundle). Keep this in sync with
|
|
5058
5069
|
* `package.json` `version`.
|
|
5059
5070
|
*/
|
|
5060
|
-
const VERSION = "0.10.
|
|
5071
|
+
const VERSION = "0.10.10-alpha.0";
|
|
5061
5072
|
|
|
5062
5073
|
/**
|
|
5063
5074
|
* `HttpClient` — the one place the unified {@link Client} talks to the
|
|
@@ -7617,6 +7628,13 @@ class Space {
|
|
|
7617
7628
|
async getFile(manifest) {
|
|
7618
7629
|
return this.fileStorage().readFileFromShards(manifest);
|
|
7619
7630
|
}
|
|
7631
|
+
/** Streaming read: async-iterate a stored file's decrypted chunks in order,
|
|
7632
|
+
* never holding the whole file in memory. Use for multi-GB files (a single
|
|
7633
|
+
* `Uint8Array` can't hold them) — e.g. a transcoder piping the raw to a temp
|
|
7634
|
+
* file. Same peer/origin shard sourcing as {@link getFile}. */
|
|
7635
|
+
getFileStream(manifest) {
|
|
7636
|
+
return this.fileStorage().readChunksFromShards(manifest);
|
|
7637
|
+
}
|
|
7620
7638
|
/** Declare a file's shards (ref++ + meter) for a manifest already stored —
|
|
7621
7639
|
* used to back-fill accounting for files written before commit existed, or to
|
|
7622
7640
|
* register a manifest received via sharing. `putFile` already commits new
|