in kit/svelteKitCustomClient/client.js [1875:1967]
async function load_data(url, invalid) {
const data_url = new URL(url);
data_url.pathname = add_data_suffix(url.pathname);
if (url.pathname.endsWith("/")) {
data_url.searchParams.append(TRAILING_SLASH_PARAM, "1");
}
if (DEV && url.searchParams.has(INVALIDATED_PARAM)) {
throw new Error(`Cannot used reserved query parameter "${INVALIDATED_PARAM}"`);
}
data_url.searchParams.append(INVALIDATED_PARAM, invalid.map((i) => (i ? "1" : "0")).join(""));
const res = await native_fetch(data_url.href);
if (!res.ok) {
// error message is a JSON-stringified string which devalue can't handle at the top level
// turn it into a HttpError to not call handleError on the client again (was already handled on the server)
throw new HttpError(res.status, await res.json());
}
// TODO: fix eslint error
// eslint-disable-next-line
return new Promise(async (resolve) => {
/**
* Map of deferred promises that will be resolved by a subsequent chunk of data
* @type {Map<string, import('types').Deferred>}
*/
const deferreds = new Map();
const reader = /** @type {ReadableStream<Uint8Array>} */ (res.body).getReader();
const decoder = new TextDecoder();
/**
* @param {any} data
*/
function deserialize(data) {
return devalue.unflatten(data, {
Promise: (id) => {
return new Promise((fulfil, reject) => {
deferreds.set(id, { fulfil, reject });
});
},
});
}
let text = "";
while (true) {
// Format follows ndjson (each line is a JSON object) or regular JSON spec
const { done, value } = await reader.read();
if (done && !text) break;
text += !value && text ? "\n" : decoder.decode(value); // no value -> final chunk -> add a new line to trigger the last parse
while (true) {
const split = text.indexOf("\n");
if (split === -1) {
break;
}
const node = JSON.parse(text.slice(0, split));
text = text.slice(split + 1);
if (node.type === "redirect") {
return resolve(node);
}
if (node.type === "data") {
// This is the first (and possibly only, if no pending promises) chunk
node.nodes?.forEach((/** @type {any} */ node) => {
if (node?.type === "data") {
node.uses = deserialize_uses(node.uses);
node.data = deserialize(node.data);
}
});
resolve(node);
} else if (node.type === "chunk") {
// This is a subsequent chunk containing deferred data
const { id, data, error } = node;
const deferred = /** @type {import('types').Deferred} */ (deferreds.get(id));
deferreds.delete(id);
if (error) {
deferred.reject(deserialize(error));
} else {
deferred.fulfil(deserialize(data));
}
}
}
}
});
// TODO edge case handling necessary? stream() read fails?
}