@solidjs/web 2.0.0-beta.15 → 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/server.cjs CHANGED
@@ -60,9 +60,9 @@ const syncOptions = {
60
60
  sync: true
61
61
  };
62
62
  const effect = (fn, effectFn, options) => solidJs.createRenderEffect(fn, effectFn, options ? {
63
- transparent: true,
64
63
  sync: true,
65
- ...options
64
+ ...options,
65
+ transparent: !options.scope
66
66
  } : transparentOptions);
67
67
  const memo = fn => solidJs.createMemo(() => fn(), syncOptions);
68
68
 
@@ -94,9 +94,15 @@ function getLocalHeaderScript(id) {
94
94
  return seroval.getCrossReferenceHeader(id) + ";";
95
95
  }
96
96
 
97
+ function joinAssetPath(base, file) {
98
+ if (/^(?:[a-z][a-z0-9+.-]*:)?\/\//i.test(file)) return file;
99
+ if (typeof base !== "string" || !base) base = "/";
100
+ if (base[base.length - 1] !== "/") base += "/";
101
+ return base + (file[0] === "/" ? file.slice(1) : file);
102
+ }
97
103
  function resolveAssets(moduleUrl, manifest) {
98
104
  if (!manifest) return null;
99
- const base = manifest._base || "/";
105
+ const base = manifest._base;
100
106
  const entry = manifest[moduleUrl];
101
107
  if (!entry) return null;
102
108
  const css = [];
@@ -107,8 +113,8 @@ function resolveAssets(moduleUrl, manifest) {
107
113
  visited.add(key);
108
114
  const e = manifest[key];
109
115
  if (!e) return;
110
- js.push(base + e.file);
111
- if (e.css) for (let i = 0; i < e.css.length; i++) css.push(base + e.css[i]);
116
+ js.push(joinAssetPath(base, e.file));
117
+ if (e.css) for (let i = 0; i < e.css.length; i++) css.push(joinAssetPath(base, e.css[i]));
112
118
  if (e.imports) for (let i = 0; i < e.imports.length; i++) walk(e.imports[i]);
113
119
  };
114
120
  walk(moduleUrl);
@@ -135,25 +141,48 @@ function createAssetTracking() {
135
141
  const boundaryModules = new Map();
136
142
  const boundaryStyles = new Map();
137
143
  const emittedAssets = new Set();
144
+ const inlineStyles = new Map();
138
145
  let currentBoundaryId = null;
139
146
  return {
140
147
  boundaryModules,
141
148
  boundaryStyles,
142
149
  emittedAssets,
150
+ inlineStyles,
151
+ registerInlineStyle(desc) {
152
+ let entry = inlineStyles.get(desc.id);
153
+ if (!entry) {
154
+ entry = {
155
+ id: desc.id,
156
+ content: desc.content || "",
157
+ attrs: desc.attrs,
158
+ emitted: false
159
+ };
160
+ inlineStyles.set(desc.id, entry);
161
+ }
162
+ if (currentBoundaryId) {
163
+ let styles = boundaryStyles.get(currentBoundaryId);
164
+ if (!styles) {
165
+ styles = new Set();
166
+ boundaryStyles.set(currentBoundaryId, styles);
167
+ }
168
+ styles.add(entry);
169
+ }
170
+ return entry;
171
+ },
143
172
  get currentBoundaryId() {
144
173
  return currentBoundaryId;
145
174
  },
146
175
  set currentBoundaryId(v) {
147
176
  currentBoundaryId = v;
148
177
  },
149
- registerModule(moduleUrl, entryUrl) {
178
+ registerModule(key, entryUrl) {
150
179
  const id = currentBoundaryId || "";
151
180
  let map = boundaryModules.get(id);
152
181
  if (!map) {
153
182
  map = {};
154
183
  boundaryModules.set(id, map);
155
184
  }
156
- map[moduleUrl] = entryUrl;
185
+ map[key] = entryUrl;
157
186
  },
158
187
  getBoundaryModules(id) {
159
188
  return boundaryModules.get(id) || null;
@@ -214,16 +243,20 @@ function renderToString(code, options = {}) {
214
243
  }
215
244
  serializer.write(id, p);
216
245
  },
217
- registerAsset(type, url) {
246
+ registerAsset(type, value) {
247
+ if (type === "inline-style") {
248
+ tracking.registerInlineStyle(value);
249
+ return;
250
+ }
218
251
  if (tracking.currentBoundaryId && type === "style") {
219
252
  let styles = tracking.boundaryStyles.get(tracking.currentBoundaryId);
220
253
  if (!styles) {
221
254
  styles = new Set();
222
255
  tracking.boundaryStyles.set(tracking.currentBoundaryId, styles);
223
256
  }
224
- styles.add(url);
257
+ styles.add(value);
225
258
  }
226
- tracking.emittedAssets.add(url);
259
+ tracking.emittedAssets.add(value);
227
260
  }
228
261
  };
229
262
  applyAssetTracking(solidJs.sharedConfig.context, tracking, manifest);
@@ -239,6 +272,7 @@ function renderToString(code, options = {}) {
239
272
  serializer.close();
240
273
  html = injectAssets(solidJs.sharedConfig.context.assets, html);
241
274
  html = injectPreloadLinks(tracking.emittedAssets, html);
275
+ html = injectInlineStyles(tracking.inlineStyles, html, nonce);
242
276
  if (scripts.length) html = injectScripts(html, scripts, options.nonce);
243
277
  return html;
244
278
  }
@@ -349,19 +383,27 @@ function renderToStream(code, options = {}) {
349
383
  async: true,
350
384
  assets: [],
351
385
  nonce,
352
- registerAsset(type, url) {
386
+ registerAsset(type, value) {
387
+ if (type === "inline-style") {
388
+ const entry = tracking.registerInlineStyle(value);
389
+ if (firstFlushed && !tracking.currentBoundaryId && !entry.emitted) {
390
+ entry.emitted = true;
391
+ buffer.write(renderInlineStyle(entry, nonce));
392
+ }
393
+ return;
394
+ }
353
395
  if (tracking.currentBoundaryId && type === "style") {
354
396
  let styles = tracking.boundaryStyles.get(tracking.currentBoundaryId);
355
397
  if (!styles) {
356
398
  styles = new Set();
357
399
  tracking.boundaryStyles.set(tracking.currentBoundaryId, styles);
358
400
  }
359
- styles.add(url);
401
+ styles.add(value);
360
402
  }
361
- if (!tracking.emittedAssets.has(url)) {
362
- tracking.emittedAssets.add(url);
403
+ if (!tracking.emittedAssets.has(value)) {
404
+ tracking.emittedAssets.add(value);
363
405
  if (firstFlushed && type === "module") {
364
- buffer.write(`<link rel="modulepreload" href="${url}">`);
406
+ buffer.write(`<link rel="modulepreload" href="${value}">`);
365
407
  }
366
408
  }
367
409
  },
@@ -445,10 +487,13 @@ function renderToStream(code, options = {}) {
445
487
  serializeFragmentAssets(key, tracking.boundaryModules, context);
446
488
  const styles = collectStreamStyles(key, tracking, headStyles);
447
489
  const deferActivation = !!revealGroup;
448
- if (styles.length) {
449
- emitTask(`$dfs("${key}",${styles.length},${deferActivation ? 1 : 0})`);
490
+ for (let i = 0; i < styles.inline.length; i++) {
491
+ buffer.write(renderInlineStyle(styles.inline[i], nonce));
492
+ }
493
+ if (styles.links.length) {
494
+ emitTask(`$dfs("${key}",${styles.links.length},${deferActivation ? 1 : 0})`);
450
495
  writeTasks();
451
- for (const url of styles) {
496
+ for (const url of styles.links) {
452
497
  buffer.write(`<link rel="stylesheet" href="${url}" onload="$dfc('${key}')" onerror="$dfc('${key}')">`);
453
498
  }
454
499
  buffer.write(`<template id="${key}">${value !== undefined ? value : " "}</template>`);
@@ -497,38 +542,41 @@ function renderToStream(code, options = {}) {
497
542
  }, {
498
543
  id: renderId
499
544
  });
500
- function doShell() {
501
- if (shellCompleted) return;
502
- if (rootHoles) {
503
- const pending = [];
504
- for (const {
505
- id,
506
- fn
507
- } of rootHoles) {
508
- const marker = `<!--rh${id}-->`;
509
- const res = resolveSSRNode(fn);
510
- if (!res.h.length) {
511
- html = html.replace(marker, res.t[0]);
512
- } else {
513
- let out = res.t[0];
514
- for (let j = 0; j < res.h.length; j++) {
515
- const newId = nextHoleId++;
516
- pending.push({
517
- id: newId,
518
- fn: res.h[j]
519
- });
520
- out += `<!--rh${newId}-->` + res.t[j + 1];
521
- }
522
- html = html.replace(marker, out);
523
- for (const p of res.p) blockingPromises.add(p);
545
+ function resolveRootHoles() {
546
+ if (!rootHoles) return true;
547
+ const pending = [];
548
+ for (const {
549
+ id,
550
+ fn
551
+ } of rootHoles) {
552
+ const marker = `<!--rh${id}-->`;
553
+ const res = resolveSSRNode(fn);
554
+ if (!res.h.length) {
555
+ html = html.replace(marker, res.t[0]);
556
+ } else {
557
+ let out = res.t[0];
558
+ for (let j = 0; j < res.h.length; j++) {
559
+ const newId = nextHoleId++;
560
+ pending.push({
561
+ id: newId,
562
+ fn: res.h[j]
563
+ });
564
+ out += `<!--rh${newId}-->` + res.t[j + 1];
524
565
  }
566
+ html = html.replace(marker, out);
567
+ for (const p of res.p) blockingPromises.add(p);
525
568
  }
526
- if (pending.length) {
527
- rootHoles = pending;
528
- return;
529
- }
530
- rootHoles = null;
531
569
  }
570
+ if (pending.length) {
571
+ rootHoles = pending;
572
+ return false;
573
+ }
574
+ rootHoles = null;
575
+ return true;
576
+ }
577
+ function doShell() {
578
+ if (shellCompleted) return;
579
+ if (!resolveRootHoles()) return;
532
580
  solidJs.sharedConfig.context = context;
533
581
  html = injectAssets(context.assets, html);
534
582
  headStyles = new Set();
@@ -536,6 +584,7 @@ function renderToStream(code, options = {}) {
536
584
  if (url.endsWith(".css")) headStyles.add(url);
537
585
  }
538
586
  html = injectPreloadLinks(tracking.emittedAssets, html);
587
+ html = injectInlineStyles(tracking.inlineStyles, html, nonce);
539
588
  serializeRootAssets();
540
589
  if (tasks.length) html = injectScripts(html, tasks, nonce);
541
590
  buffer.write(html);
@@ -560,7 +609,15 @@ function renderToStream(code, options = {}) {
560
609
  complete();
561
610
  };
562
611
  } else onCompleteAll = complete;
563
- queue(flushEnd);
612
+ function flush() {
613
+ allSettled(blockingPromises).then(() => {
614
+ setTimeout(() => {
615
+ if (!resolveRootHoles()) return flush();
616
+ queue(flushEnd);
617
+ });
618
+ });
619
+ }
620
+ flush();
564
621
  },
565
622
  pipe(w) {
566
623
  function flush() {
@@ -833,10 +890,11 @@ function ssrStyleProperty(name, value) {
833
890
  return value != null ? name + value : "";
834
891
  }
835
892
  function ssrElement(tag, props, children, needsId) {
893
+ const hk = needsId ? ssrHydrationKey() : "";
836
894
  if (props == null) props = {};else if (typeof props === "function") props = props();
837
895
  const skipChildren = VOID_ELEMENTS.test(tag);
838
896
  const keys = Object.keys(props);
839
- let result = `<${tag}${needsId ? ssrHydrationKey() : ""} `;
897
+ let result = `<${tag}${hk} `;
840
898
  for (let i = 0; i < keys.length; i++) {
841
899
  const prop = keys[i];
842
900
  if (ChildProperties.has(prop)) {
@@ -881,7 +939,10 @@ function escape(s, attr) {
881
939
  for (let i = 0; i < s.length; i++) s[i] = escape(s[i]);
882
940
  return s;
883
941
  }
884
- if (attr && t === "boolean") return s;
942
+ if (attr) {
943
+ if (s == null || t === "boolean" || t === "number") return s;
944
+ return escape(String(s), attr);
945
+ }
885
946
  return s;
886
947
  }
887
948
  const delimCode = attr ? 34 : 60;
@@ -941,29 +1002,6 @@ function tryJoinPlainSSRArray(nodes) {
941
1002
  }
942
1003
  return out;
943
1004
  }
944
- function mergeProps(...sources) {
945
- const target = {};
946
- for (let i = 0; i < sources.length; i++) {
947
- let source = sources[i];
948
- if (typeof source === "function") source = source();
949
- if (source) {
950
- const descriptors = Object.getOwnPropertyDescriptors(source);
951
- for (const key in descriptors) {
952
- if (key in target) continue;
953
- Object.defineProperty(target, key, {
954
- enumerable: true,
955
- get() {
956
- for (let i = sources.length - 1; i >= 0; i--) {
957
- const v = (sources[i] || {})[key];
958
- if (v !== undefined) return v;
959
- }
960
- }
961
- });
962
- }
963
- }
964
- }
965
- return target;
966
- }
967
1005
  function getHydrationKey() {
968
1006
  const hydrate = solidJs.sharedConfig.context;
969
1007
  return hydrate && solidJs.sharedConfig.getNextContextId();
@@ -1040,14 +1078,48 @@ function propagateBoundaryStyles(childKey, parentKey, tracking) {
1040
1078
  }
1041
1079
  function collectStreamStyles(key, tracking, headStyles) {
1042
1080
  const styles = tracking.getBoundaryStyles(key);
1043
- if (!styles) return [];
1044
- const result = [];
1045
- for (const url of styles) {
1046
- if (!headStyles || !headStyles.has(url)) {
1047
- result.push(url);
1081
+ const links = [];
1082
+ const inline = [];
1083
+ if (!styles) return {
1084
+ links,
1085
+ inline
1086
+ };
1087
+ for (const entry of styles) {
1088
+ if (typeof entry === "string") {
1089
+ if (!headStyles || !headStyles.has(entry)) links.push(entry);
1090
+ } else if (!entry.emitted) {
1091
+ entry.emitted = true;
1092
+ inline.push(entry);
1048
1093
  }
1049
1094
  }
1050
- return result;
1095
+ return {
1096
+ links,
1097
+ inline
1098
+ };
1099
+ }
1100
+ function escapeStyleContent(content) {
1101
+ return content.replace(/<\/(style)/gi, "<\\/$1");
1102
+ }
1103
+ function renderInlineStyle(entry, nonce) {
1104
+ let attrs = "";
1105
+ if (entry.attrs) {
1106
+ for (const name in entry.attrs) {
1107
+ attrs += ` ${name}="${escape(String(entry.attrs[name]), true)}"`;
1108
+ }
1109
+ }
1110
+ return `<style${nonce ? ` nonce="${nonce}"` : ""} data-asset="${escape(entry.id, true)}"${attrs}>${escapeStyleContent(entry.content)}</style>`;
1111
+ }
1112
+ function injectInlineStyles(inlineStyles, html, nonce) {
1113
+ if (!inlineStyles.size) return html;
1114
+ const index = html.indexOf("</head>");
1115
+ if (index === -1) return html;
1116
+ let out = "";
1117
+ for (const entry of inlineStyles.values()) {
1118
+ if (entry.emitted) continue;
1119
+ entry.emitted = true;
1120
+ out += renderInlineStyle(entry, nonce);
1121
+ }
1122
+ return out ? html.slice(0, index) + out + html.slice(index) : html;
1051
1123
  }
1052
1124
  function injectScripts(html, scripts, nonce) {
1053
1125
  const tag = `<script${nonce ? ` nonce="${nonce}"` : ""}>${scripts}</script>`;
@@ -1112,6 +1184,10 @@ function tryResolveString(node) {
1112
1184
  if (node.h && node.h.length > 0) return {
1113
1185
  merge: node
1114
1186
  };
1187
+ if (node.t === undefined) {
1188
+ console.warn(`Unrecognized value. Skipped inserting`, node);
1189
+ return "";
1190
+ }
1115
1191
  return Array.isArray(node.t) ? node.t[0] : node.t;
1116
1192
  }
1117
1193
  if (t === "function") {
@@ -1150,7 +1226,9 @@ function resolveSSRNode(node, result = {
1150
1226
  result.h.push(...node.h);
1151
1227
  result.p.push(...node.p);
1152
1228
  }
1153
- } else result.t[result.t.length - 1] += node.t;
1229
+ } else if (node.t !== undefined) {
1230
+ result.t[result.t.length - 1] += node.t;
1231
+ } else console.warn(`Unrecognized value. Skipped inserting`, node);
1154
1232
  } else if (t === "function") {
1155
1233
  try {
1156
1234
  resolveSSRNode(node(), result);
@@ -1187,15 +1265,38 @@ function dynamic(source) {
1187
1265
  const o = solidJs.getOwner();
1188
1266
  if (o?.id != null) solidJs.getNextChildId(o);
1189
1267
  return props => {
1190
- const memoOwner = solidJs.createOwner();
1191
- return solidJs.runWithOwner(memoOwner, () => {
1192
- const comp = source(),
1193
- t = typeof comp;
1194
- if (comp) {
1195
- if (t === "function") return comp(props);else if (t === "string") {
1196
- return ssrElement(comp, props, undefined, true);
1268
+ const comp = source();
1269
+ let p;
1270
+ let settled = false;
1271
+ let value;
1272
+ let error;
1273
+ if (comp && typeof comp.then === "function") {
1274
+ p = comp;
1275
+ p.then(v => {
1276
+ value = v;
1277
+ settled = true;
1278
+ }, err => {
1279
+ error = err;
1280
+ settled = true;
1281
+ });
1282
+ const ctx = solidJs.sharedConfig.context;
1283
+ if (ctx?.async) ctx.block(p.then(() => {}, () => {}));
1284
+ }
1285
+ return solidJs.createMemo(() => {
1286
+ let c = comp;
1287
+ if (p) {
1288
+ if (!settled) throw new solidJs.NotReadyError(p);
1289
+ if (error) throw error;
1290
+ c = value;
1291
+ }
1292
+ if (c) {
1293
+ if (typeof c === "function") return c(props);
1294
+ if (typeof c === "string") {
1295
+ return ssrElement(c, props, undefined, true);
1197
1296
  }
1198
1297
  }
1298
+ }, {
1299
+ sync: true
1199
1300
  });
1200
1301
  };
1201
1302
  }
@@ -1255,6 +1356,14 @@ Object.defineProperty(exports, "getOwner", {
1255
1356
  enumerable: true,
1256
1357
  get: function () { return solidJs.getOwner; }
1257
1358
  });
1359
+ Object.defineProperty(exports, "mergeProps", {
1360
+ enumerable: true,
1361
+ get: function () { return solidJs.merge; }
1362
+ });
1363
+ Object.defineProperty(exports, "scope", {
1364
+ enumerable: true,
1365
+ get: function () { return solidJs.ssrScope; }
1366
+ });
1258
1367
  Object.defineProperty(exports, "untrack", {
1259
1368
  enumerable: true,
1260
1369
  get: function () { return solidJs.untrack; }
@@ -1273,6 +1382,7 @@ exports.RawTextElements = RawTextElements;
1273
1382
  exports.RequestContext = RequestContext;
1274
1383
  exports.SVGElements = SVGElements;
1275
1384
  exports.VoidElements = VoidElements;
1385
+ exports.acquireAsset = notSup;
1276
1386
  exports.addEvent = notSup;
1277
1387
  exports.applyRef = applyRef;
1278
1388
  exports.assign = notSup;
@@ -1295,7 +1405,6 @@ exports.insert = notSup;
1295
1405
  exports.isDev = isDev;
1296
1406
  exports.isServer = isServer;
1297
1407
  exports.memo = memo;
1298
- exports.mergeProps = mergeProps;
1299
1408
  exports.ref = notSup;
1300
1409
  exports.registerDelegatedContainer = notSup;
1301
1410
  exports.registerDelegatedRoot = notSup;