@solidjs/web 2.0.0-beta.16 → 2.0.0-beta.17
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 +136 -11
- package/dist/dev.js +136 -12
- package/dist/server.cjs +100 -21
- package/dist/server.js +100 -22
- package/dist/web.cjs +136 -11
- package/dist/web.js +136 -12
- package/package.json +3 -3
- package/types/client.d.ts +13 -0
- package/types/server.d.ts +2 -0
- package/types-cjs/client.d.cts +13 -0
- package/types-cjs/server.d.cts +2 -0
- package/storage/types/index.d.ts +0 -2
- package/storage/types/src/jsx.d.ts +0 -29
- package/storage/types-cjs/index.d.cts +0 -2
- package/storage/types-cjs/src/jsx.d.cts +0 -29
package/dist/server.js
CHANGED
|
@@ -140,25 +140,48 @@ function createAssetTracking() {
|
|
|
140
140
|
const boundaryModules = new Map();
|
|
141
141
|
const boundaryStyles = new Map();
|
|
142
142
|
const emittedAssets = new Set();
|
|
143
|
+
const inlineStyles = new Map();
|
|
143
144
|
let currentBoundaryId = null;
|
|
144
145
|
return {
|
|
145
146
|
boundaryModules,
|
|
146
147
|
boundaryStyles,
|
|
147
148
|
emittedAssets,
|
|
149
|
+
inlineStyles,
|
|
150
|
+
registerInlineStyle(desc) {
|
|
151
|
+
let entry = inlineStyles.get(desc.id);
|
|
152
|
+
if (!entry) {
|
|
153
|
+
entry = {
|
|
154
|
+
id: desc.id,
|
|
155
|
+
content: desc.content || "",
|
|
156
|
+
attrs: desc.attrs,
|
|
157
|
+
emitted: false
|
|
158
|
+
};
|
|
159
|
+
inlineStyles.set(desc.id, entry);
|
|
160
|
+
}
|
|
161
|
+
if (currentBoundaryId) {
|
|
162
|
+
let styles = boundaryStyles.get(currentBoundaryId);
|
|
163
|
+
if (!styles) {
|
|
164
|
+
styles = new Set();
|
|
165
|
+
boundaryStyles.set(currentBoundaryId, styles);
|
|
166
|
+
}
|
|
167
|
+
styles.add(entry);
|
|
168
|
+
}
|
|
169
|
+
return entry;
|
|
170
|
+
},
|
|
148
171
|
get currentBoundaryId() {
|
|
149
172
|
return currentBoundaryId;
|
|
150
173
|
},
|
|
151
174
|
set currentBoundaryId(v) {
|
|
152
175
|
currentBoundaryId = v;
|
|
153
176
|
},
|
|
154
|
-
registerModule(
|
|
177
|
+
registerModule(key, entryUrl) {
|
|
155
178
|
const id = currentBoundaryId || "";
|
|
156
179
|
let map = boundaryModules.get(id);
|
|
157
180
|
if (!map) {
|
|
158
181
|
map = {};
|
|
159
182
|
boundaryModules.set(id, map);
|
|
160
183
|
}
|
|
161
|
-
map[
|
|
184
|
+
map[key] = entryUrl;
|
|
162
185
|
},
|
|
163
186
|
getBoundaryModules(id) {
|
|
164
187
|
return boundaryModules.get(id) || null;
|
|
@@ -219,16 +242,20 @@ function renderToString(code, options = {}) {
|
|
|
219
242
|
}
|
|
220
243
|
serializer.write(id, p);
|
|
221
244
|
},
|
|
222
|
-
registerAsset(type,
|
|
245
|
+
registerAsset(type, value) {
|
|
246
|
+
if (type === "inline-style") {
|
|
247
|
+
tracking.registerInlineStyle(value);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
223
250
|
if (tracking.currentBoundaryId && type === "style") {
|
|
224
251
|
let styles = tracking.boundaryStyles.get(tracking.currentBoundaryId);
|
|
225
252
|
if (!styles) {
|
|
226
253
|
styles = new Set();
|
|
227
254
|
tracking.boundaryStyles.set(tracking.currentBoundaryId, styles);
|
|
228
255
|
}
|
|
229
|
-
styles.add(
|
|
256
|
+
styles.add(value);
|
|
230
257
|
}
|
|
231
|
-
tracking.emittedAssets.add(
|
|
258
|
+
tracking.emittedAssets.add(value);
|
|
232
259
|
}
|
|
233
260
|
};
|
|
234
261
|
applyAssetTracking(sharedConfig.context, tracking, manifest);
|
|
@@ -244,6 +271,7 @@ function renderToString(code, options = {}) {
|
|
|
244
271
|
serializer.close();
|
|
245
272
|
html = injectAssets(sharedConfig.context.assets, html);
|
|
246
273
|
html = injectPreloadLinks(tracking.emittedAssets, html);
|
|
274
|
+
html = injectInlineStyles(tracking.inlineStyles, html, nonce);
|
|
247
275
|
if (scripts.length) html = injectScripts(html, scripts, options.nonce);
|
|
248
276
|
return html;
|
|
249
277
|
}
|
|
@@ -354,19 +382,27 @@ function renderToStream(code, options = {}) {
|
|
|
354
382
|
async: true,
|
|
355
383
|
assets: [],
|
|
356
384
|
nonce,
|
|
357
|
-
registerAsset(type,
|
|
385
|
+
registerAsset(type, value) {
|
|
386
|
+
if (type === "inline-style") {
|
|
387
|
+
const entry = tracking.registerInlineStyle(value);
|
|
388
|
+
if (firstFlushed && !tracking.currentBoundaryId && !entry.emitted) {
|
|
389
|
+
entry.emitted = true;
|
|
390
|
+
buffer.write(renderInlineStyle(entry, nonce));
|
|
391
|
+
}
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
358
394
|
if (tracking.currentBoundaryId && type === "style") {
|
|
359
395
|
let styles = tracking.boundaryStyles.get(tracking.currentBoundaryId);
|
|
360
396
|
if (!styles) {
|
|
361
397
|
styles = new Set();
|
|
362
398
|
tracking.boundaryStyles.set(tracking.currentBoundaryId, styles);
|
|
363
399
|
}
|
|
364
|
-
styles.add(
|
|
400
|
+
styles.add(value);
|
|
365
401
|
}
|
|
366
|
-
if (!tracking.emittedAssets.has(
|
|
367
|
-
tracking.emittedAssets.add(
|
|
402
|
+
if (!tracking.emittedAssets.has(value)) {
|
|
403
|
+
tracking.emittedAssets.add(value);
|
|
368
404
|
if (firstFlushed && type === "module") {
|
|
369
|
-
buffer.write(`<link rel="modulepreload" href="${
|
|
405
|
+
buffer.write(`<link rel="modulepreload" href="${value}">`);
|
|
370
406
|
}
|
|
371
407
|
}
|
|
372
408
|
},
|
|
@@ -450,10 +486,13 @@ function renderToStream(code, options = {}) {
|
|
|
450
486
|
serializeFragmentAssets(key, tracking.boundaryModules, context);
|
|
451
487
|
const styles = collectStreamStyles(key, tracking, headStyles);
|
|
452
488
|
const deferActivation = !!revealGroup;
|
|
453
|
-
|
|
454
|
-
|
|
489
|
+
for (let i = 0; i < styles.inline.length; i++) {
|
|
490
|
+
buffer.write(renderInlineStyle(styles.inline[i], nonce));
|
|
491
|
+
}
|
|
492
|
+
if (styles.links.length) {
|
|
493
|
+
emitTask(`$dfs("${key}",${styles.links.length},${deferActivation ? 1 : 0})`);
|
|
455
494
|
writeTasks();
|
|
456
|
-
for (const url of styles) {
|
|
495
|
+
for (const url of styles.links) {
|
|
457
496
|
buffer.write(`<link rel="stylesheet" href="${url}" onload="$dfc('${key}')" onerror="$dfc('${key}')">`);
|
|
458
497
|
}
|
|
459
498
|
buffer.write(`<template id="${key}">${value !== undefined ? value : " "}</template>`);
|
|
@@ -544,6 +583,7 @@ function renderToStream(code, options = {}) {
|
|
|
544
583
|
if (url.endsWith(".css")) headStyles.add(url);
|
|
545
584
|
}
|
|
546
585
|
html = injectPreloadLinks(tracking.emittedAssets, html);
|
|
586
|
+
html = injectInlineStyles(tracking.inlineStyles, html, nonce);
|
|
547
587
|
serializeRootAssets();
|
|
548
588
|
if (tasks.length) html = injectScripts(html, tasks, nonce);
|
|
549
589
|
buffer.write(html);
|
|
@@ -849,10 +889,11 @@ function ssrStyleProperty(name, value) {
|
|
|
849
889
|
return value != null ? name + value : "";
|
|
850
890
|
}
|
|
851
891
|
function ssrElement(tag, props, children, needsId) {
|
|
892
|
+
const hk = needsId ? ssrHydrationKey() : "";
|
|
852
893
|
if (props == null) props = {};else if (typeof props === "function") props = props();
|
|
853
894
|
const skipChildren = VOID_ELEMENTS.test(tag);
|
|
854
895
|
const keys = Object.keys(props);
|
|
855
|
-
let result = `<${tag}${
|
|
896
|
+
let result = `<${tag}${hk} `;
|
|
856
897
|
for (let i = 0; i < keys.length; i++) {
|
|
857
898
|
const prop = keys[i];
|
|
858
899
|
if (ChildProperties.has(prop)) {
|
|
@@ -897,7 +938,10 @@ function escape(s, attr) {
|
|
|
897
938
|
for (let i = 0; i < s.length; i++) s[i] = escape(s[i]);
|
|
898
939
|
return s;
|
|
899
940
|
}
|
|
900
|
-
if (attr
|
|
941
|
+
if (attr) {
|
|
942
|
+
if (s == null || t === "boolean" || t === "number") return s;
|
|
943
|
+
return escape(String(s), attr);
|
|
944
|
+
}
|
|
901
945
|
return s;
|
|
902
946
|
}
|
|
903
947
|
const delimCode = attr ? 34 : 60;
|
|
@@ -1033,14 +1077,48 @@ function propagateBoundaryStyles(childKey, parentKey, tracking) {
|
|
|
1033
1077
|
}
|
|
1034
1078
|
function collectStreamStyles(key, tracking, headStyles) {
|
|
1035
1079
|
const styles = tracking.getBoundaryStyles(key);
|
|
1036
|
-
|
|
1037
|
-
const
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1080
|
+
const links = [];
|
|
1081
|
+
const inline = [];
|
|
1082
|
+
if (!styles) return {
|
|
1083
|
+
links,
|
|
1084
|
+
inline
|
|
1085
|
+
};
|
|
1086
|
+
for (const entry of styles) {
|
|
1087
|
+
if (typeof entry === "string") {
|
|
1088
|
+
if (!headStyles || !headStyles.has(entry)) links.push(entry);
|
|
1089
|
+
} else if (!entry.emitted) {
|
|
1090
|
+
entry.emitted = true;
|
|
1091
|
+
inline.push(entry);
|
|
1041
1092
|
}
|
|
1042
1093
|
}
|
|
1043
|
-
return
|
|
1094
|
+
return {
|
|
1095
|
+
links,
|
|
1096
|
+
inline
|
|
1097
|
+
};
|
|
1098
|
+
}
|
|
1099
|
+
function escapeStyleContent(content) {
|
|
1100
|
+
return content.replace(/<\/(style)/gi, "<\\/$1");
|
|
1101
|
+
}
|
|
1102
|
+
function renderInlineStyle(entry, nonce) {
|
|
1103
|
+
let attrs = "";
|
|
1104
|
+
if (entry.attrs) {
|
|
1105
|
+
for (const name in entry.attrs) {
|
|
1106
|
+
attrs += ` ${name}="${escape(String(entry.attrs[name]), true)}"`;
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
return `<style${nonce ? ` nonce="${nonce}"` : ""} data-asset="${escape(entry.id, true)}"${attrs}>${escapeStyleContent(entry.content)}</style>`;
|
|
1110
|
+
}
|
|
1111
|
+
function injectInlineStyles(inlineStyles, html, nonce) {
|
|
1112
|
+
if (!inlineStyles.size) return html;
|
|
1113
|
+
const index = html.indexOf("</head>");
|
|
1114
|
+
if (index === -1) return html;
|
|
1115
|
+
let out = "";
|
|
1116
|
+
for (const entry of inlineStyles.values()) {
|
|
1117
|
+
if (entry.emitted) continue;
|
|
1118
|
+
entry.emitted = true;
|
|
1119
|
+
out += renderInlineStyle(entry, nonce);
|
|
1120
|
+
}
|
|
1121
|
+
return out ? html.slice(0, index) + out + html.slice(index) : html;
|
|
1044
1122
|
}
|
|
1045
1123
|
function injectScripts(html, scripts, nonce) {
|
|
1046
1124
|
const tag = `<script${nonce ? ` nonce="${nonce}"` : ""}>${scripts}</script>`;
|
|
@@ -1229,4 +1307,4 @@ function Portal(props) {
|
|
|
1229
1307
|
throw new Error("Portal is not supported on the server");
|
|
1230
1308
|
}
|
|
1231
1309
|
|
|
1232
|
-
export { Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HydrationScript, MathMLElements, Namespaces, Portal, RawTextElements, RequestContext, SVGElements, VoidElements, notSup as addEvent, applyRef, notSup as assign, notSup as className, notSup as delegateEvents, dynamic, notSup as dynamicProperty, effect, escape, generateHydrationScript, getAssets, notSup as getDelegatedRoot, getHydrationKey, notSup as getNextElement, notSup as getNextMarker, notSup as getNextMatch, getRequestEvent, notSup as hydrate, notSup as insert, isDev, isServer, memo, notSup as ref, notSup as registerDelegatedContainer, notSup as registerDelegatedRoot, notSup as render, renderToStream, renderToString, renderToStringAsync, notSup as runHydrationEvents, notSup as setAttribute, notSup as setAttributeNS, notSup as setProperty, notSup as setStyleProperty, notSup as spread, ssr, ssrAttribute, ssrClassName, ssrElement, ssrGroup, ssrHydrationKey, ssrStyle, ssrStyleProperty, notSup as style, notSup as template, notSup as unregisterDelegatedContainer, notSup as unregisterDelegatedRoot, useAssets };
|
|
1310
|
+
export { Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HydrationScript, MathMLElements, Namespaces, Portal, RawTextElements, RequestContext, SVGElements, VoidElements, notSup as acquireAsset, notSup as addEvent, applyRef, notSup as assign, notSup as className, notSup as delegateEvents, dynamic, notSup as dynamicProperty, effect, escape, generateHydrationScript, getAssets, notSup as getDelegatedRoot, getHydrationKey, notSup as getNextElement, notSup as getNextMarker, notSup as getNextMatch, getRequestEvent, notSup as hydrate, notSup as insert, isDev, isServer, memo, notSup as ref, notSup as registerDelegatedContainer, notSup as registerDelegatedRoot, notSup as render, renderToStream, renderToString, renderToStringAsync, notSup as runHydrationEvents, notSup as setAttribute, notSup as setAttributeNS, notSup as setProperty, notSup as setStyleProperty, notSup as spread, ssr, ssrAttribute, ssrClassName, ssrElement, ssrGroup, ssrHydrationKey, ssrStyle, ssrStyleProperty, notSup as style, notSup as template, notSup as unregisterDelegatedContainer, notSup as unregisterDelegatedRoot, useAssets };
|
package/dist/web.cjs
CHANGED
|
@@ -504,22 +504,117 @@ function assign(node, props, skipChildren, prevProps = {}, skipRef = false) {
|
|
|
504
504
|
prevProps[prop] = assignProp(node, prop, props[prop], prevProps[prop], skipRef, nodeName);
|
|
505
505
|
}
|
|
506
506
|
}
|
|
507
|
+
const ASSET_REMOVAL_GRACE = 100;
|
|
508
|
+
const assetRegistry = new Map();
|
|
509
|
+
function assetEntryKey(descriptor) {
|
|
510
|
+
if (descriptor.policy === "exclusive") return "x|" + descriptor.key;
|
|
511
|
+
return descriptor.type === "inline-style" ? "i|" + descriptor.id : descriptor.type + "|" + descriptor.href;
|
|
512
|
+
}
|
|
513
|
+
function findAssetElement(selector, attr, value) {
|
|
514
|
+
const nodes = document.querySelectorAll(selector);
|
|
515
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
516
|
+
if (nodes[i].getAttribute(attr) === value) return nodes[i];
|
|
517
|
+
}
|
|
518
|
+
return null;
|
|
519
|
+
}
|
|
520
|
+
function mountAssetElement(descriptor) {
|
|
521
|
+
let el;
|
|
522
|
+
if (descriptor.type === "inline-style") {
|
|
523
|
+
el = findAssetElement("style[data-asset]", "data-asset", descriptor.id);
|
|
524
|
+
if (!el) {
|
|
525
|
+
el = document.createElement("style");
|
|
526
|
+
el.setAttribute("data-asset", descriptor.id);
|
|
527
|
+
el.textContent = descriptor.content || "";
|
|
528
|
+
}
|
|
529
|
+
} else {
|
|
530
|
+
const rel = descriptor.type === "module" ? "modulepreload" : "stylesheet";
|
|
531
|
+
el = findAssetElement(`link[rel="${rel}"]`, "href", descriptor.href);
|
|
532
|
+
if (!el) {
|
|
533
|
+
el = document.createElement("link");
|
|
534
|
+
el.rel = rel;
|
|
535
|
+
el.href = descriptor.href;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
if (descriptor.attrs) {
|
|
539
|
+
for (const name in descriptor.attrs) el.setAttribute(name, descriptor.attrs[name]);
|
|
540
|
+
}
|
|
541
|
+
if (!el.isConnected) document.head.appendChild(el);
|
|
542
|
+
return el;
|
|
543
|
+
}
|
|
544
|
+
function acquireAsset(descriptor) {
|
|
545
|
+
const key = assetEntryKey(descriptor);
|
|
546
|
+
let entry = assetRegistry.get(key);
|
|
547
|
+
if (descriptor.policy === "exclusive") {
|
|
548
|
+
if (!entry) {
|
|
549
|
+
entry = {
|
|
550
|
+
original: descriptor.get(),
|
|
551
|
+
set: descriptor.set,
|
|
552
|
+
writers: []
|
|
553
|
+
};
|
|
554
|
+
assetRegistry.set(key, entry);
|
|
555
|
+
}
|
|
556
|
+
const writer = {
|
|
557
|
+
value: descriptor.value
|
|
558
|
+
};
|
|
559
|
+
entry.writers.push(writer);
|
|
560
|
+
entry.set(writer.value);
|
|
561
|
+
let released = false;
|
|
562
|
+
return () => {
|
|
563
|
+
if (released) return;
|
|
564
|
+
released = true;
|
|
565
|
+
const index = entry.writers.indexOf(writer);
|
|
566
|
+
const wasTop = index === entry.writers.length - 1;
|
|
567
|
+
entry.writers.splice(index, 1);
|
|
568
|
+
if (!wasTop) return;
|
|
569
|
+
if (entry.writers.length) {
|
|
570
|
+
entry.set(entry.writers[entry.writers.length - 1].value);
|
|
571
|
+
} else {
|
|
572
|
+
entry.set(entry.original);
|
|
573
|
+
assetRegistry.delete(key);
|
|
574
|
+
}
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
if (!entry) {
|
|
578
|
+
entry = {
|
|
579
|
+
count: 0,
|
|
580
|
+
element: null,
|
|
581
|
+
timer: null
|
|
582
|
+
};
|
|
583
|
+
assetRegistry.set(key, entry);
|
|
584
|
+
}
|
|
585
|
+
if (entry.timer) {
|
|
586
|
+
clearTimeout(entry.timer);
|
|
587
|
+
entry.timer = null;
|
|
588
|
+
}
|
|
589
|
+
entry.count++;
|
|
590
|
+
if (!entry.element || !entry.element.isConnected) entry.element = mountAssetElement(descriptor);
|
|
591
|
+
let released = false;
|
|
592
|
+
return () => {
|
|
593
|
+
if (released) return;
|
|
594
|
+
released = true;
|
|
595
|
+
if (--entry.count > 0) return;
|
|
596
|
+
entry.timer = setTimeout(() => {
|
|
597
|
+
assetRegistry.delete(key);
|
|
598
|
+
entry.element && entry.element.remove();
|
|
599
|
+
}, ASSET_REMOVAL_GRACE);
|
|
600
|
+
};
|
|
601
|
+
}
|
|
507
602
|
function loadModuleAssets(mapping) {
|
|
508
603
|
const hy = globalThis._$HY;
|
|
509
604
|
if (!hy) return;
|
|
510
605
|
const pending = [];
|
|
511
|
-
for (const
|
|
512
|
-
if (hy.modules[
|
|
513
|
-
const entryUrl = mapping[
|
|
514
|
-
if (!hy.loading[
|
|
515
|
-
hy.loading[
|
|
516
|
-
hy.modules[
|
|
606
|
+
for (const key in mapping) {
|
|
607
|
+
if (hy.modules[key]) continue;
|
|
608
|
+
const entryUrl = mapping[key];
|
|
609
|
+
if (!hy.loading[key]) {
|
|
610
|
+
hy.loading[key] = import(entryUrl).then(mod => {
|
|
611
|
+
hy.modules[key] = mod;
|
|
517
612
|
}, err => {
|
|
518
|
-
delete hy.loading[
|
|
613
|
+
delete hy.loading[key];
|
|
519
614
|
throw err;
|
|
520
615
|
});
|
|
521
616
|
}
|
|
522
|
-
pending.push(hy.loading[
|
|
617
|
+
pending.push(hy.loading[key]);
|
|
523
618
|
}
|
|
524
619
|
return pending.length ? Promise.all(pending).then(() => {}) : undefined;
|
|
525
620
|
}
|
|
@@ -806,7 +901,13 @@ function insertExpression(parent, value, current, marker) {
|
|
|
806
901
|
const tc = typeof current;
|
|
807
902
|
if (tc === "string" || tc === "number") {
|
|
808
903
|
parent.firstChild.data = value;
|
|
809
|
-
} else
|
|
904
|
+
} else {
|
|
905
|
+
const owned = ownedChildCount(current);
|
|
906
|
+
if (owned === -1 || owned === parent.childNodes.length) parent.textContent = value;else {
|
|
907
|
+
removeOwnedChildren(parent, current);
|
|
908
|
+
parent.insertBefore(document.createTextNode(value), parent.firstChild);
|
|
909
|
+
}
|
|
910
|
+
}
|
|
810
911
|
} else if (value === undefined) {
|
|
811
912
|
cleanChildren(parent, current, marker);
|
|
812
913
|
} else if (value.nodeType) {
|
|
@@ -829,7 +930,7 @@ function insertExpression(parent, value, current, marker) {
|
|
|
829
930
|
appendNodes(parent, value, marker);
|
|
830
931
|
} else reconcileArrays(parent, current, value, marker);
|
|
831
932
|
} else {
|
|
832
|
-
current && cleanChildren(parent);
|
|
933
|
+
current && cleanChildren(parent, current);
|
|
833
934
|
appendNodes(parent, value);
|
|
834
935
|
}
|
|
835
936
|
} else ;
|
|
@@ -869,8 +970,31 @@ function appendNodes(parent, array, marker = null) {
|
|
|
869
970
|
if (marker) n[$$SLOT] = marker;
|
|
870
971
|
}
|
|
871
972
|
}
|
|
973
|
+
function ownedChildCount(current) {
|
|
974
|
+
if (Array.isArray(current)) return current.length;
|
|
975
|
+
if (current == null) return -1;
|
|
976
|
+
if (current === "") return 0;
|
|
977
|
+
return 1;
|
|
978
|
+
}
|
|
979
|
+
function removeOwnedChildren(parent, current) {
|
|
980
|
+
if (Array.isArray(current)) {
|
|
981
|
+
for (let i = 0; i < current.length; i++) {
|
|
982
|
+
const el = current[i];
|
|
983
|
+
if (el.parentNode === parent) el.remove();
|
|
984
|
+
}
|
|
985
|
+
} else if (current.nodeType) {
|
|
986
|
+
if (current.parentNode === parent) current.remove();
|
|
987
|
+
} else {
|
|
988
|
+
const first = parent.firstChild;
|
|
989
|
+
if (first && first.nodeType === 3) first.remove();
|
|
990
|
+
}
|
|
991
|
+
}
|
|
872
992
|
function cleanChildren(parent, current, marker, replacement) {
|
|
873
|
-
if (marker === undefined)
|
|
993
|
+
if (marker === undefined) {
|
|
994
|
+
const owned = ownedChildCount(current);
|
|
995
|
+
if (owned === -1 || owned === parent.childNodes.length) return parent.textContent = "";
|
|
996
|
+
return removeOwnedChildren(parent, current);
|
|
997
|
+
}
|
|
874
998
|
if (current.length) {
|
|
875
999
|
let inserted = false;
|
|
876
1000
|
for (let i = current.length - 1; i >= 0; i--) {
|
|
@@ -1072,6 +1196,7 @@ exports.RawTextElements = RawTextElements;
|
|
|
1072
1196
|
exports.RequestContext = RequestContext;
|
|
1073
1197
|
exports.SVGElements = SVGElements;
|
|
1074
1198
|
exports.VoidElements = VoidElements;
|
|
1199
|
+
exports.acquireAsset = acquireAsset;
|
|
1075
1200
|
exports.addEvent = addEvent;
|
|
1076
1201
|
exports.applyRef = applyRef;
|
|
1077
1202
|
exports.assign = assign;
|
package/dist/web.js
CHANGED
|
@@ -503,22 +503,117 @@ function assign(node, props, skipChildren, prevProps = {}, skipRef = false) {
|
|
|
503
503
|
prevProps[prop] = assignProp(node, prop, props[prop], prevProps[prop], skipRef, nodeName);
|
|
504
504
|
}
|
|
505
505
|
}
|
|
506
|
+
const ASSET_REMOVAL_GRACE = 100;
|
|
507
|
+
const assetRegistry = new Map();
|
|
508
|
+
function assetEntryKey(descriptor) {
|
|
509
|
+
if (descriptor.policy === "exclusive") return "x|" + descriptor.key;
|
|
510
|
+
return descriptor.type === "inline-style" ? "i|" + descriptor.id : descriptor.type + "|" + descriptor.href;
|
|
511
|
+
}
|
|
512
|
+
function findAssetElement(selector, attr, value) {
|
|
513
|
+
const nodes = document.querySelectorAll(selector);
|
|
514
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
515
|
+
if (nodes[i].getAttribute(attr) === value) return nodes[i];
|
|
516
|
+
}
|
|
517
|
+
return null;
|
|
518
|
+
}
|
|
519
|
+
function mountAssetElement(descriptor) {
|
|
520
|
+
let el;
|
|
521
|
+
if (descriptor.type === "inline-style") {
|
|
522
|
+
el = findAssetElement("style[data-asset]", "data-asset", descriptor.id);
|
|
523
|
+
if (!el) {
|
|
524
|
+
el = document.createElement("style");
|
|
525
|
+
el.setAttribute("data-asset", descriptor.id);
|
|
526
|
+
el.textContent = descriptor.content || "";
|
|
527
|
+
}
|
|
528
|
+
} else {
|
|
529
|
+
const rel = descriptor.type === "module" ? "modulepreload" : "stylesheet";
|
|
530
|
+
el = findAssetElement(`link[rel="${rel}"]`, "href", descriptor.href);
|
|
531
|
+
if (!el) {
|
|
532
|
+
el = document.createElement("link");
|
|
533
|
+
el.rel = rel;
|
|
534
|
+
el.href = descriptor.href;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
if (descriptor.attrs) {
|
|
538
|
+
for (const name in descriptor.attrs) el.setAttribute(name, descriptor.attrs[name]);
|
|
539
|
+
}
|
|
540
|
+
if (!el.isConnected) document.head.appendChild(el);
|
|
541
|
+
return el;
|
|
542
|
+
}
|
|
543
|
+
function acquireAsset(descriptor) {
|
|
544
|
+
const key = assetEntryKey(descriptor);
|
|
545
|
+
let entry = assetRegistry.get(key);
|
|
546
|
+
if (descriptor.policy === "exclusive") {
|
|
547
|
+
if (!entry) {
|
|
548
|
+
entry = {
|
|
549
|
+
original: descriptor.get(),
|
|
550
|
+
set: descriptor.set,
|
|
551
|
+
writers: []
|
|
552
|
+
};
|
|
553
|
+
assetRegistry.set(key, entry);
|
|
554
|
+
}
|
|
555
|
+
const writer = {
|
|
556
|
+
value: descriptor.value
|
|
557
|
+
};
|
|
558
|
+
entry.writers.push(writer);
|
|
559
|
+
entry.set(writer.value);
|
|
560
|
+
let released = false;
|
|
561
|
+
return () => {
|
|
562
|
+
if (released) return;
|
|
563
|
+
released = true;
|
|
564
|
+
const index = entry.writers.indexOf(writer);
|
|
565
|
+
const wasTop = index === entry.writers.length - 1;
|
|
566
|
+
entry.writers.splice(index, 1);
|
|
567
|
+
if (!wasTop) return;
|
|
568
|
+
if (entry.writers.length) {
|
|
569
|
+
entry.set(entry.writers[entry.writers.length - 1].value);
|
|
570
|
+
} else {
|
|
571
|
+
entry.set(entry.original);
|
|
572
|
+
assetRegistry.delete(key);
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
if (!entry) {
|
|
577
|
+
entry = {
|
|
578
|
+
count: 0,
|
|
579
|
+
element: null,
|
|
580
|
+
timer: null
|
|
581
|
+
};
|
|
582
|
+
assetRegistry.set(key, entry);
|
|
583
|
+
}
|
|
584
|
+
if (entry.timer) {
|
|
585
|
+
clearTimeout(entry.timer);
|
|
586
|
+
entry.timer = null;
|
|
587
|
+
}
|
|
588
|
+
entry.count++;
|
|
589
|
+
if (!entry.element || !entry.element.isConnected) entry.element = mountAssetElement(descriptor);
|
|
590
|
+
let released = false;
|
|
591
|
+
return () => {
|
|
592
|
+
if (released) return;
|
|
593
|
+
released = true;
|
|
594
|
+
if (--entry.count > 0) return;
|
|
595
|
+
entry.timer = setTimeout(() => {
|
|
596
|
+
assetRegistry.delete(key);
|
|
597
|
+
entry.element && entry.element.remove();
|
|
598
|
+
}, ASSET_REMOVAL_GRACE);
|
|
599
|
+
};
|
|
600
|
+
}
|
|
506
601
|
function loadModuleAssets(mapping) {
|
|
507
602
|
const hy = globalThis._$HY;
|
|
508
603
|
if (!hy) return;
|
|
509
604
|
const pending = [];
|
|
510
|
-
for (const
|
|
511
|
-
if (hy.modules[
|
|
512
|
-
const entryUrl = mapping[
|
|
513
|
-
if (!hy.loading[
|
|
514
|
-
hy.loading[
|
|
515
|
-
hy.modules[
|
|
605
|
+
for (const key in mapping) {
|
|
606
|
+
if (hy.modules[key]) continue;
|
|
607
|
+
const entryUrl = mapping[key];
|
|
608
|
+
if (!hy.loading[key]) {
|
|
609
|
+
hy.loading[key] = import(entryUrl).then(mod => {
|
|
610
|
+
hy.modules[key] = mod;
|
|
516
611
|
}, err => {
|
|
517
|
-
delete hy.loading[
|
|
612
|
+
delete hy.loading[key];
|
|
518
613
|
throw err;
|
|
519
614
|
});
|
|
520
615
|
}
|
|
521
|
-
pending.push(hy.loading[
|
|
616
|
+
pending.push(hy.loading[key]);
|
|
522
617
|
}
|
|
523
618
|
return pending.length ? Promise.all(pending).then(() => {}) : undefined;
|
|
524
619
|
}
|
|
@@ -805,7 +900,13 @@ function insertExpression(parent, value, current, marker) {
|
|
|
805
900
|
const tc = typeof current;
|
|
806
901
|
if (tc === "string" || tc === "number") {
|
|
807
902
|
parent.firstChild.data = value;
|
|
808
|
-
} else
|
|
903
|
+
} else {
|
|
904
|
+
const owned = ownedChildCount(current);
|
|
905
|
+
if (owned === -1 || owned === parent.childNodes.length) parent.textContent = value;else {
|
|
906
|
+
removeOwnedChildren(parent, current);
|
|
907
|
+
parent.insertBefore(document.createTextNode(value), parent.firstChild);
|
|
908
|
+
}
|
|
909
|
+
}
|
|
809
910
|
} else if (value === undefined) {
|
|
810
911
|
cleanChildren(parent, current, marker);
|
|
811
912
|
} else if (value.nodeType) {
|
|
@@ -828,7 +929,7 @@ function insertExpression(parent, value, current, marker) {
|
|
|
828
929
|
appendNodes(parent, value, marker);
|
|
829
930
|
} else reconcileArrays(parent, current, value, marker);
|
|
830
931
|
} else {
|
|
831
|
-
current && cleanChildren(parent);
|
|
932
|
+
current && cleanChildren(parent, current);
|
|
832
933
|
appendNodes(parent, value);
|
|
833
934
|
}
|
|
834
935
|
} else ;
|
|
@@ -868,8 +969,31 @@ function appendNodes(parent, array, marker = null) {
|
|
|
868
969
|
if (marker) n[$$SLOT] = marker;
|
|
869
970
|
}
|
|
870
971
|
}
|
|
972
|
+
function ownedChildCount(current) {
|
|
973
|
+
if (Array.isArray(current)) return current.length;
|
|
974
|
+
if (current == null) return -1;
|
|
975
|
+
if (current === "") return 0;
|
|
976
|
+
return 1;
|
|
977
|
+
}
|
|
978
|
+
function removeOwnedChildren(parent, current) {
|
|
979
|
+
if (Array.isArray(current)) {
|
|
980
|
+
for (let i = 0; i < current.length; i++) {
|
|
981
|
+
const el = current[i];
|
|
982
|
+
if (el.parentNode === parent) el.remove();
|
|
983
|
+
}
|
|
984
|
+
} else if (current.nodeType) {
|
|
985
|
+
if (current.parentNode === parent) current.remove();
|
|
986
|
+
} else {
|
|
987
|
+
const first = parent.firstChild;
|
|
988
|
+
if (first && first.nodeType === 3) first.remove();
|
|
989
|
+
}
|
|
990
|
+
}
|
|
871
991
|
function cleanChildren(parent, current, marker, replacement) {
|
|
872
|
-
if (marker === undefined)
|
|
992
|
+
if (marker === undefined) {
|
|
993
|
+
const owned = ownedChildCount(current);
|
|
994
|
+
if (owned === -1 || owned === parent.childNodes.length) return parent.textContent = "";
|
|
995
|
+
return removeOwnedChildren(parent, current);
|
|
996
|
+
}
|
|
873
997
|
if (current.length) {
|
|
874
998
|
let inserted = false;
|
|
875
999
|
for (let i = current.length - 1; i >= 0; i--) {
|
|
@@ -1005,4 +1129,4 @@ function createElement(tagName, is = undefined) {
|
|
|
1005
1129
|
});
|
|
1006
1130
|
}
|
|
1007
1131
|
|
|
1008
|
-
export { voidFn as Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, voidFn as HydrationScript, MathMLElements, Namespaces, Portal, RawTextElements, RequestContext, SVGElements, VoidElements, addEvent, applyRef, assign, className, delegateEvents, dynamic, dynamicProperty, effect, escape, voidFn as generateHydrationScript, voidFn as getAssets, getDelegatedRoot, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, voidFn as getRequestEvent, hydrate, insert, isDev, isServer, memo, mergeProps, ref, registerDelegatedContainer, registerDelegatedRoot, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, runHydrationEvents, scope, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrStyle, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, voidFn as useAssets };
|
|
1132
|
+
export { voidFn as Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, voidFn as HydrationScript, MathMLElements, Namespaces, Portal, RawTextElements, RequestContext, SVGElements, VoidElements, acquireAsset, addEvent, applyRef, assign, className, delegateEvents, dynamic, dynamicProperty, effect, escape, voidFn as generateHydrationScript, voidFn as getAssets, getDelegatedRoot, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, voidFn as getRequestEvent, hydrate, insert, isDev, isServer, memo, mergeProps, ref, registerDelegatedContainer, registerDelegatedRoot, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, runHydrationEvents, scope, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrStyle, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, voidFn as useAssets };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidjs/web",
|
|
3
3
|
"description": "Solid's web runtime: client rendering, hydration, SSR, and DOM-specific control flow (Portal, Dynamic).",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.17",
|
|
5
5
|
"author": "Ryan Carniato",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://solidjs.com",
|
|
@@ -137,10 +137,10 @@
|
|
|
137
137
|
"seroval-plugins": "^1.1.0"
|
|
138
138
|
},
|
|
139
139
|
"peerDependencies": {
|
|
140
|
-
"solid-js": "^2.0.0-beta.
|
|
140
|
+
"solid-js": "^2.0.0-beta.17"
|
|
141
141
|
},
|
|
142
142
|
"devDependencies": {
|
|
143
|
-
"solid-js": "2.0.0-beta.
|
|
143
|
+
"solid-js": "2.0.0-beta.17"
|
|
144
144
|
},
|
|
145
145
|
"scripts": {
|
|
146
146
|
"build": "npm-run-all -nl build:clean types:copy-jsx build:js",
|
package/types/client.d.ts
CHANGED
|
@@ -103,6 +103,19 @@ export function getNextMatch(start: Node, elementName: string): Element;
|
|
|
103
103
|
export function getNextMarker(start: Node): [Node, Array<Node>];
|
|
104
104
|
export function useAssets(fn: () => JSX.Element): void;
|
|
105
105
|
export function getAssets(): string;
|
|
106
|
+
export type AssetDescriptor =
|
|
107
|
+
| { type: "style"; href: string; attrs?: Record<string, string> }
|
|
108
|
+
| { type: "inline-style"; id: string; content?: string; attrs?: Record<string, string> }
|
|
109
|
+
| { type: "module"; href: string }
|
|
110
|
+
| ExclusiveAssetDescriptor<any>;
|
|
111
|
+
export interface ExclusiveAssetDescriptor<T> {
|
|
112
|
+
policy: "exclusive";
|
|
113
|
+
key: string;
|
|
114
|
+
value: T;
|
|
115
|
+
get(): T;
|
|
116
|
+
set(value: T): void;
|
|
117
|
+
}
|
|
118
|
+
export function acquireAsset(descriptor: AssetDescriptor): () => void;
|
|
106
119
|
export function HydrationScript(props?: { nonce?: string; eventNames?: string[] }): JSX.Element;
|
|
107
120
|
export function generateHydrationScript(options?: {
|
|
108
121
|
nonce?: string;
|
package/types/server.d.ts
CHANGED
|
@@ -192,3 +192,5 @@ export function ref(
|
|
|
192
192
|
): void;
|
|
193
193
|
/** @deprecated not supported on the server side */
|
|
194
194
|
export function setStyleProperty(node: Element, name: string, value: any): void;
|
|
195
|
+
/** @deprecated not supported on the server side — register assets through the render context instead */
|
|
196
|
+
export function acquireAsset(descriptor: unknown): () => void;
|
package/types-cjs/client.d.cts
CHANGED
|
@@ -103,6 +103,19 @@ export function getNextMatch(start: Node, elementName: string): Element;
|
|
|
103
103
|
export function getNextMarker(start: Node): [Node, Array<Node>];
|
|
104
104
|
export function useAssets(fn: () => JSX.Element): void;
|
|
105
105
|
export function getAssets(): string;
|
|
106
|
+
export type AssetDescriptor =
|
|
107
|
+
| { type: "style"; href: string; attrs?: Record<string, string> }
|
|
108
|
+
| { type: "inline-style"; id: string; content?: string; attrs?: Record<string, string> }
|
|
109
|
+
| { type: "module"; href: string }
|
|
110
|
+
| ExclusiveAssetDescriptor<any>;
|
|
111
|
+
export interface ExclusiveAssetDescriptor<T> {
|
|
112
|
+
policy: "exclusive";
|
|
113
|
+
key: string;
|
|
114
|
+
value: T;
|
|
115
|
+
get(): T;
|
|
116
|
+
set(value: T): void;
|
|
117
|
+
}
|
|
118
|
+
export function acquireAsset(descriptor: AssetDescriptor): () => void;
|
|
106
119
|
export function HydrationScript(props?: { nonce?: string; eventNames?: string[] }): JSX.Element;
|
|
107
120
|
export function generateHydrationScript(options?: {
|
|
108
121
|
nonce?: string;
|
package/types-cjs/server.d.cts
CHANGED
|
@@ -192,3 +192,5 @@ export function ref(
|
|
|
192
192
|
): void;
|
|
193
193
|
/** @deprecated not supported on the server side */
|
|
194
194
|
export function setStyleProperty(node: Element, name: string, value: any): void;
|
|
195
|
+
/** @deprecated not supported on the server side — register assets through the render context instead */
|
|
196
|
+
export function acquireAsset(descriptor: unknown): () => void;
|