@ai-ecoverse/slicc-kernel 1.54.8 → 1.54.9
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 +4 -2
- package/dist/index.js +40 -10
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +180 -25
- package/dist/kernel-worker.js.map +3 -3
- package/dist/node.js +220 -35
- package/dist/node.js.map +3 -3
- package/package.json +1 -1
package/dist/node.js
CHANGED
|
@@ -2813,7 +2813,7 @@ var OpfsFs = class {
|
|
|
2813
2813
|
const swap = targetStat?.isDirectory === true;
|
|
2814
2814
|
const staging = swap ? `.${name2}.${crypto.randomUUID()}` : name2;
|
|
2815
2815
|
this.forget(destination);
|
|
2816
|
-
const
|
|
2816
|
+
const timed2 = await this.explicitTimes(source.path);
|
|
2817
2817
|
const moved2 = await this.place(source.handle, dir, staging);
|
|
2818
2818
|
if (swap) await this.rm(destination, { recursive: true });
|
|
2819
2819
|
await this.meta.move(source.path, destination, carry);
|
|
@@ -2825,7 +2825,7 @@ var OpfsFs = class {
|
|
|
2825
2825
|
if (!placed) await dir.removeEntry(staging, { recursive: true });
|
|
2826
2826
|
copied ||= !placed;
|
|
2827
2827
|
}
|
|
2828
|
-
if (copied) await this.restamp(destination,
|
|
2828
|
+
if (copied) await this.restamp(destination, timed2);
|
|
2829
2829
|
this.changed(source.path, destination);
|
|
2830
2830
|
this.touch(parentOf2(source.path), parent.path);
|
|
2831
2831
|
}
|
|
@@ -2834,16 +2834,16 @@ var OpfsFs = class {
|
|
|
2834
2834
|
return handle.kind === "file" ? (await handle.getFile()).lastModified : 0;
|
|
2835
2835
|
}
|
|
2836
2836
|
async explicitTimes(path) {
|
|
2837
|
-
const
|
|
2837
|
+
const timed2 = [];
|
|
2838
2838
|
for (const entry of await this.meta.under(path)) {
|
|
2839
2839
|
if (entry.mtimeFor === void 0 || entry.link !== void 0) continue;
|
|
2840
2840
|
const current = await this.modified(entry.path).catch(() => void 0);
|
|
2841
|
-
if (current === entry.mtimeFor)
|
|
2841
|
+
if (current === entry.mtimeFor) timed2.push(entry.path.slice(path.length));
|
|
2842
2842
|
}
|
|
2843
|
-
return
|
|
2843
|
+
return timed2;
|
|
2844
2844
|
}
|
|
2845
|
-
async restamp(path,
|
|
2846
|
-
for (const rest2 of
|
|
2845
|
+
async restamp(path, timed2) {
|
|
2846
|
+
for (const rest2 of timed2) {
|
|
2847
2847
|
const mtimeFor = await this.modified(path + rest2);
|
|
2848
2848
|
await this.meta.update(path + rest2, (entry) => entry && { ...entry, mtimeFor });
|
|
2849
2849
|
}
|
|
@@ -11573,11 +11573,24 @@ var HostfsClient = class {
|
|
|
11573
11573
|
get maxIo() {
|
|
11574
11574
|
return this.capabilities.maxIo ?? HOSTFS_IO;
|
|
11575
11575
|
}
|
|
11576
|
-
|
|
11576
|
+
retired;
|
|
11577
|
+
stop = new AbortController();
|
|
11578
|
+
get gone() {
|
|
11579
|
+
return this.retired !== void 0;
|
|
11580
|
+
}
|
|
11581
|
+
retire(why) {
|
|
11582
|
+
this.retired ??= why;
|
|
11583
|
+
this.stop.abort();
|
|
11584
|
+
}
|
|
11585
|
+
async send(path, init, handle = false, retried = false, cleanup = false) {
|
|
11586
|
+
if (this.retired && !cleanup) throw fsError2("ENOTCONN", this.retired);
|
|
11587
|
+
const stop = cleanup ? void 0 : this.stop.signal;
|
|
11588
|
+
const signal = init.signal && stop ? AbortSignal.any([init.signal, stop]) : init.signal ?? stop;
|
|
11577
11589
|
let response;
|
|
11578
11590
|
try {
|
|
11579
11591
|
response = await this.fetch(`${this.grant.url}${path}`, {
|
|
11580
11592
|
...init,
|
|
11593
|
+
...signal ? { signal } : {},
|
|
11581
11594
|
credentials: "omit",
|
|
11582
11595
|
headers: {
|
|
11583
11596
|
...init.headers,
|
|
@@ -11614,6 +11627,20 @@ var HostfsClient = class {
|
|
|
11614
11627
|
);
|
|
11615
11628
|
return await response.json();
|
|
11616
11629
|
}
|
|
11630
|
+
async cleanup(op, body) {
|
|
11631
|
+
const response = await this.send(
|
|
11632
|
+
"/api/hostfs",
|
|
11633
|
+
{
|
|
11634
|
+
method: "POST",
|
|
11635
|
+
headers: { "Content-Type": "application/json" },
|
|
11636
|
+
body: JSON.stringify({ op, ...body })
|
|
11637
|
+
},
|
|
11638
|
+
true,
|
|
11639
|
+
false,
|
|
11640
|
+
true
|
|
11641
|
+
);
|
|
11642
|
+
await response.body?.cancel();
|
|
11643
|
+
}
|
|
11617
11644
|
async read(fh, offset, size, ifMatch) {
|
|
11618
11645
|
const response = await this.send(
|
|
11619
11646
|
"/api/hostfs",
|
|
@@ -11681,6 +11708,11 @@ function hostfsHandlers(current) {
|
|
|
11681
11708
|
return fresh(remote);
|
|
11682
11709
|
};
|
|
11683
11710
|
const call = (op, body = {}) => current().call(op, body);
|
|
11711
|
+
const settle = (client, restore) => client.call("setattr", restore).catch((err) => {
|
|
11712
|
+
if (!client.gone || !client.cleanup) throw err;
|
|
11713
|
+
void client.cleanup("setattr", restore).catch(() => {
|
|
11714
|
+
});
|
|
11715
|
+
});
|
|
11684
11716
|
async function writable(client, path, flags) {
|
|
11685
11717
|
const { ifMatch: _, ...asked } = flags;
|
|
11686
11718
|
const opening = () => client.call("open", { path: rel(path), ...asked });
|
|
@@ -11691,9 +11723,9 @@ function hostfsHandlers(current) {
|
|
|
11691
11723
|
const mode = (await client.call("stat", { path: rel(path) })).mode ?? 0;
|
|
11692
11724
|
if (mode & 128) throw err;
|
|
11693
11725
|
const restore = { path: rel(path), mode };
|
|
11694
|
-
await client.call("setattr", { path: rel(path), mode: mode | 128 })
|
|
11695
|
-
|
|
11696
|
-
|
|
11726
|
+
const opened2 = await client.call("setattr", { path: rel(path), mode: mode | 128 }).then(opening).catch(async (again) => {
|
|
11727
|
+
await settle(client, restore).catch(() => {
|
|
11728
|
+
});
|
|
11697
11729
|
throw again;
|
|
11698
11730
|
});
|
|
11699
11731
|
return { opened: opened2, restore };
|
|
@@ -11748,7 +11780,7 @@ function hostfsHandlers(current) {
|
|
|
11748
11780
|
try {
|
|
11749
11781
|
await fresh(remote).client.call("release", { fh: remote.fh }, true);
|
|
11750
11782
|
} finally {
|
|
11751
|
-
if (remote.restore) await current()
|
|
11783
|
+
if (remote.restore) await settle(current(), remote.restore);
|
|
11752
11784
|
}
|
|
11753
11785
|
},
|
|
11754
11786
|
mkdir: async (path) => void await call("mkdir", { path: rel(path) }),
|
|
@@ -11878,6 +11910,73 @@ function invalidation(event) {
|
|
|
11878
11910
|
return event.paths ?? true;
|
|
11879
11911
|
}
|
|
11880
11912
|
var PORT_REQUEST_MS = 6e4;
|
|
11913
|
+
var HOSTFS_CALL_MS = 2e4;
|
|
11914
|
+
var PORT_BEAT_MS = 1e3;
|
|
11915
|
+
var PORT_DEAD_MS = 1e4;
|
|
11916
|
+
var PORT_LINGER_MS = 1e3;
|
|
11917
|
+
function timed(transport, ms) {
|
|
11918
|
+
const inflight = /* @__PURE__ */ new Set();
|
|
11919
|
+
const guard = (name2, run2, late, expire) => new Promise((resolve, reject) => {
|
|
11920
|
+
let expired = false;
|
|
11921
|
+
const running = run2();
|
|
11922
|
+
inflight.add(running);
|
|
11923
|
+
const done4 = () => inflight.delete(running);
|
|
11924
|
+
running.then(done4, done4);
|
|
11925
|
+
const timer = setTimeout(() => {
|
|
11926
|
+
expired = true;
|
|
11927
|
+
const why = `the host folder did not answer ${name2} within ${ms} ms`;
|
|
11928
|
+
transport.retire?.(why);
|
|
11929
|
+
expire?.(running);
|
|
11930
|
+
reject(fsError2("ENOTCONN", why));
|
|
11931
|
+
}, ms);
|
|
11932
|
+
running.then(
|
|
11933
|
+
(value) => {
|
|
11934
|
+
clearTimeout(timer);
|
|
11935
|
+
if (expired) late?.(value);
|
|
11936
|
+
resolve(value);
|
|
11937
|
+
},
|
|
11938
|
+
(err) => {
|
|
11939
|
+
clearTimeout(timer);
|
|
11940
|
+
reject(err);
|
|
11941
|
+
}
|
|
11942
|
+
);
|
|
11943
|
+
});
|
|
11944
|
+
const cleanup = async (op, body, skip) => {
|
|
11945
|
+
await Promise.allSettled([...inflight].filter((work) => work !== skip));
|
|
11946
|
+
await transport.cleanup?.(op, body);
|
|
11947
|
+
};
|
|
11948
|
+
const release = (opened2) => {
|
|
11949
|
+
const fh = opened2?.fh;
|
|
11950
|
+
if (typeof fh === "number") void cleanup("release", { fh }).catch(() => {
|
|
11951
|
+
});
|
|
11952
|
+
};
|
|
11953
|
+
return {
|
|
11954
|
+
get capabilities() {
|
|
11955
|
+
return transport.capabilities;
|
|
11956
|
+
},
|
|
11957
|
+
get token() {
|
|
11958
|
+
return transport.token;
|
|
11959
|
+
},
|
|
11960
|
+
get maxIo() {
|
|
11961
|
+
return transport.maxIo;
|
|
11962
|
+
},
|
|
11963
|
+
get gone() {
|
|
11964
|
+
return transport.gone;
|
|
11965
|
+
},
|
|
11966
|
+
retire: (why) => transport.retire?.(why),
|
|
11967
|
+
...transport.cleanup ? { cleanup } : {},
|
|
11968
|
+
call: (op, body, handle) => guard(
|
|
11969
|
+
op,
|
|
11970
|
+
() => transport.call(op, body, handle),
|
|
11971
|
+
op === "open" ? release : void 0,
|
|
11972
|
+
op === "release" ? (running) => void cleanup("release", body ?? {}, running).catch(() => {
|
|
11973
|
+
}) : void 0
|
|
11974
|
+
),
|
|
11975
|
+
read: (fh, offset, size, ifMatch) => guard("read", () => transport.read(fh, offset, size, ifMatch)),
|
|
11976
|
+
write: (fh, offset, bytes) => guard("write", () => transport.write(fh, offset, bytes)),
|
|
11977
|
+
watch: (signal, onEvent, onOpen) => transport.watch(signal, onEvent, onOpen)
|
|
11978
|
+
};
|
|
11979
|
+
}
|
|
11881
11980
|
var PORT_MS_PER_MIB = 1e3;
|
|
11882
11981
|
var nextPortToken = 0;
|
|
11883
11982
|
var PortTransport = class {
|
|
@@ -11888,13 +11987,25 @@ var PortTransport = class {
|
|
|
11888
11987
|
waiting = /* @__PURE__ */ new Map();
|
|
11889
11988
|
next = 0;
|
|
11890
11989
|
dead;
|
|
11891
|
-
|
|
11990
|
+
beatMs;
|
|
11991
|
+
deadMs;
|
|
11992
|
+
lingerMs;
|
|
11993
|
+
beat;
|
|
11994
|
+
answers = false;
|
|
11995
|
+
pinged;
|
|
11996
|
+
constructor(grant, liveness = {}) {
|
|
11892
11997
|
this.port = grant.port;
|
|
11893
|
-
this.requestMs = requestMs;
|
|
11998
|
+
this.requestMs = liveness.requestMs ?? PORT_REQUEST_MS;
|
|
11999
|
+
this.beatMs = liveness.beatMs ?? PORT_BEAT_MS;
|
|
12000
|
+
this.deadMs = liveness.deadMs ?? PORT_DEAD_MS;
|
|
12001
|
+
this.lingerMs = liveness.lingerMs ?? PORT_LINGER_MS;
|
|
11894
12002
|
this.capabilities = grant.capabilities ?? {};
|
|
11895
12003
|
this.token = grant.token ?? `port-${++nextPortToken}`;
|
|
11896
12004
|
this.port.addEventListener("message", (event) => {
|
|
11897
|
-
|
|
12005
|
+
if (event.data?.pong) {
|
|
12006
|
+
this.answers = true;
|
|
12007
|
+
this.pinged = void 0;
|
|
12008
|
+
} else this.waiting.get(event.data?.id)?.(event.data);
|
|
11898
12009
|
});
|
|
11899
12010
|
this.port.addEventListener("close", () => this.fail("the folder's port closed"));
|
|
11900
12011
|
this.port.start();
|
|
@@ -11905,8 +12016,51 @@ var PortTransport = class {
|
|
|
11905
12016
|
get gone() {
|
|
11906
12017
|
return this.dead !== void 0;
|
|
11907
12018
|
}
|
|
12019
|
+
retire(why) {
|
|
12020
|
+
this.fail(why);
|
|
12021
|
+
}
|
|
12022
|
+
ping() {
|
|
12023
|
+
if (this.pinged !== void 0) return;
|
|
12024
|
+
this.pinged = Date.now();
|
|
12025
|
+
try {
|
|
12026
|
+
this.port.postMessage({ id: 0, op: "ping" });
|
|
12027
|
+
} catch {
|
|
12028
|
+
}
|
|
12029
|
+
}
|
|
12030
|
+
watchBeat() {
|
|
12031
|
+
if (this.beat || this.dead) return;
|
|
12032
|
+
this.ping();
|
|
12033
|
+
this.beat = setInterval(() => {
|
|
12034
|
+
if (this.waiting.size === 0) {
|
|
12035
|
+
clearInterval(this.beat);
|
|
12036
|
+
this.beat = void 0;
|
|
12037
|
+
return;
|
|
12038
|
+
}
|
|
12039
|
+
if (this.answers && this.pinged !== void 0 && Date.now() - this.pinged > this.deadMs) {
|
|
12040
|
+
this.fail("the folder's port stopped answering");
|
|
12041
|
+
return;
|
|
12042
|
+
}
|
|
12043
|
+
this.ping();
|
|
12044
|
+
}, this.beatMs);
|
|
12045
|
+
}
|
|
12046
|
+
async cleanup(op, body) {
|
|
12047
|
+
if (this.closed) throw fsError2("ENOTCONN", "the folder's port is closed");
|
|
12048
|
+
this.port.postMessage({ id: 0, op: "cleanup", name: op, body });
|
|
12049
|
+
}
|
|
12050
|
+
closed = false;
|
|
11908
12051
|
fail(why) {
|
|
11909
|
-
if (this.dead === void 0)
|
|
12052
|
+
if (this.dead === void 0) {
|
|
12053
|
+
setTimeout(() => {
|
|
12054
|
+
try {
|
|
12055
|
+
this.port.postMessage({ id: 0, op: "bye" });
|
|
12056
|
+
} catch {
|
|
12057
|
+
}
|
|
12058
|
+
this.closed = true;
|
|
12059
|
+
this.port.close();
|
|
12060
|
+
}, this.lingerMs);
|
|
12061
|
+
}
|
|
12062
|
+
clearInterval(this.beat);
|
|
12063
|
+
this.beat = void 0;
|
|
11910
12064
|
this.dead ??= why;
|
|
11911
12065
|
for (const settle of [...this.waiting.values()])
|
|
11912
12066
|
settle({ id: 0, error: { code: "ENOTCONN", message: why } });
|
|
@@ -11923,6 +12077,7 @@ var PortTransport = class {
|
|
|
11923
12077
|
},
|
|
11924
12078
|
this.requestMs + Math.ceil(bytes / 1048576) * PORT_MS_PER_MIB
|
|
11925
12079
|
);
|
|
12080
|
+
this.watchBeat();
|
|
11926
12081
|
this.waiting.set(id2, (reply) => {
|
|
11927
12082
|
clearTimeout(timer);
|
|
11928
12083
|
this.waiting.delete(id2);
|
|
@@ -11969,6 +12124,7 @@ var PortTransport = class {
|
|
|
11969
12124
|
}
|
|
11970
12125
|
resolve();
|
|
11971
12126
|
};
|
|
12127
|
+
this.watchBeat();
|
|
11972
12128
|
this.waiting.set(id2, (reply) => {
|
|
11973
12129
|
if (reply.open) return onOpen();
|
|
11974
12130
|
if (reply.event) return onEvent(reply.event);
|
|
@@ -11992,11 +12148,38 @@ var errorOf = (err) => ({
|
|
|
11992
12148
|
});
|
|
11993
12149
|
function serveHostfsPort(port, transport) {
|
|
11994
12150
|
const watches = /* @__PURE__ */ new Map();
|
|
12151
|
+
const handles = /* @__PURE__ */ new Set();
|
|
12152
|
+
let stopped = false;
|
|
12153
|
+
const closeHandles = () => {
|
|
12154
|
+
for (const fh of handles) void transport.call("release", { fh }, true).catch(() => {
|
|
12155
|
+
});
|
|
12156
|
+
handles.clear();
|
|
12157
|
+
};
|
|
11995
12158
|
const send = (reply, transfer = []) => port.postMessage(reply, transfer);
|
|
12159
|
+
const pending = /* @__PURE__ */ new Set();
|
|
12160
|
+
const track = (work) => {
|
|
12161
|
+
pending.add(work);
|
|
12162
|
+
const done4 = () => pending.delete(work);
|
|
12163
|
+
work.then(done4, done4);
|
|
12164
|
+
return work;
|
|
12165
|
+
};
|
|
12166
|
+
const answer = async (name2, body) => {
|
|
12167
|
+
const result = await track(transport.call(name2, body));
|
|
12168
|
+
const opened2 = result?.fh;
|
|
12169
|
+
if (name2 === "open" && typeof opened2 === "number") handles.add(opened2);
|
|
12170
|
+
if (name2 === "release") handles.delete(body?.fh);
|
|
12171
|
+
if (stopped) closeHandles();
|
|
12172
|
+
return result;
|
|
12173
|
+
};
|
|
11996
12174
|
const listener = async ({
|
|
11997
12175
|
data
|
|
11998
12176
|
}) => {
|
|
11999
12177
|
const { id: id2, op } = data;
|
|
12178
|
+
if (op === "ping") return send({ id: id2, pong: true });
|
|
12179
|
+
if (op === "bye") return stop();
|
|
12180
|
+
if (op === "cleanup")
|
|
12181
|
+
return void Promise.allSettled([...pending]).then(() => answer(data.name, data.body)).catch(() => {
|
|
12182
|
+
});
|
|
12000
12183
|
if (op === "unwatch") return watches.get(id2)?.abort();
|
|
12001
12184
|
if (op === "watch") {
|
|
12002
12185
|
const stop2 = new AbortController();
|
|
@@ -12017,32 +12200,35 @@ function serveHostfsPort(port, transport) {
|
|
|
12017
12200
|
}
|
|
12018
12201
|
try {
|
|
12019
12202
|
if (op === "read") {
|
|
12020
|
-
const read = await
|
|
12021
|
-
|
|
12022
|
-
|
|
12023
|
-
|
|
12024
|
-
|
|
12203
|
+
const read = await track(
|
|
12204
|
+
transport.read(
|
|
12205
|
+
data.fh,
|
|
12206
|
+
data.offset,
|
|
12207
|
+
data.size,
|
|
12208
|
+
data.ifMatch
|
|
12209
|
+
)
|
|
12025
12210
|
);
|
|
12026
12211
|
const bytes = read.slice();
|
|
12027
12212
|
return send({ id: id2, bytes }, [bytes.buffer]);
|
|
12028
12213
|
}
|
|
12029
12214
|
if (op === "write") {
|
|
12030
|
-
await
|
|
12215
|
+
await track(
|
|
12216
|
+
transport.write(data.fh, data.offset, data.bytes)
|
|
12217
|
+
);
|
|
12031
12218
|
return send({ id: id2 });
|
|
12032
12219
|
}
|
|
12033
12220
|
if (op !== "call") throw fsError2("EINVAL", `unknown hostfs port op ${op}`);
|
|
12034
|
-
send({
|
|
12035
|
-
id: id2,
|
|
12036
|
-
result: await transport.call(data.name, data.body)
|
|
12037
|
-
});
|
|
12221
|
+
send({ id: id2, result: await answer(data.name, data.body) });
|
|
12038
12222
|
} catch (err) {
|
|
12039
12223
|
send({ id: id2, error: errorOf(err) });
|
|
12040
12224
|
}
|
|
12041
12225
|
};
|
|
12042
12226
|
const stop = () => {
|
|
12227
|
+
stopped = true;
|
|
12043
12228
|
port.removeEventListener("message", listener);
|
|
12044
12229
|
port.removeEventListener("close", stop);
|
|
12045
12230
|
for (const watch of watches.values()) watch.abort();
|
|
12231
|
+
closeHandles();
|
|
12046
12232
|
port.close();
|
|
12047
12233
|
};
|
|
12048
12234
|
port.addEventListener("message", listener);
|
|
@@ -12050,10 +12236,10 @@ function serveHostfsPort(port, transport) {
|
|
|
12050
12236
|
port.start();
|
|
12051
12237
|
return stop;
|
|
12052
12238
|
}
|
|
12053
|
-
function grantConnect(hook, fetch2,
|
|
12239
|
+
function grantConnect(hook, fetch2, liveness = {}) {
|
|
12054
12240
|
return async (source, options) => {
|
|
12055
12241
|
const first = await hook(source, options);
|
|
12056
|
-
if ("port" in first) return new PortTransport(first,
|
|
12242
|
+
if ("port" in first) return new PortTransport(first, liveness);
|
|
12057
12243
|
const grant = async () => {
|
|
12058
12244
|
const again = await hook(source, options);
|
|
12059
12245
|
if ("port" in again)
|
|
@@ -12073,7 +12259,10 @@ async function openHostfs(spec, connect, timing = {}) {
|
|
|
12073
12259
|
const stop = new AbortController();
|
|
12074
12260
|
let active;
|
|
12075
12261
|
const handlers = hostfsHandlers(() => active);
|
|
12076
|
-
const ranged2 = () =>
|
|
12262
|
+
const ranged2 = () => ({
|
|
12263
|
+
...active?.capabilities.ranges === true ? { ranges: true } : {},
|
|
12264
|
+
...active ? { maxIo: Math.min(active.maxIo, HOSTFS_IO) } : {}
|
|
12265
|
+
});
|
|
12077
12266
|
const served = serveFilesystem(
|
|
12078
12267
|
port2,
|
|
12079
12268
|
{ ...slot.handlers, mount: ranged2 },
|
|
@@ -12089,7 +12278,7 @@ async function openHostfs(spec, connect, timing = {}) {
|
|
|
12089
12278
|
{
|
|
12090
12279
|
connect: () => connect(spec.source, { readonly: readonly2 }),
|
|
12091
12280
|
up(client) {
|
|
12092
|
-
active = client;
|
|
12281
|
+
active = timed(client, timing.callMs ?? HOSTFS_CALL_MS);
|
|
12093
12282
|
slot.insert(client, handlers);
|
|
12094
12283
|
served.invalidate(true);
|
|
12095
12284
|
},
|
|
@@ -13118,11 +13307,7 @@ var Launcher = class {
|
|
|
13118
13307
|
throw fsError("ENODEV", "this kernel has no hostfs hook (createKernel({ hostfs }))");
|
|
13119
13308
|
return openHostfs(
|
|
13120
13309
|
spec,
|
|
13121
|
-
grantConnect(
|
|
13122
|
-
hostfs,
|
|
13123
|
-
hostfsFetch ?? ((url, init) => fetch(url, init)),
|
|
13124
|
-
hostfsTiming?.requestMs
|
|
13125
|
-
),
|
|
13310
|
+
grantConnect(hostfs, hostfsFetch ?? ((url, init) => fetch(url, init)), hostfsTiming),
|
|
13126
13311
|
hostfsTiming
|
|
13127
13312
|
);
|
|
13128
13313
|
}
|