@solidjs/web 2.0.0-beta.29 → 2.0.0-beta.30
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/dev.cjs +329 -2
- package/dist/dev.js +329 -3
- package/dist/server.cjs +451 -20
- package/dist/server.js +451 -21
- package/dist/web.cjs +325 -2
- package/dist/web.js +325 -3
- package/frames/dist/client.cjs +177 -34
- package/frames/dist/client.dev.cjs +177 -34
- package/frames/dist/client.dev.js +178 -35
- package/frames/dist/client.js +178 -35
- package/frames/dist/server.cjs +405 -17
- package/frames/dist/server.js +405 -17
- package/package.json +3 -3
- package/types/client.d.ts +20 -0
- package/types/frames/frame-client.d.ts +25 -0
- package/types/frames/frame-transport.d.ts +26 -0
- package/types/index.d.ts +1 -22
- package/types/server.d.ts +50 -0
- package/types-cjs/client.d.cts +20 -0
- package/types-cjs/frames/frame-client.d.cts +25 -0
- package/types-cjs/frames/frame-transport.d.cts +26 -0
- package/types-cjs/index.d.cts +1 -22
- package/types-cjs/server.d.cts +50 -0
package/dist/web.js
CHANGED
|
@@ -169,6 +169,88 @@ function reconcileArrays(parentNode, a, b, marker) {
|
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
+
const HEAD_ELIGIBLE_TAGS = new Set(["title", "meta", "link", "style", "script", "base"]);
|
|
173
|
+
const HEAD_ATTR_NAME = /^[a-zA-Z_][a-zA-Z0-9_:.-]*$/;
|
|
174
|
+
const RESOURCE_LINK_RELS = new Set(["preload", "modulepreload", "prefetch", "preconnect", "dns-prefetch", "icon", "stylesheet"]);
|
|
175
|
+
const RESOURCE_QUALIFIERS = ["as", "crossorigin", "type", "media", "imagesrcset", "imagesizes"];
|
|
176
|
+
function evalHeadValue(v) {
|
|
177
|
+
return typeof v === "function" ? v() : v;
|
|
178
|
+
}
|
|
179
|
+
function evalHeadProps(props, presets) {
|
|
180
|
+
const out = {};
|
|
181
|
+
for (const name in props) out[name] = presets && name in presets ? presets[name] : evalHeadValue(props[name]);
|
|
182
|
+
return out;
|
|
183
|
+
}
|
|
184
|
+
function classifyHeadTag(desc) {
|
|
185
|
+
const tag = desc.tag;
|
|
186
|
+
if (tag === "link") {
|
|
187
|
+
const rel = evalHeadValue(desc.props && desc.props.rel);
|
|
188
|
+
return {
|
|
189
|
+
resource: RESOURCE_LINK_RELS.has(rel),
|
|
190
|
+
rel
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
if (tag === "style") return {
|
|
194
|
+
resource: !!(desc.props && "href" in desc.props)
|
|
195
|
+
};
|
|
196
|
+
if (tag === "script") return {
|
|
197
|
+
resource: !!(desc.props && "src" in desc.props)
|
|
198
|
+
};
|
|
199
|
+
return {
|
|
200
|
+
resource: false
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
function resourceIdentity(tag, props) {
|
|
204
|
+
let id = "res:" + tag + ":" + (props.rel || "") + ":" + (props.href || props.src || "");
|
|
205
|
+
for (let i = 0; i < RESOURCE_QUALIFIERS.length; i++) {
|
|
206
|
+
const q = RESOURCE_QUALIFIERS[i];
|
|
207
|
+
if (props[q] != null) id += ":" + q + "=" + props[q];
|
|
208
|
+
}
|
|
209
|
+
return id;
|
|
210
|
+
}
|
|
211
|
+
function replaceableIdentity(tag, props, key, unique) {
|
|
212
|
+
if (tag === "title") return "title";
|
|
213
|
+
if (tag === "base") return "base";
|
|
214
|
+
if (tag === "meta" && props.charset != null) return "charset";
|
|
215
|
+
if (key != null) return tag + ":key:" + key;
|
|
216
|
+
if (tag === "meta") {
|
|
217
|
+
if (props.name != null) return "meta:name:" + props.name;
|
|
218
|
+
if (props.property != null) return "meta:property:" + props.property;
|
|
219
|
+
if (props["http-equiv"] != null) return "meta:http-equiv:" + props["http-equiv"];
|
|
220
|
+
return unique;
|
|
221
|
+
}
|
|
222
|
+
if (tag === "link") return "link:" + (props.rel || "") + ":" + (props.href || "");
|
|
223
|
+
return unique;
|
|
224
|
+
}
|
|
225
|
+
function resolveHead(groups) {
|
|
226
|
+
const winners = new Map();
|
|
227
|
+
const sorted = groups.slice().sort((a, b) => a.seq - b.seq);
|
|
228
|
+
for (let i = 0; i < sorted.length; i++) {
|
|
229
|
+
const group = sorted[i];
|
|
230
|
+
const byIdentity = new Map();
|
|
231
|
+
for (let j = 0; j < group.tags.length; j++) {
|
|
232
|
+
const t = group.tags[j];
|
|
233
|
+
let list = byIdentity.get(t.identity);
|
|
234
|
+
if (!list) byIdentity.set(t.identity, list = []);
|
|
235
|
+
list.push(t);
|
|
236
|
+
}
|
|
237
|
+
for (const [identity, tags] of byIdentity) {
|
|
238
|
+
if (identity === "title") {
|
|
239
|
+
winners.set(identity, {
|
|
240
|
+
seq: group.seq,
|
|
241
|
+
tags: [tags[tags.length - 1]]
|
|
242
|
+
});
|
|
243
|
+
} else {
|
|
244
|
+
winners.set(identity, {
|
|
245
|
+
seq: group.seq,
|
|
246
|
+
tags
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return winners;
|
|
252
|
+
}
|
|
253
|
+
|
|
172
254
|
const $$EVENT_OWNER = "_$DX_EVENT_OWNER";
|
|
173
255
|
const INNER_OWNED = {};
|
|
174
256
|
const delegatedEvents = new Set();
|
|
@@ -649,6 +731,232 @@ function acquireAsset(descriptor) {
|
|
|
649
731
|
}, ASSET_REMOVAL_GRACE);
|
|
650
732
|
};
|
|
651
733
|
}
|
|
734
|
+
let headRegistrations = null;
|
|
735
|
+
let headSeq = 0;
|
|
736
|
+
let headUid = 0;
|
|
737
|
+
let headOwned = null;
|
|
738
|
+
let headApplied = null;
|
|
739
|
+
let headFallbackTitle = null;
|
|
740
|
+
let headScheduled = false;
|
|
741
|
+
const headMountedResources = new Set();
|
|
742
|
+
function initHeadRegistry() {
|
|
743
|
+
if (headRegistrations) return;
|
|
744
|
+
headRegistrations = [];
|
|
745
|
+
headOwned = new Map();
|
|
746
|
+
headApplied = new Map();
|
|
747
|
+
const t = document.querySelector("title");
|
|
748
|
+
headFallbackTitle = t && !t.hasAttribute("data-dh") ? t.textContent : null;
|
|
749
|
+
if (globalThis._$HY) globalThis._$HY.h = applyServerHeadOps;
|
|
750
|
+
}
|
|
751
|
+
function applyServerHeadOps(ops) {
|
|
752
|
+
for (let i = 0; i < ops.length; i++) {
|
|
753
|
+
const op = ops[i];
|
|
754
|
+
const identity = op[0] === "t" ? "title" : op[1];
|
|
755
|
+
if (headOwned.has(identity)) continue;
|
|
756
|
+
if (op[0] === "t") setHeadTitle(op[1]);else if (op[0] === "r") {
|
|
757
|
+
const els = headMarkedElements(identity);
|
|
758
|
+
for (let j = 0; j < els.length; j++) els[j].remove();
|
|
759
|
+
} else {
|
|
760
|
+
const el = document.createElement(op[2]);
|
|
761
|
+
for (const name in op[3]) el.setAttribute(name, op[3][name]);
|
|
762
|
+
if (op[4] != null) el.textContent = op[4];
|
|
763
|
+
el.setAttribute("data-dh", identity);
|
|
764
|
+
document.head.appendChild(el);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
function headMarkedElements(identity) {
|
|
769
|
+
const nodes = document.head.querySelectorAll("[data-dh]");
|
|
770
|
+
const out = [];
|
|
771
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
772
|
+
if (nodes[i].getAttribute("data-dh") === identity) out.push(nodes[i]);
|
|
773
|
+
}
|
|
774
|
+
return out;
|
|
775
|
+
}
|
|
776
|
+
function setHeadTitle(text) {
|
|
777
|
+
let el = document.querySelector("title");
|
|
778
|
+
if (!el) {
|
|
779
|
+
el = document.createElement("title");
|
|
780
|
+
document.head.appendChild(el);
|
|
781
|
+
}
|
|
782
|
+
el.textContent = text;
|
|
783
|
+
el.setAttribute("data-dh", "title");
|
|
784
|
+
return el;
|
|
785
|
+
}
|
|
786
|
+
function scheduleHeadApply() {
|
|
787
|
+
if (headScheduled) return;
|
|
788
|
+
headScheduled = true;
|
|
789
|
+
queueMicrotask(flushHeadRegistry);
|
|
790
|
+
}
|
|
791
|
+
function flushHeadRegistry() {
|
|
792
|
+
if (sharedConfig.hydrating) {
|
|
793
|
+
setTimeout(flushHeadRegistry, 0);
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
headScheduled = false;
|
|
797
|
+
const winners = resolveHead(headRegistrations);
|
|
798
|
+
for (const [identity, els] of headOwned) {
|
|
799
|
+
if (winners.has(identity)) continue;
|
|
800
|
+
headOwned.delete(identity);
|
|
801
|
+
headApplied.delete(identity);
|
|
802
|
+
if (identity === "title") {
|
|
803
|
+
if (headFallbackTitle != null) setHeadTitle(headFallbackTitle).removeAttribute("data-dh");
|
|
804
|
+
} else {
|
|
805
|
+
for (let i = 0; i < els.length; i++) els[i].remove();
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
for (const [identity, winner] of winners) {
|
|
809
|
+
let sig = "";
|
|
810
|
+
for (let i = 0; i < winner.tags.length; i++) sig += winner.tags[i].tag + JSON.stringify(winner.tags[i].props) + "|";
|
|
811
|
+
if (headApplied.get(identity) === sig) continue;
|
|
812
|
+
headApplied.set(identity, sig);
|
|
813
|
+
if (identity === "base" || identity === "charset") {
|
|
814
|
+
continue;
|
|
815
|
+
}
|
|
816
|
+
if (identity === "title") {
|
|
817
|
+
const children = winner.tags[0].props.children;
|
|
818
|
+
setHeadTitle(children == null ? "" : String(children));
|
|
819
|
+
headOwned.set(identity, []);
|
|
820
|
+
continue;
|
|
821
|
+
}
|
|
822
|
+
const existing = headMarkedElements(identity);
|
|
823
|
+
const els = [];
|
|
824
|
+
for (let i = 0; i < winner.tags.length; i++) {
|
|
825
|
+
els.push(renderHeadElement(winner.tags[i], identity, existing));
|
|
826
|
+
}
|
|
827
|
+
for (let i = 0; i < existing.length; i++) {
|
|
828
|
+
if (els.indexOf(existing[i]) === -1) existing[i].remove();
|
|
829
|
+
}
|
|
830
|
+
headOwned.set(identity, els);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
function renderHeadElement(t, identity, existing) {
|
|
834
|
+
for (let i = 0; i < existing.length; i++) {
|
|
835
|
+
if (headElementMatches(existing[i], t)) return existing.splice(i, 1)[0];
|
|
836
|
+
}
|
|
837
|
+
const el = document.createElement(t.tag);
|
|
838
|
+
for (const name in t.props) {
|
|
839
|
+
if (name === "children" || name === "ref" || name.slice(0, 2) === "on") continue;
|
|
840
|
+
if (!HEAD_ATTR_NAME.test(name)) {
|
|
841
|
+
continue;
|
|
842
|
+
}
|
|
843
|
+
const v = t.props[name];
|
|
844
|
+
if (v == null || v === false) continue;
|
|
845
|
+
el.setAttribute(name, v === true ? "" : String(v));
|
|
846
|
+
}
|
|
847
|
+
if (t.props.children != null) el.textContent = String(t.props.children);
|
|
848
|
+
el.setAttribute("data-dh", identity);
|
|
849
|
+
document.head.appendChild(el);
|
|
850
|
+
return el;
|
|
851
|
+
}
|
|
852
|
+
function headElementMatches(el, t) {
|
|
853
|
+
if (el.tagName.toLowerCase() !== t.tag) return false;
|
|
854
|
+
for (const name in t.props) {
|
|
855
|
+
if (name === "children" || name === "ref" || name.slice(0, 2) === "on") continue;
|
|
856
|
+
if (!HEAD_ATTR_NAME.test(name)) continue;
|
|
857
|
+
const v = t.props[name];
|
|
858
|
+
if (v == null || v === false) {
|
|
859
|
+
if (el.hasAttribute(name)) return false;
|
|
860
|
+
} else if (el.getAttribute(name) !== (v === true ? "" : String(v))) return false;
|
|
861
|
+
}
|
|
862
|
+
const children = t.props.children;
|
|
863
|
+
return (children == null ? "" : String(children)) === el.textContent;
|
|
864
|
+
}
|
|
865
|
+
function acquireHeadResource(tag, props) {
|
|
866
|
+
if (tag === "link" && (props.rel === "stylesheet" || props.rel === "modulepreload")) {
|
|
867
|
+
const descriptor = {
|
|
868
|
+
type: props.rel === "stylesheet" ? "style" : "module",
|
|
869
|
+
href: props.href
|
|
870
|
+
};
|
|
871
|
+
let attrs = null;
|
|
872
|
+
for (const name in props) {
|
|
873
|
+
if (name === "rel" || name === "href") continue;
|
|
874
|
+
if (!HEAD_ATTR_NAME.test(name)) continue;
|
|
875
|
+
const v = props[name];
|
|
876
|
+
if (v == null || v === false) continue;
|
|
877
|
+
(attrs || (attrs = {}))[name] = v === true ? "" : String(v);
|
|
878
|
+
}
|
|
879
|
+
if (attrs) descriptor.attrs = attrs;
|
|
880
|
+
return acquireAsset(descriptor);
|
|
881
|
+
}
|
|
882
|
+
const identity = resourceIdentity(tag, props);
|
|
883
|
+
if (headMountedResources.has(identity)) return noopFn;
|
|
884
|
+
headMountedResources.add(identity);
|
|
885
|
+
const url = props.href || props.src;
|
|
886
|
+
let el = null;
|
|
887
|
+
if (url != null) {
|
|
888
|
+
if (tag === "link") el = findAssetElement(`link[rel="${props.rel}"]`, "href", url);else if (tag === "script") el = findAssetElement("script[src]", "src", url);else el = findAssetElement("style[href]", "href", url);
|
|
889
|
+
}
|
|
890
|
+
if (!el) {
|
|
891
|
+
el = document.createElement(tag);
|
|
892
|
+
for (const name in props) {
|
|
893
|
+
if (name === "children" || name === "ref" || name.slice(0, 2) === "on") continue;
|
|
894
|
+
if (!HEAD_ATTR_NAME.test(name)) continue;
|
|
895
|
+
const v = props[name];
|
|
896
|
+
if (v == null || v === false) continue;
|
|
897
|
+
el.setAttribute(name, v === true ? "" : String(v));
|
|
898
|
+
}
|
|
899
|
+
if (props.children != null) el.textContent = String(props.children);
|
|
900
|
+
document.head.appendChild(el);
|
|
901
|
+
}
|
|
902
|
+
return noopFn;
|
|
903
|
+
}
|
|
904
|
+
function noopFn() {}
|
|
905
|
+
function useHead(tags) {
|
|
906
|
+
const list = Array.isArray(tags) ? tags : [tags];
|
|
907
|
+
initHeadRegistry();
|
|
908
|
+
const reg = {
|
|
909
|
+
seq: -1,
|
|
910
|
+
tags: null
|
|
911
|
+
};
|
|
912
|
+
const uid = ++headUid;
|
|
913
|
+
effect(() => {
|
|
914
|
+
const replaceable = [];
|
|
915
|
+
const resources = [];
|
|
916
|
+
for (let i = 0; i < list.length; i++) {
|
|
917
|
+
const desc = list[i];
|
|
918
|
+
if (!desc || !HEAD_ELIGIBLE_TAGS.has(desc.tag)) {
|
|
919
|
+
continue;
|
|
920
|
+
}
|
|
921
|
+
const cls = classifyHeadTag(desc);
|
|
922
|
+
const props = evalHeadProps(desc.props || {}, cls.rel !== undefined ? {
|
|
923
|
+
rel: cls.rel
|
|
924
|
+
} : undefined);
|
|
925
|
+
if (cls.resource) {
|
|
926
|
+
resources.push({
|
|
927
|
+
tag: desc.tag,
|
|
928
|
+
props
|
|
929
|
+
});
|
|
930
|
+
} else {
|
|
931
|
+
const key = evalHeadValue(desc.key);
|
|
932
|
+
replaceable.push({
|
|
933
|
+
tag: desc.tag,
|
|
934
|
+
props,
|
|
935
|
+
identity: replaceableIdentity(desc.tag, props, key, "u:c" + uid + ":" + i)
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
return {
|
|
940
|
+
replaceable,
|
|
941
|
+
resources
|
|
942
|
+
};
|
|
943
|
+
}, evaluated => {
|
|
944
|
+
const releases = [];
|
|
945
|
+
for (let i = 0; i < evaluated.resources.length; i++) {
|
|
946
|
+
releases.push(acquireHeadResource(evaluated.resources[i].tag, evaluated.resources[i].props));
|
|
947
|
+
}
|
|
948
|
+
reg.tags = evaluated.replaceable;
|
|
949
|
+
if (reg.seq < 0) reg.seq = ++headSeq;
|
|
950
|
+
if (headRegistrations.indexOf(reg) === -1) headRegistrations.push(reg);
|
|
951
|
+
scheduleHeadApply();
|
|
952
|
+
return () => {
|
|
953
|
+
const idx = headRegistrations.indexOf(reg);
|
|
954
|
+
if (idx > -1) headRegistrations.splice(idx, 1);
|
|
955
|
+
for (let i = 0; i < releases.length; i++) releases[i]();
|
|
956
|
+
scheduleHeadApply();
|
|
957
|
+
};
|
|
958
|
+
});
|
|
959
|
+
}
|
|
652
960
|
function loadModuleAssets(mapping) {
|
|
653
961
|
const hy = globalThis._$HY;
|
|
654
962
|
if (!hy) return;
|
|
@@ -1250,8 +1558,21 @@ function portalImpl(props) {
|
|
|
1250
1558
|
});
|
|
1251
1559
|
return treeMarker;
|
|
1252
1560
|
}
|
|
1561
|
+
const COMPONENT_HANDOFF = Symbol.for("dom-expressions.component-handoff");
|
|
1562
|
+
function resolveHandoff(next, prev) {
|
|
1563
|
+
const handoff = typeof next === "function" && next !== null && next[COMPONENT_HANDOFF];
|
|
1564
|
+
return handoff && handoff.take(prev) ? prev : next;
|
|
1565
|
+
}
|
|
1253
1566
|
function dynamic(source) {
|
|
1254
|
-
|
|
1567
|
+
let latest = 0;
|
|
1568
|
+
const cached = createMemo(prev => {
|
|
1569
|
+
const next = source();
|
|
1570
|
+
if (!next || typeof next.then !== "function") return resolveHandoff(next, prev);
|
|
1571
|
+
const token = ++latest;
|
|
1572
|
+
return {
|
|
1573
|
+
then: (onFulfilled, onRejected) => next.then(resolved => onFulfilled(token === latest ? resolveHandoff(resolved, prev) : resolved), onRejected)
|
|
1574
|
+
};
|
|
1575
|
+
}, {
|
|
1255
1576
|
lazy: true
|
|
1256
1577
|
});
|
|
1257
1578
|
return props => {
|
|
@@ -1280,7 +1601,8 @@ function createElement(tagName, is = undefined) {
|
|
|
1280
1601
|
function loadClientOnly(fn, setComp) {
|
|
1281
1602
|
fn().then(m => setComp(() => m.default));
|
|
1282
1603
|
}
|
|
1283
|
-
function clientOnly(fn, options = {}
|
|
1604
|
+
function clientOnly(fn, options = {},
|
|
1605
|
+
_moduleUrl) {
|
|
1284
1606
|
const [comp, setComp] = createSignal();
|
|
1285
1607
|
let started = !options.lazy;
|
|
1286
1608
|
started && loadClientOnly(fn, setComp);
|
|
@@ -1304,4 +1626,4 @@ function clientOnly(fn, options = {}) {
|
|
|
1304
1626
|
function httpStatus(_code, _text) {}
|
|
1305
1627
|
function httpHeader(_name, _value, _options) {}
|
|
1306
1628
|
|
|
1307
|
-
export { voidFn as Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, voidFn as HydrationScript, MathMLElements, Namespaces, Portal, REVALIDATE_HEADER, RawTextElements, RequestContext, ResponseEnvelope, SVGElements, VoidElements, acquireAsset, addEvent, applyRef, assign, claimElement, claimElementTree, className, clientOnly, delegateEvents, dynamic, dynamicProperty, effect, escape, voidFn as generateHydrationScript, voidFn as getAssets, getDelegatedRoot, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, voidFn as getRequestEvent, httpHeader, httpStatus, hydrate, insert, installHydrationRuntime, isDev, isHref, isResponseEnvelope, isServer, memo, mergeProps, redirect, ref, registerDelegatedContainer, registerDelegatedRoot, registerElementClaim, reload, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, respond, runHydrationEvents, scope, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrStyle, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, voidFn as useAssets };
|
|
1629
|
+
export { voidFn as Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, voidFn as HydrationScript, MathMLElements, Namespaces, Portal, REVALIDATE_HEADER, RawTextElements, RequestContext, ResponseEnvelope, SVGElements, VoidElements, acquireAsset, addEvent, applyRef, assign, claimElement, claimElementTree, className, clientOnly, delegateEvents, dynamic, dynamicProperty, effect, escape, voidFn as generateHydrationScript, voidFn as getAssets, getDelegatedRoot, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, voidFn as getRequestEvent, httpHeader, httpStatus, hydrate, insert, installHydrationRuntime, isDev, isHref, isResponseEnvelope, isServer, memo, mergeProps, redirect, ref, registerDelegatedContainer, registerDelegatedRoot, registerElementClaim, reload, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, respond, runHydrationEvents, scope, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrStyle, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, voidFn as useAssets, useHead };
|