@muhkoo/connect 0.15.0-alpha.0 → 0.15.0-alpha.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/dist/browser/index.js +53 -24
- package/dist/browser/index.js.map +1 -1
- package/dist/connect.d.ts +24 -1
- package/dist/server/index.js +53 -24
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
package/dist/connect.d.ts
CHANGED
|
@@ -6757,6 +6757,8 @@ interface VfsContentStore {
|
|
|
6757
6757
|
write(data: Uint8Array | Blob, meta: {
|
|
6758
6758
|
name: string;
|
|
6759
6759
|
type: string;
|
|
6760
|
+
}, opts?: {
|
|
6761
|
+
onProgress?: (done: number, total: number) => void;
|
|
6760
6762
|
}): Promise<{
|
|
6761
6763
|
manifest: FileManifest;
|
|
6762
6764
|
size: number;
|
|
@@ -6817,6 +6819,18 @@ declare class VfsNamespace {
|
|
|
6817
6819
|
* than by TTL — a stale directory listing shows files that are not there.
|
|
6818
6820
|
*/
|
|
6819
6821
|
private cache;
|
|
6822
|
+
/**
|
|
6823
|
+
* The write of each directory record still in flight, by id.
|
|
6824
|
+
*
|
|
6825
|
+
* Two writes of one record must land in the order they were made. The
|
|
6826
|
+
* personal space has no compare-and-swap: of two writes of one key that
|
|
6827
|
+
* are in flight together it keeps whichever request finishes last, and
|
|
6828
|
+
* that is often the one sent first. Then the earlier write, sealed before
|
|
6829
|
+
* the later edit was made, undoes it. That is how a file deleted forever
|
|
6830
|
+
* from the Trash, while the move that put it there was still being
|
|
6831
|
+
* written, came back. So each write waits for the one before it.
|
|
6832
|
+
*/
|
|
6833
|
+
private readonly writing;
|
|
6820
6834
|
private readonly historyLimit;
|
|
6821
6835
|
private readonly maxEntries;
|
|
6822
6836
|
private readonly maxPathChars;
|
|
@@ -6975,6 +6989,7 @@ declare class VfsNamespace {
|
|
|
6975
6989
|
*/
|
|
6976
6990
|
writeFile(path: string, data: Uint8Array | string | Blob, opts?: {
|
|
6977
6991
|
type?: string;
|
|
6992
|
+
onProgress?: (done: number, total: number) => void;
|
|
6978
6993
|
}): Promise<VfsStat>;
|
|
6979
6994
|
/**
|
|
6980
6995
|
* Delete a file, or a directory when `recursive`.
|
|
@@ -7088,6 +7103,14 @@ declare class VfsNamespace {
|
|
|
7088
7103
|
private readRecord;
|
|
7089
7104
|
/** Apply an edit to a directory record and persist it. */
|
|
7090
7105
|
private mutate;
|
|
7106
|
+
/**
|
|
7107
|
+
* Seal a directory record as it stands NOW and put it in the store.
|
|
7108
|
+
*
|
|
7109
|
+
* Read at the moment of sending, not when the edit was made, so a write
|
|
7110
|
+
* that waited behind another carries every edit made to the record by
|
|
7111
|
+
* then, its own included.
|
|
7112
|
+
*/
|
|
7113
|
+
private writeRecord;
|
|
7091
7114
|
private createDir;
|
|
7092
7115
|
/**
|
|
7093
7116
|
* Every directory record in a subtree, each once, opened - and nothing
|
|
@@ -8975,7 +8998,7 @@ declare function getId(row: {
|
|
|
8975
8998
|
* expect (and isn't serving a stale cached bundle). Keep this in sync with
|
|
8976
8999
|
* `package.json` `version`.
|
|
8977
9000
|
*/
|
|
8978
|
-
declare const VERSION = "0.15.0-alpha.
|
|
9001
|
+
declare const VERSION = "0.15.0-alpha.1";
|
|
8979
9002
|
|
|
8980
9003
|
/**
|
|
8981
9004
|
* The SDK's process-global logger.
|
package/dist/server/index.js
CHANGED
|
@@ -6675,7 +6675,7 @@ async function parseOrThrow(response, op) {
|
|
|
6675
6675
|
* expect (and isn't serving a stale cached bundle). Keep this in sync with
|
|
6676
6676
|
* `package.json` `version`.
|
|
6677
6677
|
*/
|
|
6678
|
-
const VERSION = "0.15.0-alpha.
|
|
6678
|
+
const VERSION = "0.15.0-alpha.1";
|
|
6679
6679
|
|
|
6680
6680
|
/**
|
|
6681
6681
|
* `HttpClient` — the one place the unified {@link Client} talks to the
|
|
@@ -15458,6 +15458,18 @@ class VfsNamespace {
|
|
|
15458
15458
|
* than by TTL — a stale directory listing shows files that are not there.
|
|
15459
15459
|
*/
|
|
15460
15460
|
cache = new Map();
|
|
15461
|
+
/**
|
|
15462
|
+
* The write of each directory record still in flight, by id.
|
|
15463
|
+
*
|
|
15464
|
+
* Two writes of one record must land in the order they were made. The
|
|
15465
|
+
* personal space has no compare-and-swap: of two writes of one key that
|
|
15466
|
+
* are in flight together it keeps whichever request finishes last, and
|
|
15467
|
+
* that is often the one sent first. Then the earlier write, sealed before
|
|
15468
|
+
* the later edit was made, undoes it. That is how a file deleted forever
|
|
15469
|
+
* from the Trash, while the move that put it there was still being
|
|
15470
|
+
* written, came back. So each write waits for the one before it.
|
|
15471
|
+
*/
|
|
15472
|
+
writing = new Map();
|
|
15461
15473
|
historyLimit;
|
|
15462
15474
|
maxEntries;
|
|
15463
15475
|
maxPathChars;
|
|
@@ -15921,10 +15933,7 @@ class VfsNamespace {
|
|
|
15921
15933
|
const parentPath = dirname(target);
|
|
15922
15934
|
await this.mkdir(parentPath, { recursive: true });
|
|
15923
15935
|
const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
|
|
15924
|
-
const { manifest, size } = await this.deps.content.write(bytes, {
|
|
15925
|
-
name,
|
|
15926
|
-
type: opts.type ?? contentTypeFor(name),
|
|
15927
|
-
});
|
|
15936
|
+
const { manifest, size } = await this.deps.content.write(bytes, { name, type: opts.type ?? contentTypeFor(name) }, { onProgress: opts.onProgress });
|
|
15928
15937
|
const parent = await this.openDir(parentPath);
|
|
15929
15938
|
const prior = entryIn(parent.node, name);
|
|
15930
15939
|
if (prior?.kind === "dir")
|
|
@@ -16482,24 +16491,14 @@ class VfsNamespace {
|
|
|
16482
16491
|
if (Object.hasOwn(dir.node.entries, name))
|
|
16483
16492
|
delete dir.hidden[name];
|
|
16484
16493
|
}
|
|
16485
|
-
|
|
16486
|
-
|
|
16487
|
-
|
|
16494
|
+
// Not sent until any earlier write of this record has landed: see
|
|
16495
|
+
// `writing`. Whether that one worked or not, this one still goes.
|
|
16496
|
+
const before = this.writing.get(dir.id);
|
|
16497
|
+
const send = () => this.writeRecord(dir);
|
|
16498
|
+
const write = before ? before.then(send, send) : send();
|
|
16499
|
+
this.writing.set(dir.id, write);
|
|
16488
16500
|
try {
|
|
16489
|
-
|
|
16490
|
-
try {
|
|
16491
|
-
sealed = await seal(dir.key, stored);
|
|
16492
|
-
}
|
|
16493
|
-
catch (err) {
|
|
16494
|
-
// JSON.stringify's own failures: a value too deeply nested to
|
|
16495
|
-
// write. Reading drops those from a stored record, so this is
|
|
16496
|
-
// what the write itself was given.
|
|
16497
|
-
if (!(err instanceof RangeError || err instanceof TypeError))
|
|
16498
|
-
throw err;
|
|
16499
|
-
const where = dir.path ?? `the directory stored as record ${printable(dir.id, 40)}`;
|
|
16500
|
-
throw new VfsConflictError(`cannot write to ${where}: it would hold a value nested too deeply to store`);
|
|
16501
|
-
}
|
|
16502
|
-
await this.deps.store.put(dirKey(dir.id), sealed);
|
|
16501
|
+
await write;
|
|
16503
16502
|
}
|
|
16504
16503
|
catch (err) {
|
|
16505
16504
|
// The edit above was made in place, on the very object the cache
|
|
@@ -16510,8 +16509,38 @@ class VfsNamespace {
|
|
|
16510
16509
|
this.cache.delete(dir.id);
|
|
16511
16510
|
throw err;
|
|
16512
16511
|
}
|
|
16512
|
+
finally {
|
|
16513
|
+
if (this.writing.get(dir.id) === write)
|
|
16514
|
+
this.writing.delete(dir.id);
|
|
16515
|
+
}
|
|
16513
16516
|
this.cache.set(dir.id, Promise.resolve(dir));
|
|
16514
16517
|
}
|
|
16518
|
+
/**
|
|
16519
|
+
* Seal a directory record as it stands NOW and put it in the store.
|
|
16520
|
+
*
|
|
16521
|
+
* Read at the moment of sending, not when the edit was made, so a write
|
|
16522
|
+
* that waited behind another carries every edit made to the record by
|
|
16523
|
+
* then, its own included.
|
|
16524
|
+
*/
|
|
16525
|
+
async writeRecord(dir) {
|
|
16526
|
+
const stored = Object.keys(dir.hidden).length
|
|
16527
|
+
? { ...dir.node, entries: Object.assign(Object.create(null), dir.hidden, dir.node.entries) }
|
|
16528
|
+
: dir.node;
|
|
16529
|
+
let sealed;
|
|
16530
|
+
try {
|
|
16531
|
+
sealed = await seal(dir.key, stored);
|
|
16532
|
+
}
|
|
16533
|
+
catch (err) {
|
|
16534
|
+
// JSON.stringify's own failures: a value too deeply nested to
|
|
16535
|
+
// write. Reading drops those from a stored record, so this is
|
|
16536
|
+
// what the write itself was given.
|
|
16537
|
+
if (!(err instanceof RangeError || err instanceof TypeError))
|
|
16538
|
+
throw err;
|
|
16539
|
+
const where = dir.path ?? `the directory stored as record ${printable(dir.id, 40)}`;
|
|
16540
|
+
throw new VfsConflictError(`cannot write to ${where}: it would hold a value nested too deeply to store`);
|
|
16541
|
+
}
|
|
16542
|
+
await this.deps.store.put(dirKey(dir.id), sealed);
|
|
16543
|
+
}
|
|
16515
16544
|
async createDir(parentPath, name) {
|
|
16516
16545
|
assertValidName(name);
|
|
16517
16546
|
const parent = await this.openDir(parentPath);
|
|
@@ -19488,9 +19517,9 @@ class Client {
|
|
|
19488
19517
|
// GC. `storage.writeFile` would additionally index the manifest
|
|
19489
19518
|
// in the space — a second, diverging source of truth for a file
|
|
19490
19519
|
// whose handle the VFS already holds.
|
|
19491
|
-
write: async (data, meta) => {
|
|
19520
|
+
write: async (data, meta, opts) => {
|
|
19492
19521
|
const space = await resolveContentSpace();
|
|
19493
|
-
const { manifest, stat } = await space.putFile(data, { name: meta.name, type: meta.type });
|
|
19522
|
+
const { manifest, stat } = await space.putFile(data, { name: meta.name, type: meta.type }, { onProgress: opts?.onProgress });
|
|
19494
19523
|
return { manifest, size: stat.size };
|
|
19495
19524
|
},
|
|
19496
19525
|
// Reads go through the manifest alone — no space needed. That is
|