@reckona/mreact-server 0.0.181 → 0.0.183
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/boundary.js +1 -1
- package/dist/boundary.js.map +1 -1
- package/dist/flight.js +105 -72
- package/dist/flight.js.map +1 -1
- package/dist/reorder.d.ts.map +1 -1
- package/dist/reorder.js +17 -6
- package/dist/reorder.js.map +1 -1
- package/package.json +3 -3
- package/src/boundary.ts +1 -1
- package/src/flight.ts +157 -95
- package/src/reorder.ts +17 -13
package/dist/reorder.js
CHANGED
|
@@ -1,17 +1,31 @@
|
|
|
1
1
|
/** Moves out-of-order fragments into their matching placeholders within a DOM root. */
|
|
2
2
|
export function applyOutOfOrderFragments(root = document) {
|
|
3
3
|
const fragments = Array.from(root.querySelectorAll("template[data-mreact-oob-fragment]"));
|
|
4
|
+
const completionMarkers = new Map();
|
|
5
|
+
for (const marker of root.querySelectorAll("[data-mreact-oob-complete]")) {
|
|
6
|
+
const id = marker.getAttribute("data-mreact-oob-complete");
|
|
7
|
+
if (!completionMarkers.has(id)) {
|
|
8
|
+
completionMarkers.set(id, marker);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
const placeholders = new Map();
|
|
12
|
+
for (const placeholder of root.querySelectorAll("[data-mreact-oob-placeholder]")) {
|
|
13
|
+
const id = placeholder.getAttribute("data-mreact-oob-placeholder");
|
|
14
|
+
if (!placeholders.has(id)) {
|
|
15
|
+
placeholders.set(id, placeholder);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
4
18
|
for (const fragment of fragments) {
|
|
5
19
|
const id = fragment.dataset.mreactOobFragment;
|
|
6
20
|
if (id === undefined) {
|
|
7
21
|
continue;
|
|
8
22
|
}
|
|
9
|
-
const completionMarker =
|
|
23
|
+
const completionMarker = completionMarkers.get(id);
|
|
10
24
|
if (completionMarker === undefined) {
|
|
11
25
|
continue;
|
|
12
26
|
}
|
|
13
|
-
const placeholder =
|
|
14
|
-
if (placeholder ===
|
|
27
|
+
const placeholder = placeholders.get(id);
|
|
28
|
+
if (placeholder === undefined) {
|
|
15
29
|
continue;
|
|
16
30
|
}
|
|
17
31
|
placeholder.replaceWith(fragment.content.cloneNode(true));
|
|
@@ -19,7 +33,4 @@ export function applyOutOfOrderFragments(root = document) {
|
|
|
19
33
|
completionMarker.remove();
|
|
20
34
|
}
|
|
21
35
|
}
|
|
22
|
-
function cssEscape(value) {
|
|
23
|
-
return value.replaceAll("\\", "\\\\").replaceAll("\"", "\\\"");
|
|
24
|
-
}
|
|
25
36
|
//# sourceMappingURL=reorder.js.map
|
package/dist/reorder.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reorder.js","sourceRoot":"","sources":["../src/reorder.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,MAAM,UAAU,wBAAwB,CAAC,OAAmB,QAAQ;IAClE,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAC1B,IAAI,CAAC,gBAAgB,CACnB,oCAAoC,CACrC,CACF,CAAC;
|
|
1
|
+
{"version":3,"file":"reorder.js","sourceRoot":"","sources":["../src/reorder.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,MAAM,UAAU,wBAAwB,CAAC,OAAmB,QAAQ;IAClE,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAC1B,IAAI,CAAC,gBAAgB,CACnB,oCAAoC,CACrC,CACF,CAAC;IACF,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC5D,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,gBAAgB,CAAU,4BAA4B,CAAC,EAAE,CAAC;QAClF,MAAM,EAAE,GAAG,MAAM,CAAC,YAAY,CAAC,0BAA0B,CAAC,CAAC;QAC3D,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAC/B,iBAAiB,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IACD,MAAM,YAAY,GAAG,IAAI,GAAG,EAA0B,CAAC;IACvD,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,gBAAgB,CAAU,+BAA+B,CAAC,EAAE,CAAC;QAC1F,MAAM,EAAE,GAAG,WAAW,CAAC,YAAY,CAAC,6BAA6B,CAAC,CAAC;QACnE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAC1B,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,iBAAiB,CAAC;QAE9C,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YACrB,SAAS;QACX,CAAC;QAED,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnD,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;YACnC,SAAS;QACX,CAAC;QAED,MAAM,WAAW,GAAG,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzC,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,SAAS;QACX,CAAC;QAED,WAAW,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1D,QAAQ,CAAC,MAAM,EAAE,CAAC;QAClB,gBAAgB,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC;AACH,CAAC","sourcesContent":["/** Moves out-of-order fragments into their matching placeholders within a DOM root. */\nexport function applyOutOfOrderFragments(root: ParentNode = document): void {\n const fragments = Array.from(\n root.querySelectorAll<HTMLTemplateElement>(\n \"template[data-mreact-oob-fragment]\",\n ),\n );\n const completionMarkers = new Map<string | null, Element>();\n for (const marker of root.querySelectorAll<Element>(\"[data-mreact-oob-complete]\")) {\n const id = marker.getAttribute(\"data-mreact-oob-complete\");\n if (!completionMarkers.has(id)) {\n completionMarkers.set(id, marker);\n }\n }\n const placeholders = new Map<string | null, Element>();\n for (const placeholder of root.querySelectorAll<Element>(\"[data-mreact-oob-placeholder]\")) {\n const id = placeholder.getAttribute(\"data-mreact-oob-placeholder\");\n if (!placeholders.has(id)) {\n placeholders.set(id, placeholder);\n }\n }\n\n for (const fragment of fragments) {\n const id = fragment.dataset.mreactOobFragment;\n\n if (id === undefined) {\n continue;\n }\n\n const completionMarker = completionMarkers.get(id);\n if (completionMarker === undefined) {\n continue;\n }\n\n const placeholder = placeholders.get(id);\n if (placeholder === undefined) {\n continue;\n }\n\n placeholder.replaceWith(fragment.content.cloneNode(true));\n fragment.remove();\n completionMarker.remove();\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reckona/mreact-server",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.183",
|
|
4
4
|
"description": "Server rendering, streaming, hydration, and Flight primitives for mreact.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"flight",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"access": "public"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@reckona/mreact-
|
|
65
|
-
"@reckona/mreact-
|
|
64
|
+
"@reckona/mreact-compat": "0.0.183",
|
|
65
|
+
"@reckona/mreact-shared": "0.0.183"
|
|
66
66
|
}
|
|
67
67
|
}
|
package/src/boundary.ts
CHANGED
|
@@ -472,7 +472,7 @@ function isPromiseLike(value: unknown): value is PromiseLike<void> {
|
|
|
472
472
|
return isPromiseLikeUnknown(value);
|
|
473
473
|
}
|
|
474
474
|
|
|
475
|
-
const outOfOrderReorderScript = `(()=>{function apply(root){const fragments=Array.from(root.querySelectorAll("template[data-mreact-oob-fragment]"));for(const
|
|
475
|
+
const outOfOrderReorderScript = `(()=>{function apply(root){const fragments=Array.from(root.querySelectorAll("template[data-mreact-oob-fragment]"));const markers=new Map();for(const marker of root.querySelectorAll("[data-mreact-oob-complete]")){const id=marker.getAttribute("data-mreact-oob-complete");if(!markers.has(id))markers.set(id,marker);}const placeholders=new Map();for(const placeholder of root.querySelectorAll("[data-mreact-oob-placeholder]")){const id=placeholder.getAttribute("data-mreact-oob-placeholder");if(!placeholders.has(id))placeholders.set(id,placeholder);}for(const fragment of fragments){const id=fragment.getAttribute("data-mreact-oob-fragment");if(id===null)continue;const marker=markers.get(id);if(marker===undefined)continue;const placeholder=placeholders.get(id);if(placeholder===undefined)continue;placeholder.replaceWith(fragment.content.cloneNode(true));fragment.remove();marker.remove();}}apply(document);new MutationObserver(()=>apply(document)).observe(document.documentElement,{childList:true,subtree:true});})();`;
|
|
476
476
|
|
|
477
477
|
const reactSuspenseRevealScriptBody = `(self.$RC=self.$RC||function(bid,sid){var b=document.getElementById(bid);var s=document.getElementById(sid);if(!b||!s)return;var p=b.parentNode;var e=b.nextSibling;var d=0;var r=[];for(var n=e;n;n=n.nextSibling){if(n.nodeType===8){if(n.data==="$"||n.data==="$?"||n.data==="$!")d++;else if(n.data==="/$"){if(d===0){e=n;break;}d--;}}r.push(n);}for(var i=0;r[i];i++)p.removeChild(r[i]);while(s.firstChild)p.insertBefore(s.firstChild,e);s.remove();b.data="$";})`;
|
|
478
478
|
|
package/src/flight.ts
CHANGED
|
@@ -1704,202 +1704,228 @@ function parseReactFlightId(value: string): number {
|
|
|
1704
1704
|
return Number.parseInt(value, 16);
|
|
1705
1705
|
}
|
|
1706
1706
|
|
|
1707
|
-
|
|
1707
|
+
type FlightSerializationResult<T extends FlightModel = FlightModel> = T | Promise<T>;
|
|
1708
|
+
|
|
1709
|
+
function serializeFlightValue(
|
|
1708
1710
|
value: unknown,
|
|
1709
1711
|
state: FlightSerializationState,
|
|
1710
1712
|
depth: number,
|
|
1711
|
-
):
|
|
1713
|
+
): FlightSerializationResult {
|
|
1712
1714
|
if (depth > MAX_FLIGHT_DECODE_DEPTH) flightTooDeep();
|
|
1713
1715
|
|
|
1714
|
-
|
|
1716
|
+
if (isThenable(value)) {
|
|
1717
|
+
return Promise.resolve(value).then((awaited) => serializeFlightValue(awaited, state, depth));
|
|
1718
|
+
}
|
|
1715
1719
|
|
|
1716
|
-
if (
|
|
1720
|
+
if (value === null) {
|
|
1717
1721
|
return null;
|
|
1718
1722
|
}
|
|
1719
1723
|
|
|
1720
|
-
if (
|
|
1724
|
+
if (value === undefined) {
|
|
1721
1725
|
return { kind: "undefined" };
|
|
1722
1726
|
}
|
|
1723
1727
|
|
|
1724
|
-
if (typeof
|
|
1725
|
-
return
|
|
1728
|
+
if (typeof value === "string" || typeof value === "boolean") {
|
|
1729
|
+
return value;
|
|
1726
1730
|
}
|
|
1727
1731
|
|
|
1728
|
-
if (typeof
|
|
1729
|
-
if (Number.isNaN(
|
|
1732
|
+
if (typeof value === "number") {
|
|
1733
|
+
if (Number.isNaN(value)) {
|
|
1730
1734
|
return { kind: "number", value: "NaN" };
|
|
1731
1735
|
}
|
|
1732
1736
|
|
|
1733
|
-
if (
|
|
1737
|
+
if (value === Infinity) {
|
|
1734
1738
|
return { kind: "number", value: "Infinity" };
|
|
1735
1739
|
}
|
|
1736
1740
|
|
|
1737
|
-
if (
|
|
1741
|
+
if (value === -Infinity) {
|
|
1738
1742
|
return { kind: "number", value: "-Infinity" };
|
|
1739
1743
|
}
|
|
1740
1744
|
|
|
1741
|
-
if (Object.is(
|
|
1745
|
+
if (Object.is(value, -0)) {
|
|
1742
1746
|
return { kind: "number", value: "-0" };
|
|
1743
1747
|
}
|
|
1744
1748
|
|
|
1745
|
-
return
|
|
1749
|
+
return value;
|
|
1746
1750
|
}
|
|
1747
1751
|
|
|
1748
|
-
if (typeof
|
|
1749
|
-
return { kind: "bigint", value:
|
|
1752
|
+
if (typeof value === "bigint") {
|
|
1753
|
+
return { kind: "bigint", value: value.toString() };
|
|
1750
1754
|
}
|
|
1751
1755
|
|
|
1752
|
-
if (typeof
|
|
1753
|
-
return { kind: "symbol", name: Symbol.keyFor(
|
|
1756
|
+
if (typeof value === "symbol") {
|
|
1757
|
+
return { kind: "symbol", name: Symbol.keyFor(value) ?? value.description ?? "" };
|
|
1754
1758
|
}
|
|
1755
1759
|
|
|
1756
|
-
if (Array.isArray(
|
|
1757
|
-
return
|
|
1760
|
+
if (Array.isArray(value)) {
|
|
1761
|
+
return resolveFlightArray(value.map((item) => serializeFlightValue(item, state, depth + 1)));
|
|
1758
1762
|
}
|
|
1759
1763
|
|
|
1760
|
-
if (isServerReference(
|
|
1761
|
-
|
|
1764
|
+
if (isServerReference(value)) {
|
|
1765
|
+
const id = getServerReferenceId(value, state);
|
|
1766
|
+
return resolveFlightResult(id, (resolvedId) => ({
|
|
1762
1767
|
kind: "server-reference",
|
|
1763
|
-
id:
|
|
1764
|
-
};
|
|
1768
|
+
id: resolvedId,
|
|
1769
|
+
}));
|
|
1765
1770
|
}
|
|
1766
1771
|
|
|
1767
|
-
if (isReactCompatElement(
|
|
1768
|
-
return
|
|
1772
|
+
if (isReactCompatElement(value)) {
|
|
1773
|
+
return serializeElement(value, state, depth + 1);
|
|
1769
1774
|
}
|
|
1770
1775
|
|
|
1771
|
-
if (
|
|
1772
|
-
return { kind: "date", value:
|
|
1776
|
+
if (value instanceof Date) {
|
|
1777
|
+
return { kind: "date", value: value.toJSON() };
|
|
1773
1778
|
}
|
|
1774
1779
|
|
|
1775
|
-
if (
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
[
|
|
1782
|
-
await serializeFlightValue(key, state, depth + 1),
|
|
1783
|
-
await serializeFlightValue(value, state, depth + 1),
|
|
1784
|
-
] as [FlightModel, FlightModel],
|
|
1780
|
+
if (value instanceof Map) {
|
|
1781
|
+
const entries = resolveFlightArray(
|
|
1782
|
+
Array.from(value.entries()).map(([key, entryValue]) =>
|
|
1783
|
+
resolveFlightTuple(
|
|
1784
|
+
serializeFlightValue(key, state, depth + 1),
|
|
1785
|
+
serializeFlightValue(entryValue, state, depth + 1),
|
|
1785
1786
|
),
|
|
1786
1787
|
),
|
|
1787
|
-
|
|
1788
|
+
);
|
|
1789
|
+
return resolveFlightResult(entries, (resolvedEntries) => ({
|
|
1790
|
+
kind: "map",
|
|
1791
|
+
entries: resolvedEntries,
|
|
1792
|
+
}));
|
|
1788
1793
|
}
|
|
1789
1794
|
|
|
1790
|
-
if (
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
Array.from(awaited.values()).map((value) => serializeFlightValue(value, state, depth + 1)),
|
|
1795
|
+
if (value instanceof Set) {
|
|
1796
|
+
const values = resolveFlightArray(
|
|
1797
|
+
Array.from(value.values()).map((entryValue) =>
|
|
1798
|
+
serializeFlightValue(entryValue, state, depth + 1),
|
|
1795
1799
|
),
|
|
1796
|
-
|
|
1800
|
+
);
|
|
1801
|
+
return resolveFlightResult(values, (resolvedValues) => ({
|
|
1802
|
+
kind: "set",
|
|
1803
|
+
values: resolvedValues,
|
|
1804
|
+
}));
|
|
1797
1805
|
}
|
|
1798
1806
|
|
|
1799
|
-
if (isFormDataLike(
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
),
|
|
1807
|
+
if (isFormDataLike(value)) {
|
|
1808
|
+
const entries = resolveFlightArray(
|
|
1809
|
+
Array.from(value.entries()).map(([key, entryValue]) =>
|
|
1810
|
+
resolveFlightResult(serializeFlightValue(entryValue, state, depth + 1), (resolvedValue) => [
|
|
1811
|
+
key,
|
|
1812
|
+
resolvedValue,
|
|
1813
|
+
] as [string, FlightModel]),
|
|
1807
1814
|
),
|
|
1808
|
-
|
|
1815
|
+
);
|
|
1816
|
+
return resolveFlightResult(entries, (resolvedEntries) => ({
|
|
1817
|
+
kind: "form-data",
|
|
1818
|
+
entries: resolvedEntries,
|
|
1819
|
+
}));
|
|
1809
1820
|
}
|
|
1810
1821
|
|
|
1811
|
-
if (isIterableObject(
|
|
1812
|
-
|
|
1822
|
+
if (isIterableObject(value)) {
|
|
1823
|
+
const values = resolveFlightArray(
|
|
1824
|
+
Array.from(value).map((entryValue) => serializeFlightValue(entryValue, state, depth + 1)),
|
|
1825
|
+
);
|
|
1826
|
+
return resolveFlightResult(values, (resolvedValues) => ({
|
|
1813
1827
|
kind: "iterable",
|
|
1814
|
-
values:
|
|
1815
|
-
|
|
1816
|
-
),
|
|
1817
|
-
};
|
|
1828
|
+
values: resolvedValues,
|
|
1829
|
+
}));
|
|
1818
1830
|
}
|
|
1819
1831
|
|
|
1820
|
-
if (
|
|
1832
|
+
if (value instanceof Error) {
|
|
1821
1833
|
return {
|
|
1822
1834
|
kind: "error",
|
|
1823
|
-
name:
|
|
1824
|
-
message:
|
|
1835
|
+
name: value.name,
|
|
1836
|
+
message: value.message,
|
|
1825
1837
|
};
|
|
1826
1838
|
}
|
|
1827
1839
|
|
|
1828
|
-
if (typeof
|
|
1829
|
-
return
|
|
1840
|
+
if (typeof value === "object") {
|
|
1841
|
+
return serializeObject(value as Record<string, unknown>, state, depth + 1);
|
|
1830
1842
|
}
|
|
1831
1843
|
|
|
1832
|
-
throw new TypeError(`Unsupported Flight value: ${typeof
|
|
1844
|
+
throw new TypeError(`Unsupported Flight value: ${typeof value}`);
|
|
1833
1845
|
}
|
|
1834
1846
|
|
|
1835
|
-
|
|
1847
|
+
function serializeElement(
|
|
1836
1848
|
element: ReactCompatElementLike,
|
|
1837
1849
|
state: FlightSerializationState,
|
|
1838
1850
|
depth: number,
|
|
1839
|
-
):
|
|
1851
|
+
): FlightSerializationResult<FlightElementModel | FlightModel> {
|
|
1840
1852
|
if (typeof element.type === "function") {
|
|
1841
|
-
return
|
|
1853
|
+
return serializeFlightValue(element.type(element.props), state, depth + 1);
|
|
1842
1854
|
}
|
|
1843
1855
|
|
|
1844
1856
|
if (isClientReference(element.type)) {
|
|
1845
|
-
|
|
1857
|
+
const elementType = element.type;
|
|
1858
|
+
const props = serializeProps(element.props, state, depth + 1);
|
|
1859
|
+
return resolveFlightResult(props, (resolvedProps) => ({
|
|
1846
1860
|
kind: "element",
|
|
1847
1861
|
type: {
|
|
1848
1862
|
kind: "client-reference",
|
|
1849
|
-
id: getClientReferenceId(
|
|
1863
|
+
id: getClientReferenceId(elementType, state),
|
|
1850
1864
|
},
|
|
1851
1865
|
key: element.key,
|
|
1852
|
-
props:
|
|
1853
|
-
};
|
|
1866
|
+
props: resolvedProps,
|
|
1867
|
+
}));
|
|
1854
1868
|
}
|
|
1855
1869
|
|
|
1856
1870
|
if (typeof element.type === "string") {
|
|
1857
|
-
|
|
1871
|
+
const elementType = element.type;
|
|
1872
|
+
const props = serializeProps(element.props, state, depth + 1);
|
|
1873
|
+
return resolveFlightResult(props, (resolvedProps) => ({
|
|
1858
1874
|
kind: "element",
|
|
1859
|
-
type:
|
|
1875
|
+
type: elementType,
|
|
1860
1876
|
key: element.key,
|
|
1861
|
-
props:
|
|
1862
|
-
};
|
|
1877
|
+
props: resolvedProps,
|
|
1878
|
+
}));
|
|
1863
1879
|
}
|
|
1864
1880
|
|
|
1865
1881
|
if (element.type === REACT_COMPAT_FRAGMENT_TYPE) {
|
|
1866
|
-
|
|
1882
|
+
const props = serializeProps(element.props, state, depth + 1);
|
|
1883
|
+
return resolveFlightResult(props, (resolvedProps) => ({
|
|
1867
1884
|
kind: "element",
|
|
1868
1885
|
type: { kind: "fragment" },
|
|
1869
1886
|
key: element.key,
|
|
1870
|
-
props:
|
|
1871
|
-
};
|
|
1887
|
+
props: resolvedProps,
|
|
1888
|
+
}));
|
|
1872
1889
|
}
|
|
1873
1890
|
|
|
1874
1891
|
throw new TypeError("Unsupported Flight element type.");
|
|
1875
1892
|
}
|
|
1876
1893
|
|
|
1877
|
-
|
|
1894
|
+
function serializeProps(
|
|
1878
1895
|
props: Record<string, unknown>,
|
|
1879
1896
|
state: FlightSerializationState,
|
|
1880
1897
|
depth: number,
|
|
1881
|
-
):
|
|
1882
|
-
const entries =
|
|
1883
|
-
Object.entries(props).map(
|
|
1884
|
-
|
|
1898
|
+
): FlightSerializationResult<Record<string, FlightModel>> {
|
|
1899
|
+
const entries = resolveFlightArray(
|
|
1900
|
+
Object.entries(props).map(([key, value]) =>
|
|
1901
|
+
resolveFlightResult(serializeFlightValue(value, state, depth + 1), (resolvedValue) => [
|
|
1902
|
+
key,
|
|
1903
|
+
resolvedValue,
|
|
1904
|
+
]),
|
|
1885
1905
|
),
|
|
1886
1906
|
);
|
|
1887
1907
|
|
|
1888
|
-
return Object.fromEntries(
|
|
1908
|
+
return resolveFlightResult(entries, (resolvedEntries) => Object.fromEntries(resolvedEntries));
|
|
1889
1909
|
}
|
|
1890
1910
|
|
|
1891
|
-
|
|
1911
|
+
function serializeObject(
|
|
1892
1912
|
object: Record<string, unknown>,
|
|
1893
1913
|
state: FlightSerializationState,
|
|
1894
1914
|
depth: number,
|
|
1895
|
-
):
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1915
|
+
): FlightSerializationResult<FlightObjectModel> {
|
|
1916
|
+
const entries = resolveFlightArray(
|
|
1917
|
+
Object.entries(object).map(([key, value]) =>
|
|
1918
|
+
resolveFlightResult(
|
|
1919
|
+
serializeFlightValue(value, state, depth + 1),
|
|
1920
|
+
(resolvedValue) => [key, resolvedValue] as const,
|
|
1900
1921
|
),
|
|
1901
1922
|
),
|
|
1902
|
-
)
|
|
1923
|
+
);
|
|
1924
|
+
|
|
1925
|
+
return resolveFlightResult(
|
|
1926
|
+
entries,
|
|
1927
|
+
(resolvedEntries) => Object.fromEntries(resolvedEntries) as FlightObjectModel,
|
|
1928
|
+
);
|
|
1903
1929
|
}
|
|
1904
1930
|
|
|
1905
1931
|
function getClientReferenceId(reference: ClientReference, state: FlightSerializationState): number {
|
|
@@ -1921,14 +1947,24 @@ function getClientReferenceId(reference: ClientReference, state: FlightSerializa
|
|
|
1921
1947
|
return id;
|
|
1922
1948
|
}
|
|
1923
1949
|
|
|
1924
|
-
|
|
1950
|
+
function getServerReferenceId(
|
|
1925
1951
|
reference: ServerReference,
|
|
1926
1952
|
state: FlightSerializationState,
|
|
1927
|
-
): Promise<number> {
|
|
1953
|
+
): number | Promise<number> {
|
|
1928
1954
|
const serializedBound =
|
|
1929
1955
|
reference.bound === undefined
|
|
1930
1956
|
? undefined
|
|
1931
|
-
:
|
|
1957
|
+
: resolveFlightArray(reference.bound.map((value) => serializeFlightValue(value, state, 0)));
|
|
1958
|
+
return resolveFlightResult(serializedBound, (resolvedBound) =>
|
|
1959
|
+
getServerReferenceIdForBound(reference, state, resolvedBound),
|
|
1960
|
+
);
|
|
1961
|
+
}
|
|
1962
|
+
|
|
1963
|
+
function getServerReferenceIdForBound(
|
|
1964
|
+
reference: ServerReference,
|
|
1965
|
+
state: FlightSerializationState,
|
|
1966
|
+
serializedBound: FlightModel[] | undefined,
|
|
1967
|
+
): number {
|
|
1932
1968
|
const key = `${reference.moduleId}:${reference.exportName}:${JSON.stringify(serializedBound ?? null)}`;
|
|
1933
1969
|
const existing = state.serverReferenceIndexes.get(key);
|
|
1934
1970
|
|
|
@@ -1947,6 +1983,24 @@ async function getServerReferenceId(
|
|
|
1947
1983
|
return id;
|
|
1948
1984
|
}
|
|
1949
1985
|
|
|
1986
|
+
function resolveFlightArray<T>(values: Array<T | Promise<T>>): T[] | Promise<T[]> {
|
|
1987
|
+
return values.some(isThenable) ? Promise.all(values) : (values as T[]);
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
function resolveFlightTuple<TLeft, TRight>(
|
|
1991
|
+
left: TLeft | Promise<TLeft>,
|
|
1992
|
+
right: TRight | Promise<TRight>,
|
|
1993
|
+
): [TLeft, TRight] | Promise<[TLeft, TRight]> {
|
|
1994
|
+
return isThenable(left) || isThenable(right) ? Promise.all([left, right]) : [left, right];
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1997
|
+
function resolveFlightResult<T, TResult>(
|
|
1998
|
+
value: T | Promise<T>,
|
|
1999
|
+
map: (value: T) => TResult,
|
|
2000
|
+
): TResult | Promise<TResult> {
|
|
2001
|
+
return isThenable(value) ? value.then(map) : map(value);
|
|
2002
|
+
}
|
|
2003
|
+
|
|
1950
2004
|
function isReactCompatElement(value: unknown): value is ReactCompatElementLike {
|
|
1951
2005
|
return (
|
|
1952
2006
|
typeof value === "object" &&
|
|
@@ -1955,6 +2009,14 @@ function isReactCompatElement(value: unknown): value is ReactCompatElementLike {
|
|
|
1955
2009
|
);
|
|
1956
2010
|
}
|
|
1957
2011
|
|
|
2012
|
+
function isThenable(value: unknown): value is PromiseLike<unknown> {
|
|
2013
|
+
return (
|
|
2014
|
+
value !== null &&
|
|
2015
|
+
(typeof value === "object" || typeof value === "function") &&
|
|
2016
|
+
typeof (value as { then?: unknown }).then === "function"
|
|
2017
|
+
);
|
|
2018
|
+
}
|
|
2019
|
+
|
|
1958
2020
|
function isFormDataLike(value: unknown): value is FormData {
|
|
1959
2021
|
return typeof FormData !== "undefined" && value instanceof FormData;
|
|
1960
2022
|
}
|
package/src/reorder.ts
CHANGED
|
@@ -5,6 +5,20 @@ export function applyOutOfOrderFragments(root: ParentNode = document): void {
|
|
|
5
5
|
"template[data-mreact-oob-fragment]",
|
|
6
6
|
),
|
|
7
7
|
);
|
|
8
|
+
const completionMarkers = new Map<string | null, Element>();
|
|
9
|
+
for (const marker of root.querySelectorAll<Element>("[data-mreact-oob-complete]")) {
|
|
10
|
+
const id = marker.getAttribute("data-mreact-oob-complete");
|
|
11
|
+
if (!completionMarkers.has(id)) {
|
|
12
|
+
completionMarkers.set(id, marker);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
const placeholders = new Map<string | null, Element>();
|
|
16
|
+
for (const placeholder of root.querySelectorAll<Element>("[data-mreact-oob-placeholder]")) {
|
|
17
|
+
const id = placeholder.getAttribute("data-mreact-oob-placeholder");
|
|
18
|
+
if (!placeholders.has(id)) {
|
|
19
|
+
placeholders.set(id, placeholder);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
8
22
|
|
|
9
23
|
for (const fragment of fragments) {
|
|
10
24
|
const id = fragment.dataset.mreactOobFragment;
|
|
@@ -13,19 +27,13 @@ export function applyOutOfOrderFragments(root: ParentNode = document): void {
|
|
|
13
27
|
continue;
|
|
14
28
|
}
|
|
15
29
|
|
|
16
|
-
const completionMarker =
|
|
17
|
-
root.querySelectorAll<Element>("[data-mreact-oob-complete]"),
|
|
18
|
-
).find((candidate) => candidate.getAttribute("data-mreact-oob-complete") === id);
|
|
19
|
-
|
|
30
|
+
const completionMarker = completionMarkers.get(id);
|
|
20
31
|
if (completionMarker === undefined) {
|
|
21
32
|
continue;
|
|
22
33
|
}
|
|
23
34
|
|
|
24
|
-
const placeholder =
|
|
25
|
-
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
if (placeholder === null) {
|
|
35
|
+
const placeholder = placeholders.get(id);
|
|
36
|
+
if (placeholder === undefined) {
|
|
29
37
|
continue;
|
|
30
38
|
}
|
|
31
39
|
|
|
@@ -34,7 +42,3 @@ export function applyOutOfOrderFragments(root: ParentNode = document): void {
|
|
|
34
42
|
completionMarker.remove();
|
|
35
43
|
}
|
|
36
44
|
}
|
|
37
|
-
|
|
38
|
-
function cssEscape(value: string): string {
|
|
39
|
-
return value.replaceAll("\\", "\\\\").replaceAll("\"", "\\\"");
|
|
40
|
-
}
|