solid-js 1.2.4 → 1.3.0-beta.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/dist/dev.cjs +66 -35
- package/dist/dev.js +67 -35
- package/dist/server.cjs +20 -51
- package/dist/server.js +21 -51
- package/dist/solid.cjs +66 -35
- package/dist/solid.js +67 -35
- package/package.json +2 -2
- package/types/index.d.ts +0 -1
- package/types/reactive/signal.d.ts +76 -78
- package/types/render/hydration.d.ts +3 -2
- package/types/server/index.d.ts +1 -1
- package/types/server/reactive.d.ts +1 -2
- package/types/server/rendering.d.ts +2 -1
- package/web/dist/dev.cjs +24 -19
- package/web/dist/dev.js +25 -19
- package/web/dist/server.cjs +213 -102
- package/web/dist/server.js +214 -104
- package/web/dist/web.cjs +24 -19
- package/web/dist/web.js +25 -19
- package/web/types/client.d.ts +0 -1
- package/web/types/core.d.ts +2 -2
package/web/dist/server.cjs
CHANGED
|
@@ -232,111 +232,160 @@ function stringifyString(str) {
|
|
|
232
232
|
return result;
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
+
const REPLACE_SCRIPT = `function $df(e,t){t=document.getElementById(e),document.getElementById("pl"+e).replaceWith(...t.childNodes),_$HY.set(e)}`;
|
|
235
236
|
function renderToString(code, options = {}) {
|
|
236
|
-
solidJs.sharedConfig.context =
|
|
237
|
+
solidJs.sharedConfig.context = {
|
|
237
238
|
id: "",
|
|
238
239
|
count: 0,
|
|
239
|
-
|
|
240
|
-
|
|
240
|
+
suspense: {},
|
|
241
|
+
assets: [],
|
|
242
|
+
nonce: options.nonce
|
|
243
|
+
};
|
|
241
244
|
let html = resolveSSRNode(escape(code()));
|
|
242
245
|
return injectAssets(solidJs.sharedConfig.context.assets, html);
|
|
243
246
|
}
|
|
244
247
|
function renderToStringAsync(code, options = {}) {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
};
|
|
249
|
-
const context = solidJs.sharedConfig.context =
|
|
248
|
+
const {
|
|
249
|
+
nonce,
|
|
250
|
+
timeoutMs = 30000
|
|
251
|
+
} = options;
|
|
252
|
+
const context = solidJs.sharedConfig.context = {
|
|
250
253
|
id: "",
|
|
251
254
|
count: 0,
|
|
252
255
|
resources: {},
|
|
253
256
|
suspense: {},
|
|
254
257
|
assets: [],
|
|
255
|
-
async: true
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
258
|
+
async: true,
|
|
259
|
+
nonce
|
|
260
|
+
};
|
|
261
|
+
let scripts = "";
|
|
262
|
+
solidJs.sharedConfig.context.writeResource = (id, p) => p.then(d => scripts += `_$HY.set("${id}", ${devalue(d)});`);
|
|
263
|
+
const timeout = new Promise((_, reject) => setTimeout(() => reject("renderToString timed out"), timeoutMs));
|
|
264
|
+
return Promise.race([asyncWrap(() => escape(code())), timeout]).then(res => {
|
|
265
|
+
let html = injectAssets(context.assets, resolveSSRNode(res));
|
|
266
|
+
if (scripts.length) html = injectScripts(html, scripts, nonce);
|
|
267
|
+
return html;
|
|
261
268
|
});
|
|
262
269
|
}
|
|
263
|
-
function
|
|
270
|
+
function renderToPipeableStream(code, options) {
|
|
264
271
|
const {
|
|
265
272
|
nonce,
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
}) => startWriting(),
|
|
269
|
-
onComplete
|
|
273
|
+
onCompleteShell,
|
|
274
|
+
onCompleteAll
|
|
270
275
|
} = options;
|
|
271
276
|
const tmp = [];
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
+
const tasks = [];
|
|
278
|
+
const registry = new Set();
|
|
279
|
+
const checkEnd = () => {
|
|
280
|
+
if (!registry.size && !completed) {
|
|
281
|
+
onCompleteAll && onCompleteAll(result);
|
|
282
|
+
writable && writable.end();
|
|
283
|
+
completed = true;
|
|
277
284
|
}
|
|
278
285
|
};
|
|
279
|
-
const
|
|
280
|
-
|
|
281
|
-
buffer =
|
|
282
|
-
|
|
283
|
-
setTimeout(checkEnd);
|
|
284
|
-
},
|
|
285
|
-
write(c) {
|
|
286
|
-
writable.write(c);
|
|
287
|
-
},
|
|
288
|
-
abort() {
|
|
289
|
-
completed = count;
|
|
290
|
-
checkEnd();
|
|
286
|
+
const writeInitialScript = () => {
|
|
287
|
+
if (tasks.length) {
|
|
288
|
+
buffer.write(`<script${nonce ? ` nonce="${nonce}"` : ""}>${tasks.join(";")}</script>`);
|
|
289
|
+
tasks.length = 0;
|
|
291
290
|
}
|
|
291
|
+
scheduled = false;
|
|
292
292
|
};
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
293
|
+
let writable;
|
|
294
|
+
let completed = false;
|
|
295
|
+
let scriptFlushed = false;
|
|
296
|
+
let scheduled = true;
|
|
297
|
+
let buffer = {
|
|
298
|
+
write(payload) {
|
|
299
|
+
tmp.push(payload);
|
|
297
300
|
}
|
|
298
301
|
};
|
|
299
|
-
solidJs.sharedConfig.context =
|
|
302
|
+
solidJs.sharedConfig.context = {
|
|
300
303
|
id: "",
|
|
301
304
|
count: 0,
|
|
305
|
+
async: true,
|
|
302
306
|
streaming: true,
|
|
307
|
+
resources: {},
|
|
303
308
|
suspense: {},
|
|
304
|
-
assets: []
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
309
|
+
assets: [],
|
|
310
|
+
nonce,
|
|
311
|
+
writeResource(id, p) {
|
|
312
|
+
if (!scheduled) {
|
|
313
|
+
Promise.resolve().then(writeInitialScript);
|
|
314
|
+
scheduled = true;
|
|
315
|
+
}
|
|
316
|
+
tasks.push(`_$HY.init("${id}")`);
|
|
317
|
+
p.then(d => {
|
|
318
|
+
buffer.write(`<script${nonce ? ` nonce="${nonce}"` : ""}>_$HY.set("${id}", ${devalue(d)})</script>`);
|
|
319
|
+
});
|
|
320
|
+
},
|
|
321
|
+
registerFragment(key) {
|
|
322
|
+
registry.add(key);
|
|
323
|
+
Promise.resolve().then(() => {
|
|
324
|
+
if (registry.has(key)) {
|
|
325
|
+
if (!scheduled) {
|
|
326
|
+
Promise.resolve().then(writeInitialScript);
|
|
327
|
+
scheduled = true;
|
|
328
|
+
}
|
|
329
|
+
tasks.push(`_$HY.init("${key}")`);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
return value => {
|
|
333
|
+
registry.delete(key);
|
|
334
|
+
if (!value) return;
|
|
335
|
+
buffer.write(`<div hidden id="${key}">${value}</div><script${nonce ? ` nonce="${nonce}"` : ""}>${!scriptFlushed ? REPLACE_SCRIPT : ""}$df("${key}")</script>`);
|
|
336
|
+
scriptFlushed = true;
|
|
337
|
+
checkEnd();
|
|
338
|
+
};
|
|
339
|
+
}
|
|
313
340
|
};
|
|
314
341
|
let html = resolveSSRNode(escape(code()));
|
|
315
342
|
html = injectAssets(solidJs.sharedConfig.context.assets, html);
|
|
316
|
-
|
|
317
|
-
|
|
343
|
+
Promise.resolve().then(() => {
|
|
344
|
+
if (tasks.length) html = injectScripts(html, tasks.join(";"), nonce);
|
|
345
|
+
buffer.write(html);
|
|
346
|
+
tasks.length = 0;
|
|
347
|
+
scheduled = false;
|
|
348
|
+
onCompleteShell && onCompleteShell();
|
|
349
|
+
});
|
|
350
|
+
return {
|
|
351
|
+
pipe(w) {
|
|
352
|
+
buffer = writable = w;
|
|
353
|
+
tmp.forEach(chunk => buffer.write(chunk));
|
|
354
|
+
if (completed) writable.end();else setTimeout(checkEnd);
|
|
355
|
+
}
|
|
356
|
+
};
|
|
318
357
|
}
|
|
319
358
|
function pipeToWritable(code, writable, options = {}) {
|
|
320
359
|
const {
|
|
321
360
|
nonce,
|
|
322
|
-
|
|
361
|
+
onCompleteShell = ({
|
|
323
362
|
startWriting
|
|
324
363
|
}) => startWriting(),
|
|
325
|
-
|
|
364
|
+
onCompleteAll
|
|
326
365
|
} = options;
|
|
327
366
|
const tmp = [];
|
|
367
|
+
const tasks = [];
|
|
328
368
|
const writer = writable.getWriter();
|
|
329
369
|
const encoder = new TextEncoder();
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
370
|
+
const registry = new Set();
|
|
371
|
+
const checkEnd = () => {
|
|
372
|
+
if (!registry.size && !completed) {
|
|
373
|
+
onCompleteAll && onCompleteAll(result);
|
|
374
|
+
writable && writable.close();
|
|
375
|
+
completed = true;
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
const writeInitialScript = () => {
|
|
379
|
+
if (tasks.length) {
|
|
380
|
+
buffer.write(encoder.encode(`<script${nonce ? ` nonce="${nonce}"` : ""}>${tasks.join(";")}</script>`));
|
|
381
|
+
tasks.length = 0;
|
|
382
|
+
}
|
|
383
|
+
scheduled = false;
|
|
384
|
+
};
|
|
385
|
+
let completed = false;
|
|
386
|
+
let scriptFlushed = false;
|
|
387
|
+
let scheduled = true;
|
|
388
|
+
let buffer = {
|
|
340
389
|
write(payload) {
|
|
341
390
|
tmp.push(payload);
|
|
342
391
|
}
|
|
@@ -351,28 +400,61 @@ function pipeToWritable(code, writable, options = {}) {
|
|
|
351
400
|
writer.write(encoder.encode(c));
|
|
352
401
|
},
|
|
353
402
|
abort() {
|
|
354
|
-
|
|
403
|
+
registry.clear();
|
|
355
404
|
checkEnd();
|
|
356
405
|
}
|
|
357
406
|
};
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
407
|
+
solidJs.sharedConfig.context = {
|
|
408
|
+
id: "",
|
|
409
|
+
count: 0,
|
|
410
|
+
async: true,
|
|
411
|
+
streaming: true,
|
|
412
|
+
resources: {},
|
|
413
|
+
suspense: {},
|
|
414
|
+
assets: [],
|
|
415
|
+
nonce,
|
|
416
|
+
writeResource(id, p) {
|
|
417
|
+
if (!scheduled) {
|
|
418
|
+
Promise.resolve().then(writeInitialScript);
|
|
419
|
+
scheduled = true;
|
|
420
|
+
}
|
|
421
|
+
tasks.push(`_$HY.init("${id}")`);
|
|
422
|
+
p.then(d => {
|
|
423
|
+
buffer.write(encoder.encode(`<script${nonce ? ` nonce="${nonce}"` : ""}>_$HY.set("${id}", ${devalue(d)})</script>`));
|
|
424
|
+
});
|
|
425
|
+
},
|
|
426
|
+
registerFragment(key) {
|
|
427
|
+
registry.add(key);
|
|
428
|
+
Promise.resolve().then(() => {
|
|
429
|
+
if (registry.has(key)) {
|
|
430
|
+
if (!scheduled) {
|
|
431
|
+
Promise.resolve().then(writeInitialScript);
|
|
432
|
+
scheduled = true;
|
|
433
|
+
}
|
|
434
|
+
tasks.push(`_$HY.init("${key}")`);
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
return value => {
|
|
438
|
+
registry.delete(key);
|
|
439
|
+
if (!value) return;
|
|
440
|
+
buffer.write(encoder.encode(`<div hidden id="${key}">${value}</div><script${nonce ? ` nonce="${nonce}"` : ""}>${!scriptFlushed ? REPLACE_SCRIPT : ""}$df("${key}")</script>`));
|
|
441
|
+
scriptFlushed = true;
|
|
442
|
+
checkEnd();
|
|
443
|
+
};
|
|
362
444
|
}
|
|
363
445
|
};
|
|
364
|
-
solidJs.sharedConfig.context.writeResource = (id, p) => {
|
|
365
|
-
count++;
|
|
366
|
-
Promise.resolve().then(() => buffer.write(encoder.encode(`<script${nonce ? ` nonce="${nonce}"` : ""}>_$HYDRATION.startResource("${id}")</script>`)));
|
|
367
|
-
p.then(d => {
|
|
368
|
-
buffer.write(encoder.encode(`<script${nonce ? ` nonce="${nonce}"` : ""}>_$HYDRATION.resolveResource("${id}", ${devalue(d)})</script>`));
|
|
369
|
-
++completed && checkEnd();
|
|
370
|
-
});
|
|
371
|
-
};
|
|
372
446
|
let html = resolveSSRNode(escape(code()));
|
|
373
447
|
html = injectAssets(solidJs.sharedConfig.context.assets, html);
|
|
374
|
-
|
|
375
|
-
|
|
448
|
+
Promise.resolve().then(() => {
|
|
449
|
+
if (tasks.length) html = injectScripts(html, tasks.join(";"), nonce);
|
|
450
|
+
buffer.write(encoder.encode(html));
|
|
451
|
+
tasks.length = 0;
|
|
452
|
+
scheduled = false;
|
|
453
|
+
onCompleteShell && onCompleteShell(result);
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
function pipeToNodeWritable(code, writable, options = {}) {
|
|
457
|
+
renderToPipeableStream(code, options).pipe(writable);
|
|
376
458
|
}
|
|
377
459
|
function Assets(props) {
|
|
378
460
|
solidJs.sharedConfig.context.assets.push(() => NoHydration({
|
|
@@ -382,15 +464,21 @@ function Assets(props) {
|
|
|
382
464
|
}));
|
|
383
465
|
return ssr(`%%$${solidJs.sharedConfig.context.assets.length - 1}%%`);
|
|
384
466
|
}
|
|
385
|
-
function HydrationScript() {
|
|
386
|
-
|
|
467
|
+
function HydrationScript(props) {
|
|
468
|
+
const {
|
|
469
|
+
nonce
|
|
470
|
+
} = solidJs.sharedConfig.context;
|
|
471
|
+
solidJs.sharedConfig.context.assets.push(() => generateHydrationScript({
|
|
472
|
+
nonce,
|
|
473
|
+
...props
|
|
474
|
+
}));
|
|
387
475
|
return ssr(`%%$${solidJs.sharedConfig.context.assets.length - 1}%%`);
|
|
388
476
|
}
|
|
389
477
|
function NoHydration(props) {
|
|
390
478
|
const c = solidJs.sharedConfig.context;
|
|
391
|
-
|
|
479
|
+
c.noHydrate = true;
|
|
392
480
|
const children = props.children;
|
|
393
|
-
|
|
481
|
+
c.noHydrate = false;
|
|
394
482
|
return children;
|
|
395
483
|
}
|
|
396
484
|
function ssr(t, ...nodes) {
|
|
@@ -518,26 +606,13 @@ function resolveSSRNode(node) {
|
|
|
518
606
|
}
|
|
519
607
|
function getHydrationKey() {
|
|
520
608
|
const hydrate = solidJs.sharedConfig.context;
|
|
521
|
-
return hydrate && `${hydrate.id}${hydrate.count++}`;
|
|
609
|
+
return hydrate && !hydrate.noHydrate && `${hydrate.id}${hydrate.count++}`;
|
|
522
610
|
}
|
|
523
|
-
function generateHydrationScript(
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
eventNames = ["click", "input"]
|
|
529
|
-
} = solidJs.sharedConfig.context;
|
|
530
|
-
let s = `<script${nonce ? ` nonce="${nonce}"` : ""}>(()=>{_$HYDRATION={events:[],completed:new WeakSet};const t=e=>e&&e.hasAttribute&&(e.hasAttribute("data-hk")?e:t(e.host&&e.host instanceof Node?e.host:e.parentNode)),e=e=>{let o=e.composedPath&&e.composedPath()[0]||e.target,s=t(o);s&&!_$HYDRATION.completed.has(s)&&_$HYDRATION.events.push([s,e])};["${eventNames.join('","')}"].forEach(t=>document.addEventListener(t,e))})();`;
|
|
531
|
-
if (streaming) {
|
|
532
|
-
s += `(()=>{const e=_$HYDRATION,o={};e.startResource=e=>{let r;o[e]=[new Promise(e=>r=e),r]},e.resolveResource=(e,r)=>{const n=o[e];if(!n)return o[e]=[r];n[1](r)},e.loadResource=e=>{const r=o[e];if(r)return r[0]}})();`;
|
|
533
|
-
}
|
|
534
|
-
if (resources) {
|
|
535
|
-
s += `_$HYDRATION.resources = ${devalue(Object.keys(resources).reduce((r, k) => {
|
|
536
|
-
r[k] = resources[k].data;
|
|
537
|
-
return r;
|
|
538
|
-
}, {}))};`;
|
|
539
|
-
}
|
|
540
|
-
return s + `</script>`;
|
|
611
|
+
function generateHydrationScript({
|
|
612
|
+
eventNames = ["click", "input"],
|
|
613
|
+
nonce
|
|
614
|
+
}) {
|
|
615
|
+
return `<script${nonce ? ` nonce="${nonce}"` : ""}>((e,t,o={})=>{t=e=>e&&e.hasAttribute&&(e.hasAttribute("data-hk")?e:t(e.host&&e.host instanceof Node?e.host:e.parentNode)),["${eventNames.join('","')}"].forEach((o=>document.addEventListener(o,(o=>{let n=o.composedPath&&o.composedPath()[0]||o.target,s=t(n);s&&!e.completed.has(s)&&e.events.push([s,o])})))),e.init=(e,t)=>{o[e]=[new Promise((e=>t=e)),t]},e.set=(e,t,n)=>{if(!(n=o[e]))return o[e]=[t];n[1](t)},e.load=(e,t)=>{if(t=o[e])return t[0]}})(window._$HY||(_$HY={events:[],completed:new WeakSet}));</script><!xs>`;
|
|
541
616
|
}
|
|
542
617
|
function injectAssets(assets, html) {
|
|
543
618
|
for (let i = 0; i < assets.length; i++) {
|
|
@@ -545,6 +620,41 @@ function injectAssets(assets, html) {
|
|
|
545
620
|
}
|
|
546
621
|
return html;
|
|
547
622
|
}
|
|
623
|
+
function injectScripts(html, scripts, nonce) {
|
|
624
|
+
const tag = `<script${nonce ? ` nonce="${nonce}"` : ""}>${scripts}</script>`;
|
|
625
|
+
const index = html.indexOf("<!xs>");
|
|
626
|
+
if (index > -1) {
|
|
627
|
+
return html.slice(0, index) + tag + html.slice(index);
|
|
628
|
+
}
|
|
629
|
+
return html + tag;
|
|
630
|
+
}
|
|
631
|
+
const FRAGMENT_REPLACE = /<!\[([\d.]+)\]>/;
|
|
632
|
+
function asyncWrap(fn) {
|
|
633
|
+
return new Promise(resolve => {
|
|
634
|
+
const registry = new Set();
|
|
635
|
+
const cache = Object.create(null);
|
|
636
|
+
solidJs.sharedConfig.context.registerFragment = register;
|
|
637
|
+
const rendered = fn();
|
|
638
|
+
if (!registry.size) resolve(rendered);
|
|
639
|
+
function register(key) {
|
|
640
|
+
registry.add(key);
|
|
641
|
+
return value => {
|
|
642
|
+
if (value) cache[key] = value;
|
|
643
|
+
registry.delete(key);
|
|
644
|
+
if (!registry.size) Promise.resolve().then(() => {
|
|
645
|
+
let source = resolveSSRNode(rendered);
|
|
646
|
+
let final = "";
|
|
647
|
+
let match;
|
|
648
|
+
while (match = source.match(FRAGMENT_REPLACE)) {
|
|
649
|
+
final += source.substring(0, match.index);
|
|
650
|
+
source = cache[match[1]] + source.substring(match.index + match[0].length);
|
|
651
|
+
}
|
|
652
|
+
resolve(final + source);
|
|
653
|
+
});
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
});
|
|
657
|
+
}
|
|
548
658
|
|
|
549
659
|
const isServer = true;
|
|
550
660
|
function spread() {}
|
|
@@ -634,6 +744,7 @@ exports.getHydrationKey = getHydrationKey;
|
|
|
634
744
|
exports.isServer = isServer;
|
|
635
745
|
exports.pipeToNodeWritable = pipeToNodeWritable;
|
|
636
746
|
exports.pipeToWritable = pipeToWritable;
|
|
747
|
+
exports.renderToPipeableStream = renderToPipeableStream;
|
|
637
748
|
exports.renderToString = renderToString;
|
|
638
749
|
exports.renderToStringAsync = renderToStringAsync;
|
|
639
750
|
exports.resolveSSRNode = resolveSSRNode;
|