@uniweb/runtime 0.15.0 → 0.16.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/ssr.js +36 -28
- package/dist/ssr.js.map +1 -1
- package/package.json +3 -3
- package/src/default-fetcher.js +63 -63
- package/src/isolate-api.js +2 -1
- package/src/page-renderer.js +2 -2
- package/src/prefetch.js +2 -2
- package/src/setup.js +1 -4
package/dist/ssr.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isRichSchema, deriveCacheKey, resolveDefaultLocale, hasDarkScheme, createUniweb,
|
|
1
|
+
import { isRichSchema, deriveCacheKey, resolveDefaultLocale, hasDarkScheme, createUniweb, substitutePlaceholders, resolveServiceUrl, matchWhere, sortRecords, sortToWire } from "@uniweb/core";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { renderToString } from "react-dom/server";
|
|
4
4
|
import { sectionDomId } from "@uniweb/core/section-id";
|
|
@@ -839,25 +839,31 @@ function generate404Html({ baseHtml, website, siteContent }) {
|
|
|
839
839
|
}
|
|
840
840
|
return { html, hasNotFoundPage: !!notFoundPage };
|
|
841
841
|
}
|
|
842
|
-
function createDefaultFetcher({ basePath = "", dev = false,
|
|
842
|
+
function createDefaultFetcher({ basePath = "", dev = false, fetch: fetchImpl = null } = {}) {
|
|
843
843
|
const doFetch = (input, init) => (fetchImpl || globalThis.fetch)(input, init);
|
|
844
844
|
const pathPrefix = basePath && basePath !== "/" ? basePath.replace(/\/$/, "") : "";
|
|
845
|
-
const stampedArrayKey = records?.envelope && typeof records.envelope === "object" && typeof records.envelope.records === "string" && records.envelope.records.length ? records.envelope.records : null;
|
|
846
|
-
const laneEnvelope = stampedArrayKey ? { list: stampedArrayKey } : null;
|
|
847
845
|
const doorQueues = /* @__PURE__ */ new Map();
|
|
848
|
-
const askDoor = (request, ctx) =>
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
doorQueues.set(url, queue);
|
|
854
|
-
queueMicrotask(() => {
|
|
855
|
-
doorQueues.delete(url);
|
|
856
|
-
flushDoor(url, queue, doFetch);
|
|
846
|
+
const askDoor = (request, ctx) => {
|
|
847
|
+
if (typeof request.schema !== "string" || !request.schema) {
|
|
848
|
+
return Promise.resolve({
|
|
849
|
+
data: null,
|
|
850
|
+
error: `the payload stamps a records door but carries no Model ref for query "${request.query ?? request.as}" (config.queries) — the door cannot be asked`
|
|
857
851
|
});
|
|
858
852
|
}
|
|
859
|
-
|
|
860
|
-
|
|
853
|
+
return new Promise((resolve) => {
|
|
854
|
+
const url = resolveServiceUrl(request.door, pathPrefix);
|
|
855
|
+
let queue = doorQueues.get(url);
|
|
856
|
+
if (!queue) {
|
|
857
|
+
queue = [];
|
|
858
|
+
doorQueues.set(url, queue);
|
|
859
|
+
queueMicrotask(() => {
|
|
860
|
+
doorQueues.delete(url);
|
|
861
|
+
flushDoor(url, queue, doFetch);
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
queue.push({ request, ctx, resolve });
|
|
865
|
+
});
|
|
866
|
+
};
|
|
861
867
|
return {
|
|
862
868
|
/**
|
|
863
869
|
* The cache identity is the request's ADDRESS — or, on a question door,
|
|
@@ -873,24 +879,19 @@ function createDefaultFetcher({ basePath = "", dev = false, records = null, fetc
|
|
|
873
879
|
async resolve(request, ctx = {}) {
|
|
874
880
|
if (!request) return { data: null };
|
|
875
881
|
if (request.door) return askDoor(request, ctx);
|
|
876
|
-
const { path, url,
|
|
882
|
+
const { path, url, transform, body: rawBody } = request;
|
|
877
883
|
let method = (request.method || "GET").toUpperCase();
|
|
878
884
|
if (method !== "GET" && method !== "POST") {
|
|
879
885
|
console.warn(`[default-fetcher] method "${request.method}" is not supported — falling back to GET.`);
|
|
880
886
|
method = "GET";
|
|
881
887
|
}
|
|
882
888
|
let target;
|
|
883
|
-
if (
|
|
884
|
-
target = resolveServiceUrl(endpoint, pathPrefix);
|
|
885
|
-
if (typeof request.locale === "string" && request.locale) {
|
|
886
|
-
target += (target.includes("?") ? "&" : "?") + "locale=" + encodeURIComponent(request.locale);
|
|
887
|
-
}
|
|
888
|
-
} else if (path) {
|
|
889
|
+
if (path) {
|
|
889
890
|
target = pathPrefix && path.startsWith("/") && !path.startsWith("//") ? pathPrefix + path : path;
|
|
890
891
|
} else if (url) {
|
|
891
892
|
target = url;
|
|
892
893
|
} else {
|
|
893
|
-
return { data: [], error: "No path, url or
|
|
894
|
+
return { data: [], error: "No path, url or door specified" };
|
|
894
895
|
}
|
|
895
896
|
const init = { signal: ctx.signal, method };
|
|
896
897
|
if (method === "POST") {
|
|
@@ -903,8 +904,7 @@ function createDefaultFetcher({ basePath = "", dev = false, records = null, fetc
|
|
|
903
904
|
}
|
|
904
905
|
try {
|
|
905
906
|
const response = await doFetch(target, init);
|
|
906
|
-
const
|
|
907
|
-
const envelope = requestEnvelope ?? (endpoint && laneEnvelope ? laneEnvelope : {});
|
|
907
|
+
const envelope = request.envelope && typeof request.envelope === "object" ? request.envelope : {};
|
|
908
908
|
if (!response.ok) {
|
|
909
909
|
let extracted;
|
|
910
910
|
if (envelope.error) {
|
|
@@ -999,7 +999,13 @@ async function flushDoor(url, queue, doFetch) {
|
|
|
999
999
|
body: JSON.stringify(body)
|
|
1000
1000
|
});
|
|
1001
1001
|
if (!response.ok) {
|
|
1002
|
-
|
|
1002
|
+
let detail = null;
|
|
1003
|
+
try {
|
|
1004
|
+
const problem = safeParseJSON(await response.text());
|
|
1005
|
+
if (problem && typeof problem.detail === "string" && problem.detail) detail = problem.detail;
|
|
1006
|
+
} catch {
|
|
1007
|
+
}
|
|
1008
|
+
const error = detail ? `HTTP ${response.status}: ${detail}` : `HTTP ${response.status}: ${response.statusText}`;
|
|
1003
1009
|
for (const entry of queue) entry.resolve({ data: null, error });
|
|
1004
1010
|
return;
|
|
1005
1011
|
}
|
|
@@ -1016,7 +1022,10 @@ async function flushDoor(url, queue, doFetch) {
|
|
|
1016
1022
|
const key = keys[i];
|
|
1017
1023
|
if (key in errors) {
|
|
1018
1024
|
const e = errors[key];
|
|
1019
|
-
|
|
1025
|
+
const detail = typeof e === "string" ? e : e?.detail || e?.message || JSON.stringify(e);
|
|
1026
|
+
const out = { data: null, error: detail };
|
|
1027
|
+
if (e && typeof e === "object" && typeof e.code === "string") out.code = e.code;
|
|
1028
|
+
entry.resolve(out);
|
|
1020
1029
|
return;
|
|
1021
1030
|
}
|
|
1022
1031
|
if (!(key in data)) {
|
|
@@ -1139,7 +1148,6 @@ async function executeFetchConfigs(configs, { content, fetch: fetch2 = null, dev
|
|
|
1139
1148
|
}
|
|
1140
1149
|
const fetcher = createDefaultFetcher({
|
|
1141
1150
|
basePath: content?.config?.base || "",
|
|
1142
|
-
records: content?.config?.records ?? null,
|
|
1143
1151
|
dev,
|
|
1144
1152
|
fetch: fetch2
|
|
1145
1153
|
});
|