@solidjs/web 2.0.0-rc.0 → 2.0.0-rc.2
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 +1 -1
- package/dist/dev.cjs +40 -11
- package/dist/dev.js +39 -12
- package/dist/server.cjs +419 -69
- package/dist/server.js +411 -73
- package/dist/web.cjs +37 -11
- package/dist/web.js +36 -12
- package/frames/dist/client.cjs +94 -8
- package/frames/dist/client.dev.cjs +97 -8
- package/frames/dist/client.dev.js +98 -9
- package/frames/dist/client.js +95 -9
- package/frames/dist/server.cjs +266 -56
- package/frames/dist/server.js +267 -57
- package/package.json +4 -3
- package/serialization/dist/decode.cjs +32 -3
- package/serialization/dist/decode.js +33 -4
- package/serialization/dist/serialization.cjs +32 -3
- package/serialization/dist/serialization.js +33 -4
- package/server-functions/dist/client.cjs +196 -8
- package/server-functions/dist/client.js +195 -9
- package/server-functions/dist/server.cjs +201 -36
- package/server-functions/dist/server.dev.cjs +201 -36
- package/server-functions/dist/server.dev.js +199 -37
- package/server-functions/dist/server.js +199 -37
- package/types/core.d.ts +3 -0
- package/types/frames/frame-client.d.ts +18 -0
- package/types/index.d.ts +16 -2
- package/types/jsx.d.ts +9 -0
- package/types/server-functions/client.d.ts +61 -0
- package/types/server-functions/server.d.ts +94 -1
- package/types/server-mock.d.ts +11 -2
- package/types/server.d.ts +23 -2
- package/types-cjs/core.d.cts +3 -0
- package/types-cjs/frames/frame-client.d.cts +18 -0
- package/types-cjs/index.d.cts +16 -2
- package/types-cjs/jsx.d.cts +9 -0
- package/types-cjs/server-functions/client.d.cts +61 -0
- package/types-cjs/server-functions/server.d.cts +94 -1
- package/types-cjs/server-mock.d.cts +11 -2
- package/types-cjs/server.d.cts +23 -2
package/frames/dist/server.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createMemo, runWithOwner, createOwner, sharedConfig, createRoot, ssrHandleError, getOwner, inServerComponentScope, creationStamp, NoHydration, runInServerComponentScope, Hydration, getProjectionTrace } from 'solid-js';
|
|
2
|
-
import { Feature, toCrossJSONStream, Serializer, getCrossReferenceHeader } from 'seroval';
|
|
2
|
+
import { Feature, createStream, toCrossJSONStream, Serializer, getCrossReferenceHeader } from 'seroval';
|
|
3
3
|
import { AbortSignalPlugin, CustomEventPlugin, DOMExceptionPlugin, EventPlugin, FormDataPlugin, HeadersPlugin, ReadableStreamPlugin, RequestPlugin, ResponsePlugin, URLSearchParamsPlugin, URLPlugin } from 'seroval-plugins/web';
|
|
4
4
|
|
|
5
5
|
const STATE = Symbol.for("dom-expressions.container-trace-state");
|
|
@@ -10,6 +10,9 @@ const state = globalThis[STATE] || (globalThis[STATE] = {
|
|
|
10
10
|
function setContainerTraceResolver(fn) {
|
|
11
11
|
state.resolveTrace = fn;
|
|
12
12
|
}
|
|
13
|
+
function setContainerTraceStreamMint(fn) {
|
|
14
|
+
state.streamOf = fn;
|
|
15
|
+
}
|
|
13
16
|
function isContainerTraced(value) {
|
|
14
17
|
const resolve = state.resolveTrace;
|
|
15
18
|
return !!(resolve && value && typeof value === "object" && resolve(value));
|
|
@@ -58,9 +61,10 @@ function materialize(marker) {
|
|
|
58
61
|
}
|
|
59
62
|
function parseTrace(value, ctx) {
|
|
60
63
|
const trace = value[TRACE];
|
|
64
|
+
const sub = trace.subscribe();
|
|
61
65
|
return {
|
|
62
66
|
a: trace.array ? 1 : 0,
|
|
63
|
-
i: ctx.parse(
|
|
67
|
+
i: ctx.parse(state.streamOf ? state.streamOf(sub) : sub)
|
|
64
68
|
};
|
|
65
69
|
}
|
|
66
70
|
const ContainerTracePlugin = {
|
|
@@ -74,9 +78,10 @@ const ContainerTracePlugin = {
|
|
|
74
78
|
},
|
|
75
79
|
async async(value, ctx) {
|
|
76
80
|
const trace = value[TRACE];
|
|
81
|
+
const sub = trace.subscribe();
|
|
77
82
|
return {
|
|
78
83
|
a: trace.array ? 1 : 0,
|
|
79
|
-
i: await ctx.parse(
|
|
84
|
+
i: await ctx.parse(state.streamOf ? state.streamOf(sub) : sub)
|
|
80
85
|
};
|
|
81
86
|
},
|
|
82
87
|
stream: parseTrace
|
|
@@ -101,6 +106,18 @@ const ssrAsyncValue = value => createMemo(() => value, {
|
|
|
101
106
|
serialize: false
|
|
102
107
|
});
|
|
103
108
|
|
|
109
|
+
setContainerTraceStreamMint(iterable => {
|
|
110
|
+
const stream = createStream();
|
|
111
|
+
(async () => {
|
|
112
|
+
try {
|
|
113
|
+
for await (const value of iterable) stream.next(value);
|
|
114
|
+
stream.return(undefined);
|
|
115
|
+
} catch (error) {
|
|
116
|
+
stream.throw(error);
|
|
117
|
+
}
|
|
118
|
+
})();
|
|
119
|
+
return stream;
|
|
120
|
+
});
|
|
104
121
|
const DEFAULT_WEB_PLUGINS = Object.freeze([AbortSignalPlugin,
|
|
105
122
|
CustomEventPlugin, DOMExceptionPlugin, EventPlugin,
|
|
106
123
|
FormDataPlugin, HeadersPlugin, ReadableStreamPlugin, RequestPlugin, ResponsePlugin, URLSearchParamsPlugin, URLPlugin,
|
|
@@ -480,6 +497,7 @@ function registerEntryAssets(manifest) {
|
|
|
480
497
|
const assets = resolveAssets(key, manifest);
|
|
481
498
|
if (assets) {
|
|
482
499
|
for (let i = 0; i < assets.css.length; i++) ctx.registerAsset("style", assets.css[i]);
|
|
500
|
+
for (let i = 1; i < assets.js.length; i++) ctx.registerAsset("module", assets.js[i]);
|
|
483
501
|
}
|
|
484
502
|
return;
|
|
485
503
|
}
|
|
@@ -739,7 +757,7 @@ function emitHeadResource(registry, context, tracking, emitResource, nonce, desc
|
|
|
739
757
|
if (!styles) tracking.boundaryStyles.set(tracking.currentBoundaryId, styles = new Set());
|
|
740
758
|
styles.add(entry);
|
|
741
759
|
}
|
|
742
|
-
const markup = `<link${attrHtml}>`;
|
|
760
|
+
const markup = `<link${attrHtml}${nonceAttr(nonce, "style")}>`;
|
|
743
761
|
if (emitResource) emitResource(markup, entry);else {
|
|
744
762
|
registry.eagerHtml += markup;
|
|
745
763
|
entry.emitted = true;
|
|
@@ -837,7 +855,7 @@ function headGroupSignature(winner) {
|
|
|
837
855
|
}
|
|
838
856
|
return sig;
|
|
839
857
|
}
|
|
840
|
-
function renderShellHead(registry, nonce, isPendingFragment) {
|
|
858
|
+
function renderShellHead(registry, nonce, isPendingFragment, noScripts) {
|
|
841
859
|
commitHeadBoundary(registry, "", isPendingFragment);
|
|
842
860
|
registry.shellFlushed = true;
|
|
843
861
|
const winners = resolveHead(registry.committed);
|
|
@@ -847,8 +865,14 @@ function renderShellHead(registry, nonce, isPendingFragment) {
|
|
|
847
865
|
let metas = "";
|
|
848
866
|
let others = "";
|
|
849
867
|
let scripts = "";
|
|
868
|
+
let title = null;
|
|
850
869
|
for (const [identity, winner] of winners) {
|
|
851
870
|
registry.flushed.set(identity, headGroupSignature(winner));
|
|
871
|
+
if (identity === "title") {
|
|
872
|
+
const children = winner.tags[0].props.children;
|
|
873
|
+
title = children == null ? "" : String(children);
|
|
874
|
+
continue;
|
|
875
|
+
}
|
|
852
876
|
for (let i = 0; i < winner.tags.length; i++) {
|
|
853
877
|
const t = winner.tags[i];
|
|
854
878
|
const markup = renderHeadTagMarkup(t.tag, t.props, identity, nonce);
|
|
@@ -857,10 +881,12 @@ function renderShellHead(registry, nonce, isPendingFragment) {
|
|
|
857
881
|
}
|
|
858
882
|
return {
|
|
859
883
|
prelude,
|
|
860
|
-
html: registry.eagerHtml + links + metas + others + scripts
|
|
884
|
+
html: registry.eagerHtml + links + metas + others + scripts,
|
|
885
|
+
title,
|
|
886
|
+
noScripts
|
|
861
887
|
};
|
|
862
888
|
}
|
|
863
|
-
function flushHeadFragment(registry, boundary) {
|
|
889
|
+
function flushHeadFragment(registry, boundary, nonce) {
|
|
864
890
|
const groups = commitHeadBoundary(registry, boundary);
|
|
865
891
|
if (!groups.length) return null;
|
|
866
892
|
const winners = resolveHead(registry.committed);
|
|
@@ -891,12 +917,75 @@ function flushHeadFragment(registry, boundary) {
|
|
|
891
917
|
if (v == null || v === false) continue;
|
|
892
918
|
attrs[name] = v === true ? "" : String(v);
|
|
893
919
|
}
|
|
920
|
+
if (nonce && !hasNonceProp(t.props)) {
|
|
921
|
+
const destination = nonceDestination(t.tag, t.props);
|
|
922
|
+
const value = destination && nonce[destination];
|
|
923
|
+
if (value) attrs.nonce = String(value);
|
|
924
|
+
}
|
|
894
925
|
const children = t.props.children;
|
|
895
926
|
ops.push(["a", identity, t.tag, attrs, children == null ? null : String(children)]);
|
|
896
927
|
}
|
|
897
928
|
}
|
|
898
929
|
return ops.length ? ops : null;
|
|
899
930
|
}
|
|
931
|
+
function normalizeNonce(nonce) {
|
|
932
|
+
if (nonce == null) return undefined;
|
|
933
|
+
if (typeof nonce === "string") {
|
|
934
|
+
const attr = nonce ? ` nonce="${escape(nonce, true)}"` : "";
|
|
935
|
+
return {
|
|
936
|
+
script: nonce,
|
|
937
|
+
style: nonce,
|
|
938
|
+
scriptAttr: attr,
|
|
939
|
+
styleAttr: attr
|
|
940
|
+
};
|
|
941
|
+
}
|
|
942
|
+
const script = nonce.script;
|
|
943
|
+
const style = nonce.style;
|
|
944
|
+
if (!script && !style) return undefined;
|
|
945
|
+
return {
|
|
946
|
+
script,
|
|
947
|
+
style,
|
|
948
|
+
scriptAttr: typeof script === "string" && script ? ` nonce="${escape(script, true)}"` : "",
|
|
949
|
+
styleAttr: typeof style === "string" && style ? ` nonce="${escape(style, true)}"` : ""
|
|
950
|
+
};
|
|
951
|
+
}
|
|
952
|
+
function asciiLowerCase(value) {
|
|
953
|
+
return value.replace(/[A-Z]/g, c => String.fromCharCode(c.charCodeAt(0) + 32));
|
|
954
|
+
}
|
|
955
|
+
function hasNonceProp(props) {
|
|
956
|
+
for (const name in props) if (name.length === 5 && asciiLowerCase(name) === "nonce" && props[name] != null) return true;
|
|
957
|
+
return false;
|
|
958
|
+
}
|
|
959
|
+
function nonceDestination(tag, props) {
|
|
960
|
+
if (tag === "script") return "script";
|
|
961
|
+
if (tag === "style") return "style";
|
|
962
|
+
if (tag !== "link") return null;
|
|
963
|
+
const rel = props.rel;
|
|
964
|
+
if (typeof rel !== "string") return null;
|
|
965
|
+
const rels = asciiLowerCase(rel).split(/[\t\n\f\r ]+/);
|
|
966
|
+
if (rels.includes("stylesheet")) return "style";
|
|
967
|
+
const isModulePreload = rels.includes("modulepreload");
|
|
968
|
+
if (!isModulePreload && !rels.includes("preload")) return null;
|
|
969
|
+
const as = typeof props.as === "string" ? asciiLowerCase(props.as) : "";
|
|
970
|
+
if (as === "style") return "style";
|
|
971
|
+
if (as === "script") return "script";
|
|
972
|
+
if (!isModulePreload) return null;
|
|
973
|
+
switch (as) {
|
|
974
|
+
case "fetch":
|
|
975
|
+
case "font":
|
|
976
|
+
case "image":
|
|
977
|
+
case "json":
|
|
978
|
+
case "text":
|
|
979
|
+
case "track":
|
|
980
|
+
return null;
|
|
981
|
+
default:
|
|
982
|
+
return "script";
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
function nonceAttr(nonce, destination) {
|
|
986
|
+
if (!nonce || !destination) return "";
|
|
987
|
+
return destination === "script" ? nonce.scriptAttr : nonce.styleAttr;
|
|
988
|
+
}
|
|
900
989
|
function renderHeadAttrHtml(props) {
|
|
901
990
|
let attrs = "";
|
|
902
991
|
for (const name in props) {
|
|
@@ -925,17 +1014,16 @@ function headAttrRecord(props, skipRelHref) {
|
|
|
925
1014
|
function renderHeadTagMarkup(tag, props, identity, nonce) {
|
|
926
1015
|
let attrs = renderHeadAttrHtml(props);
|
|
927
1016
|
if (identity != null) attrs += ` data-dh="${escape(identity, true)}"`;
|
|
928
|
-
if (nonce && (
|
|
1017
|
+
if (nonce && !hasNonceProp(props)) attrs += nonceAttr(nonce, nonceDestination(tag, props));
|
|
929
1018
|
if (tag === "meta" || tag === "link" || tag === "base") return `<${tag}${attrs}>`;
|
|
930
1019
|
let body = props.children == null ? "" : String(props.children);
|
|
931
1020
|
if (tag === "script") body = body.replace(/<\/(script)/gi, "<\\/$1");else if (tag === "style") body = escapeStyleContent(body);else body = escape(body);
|
|
932
1021
|
return `<${tag}${attrs}>${body}</${tag}>`;
|
|
933
1022
|
}
|
|
934
1023
|
const REPLACE_SCRIPT = `function $df(e){return _$HY.f?_$HY.f(e):$dfr(e)}function $dfr(e,n,o,t){if(!(n=document.getElementById(e)))return 0;if(!(o=document.getElementById("pl-"+e)))return(_$HY.dq=_$HY.dq||{})[e]=1,0;for(;o&&(8!==o.nodeType||o.nodeValue!=="pl-"+e);)t=o.nextSibling,o.remove(),o=t;t=o.parentNode,o.replaceWith(n.content),n.remove(),(_$HY.v=_$HY.v||{})[e]=1,_$HY.fe(e,t),_$HY.hp&&_$HY.hp[e]&&($dh(_$HY.hp[e]),delete _$HY.hp[e]),$dfd();return 1}function $dfl(e,o,n){if(!(o=document.getElementById("pl-"+e)))return(_$HY.dlq=_$HY.dlq||{})[e]=1,0;if(o._$fl)return 1;for(n=o.nextSibling;n;){if(8===n.nodeType&&n.nodeValue==="pl-"+e){o.parentNode&&o.parentNode.insertBefore(o.content.cloneNode(!0),n),o._$fl=1,$dfd();return 1}n=n.nextSibling}return 0}function $dflj(e,i){for(i=0;i<e.length;i++)$dfl(e[i])}function $dfd(e,i){if(e=_$HY.dq){_$HY.dq=0;for(i in e)$df(i)}if(e=_$HY.dlq){_$HY.dlq=0;for(i in e)$dfl(i)}}function $dfs(e,c,d){(_$HY.sc=_$HY.sc||{})[e]=c,d&&((_$HY.sd=_$HY.sd||{})[e]=1)}function $dfg(e,g,i,k){if(!(g=_$HY.sg&&_$HY.sg[e]))return;for(i=0;i<g.length;i++)if(_$HY.sc&&_$HY.sc[g[i]]>0)return;for(i=0;i<g.length;i++)k=g[i],delete _$HY.sg[k],$df(k)}function $dfc(e){if(--_$HY.sc[e]<=0){delete _$HY.sc[e],_$HY.sg&&_$HY.sg[e]?$dfg(e):!(_$HY.sd&&_$HY.sd[e])&&$df(e);_$HY.sd&&delete _$HY.sd[e]}}function $dfj(e,i,n){for(i=0;i<e.length;i++)if(_$HY.sc&&_$HY.sc[e[i]]>0){for(n=0;n<e.length;n++)(_$HY.sg=_$HY.sg||{})[e[n]]=e;return}for(i=0;i<e.length;i++)$df(e[i])}`;
|
|
935
|
-
const HEAD_SCRIPT = `function $dha(o,i,e,n){for(i=0;i<o.length;i++)e=o[i],"t"==e[0]?((n=document.querySelector("title"))||(n=document.createElement("title"),document.head.appendChild(n)),n.textContent=e[1],n.setAttribute("data-dh","title")):"r"==e[0]?$dhr(e[1]):(n=document.createElement(e[2]),Object.keys(e[3]).forEach(function(a){n.setAttribute(a,e[3][a])}),null!=e[4]&&(n.textContent=e[4]),n.setAttribute("data-dh",e[1]),document.head.appendChild(n))}function $dhr(v,l,i){for(l=document.head.querySelectorAll("[data-dh]"),i=0;i<l.length;i++)l[i].getAttribute("data-dh")==v&&l[i].remove()}function $dh(o){_$HY.h?_$HY.h(o):$dha(o)}`;
|
|
1024
|
+
const HEAD_SCRIPT = `function $dha(o,i,e,n){for(i=0;i<o.length;i++)e=o[i],"t"==e[0]?((n=document.querySelector("title"))?n.hasAttribute("data-dh")||n.setAttribute("data-dhf",n.textContent):(n=document.createElement("title"),document.head.appendChild(n)),n.textContent=e[1],n.setAttribute("data-dh","title")):"r"==e[0]?$dhr(e[1]):(n=document.createElement(e[2]),Object.keys(e[3]).forEach(function(a){n.setAttribute(a,e[3][a])}),null!=e[4]&&(n.textContent=e[4]),n.setAttribute("data-dh",e[1]),document.head.appendChild(n))}function $dhr(v,l,i){for(l=document.head.querySelectorAll("[data-dh]"),i=0;i<l.length;i++)l[i].getAttribute("data-dh")==v&&l[i].remove()}function $dh(o){_$HY.h?_$HY.h(o):$dha(o)}`;
|
|
936
1025
|
function renderToStream(code, options = {}) {
|
|
937
1026
|
let {
|
|
938
|
-
nonce,
|
|
939
1027
|
onCompleteShell,
|
|
940
1028
|
onCompleteAll,
|
|
941
1029
|
renderId = "",
|
|
@@ -943,6 +1031,7 @@ function renderToStream(code, options = {}) {
|
|
|
943
1031
|
manifest,
|
|
944
1032
|
onHead
|
|
945
1033
|
} = options;
|
|
1034
|
+
const nonce = normalizeNonce(options.nonce);
|
|
946
1035
|
let dispose;
|
|
947
1036
|
let dead = false;
|
|
948
1037
|
const abandon = () => {
|
|
@@ -967,6 +1056,32 @@ function renderToStream(code, options = {}) {
|
|
|
967
1056
|
} catch (_) {}
|
|
968
1057
|
abandon();
|
|
969
1058
|
};
|
|
1059
|
+
const coalesceWrites = (writeRaw, endRaw) => {
|
|
1060
|
+
let buf = "";
|
|
1061
|
+
let scheduled = false;
|
|
1062
|
+
const flush = () => {
|
|
1063
|
+
scheduled = false;
|
|
1064
|
+
if (!buf) return;
|
|
1065
|
+
const out = buf;
|
|
1066
|
+
buf = "";
|
|
1067
|
+
writeRaw(out);
|
|
1068
|
+
};
|
|
1069
|
+
return {
|
|
1070
|
+
write(payload) {
|
|
1071
|
+
buf += payload;
|
|
1072
|
+
if (buf.length >= 16384) return flush();
|
|
1073
|
+
if (!scheduled) {
|
|
1074
|
+
scheduled = true;
|
|
1075
|
+
deferFlush(flush);
|
|
1076
|
+
}
|
|
1077
|
+
},
|
|
1078
|
+
flush,
|
|
1079
|
+
end() {
|
|
1080
|
+
flush();
|
|
1081
|
+
endRaw();
|
|
1082
|
+
}
|
|
1083
|
+
};
|
|
1084
|
+
};
|
|
970
1085
|
const guardSink = w => ({
|
|
971
1086
|
write(payload) {
|
|
972
1087
|
if (dead) return;
|
|
@@ -986,6 +1101,23 @@ function renderToStream(code, options = {}) {
|
|
|
986
1101
|
}
|
|
987
1102
|
});
|
|
988
1103
|
const blockingPromises = new Set();
|
|
1104
|
+
const canBatchStubs = !options.serializer && !options.sink;
|
|
1105
|
+
let stubBatch = null;
|
|
1106
|
+
const STUB_BATCH_KEY = "$B";
|
|
1107
|
+
const flushStubBatch = () => {
|
|
1108
|
+
if (!stubBatch) return;
|
|
1109
|
+
const batch = stubBatch;
|
|
1110
|
+
stubBatch = null;
|
|
1111
|
+
if (batch.size === 1) {
|
|
1112
|
+
const [id, p] = batch.entries().next().value;
|
|
1113
|
+
serializer.write(id, p);
|
|
1114
|
+
return;
|
|
1115
|
+
}
|
|
1116
|
+
const obj = {};
|
|
1117
|
+
for (const [id, p] of batch) obj[id] = p;
|
|
1118
|
+
serializer.write(STUB_BATCH_KEY, obj);
|
|
1119
|
+
pushTask(`(b=>{for(var k in b)_$HY.r[k]=b[k];delete _$HY.r["${STUB_BATCH_KEY}"]})(_$HY.r["${STUB_BATCH_KEY}"])`);
|
|
1120
|
+
};
|
|
989
1121
|
let headerEmitted = false;
|
|
990
1122
|
const pushTask = task => {
|
|
991
1123
|
if (noScripts) return;
|
|
@@ -1022,10 +1154,11 @@ function renderToStream(code, options = {}) {
|
|
|
1022
1154
|
buffer.write(renderInlineStyle(styles.inline[i], nonce));
|
|
1023
1155
|
}
|
|
1024
1156
|
if (styles.links.length) {
|
|
1157
|
+
const styleAttr = nonceAttr(nonce, "style");
|
|
1025
1158
|
emitTask(`$dfs("${key}",${styles.links.length},${deferActivation ? 1 : 0})`);
|
|
1026
1159
|
writeTasks();
|
|
1027
1160
|
for (const entry of styles.links) {
|
|
1028
|
-
buffer.write(typeof entry === "string" ? `<link rel="stylesheet" href="${entry}" onload="$dfc('${key}')" onerror="$dfc('${key}')">` : `<link${entry.attrHtml} onload="$dfc('${key}')" onerror="$dfc('${key}')">`);
|
|
1161
|
+
buffer.write(typeof entry === "string" ? `<link rel="stylesheet" href="${entry}"${styleAttr} onload="$dfc('${key}')" onerror="$dfc('${key}')">` : `<link${entry.attrHtml}${styleAttr} onload="$dfc('${key}')" onerror="$dfc('${key}')">`);
|
|
1029
1162
|
}
|
|
1030
1163
|
buffer.write(`<template id="${key}">${value}</template>`);
|
|
1031
1164
|
} else {
|
|
@@ -1040,7 +1173,7 @@ function renderToStream(code, options = {}) {
|
|
|
1040
1173
|
},
|
|
1041
1174
|
asset(type, value) {
|
|
1042
1175
|
if (type === "module") {
|
|
1043
|
-
buffer.write(`<link rel="modulepreload" href="${value}">`);
|
|
1176
|
+
buffer.write(`<link rel="modulepreload" href="${value}"${nonceAttr(nonce, "script")}>`);
|
|
1044
1177
|
} else if (type === "inline-style") {
|
|
1045
1178
|
buffer.write(renderInlineStyle(value, nonce));
|
|
1046
1179
|
} else if (type === "head-tag") {
|
|
@@ -1075,6 +1208,7 @@ function renderToStream(code, options = {}) {
|
|
|
1075
1208
|
context.live.end = null;
|
|
1076
1209
|
end();
|
|
1077
1210
|
}
|
|
1211
|
+
flushStubBatch();
|
|
1078
1212
|
serializer.flush();
|
|
1079
1213
|
}));
|
|
1080
1214
|
}
|
|
@@ -1082,7 +1216,7 @@ function renderToStream(code, options = {}) {
|
|
|
1082
1216
|
const registry = new Map();
|
|
1083
1217
|
const writeTasks = () => {
|
|
1084
1218
|
if (tasks.length && !completed && firstFlushed) {
|
|
1085
|
-
buffer.write(`<script${nonce
|
|
1219
|
+
buffer.write(`<script${nonceAttr(nonce, "script")}>${tasks}</script>`);
|
|
1086
1220
|
tasks = "";
|
|
1087
1221
|
}
|
|
1088
1222
|
timer = null;
|
|
@@ -1136,7 +1270,7 @@ function renderToStream(code, options = {}) {
|
|
|
1136
1270
|
};
|
|
1137
1271
|
sharedConfig.context = context = {
|
|
1138
1272
|
async: true,
|
|
1139
|
-
nonce,
|
|
1273
|
+
nonce: options.nonce,
|
|
1140
1274
|
live: {},
|
|
1141
1275
|
registerHeadTags(tags) {
|
|
1142
1276
|
registerHeadTags(headRegistry, context, tracking,
|
|
@@ -1194,10 +1328,18 @@ function renderToStream(code, options = {}) {
|
|
|
1194
1328
|
},
|
|
1195
1329
|
serialize(id, p, deferStream) {
|
|
1196
1330
|
if (sharedConfig.context.noHydrate) return;
|
|
1197
|
-
if (!firstFlushed &&
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1331
|
+
if (!firstFlushed && p && typeof p === "object" && "then" in p) {
|
|
1332
|
+
if (deferStream) {
|
|
1333
|
+
blockingPromises.add(p);
|
|
1334
|
+
p.then(d => serializer.write(id, d)).catch(e => serializer.write(id, e));
|
|
1335
|
+
return;
|
|
1336
|
+
}
|
|
1337
|
+
if (canBatchStubs && !shellCompleted) {
|
|
1338
|
+
(stubBatch ||= new Map()).set(id, p);
|
|
1339
|
+
return;
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
serializer.write(id, p);
|
|
1201
1343
|
},
|
|
1202
1344
|
escape: escape,
|
|
1203
1345
|
resolve: resolveSSRNode,
|
|
@@ -1231,7 +1373,7 @@ function renderToStream(code, options = {}) {
|
|
|
1231
1373
|
queue(flushEnd);
|
|
1232
1374
|
}))
|
|
1233
1375
|
});
|
|
1234
|
-
serializer.write(key + "_fr", p);
|
|
1376
|
+
if (canBatchStubs && !shellCompleted) (stubBatch ||= new Map()).set(key + "_fr", p);else serializer.write(key + "_fr", p);
|
|
1235
1377
|
}
|
|
1236
1378
|
return (value, error) => {
|
|
1237
1379
|
if (registry.has(key)) {
|
|
@@ -1262,9 +1404,9 @@ function renderToStream(code, options = {}) {
|
|
|
1262
1404
|
} else {
|
|
1263
1405
|
serializeFragmentAssets(key, tracking.boundaryModules, context);
|
|
1264
1406
|
const styles = collectStreamStyles(key, tracking, headStyles);
|
|
1265
|
-
const headOps = error ? null : flushHeadFragment(headRegistry, key);
|
|
1407
|
+
const headOps = error ? null : flushHeadFragment(headRegistry, key, nonce);
|
|
1266
1408
|
if (headOps) emitHeadOps(key, headOps);
|
|
1267
|
-
sink.fragment(key, value !== undefined ? value : " ", {
|
|
1409
|
+
sink.fragment(key, resolveSSRSelectValues(value !== undefined ? value : " "), {
|
|
1268
1410
|
styles,
|
|
1269
1411
|
revealGroup,
|
|
1270
1412
|
error
|
|
@@ -1348,15 +1490,18 @@ function renderToStream(code, options = {}) {
|
|
|
1348
1490
|
function doShell() {
|
|
1349
1491
|
if (shellCompleted) return;
|
|
1350
1492
|
sharedConfig.context = context;
|
|
1493
|
+
const blockersBefore = blockingPromises.size;
|
|
1351
1494
|
if (!resolveRootHoles()) return;
|
|
1495
|
+
if (blockingPromises.size !== blockersBefore) return;
|
|
1352
1496
|
if (!headShellReady(headRegistry, p => blockingPromises.add(p))) return;
|
|
1353
1497
|
headStyles = new Set();
|
|
1354
1498
|
for (const url of tracking.emittedAssets) {
|
|
1355
1499
|
if (isCssUrl(url)) headStyles.add(url);
|
|
1356
1500
|
}
|
|
1357
1501
|
serializeRootAssets();
|
|
1358
|
-
|
|
1359
|
-
|
|
1502
|
+
flushStubBatch();
|
|
1503
|
+
const head = renderShellHead(headRegistry, nonce, k => registry.has(k), noScripts);
|
|
1504
|
+
sink.shell(resolveSSRSelectValues(html), {
|
|
1360
1505
|
preloads: tracking.emittedAssets,
|
|
1361
1506
|
inlineStyles: tracking.inlineStyles,
|
|
1362
1507
|
tasks,
|
|
@@ -1376,6 +1521,7 @@ function renderToStream(code, options = {}) {
|
|
|
1376
1521
|
let drainTurn = 0;
|
|
1377
1522
|
const scheduleFlush = fn => {
|
|
1378
1523
|
const attempt = () => {
|
|
1524
|
+
flushStubBatch();
|
|
1379
1525
|
if (registry.size !== lastRegistrySize || drainTurn++ < MIN_DRAIN_TURNS) {
|
|
1380
1526
|
if (registry.size !== lastRegistrySize) drainTurn = 0;
|
|
1381
1527
|
lastRegistrySize = registry.size;
|
|
@@ -1423,22 +1569,18 @@ function renderToStream(code, options = {}) {
|
|
|
1423
1569
|
}
|
|
1424
1570
|
};
|
|
1425
1571
|
writer.closed && writer.closed.catch(failed);
|
|
1426
|
-
writable = {
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
}
|
|
1435
|
-
};
|
|
1436
|
-
buffer = {
|
|
1437
|
-
write(payload) {
|
|
1438
|
-
pendingWrites = pendingWrites.then(() => writer.write(encoder.encode(payload))).catch(failed);
|
|
1439
|
-
}
|
|
1440
|
-
};
|
|
1572
|
+
buffer = writable = coalesceWrites(payload => {
|
|
1573
|
+
pendingWrites = pendingWrites.then(() => writer.write(encoder.encode(payload))).catch(failed);
|
|
1574
|
+
}, () => {
|
|
1575
|
+
pendingWrites.then(() => {
|
|
1576
|
+
ended = true;
|
|
1577
|
+
writer.releaseLock();
|
|
1578
|
+
w.close().catch(() => {});
|
|
1579
|
+
resolve();
|
|
1580
|
+
});
|
|
1581
|
+
});
|
|
1441
1582
|
buffer.write(tmp);
|
|
1583
|
+
buffer.flush();
|
|
1442
1584
|
firstFlushed = true;
|
|
1443
1585
|
if (completed) {
|
|
1444
1586
|
dispose();
|
|
@@ -1468,7 +1610,8 @@ function renderToStream(code, options = {}) {
|
|
|
1468
1610
|
allSettled(blockingPromises).then(() => {
|
|
1469
1611
|
scheduleFlush(() => {
|
|
1470
1612
|
try {
|
|
1471
|
-
|
|
1613
|
+
const blockersBefore = blockingPromises.size;
|
|
1614
|
+
if (!resolveRootHoles() || blockingPromises.size !== blockersBefore || !headShellReady(headRegistry, p => blockingPromises.add(p))) return flush();
|
|
1472
1615
|
} catch (err) {
|
|
1473
1616
|
failRender(err);
|
|
1474
1617
|
return resolve(tmp);
|
|
@@ -1497,8 +1640,10 @@ function renderToStream(code, options = {}) {
|
|
|
1497
1640
|
return;
|
|
1498
1641
|
}
|
|
1499
1642
|
if (!shellCompleted) return flush();
|
|
1500
|
-
|
|
1643
|
+
const sink = guardSink(w);
|
|
1644
|
+
buffer = writable = coalesceWrites(sink.write, sink.end);
|
|
1501
1645
|
buffer.write(tmp);
|
|
1646
|
+
buffer.flush();
|
|
1502
1647
|
firstFlushed = true;
|
|
1503
1648
|
if (completed) {
|
|
1504
1649
|
dispose();
|
|
@@ -2152,6 +2297,12 @@ function ssr(t) {
|
|
|
2152
2297
|
};
|
|
2153
2298
|
return result;
|
|
2154
2299
|
}
|
|
2300
|
+
const CLAIM_PROP = /*#__PURE__*/Symbol.for("dom-expressions.claim-prop");
|
|
2301
|
+
const CLAIMS_STREAM = 1;
|
|
2302
|
+
const CLAIMS_DOCUMENT = 2;
|
|
2303
|
+
function resolveSSRSelectValues(html) {
|
|
2304
|
+
return html;
|
|
2305
|
+
}
|
|
2155
2306
|
function escape(s, attr) {
|
|
2156
2307
|
const t = typeof s;
|
|
2157
2308
|
if (t !== "string") {
|
|
@@ -2173,22 +2324,20 @@ function escape(s, attr) {
|
|
|
2173
2324
|
return escapeSlow(s, attr, i);
|
|
2174
2325
|
}
|
|
2175
2326
|
const ESCAPE_CONTENT = /[&<]/;
|
|
2176
|
-
const ESCAPE_ATTR = /[&"]/;
|
|
2327
|
+
const ESCAPE_ATTR = /[&"<]/;
|
|
2177
2328
|
function escapeSlow(s, attr, start) {
|
|
2178
|
-
|
|
2179
|
-
const delimCode = attr ? 34 : 60;
|
|
2180
|
-
const escDelim = attr ? """ : "<";
|
|
2329
|
+
if (attr) return escapeAttrSlow(s, start);
|
|
2181
2330
|
const c0 = s.charCodeAt(start);
|
|
2182
|
-
let iDelim = c0 ===
|
|
2331
|
+
let iDelim = c0 === 60 ? start : s.indexOf("<", start);
|
|
2183
2332
|
let iAmp = c0 === 38 ? start : s.indexOf("&", start);
|
|
2184
2333
|
let left = 0,
|
|
2185
2334
|
out = "";
|
|
2186
2335
|
while (iDelim >= 0 && iAmp >= 0) {
|
|
2187
2336
|
if (iDelim < iAmp) {
|
|
2188
2337
|
if (left < iDelim) out += s.substring(left, iDelim);
|
|
2189
|
-
out +=
|
|
2338
|
+
out += "<";
|
|
2190
2339
|
left = iDelim + 1;
|
|
2191
|
-
iDelim = s.indexOf(
|
|
2340
|
+
iDelim = s.indexOf("<", left);
|
|
2192
2341
|
} else {
|
|
2193
2342
|
if (left < iAmp) out += s.substring(left, iAmp);
|
|
2194
2343
|
out += "&";
|
|
@@ -2199,9 +2348,9 @@ function escapeSlow(s, attr, start) {
|
|
|
2199
2348
|
if (iDelim >= 0) {
|
|
2200
2349
|
do {
|
|
2201
2350
|
if (left < iDelim) out += s.substring(left, iDelim);
|
|
2202
|
-
out +=
|
|
2351
|
+
out += "<";
|
|
2203
2352
|
left = iDelim + 1;
|
|
2204
|
-
iDelim = s.indexOf(
|
|
2353
|
+
iDelim = s.indexOf("<", left);
|
|
2205
2354
|
} while (iDelim >= 0);
|
|
2206
2355
|
} else while (iAmp >= 0) {
|
|
2207
2356
|
if (left < iAmp) out += s.substring(left, iAmp);
|
|
@@ -2211,6 +2360,36 @@ function escapeSlow(s, attr, start) {
|
|
|
2211
2360
|
}
|
|
2212
2361
|
return left < s.length ? out + s.substring(left) : out;
|
|
2213
2362
|
}
|
|
2363
|
+
function escapeAttrSlow(s, start) {
|
|
2364
|
+
const c0 = s.charCodeAt(start);
|
|
2365
|
+
let iQuot = c0 === 34 ? start : s.indexOf('"', start);
|
|
2366
|
+
let iAmp = c0 === 38 ? start : s.indexOf("&", start);
|
|
2367
|
+
let iLt = c0 === 60 ? start : s.indexOf("<", start);
|
|
2368
|
+
let left = 0,
|
|
2369
|
+
out = "";
|
|
2370
|
+
for (;;) {
|
|
2371
|
+
let i = -1,
|
|
2372
|
+
ent;
|
|
2373
|
+
if (iQuot >= 0) {
|
|
2374
|
+
i = iQuot;
|
|
2375
|
+
ent = """;
|
|
2376
|
+
}
|
|
2377
|
+
if (iAmp >= 0 && (i < 0 || iAmp < i)) {
|
|
2378
|
+
i = iAmp;
|
|
2379
|
+
ent = "&";
|
|
2380
|
+
}
|
|
2381
|
+
if (iLt >= 0 && (i < 0 || iLt < i)) {
|
|
2382
|
+
i = iLt;
|
|
2383
|
+
ent = "<";
|
|
2384
|
+
}
|
|
2385
|
+
if (i < 0) break;
|
|
2386
|
+
if (left < i) out += s.substring(left, i);
|
|
2387
|
+
out += ent;
|
|
2388
|
+
left = i + 1;
|
|
2389
|
+
if (i === iQuot) iQuot = s.indexOf('"', left);else if (i === iAmp) iAmp = s.indexOf("&", left);else iLt = s.indexOf("<", left);
|
|
2390
|
+
}
|
|
2391
|
+
return left < s.length ? out + s.substring(left) : out;
|
|
2392
|
+
}
|
|
2214
2393
|
function tryJoinPlainSSRArray(nodes) {
|
|
2215
2394
|
if (nodes.length === 0) return undefined;
|
|
2216
2395
|
let out = "";
|
|
@@ -2226,6 +2405,7 @@ function tryJoinPlainSSRArray(nodes) {
|
|
|
2226
2405
|
function queue(fn) {
|
|
2227
2406
|
return Promise.resolve().then(fn);
|
|
2228
2407
|
}
|
|
2408
|
+
const deferFlush = typeof setImmediate === "function" ? setImmediate : fn => setTimeout(fn, 0);
|
|
2229
2409
|
function allSettled(promises) {
|
|
2230
2410
|
let size = promises.size;
|
|
2231
2411
|
return Promise.allSettled(promises).then(() => {
|
|
@@ -2234,10 +2414,11 @@ function allSettled(promises) {
|
|
|
2234
2414
|
});
|
|
2235
2415
|
}
|
|
2236
2416
|
function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, headTags, onHead) {
|
|
2237
|
-
const scriptTag = scripts ? `<script${nonce
|
|
2238
|
-
const
|
|
2417
|
+
const scriptTag = scripts ? `<script${nonceAttr(nonce, "script")}>${scripts}</script>` : "";
|
|
2418
|
+
const title = headTags ? headTags.title : null;
|
|
2419
|
+
let headTagsHtml = headTags ? headTags.html : "";
|
|
2239
2420
|
const headPrelude = headTags ? headTags.prelude : "";
|
|
2240
|
-
if (!onHead && !headTagsHtml && !headPrelude && !(emittedAssets && emittedAssets.size) && !(inlineStyles && inlineStyles.size)) {
|
|
2421
|
+
if (!onHead && title == null && !headTagsHtml && !headPrelude && !(emittedAssets && emittedAssets.size) && !(inlineStyles && inlineStyles.size)) {
|
|
2241
2422
|
if (!scriptTag) return html;
|
|
2242
2423
|
const xs = html.indexOf("<!--xs-->");
|
|
2243
2424
|
return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
|
|
@@ -2249,15 +2430,33 @@ function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, hea
|
|
|
2249
2430
|
html = html.slice(0, at) + headPrelude + html.slice(at);
|
|
2250
2431
|
}
|
|
2251
2432
|
}
|
|
2252
|
-
|
|
2433
|
+
let headIdx = html.indexOf("</head>");
|
|
2253
2434
|
if (headIdx === -1) {
|
|
2254
2435
|
if (onHead) {
|
|
2255
|
-
|
|
2436
|
+
let titleHtml = "";
|
|
2437
|
+
if (title != null) {
|
|
2438
|
+
titleHtml = headTags.noScripts ? `<title data-dh="title">${escape(title)}</title>` : `<script${nonceAttr(nonce, "script")}>(function(x,t){(t=document.querySelector("title"))?(t.hasAttribute("data-dh")||t.setAttribute("data-dhf",t.textContent),t.textContent=x):(document.title=x,t=document.querySelector("title"));t&&t.setAttribute("data-dh","title")})(${JSON.stringify(title).replace(/</g, "\\u003C")})</script>`;
|
|
2439
|
+
}
|
|
2440
|
+
onHead(headPrelude + headTagsHtml + titleHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce));
|
|
2256
2441
|
}
|
|
2257
2442
|
if (!scriptTag) return html;
|
|
2258
2443
|
const xs = html.indexOf("<!--xs-->");
|
|
2259
2444
|
return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
|
|
2260
2445
|
}
|
|
2446
|
+
if (title != null) {
|
|
2447
|
+
const winner = escape(title);
|
|
2448
|
+
const open = html.match(/<head(?:\s[^>]*)?>/);
|
|
2449
|
+
const from = open ? open.index + open[0].length : 0;
|
|
2450
|
+
const m = /<title(\s[^>]*)?>([\s\S]*?)<\/title>/.exec(html.slice(from, headIdx));
|
|
2451
|
+
if (m) {
|
|
2452
|
+
const at = from + m.index;
|
|
2453
|
+
const stash = m[2].replace(/"/g, """);
|
|
2454
|
+
html = html.slice(0, at) + `<title${m[1] || ""} data-dh="title" data-dhf="${stash}">${winner}</title>` + html.slice(at + m[0].length);
|
|
2455
|
+
headIdx = html.indexOf("</head>");
|
|
2456
|
+
} else {
|
|
2457
|
+
headTagsHtml = `<title data-dh="title">${winner}</title>` + headTagsHtml;
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2261
2460
|
const head = headTagsHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce);
|
|
2262
2461
|
if (!scriptTag) return html.slice(0, headIdx) + head + html.slice(headIdx);
|
|
2263
2462
|
const xsIdx = html.indexOf("<!--xs-->");
|
|
@@ -2266,9 +2465,11 @@ function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, hea
|
|
|
2266
2465
|
}
|
|
2267
2466
|
function renderHeadAssets(emittedAssets, inlineStyles, nonce) {
|
|
2268
2467
|
let head = "";
|
|
2468
|
+
const styleAttr = nonceAttr(nonce, "style");
|
|
2469
|
+
const scriptAttr = nonceAttr(nonce, "script");
|
|
2269
2470
|
if (emittedAssets && emittedAssets.size) {
|
|
2270
2471
|
for (const url of emittedAssets) {
|
|
2271
|
-
head += isCssUrl(url) ? `<link rel="stylesheet" href="${url}">` : `<link rel="modulepreload" href="${url}">`;
|
|
2472
|
+
head += isCssUrl(url) ? `<link rel="stylesheet" href="${url}"${styleAttr}>` : `<link rel="modulepreload" href="${url}"${scriptAttr}>`;
|
|
2272
2473
|
}
|
|
2273
2474
|
}
|
|
2274
2475
|
if (inlineStyles && inlineStyles.size) {
|
|
@@ -2283,7 +2484,9 @@ function renderHeadAssets(emittedAssets, inlineStyles, nonce) {
|
|
|
2283
2484
|
function serializeFragmentAssets(key, boundaryModules, context, name = key) {
|
|
2284
2485
|
const map = boundaryModules.get(key);
|
|
2285
2486
|
if (!map || !Object.keys(map).length) return;
|
|
2286
|
-
context.serialize(name + "_assets",
|
|
2487
|
+
context.serialize(name + "_assets", {
|
|
2488
|
+
...map
|
|
2489
|
+
});
|
|
2287
2490
|
}
|
|
2288
2491
|
function propagateBoundaryStyles(childKey, parentKey, tracking) {
|
|
2289
2492
|
const childStyles = tracking.getBoundaryStyles(childKey);
|
|
@@ -2328,12 +2531,15 @@ function escapeStyleContent(content) {
|
|
|
2328
2531
|
}
|
|
2329
2532
|
function renderInlineStyle(entry, nonce) {
|
|
2330
2533
|
let attrs = "";
|
|
2534
|
+
let hasNonce = false;
|
|
2331
2535
|
if (entry.attrs) {
|
|
2332
2536
|
for (const name in entry.attrs) {
|
|
2537
|
+
if (name.length === 5 && asciiLowerCase(name) === "nonce") hasNonce = true;
|
|
2333
2538
|
attrs += ` ${name}="${escape(String(entry.attrs[name]), true)}"`;
|
|
2334
2539
|
}
|
|
2335
2540
|
}
|
|
2336
|
-
|
|
2541
|
+
const nonceHtml = hasNonce ? "" : nonceAttr(nonce, "style");
|
|
2542
|
+
return `<style${nonceHtml} data-asset="${escape(entry.id, true)}"${attrs}>${escapeStyleContent(entry.content)}</style>`;
|
|
2337
2543
|
}
|
|
2338
2544
|
function waitForFragments(registry, key) {
|
|
2339
2545
|
for (const k of [...registry.keys()].reverse()) {
|
|
@@ -2786,6 +2992,7 @@ function renderServerComponent(component, options = {}) {
|
|
|
2786
2992
|
ctx.commit = sink.commit;
|
|
2787
2993
|
ctx.commitEpoch = () => sink.epoch;
|
|
2788
2994
|
ctx.liveHoles = createLiveHoles(sink);
|
|
2995
|
+
ctx.claims = CLAIMS_STREAM;
|
|
2789
2996
|
}
|
|
2790
2997
|
return serverComponentScope(() => component(props));
|
|
2791
2998
|
};
|
|
@@ -3079,6 +3286,7 @@ function createDocumentSlotProps(clientProps, frameId) {
|
|
|
3079
3286
|
return out;
|
|
3080
3287
|
};
|
|
3081
3288
|
fn.$lhSkip = true;
|
|
3289
|
+
fn[CLAIM_PROP] = prop;
|
|
3082
3290
|
getters.set(prop, fn);
|
|
3083
3291
|
}
|
|
3084
3292
|
return fn;
|
|
@@ -3210,6 +3418,7 @@ function frameTransformDirectResult(value, {
|
|
|
3210
3418
|
},
|
|
3211
3419
|
serverOwned(() => {
|
|
3212
3420
|
armDocumentLiveHoles(sharedConfig.context);
|
|
3421
|
+
sharedConfig.context.claims = CLAIMS_DOCUMENT;
|
|
3213
3422
|
const slotProps = createDocumentSlotProps(props, id);
|
|
3214
3423
|
return serverComponentScope(() => component(slotProps));
|
|
3215
3424
|
}), {
|
|
@@ -3453,6 +3662,7 @@ function createSlotProps(sink, frame) {
|
|
|
3453
3662
|
return slotRange(occurrence);
|
|
3454
3663
|
};
|
|
3455
3664
|
fn.$lhSkip = true;
|
|
3665
|
+
fn[CLAIM_PROP] = prop;
|
|
3456
3666
|
getters.set(prop, fn);
|
|
3457
3667
|
}
|
|
3458
3668
|
return fn;
|