@solidjs/start 0.4.9 → 0.4.10

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.
@@ -22,6 +22,13 @@ import {
22
22
  } from "vinxi/server";
23
23
  import { getFetchEvent } from "../server/middleware";
24
24
 
25
+ function createChunk(data) {
26
+ const bytes = data.length;
27
+ const baseHex = bytes.toString(16);
28
+ const totalHex = '00000000'.substring(0, 8 - baseHex.length) + baseHex; // 32-bit
29
+ return new TextEncoder().encode(`;0x${totalHex};${data}`);
30
+ }
31
+
25
32
  function serializeToStream(id, value) {
26
33
  return new ReadableStream({
27
34
  start(controller) {
@@ -40,15 +47,12 @@ function serializeToStream(id, value) {
40
47
  URLPlugin
41
48
  ],
42
49
  onSerialize(data, initial) {
43
- const result = initial ? `(${getCrossReferenceHeader(id)},${data})` : data;
44
- controller.enqueue(new TextEncoder().encode(`${result};\n`));
50
+ controller.enqueue(createChunk(initial ? `(${getCrossReferenceHeader(id)},${data})` : data));
45
51
  },
46
52
  onDone() {
47
- // controller.enqueue(`delete $R["${id}"];\n`);
48
53
  controller.close();
49
54
  },
50
55
  onError(error) {
51
- // controller.enqueue(`delete $R["${id}"];\n`);
52
56
  controller.error(error);
53
57
  }
54
58
  });
@@ -13,7 +13,7 @@ import {
13
13
  } from 'seroval-plugins/web';
14
14
  import { createIslandReference } from "../server/islands";
15
15
 
16
- class ChunkReader {
16
+ class SerovalChunkReader {
17
17
  constructor(stream) {
18
18
  this.reader = stream.getReader();
19
19
  this.buffer = '';
@@ -31,10 +31,10 @@ class ChunkReader {
31
31
  }
32
32
  }
33
33
 
34
- async nextValue() {
34
+ async next() {
35
35
  // Check if the buffer is empty
36
36
  if (this.buffer === '') {
37
- // if we are already one...
37
+ // if we are already done...
38
38
  if (this.done) {
39
39
  return {
40
40
  done: true,
@@ -43,38 +43,32 @@ class ChunkReader {
43
43
  }
44
44
  // Otherwise, read a new chunk
45
45
  await this.readChunk();
46
+ return await this.next();
46
47
  }
47
- // Get the first valid seroval chunk
48
- const [first, ...rest] = this.buffer.split('\n');
49
- // Deserialize the seroval chunk
50
- const result = {
51
- done: false,
52
- value: deserialize(first),
53
- };
54
- // if it succeeds, remove the first valid chunk
55
- // from the buffer
56
- this.buffer = rest.join('\n');
57
- return result;
58
- }
59
-
60
- async next() {
61
- try {
62
- // Attempt to read a valid seroval chunk
63
- return await this.nextValue();
64
- } catch (error) {
65
- // If it happens that there's an error again
66
- // and we are done reading the buffer
67
- // then the whole stream is invalid.
48
+ // Read the "byte header"
49
+ // The byte header tells us how big the expected data is
50
+ // so we know how much data we should wait before we
51
+ // deserialize the data
52
+ const bytes = Number.parseInt(this.buffer.substring(1, 11), 16); // ;0x00000000;
53
+ // Check if the buffer has enough bytes to be parsed
54
+ while (bytes > this.buffer.length - 12) {
55
+ // If it's not enough, and the reader is done
56
+ // then the chunk is invalid.
68
57
  if (this.done) {
69
- throw new Error('Malformed server function stream.');
58
+ throw new Error('Malformed server function stream.')
70
59
  }
71
- // Since it's invalid (some syntax-related issue)
72
- // we read a new chunk, and hope there's a valid
73
- // seroval chunk there
60
+ // Otherwise, we read more chunks
74
61
  await this.readChunk();
75
- // Retry again
76
- return await this.next();
77
62
  }
63
+ // Extract the exact chunk as defined by the byte header
64
+ const partial = this.buffer.substring(12, 12 + bytes);
65
+ // The rest goes to the buffer
66
+ this.buffer = this.buffer.substring(12 + bytes);
67
+ // Deserialize the chunk
68
+ return {
69
+ done: false,
70
+ value: deserialize(partial),
71
+ };
78
72
  }
79
73
 
80
74
  async drain() {
@@ -91,7 +85,7 @@ async function deserializeStream(id, response) {
91
85
  if (!response.body) {
92
86
  throw new Error("missing body");
93
87
  }
94
- const reader = new ChunkReader(response.body);
88
+ const reader = new SerovalChunkReader(response.body);
95
89
 
96
90
  const result = await reader.next();
97
91
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidjs/start",
3
- "version": "0.4.9",
3
+ "version": "0.4.10",
4
4
  "type": "module",
5
5
  "author": "Ryan Carniato",
6
6
  "publishConfig": {
@@ -44,12 +44,12 @@
44
44
  },
45
45
  "devDependencies": {
46
46
  "solid-js": "^1.8.11",
47
- "vinxi": "^0.1.2"
47
+ "vinxi": "^0.1.4"
48
48
  },
49
49
  "dependencies": {
50
- "@vinxi/plugin-directives": "^0.1.0",
51
- "@vinxi/server-components": "^0.1.0",
52
- "@vinxi/server-functions": "^0.1.0",
50
+ "@vinxi/plugin-directives": "^0.1.2",
51
+ "@vinxi/server-components": "^0.1.2",
52
+ "@vinxi/server-functions": "^0.1.2",
53
53
  "defu": "^6.1.2",
54
54
  "error-stack-parser": "^2.1.4",
55
55
  "html-to-image": "^1.11.11",
@@ -1,8 +1,6 @@
1
1
  import {
2
2
  defineMiddleware,
3
- EventHandlerRequest,
4
3
  getRequestIP,
5
- getRequestURL,
6
4
  H3Event,
7
5
  sendWebResponse,
8
6
  toWebRequest
@@ -18,15 +16,11 @@ const eventTraps = {
18
16
  }
19
17
  };
20
18
 
21
- export function createFetchEvent(event: H3Event<EventHandlerRequest>): FetchEvent {
22
- event.web ||
23
- (event.web = {
24
- url: getRequestURL(event),
25
- request: toWebRequest(event)
26
- });
19
+ export function createFetchEvent(event: H3Event): FetchEvent {
20
+ const request = toWebRequest(event);
27
21
  return new Proxy(
28
22
  {
29
- request: event.web.request,
23
+ request: request,
30
24
  clientAddress: getRequestIP(event),
31
25
  locals: {},
32
26
  // @ts-ignore
@@ -1,8 +1,9 @@
1
1
  import type { BuiltinLanguage, Highlighter } from 'shikiji';
2
- import { getHighlighterCore } from 'shikiji/core';
3
- import { getWasmInlined } from 'shikiji/wasm';
2
+ import { getHighlighterCore, loadWasm } from 'shikiji/core';
4
3
  import { createEffect, createResource, type JSX } from 'solid-js';
5
4
 
5
+ import url from 'shikiji/onig.wasm?url';
6
+
6
7
  import langJS from 'shikiji/langs/javascript.mjs';
7
8
  import langJSX from 'shikiji/langs/jsx.mjs';
8
9
  import langTSX from 'shikiji/langs/tsx.mjs';
@@ -13,6 +14,7 @@ let HIGHLIGHTER: Highlighter;
13
14
 
14
15
  async function loadHighlighter() {
15
16
  if (!HIGHLIGHTER) {
17
+ await loadWasm(await fetch(url))
16
18
  HIGHLIGHTER = await getHighlighterCore({
17
19
  themes: [
18
20
  darkPlus,
@@ -23,7 +25,6 @@ async function loadHighlighter() {
23
25
  langTS,
24
26
  langTSX,
25
27
  ],
26
- loadWasm: getWasmInlined,
27
28
  });
28
29
  }
29
30
  return HIGHLIGHTER;
@@ -77,7 +78,7 @@ export function CodeView(props: CodeViewProps): JSX.Element | null {
77
78
  for (let i = 0, len = lines.length; i < len; i++) {
78
79
  const el = lines[i];
79
80
  if ((props.line - minLine() - 1) === i) {
80
- el.innerHTML = `<mark style="background-color:#aaaaaa80">${el.innerHTML}</mark>`;
81
+ el.classList.add('dev-overlay-error-line');
81
82
  }
82
83
  }
83
84
  }
@@ -281,4 +281,8 @@
281
281
  display: inline-block;
282
282
  text-align: right;
283
283
  color: rgba(115, 138, 148, .4)
284
+ }
285
+
286
+ .dev-overlay-error-line {
287
+ background-color: rgba(239, 68, 68, .4);
284
288
  }
@@ -1,60 +1,54 @@
1
1
  /// <reference types="vinxi/types/client" />
2
2
  import { createComponent, lazy, onCleanup } from "solid-js";
3
- import { appendStyles, cleanupStyles, updateStyles } from "vinxi/css";
3
+ import { appendStyles, cleanupStyles, updateStyles, preloadStyles } from "vinxi/css";
4
4
 
5
5
  import { renderAsset } from "../server/renderAsset";
6
6
 
7
- export default function lazyRoute(
8
- component,
9
- clientManifest,
10
- serverManifest,
11
- exported = "default",
12
- ) {
13
- return lazy(async () => {
14
- if (import.meta.env.DEV) {
15
- let manifest = import.meta.env.SSR ? serverManifest : clientManifest;
7
+ export default function lazyRoute(component, clientManifest, serverManifest, exported = "default") {
8
+ return lazy(async () => {
9
+ if (import.meta.env.DEV) {
10
+ let manifest = import.meta.env.SSR ? serverManifest : clientManifest;
16
11
 
17
- const mod = await manifest.inputs[component.src].import();
18
- if (!mod[exported]) console.error(`Module ${component.src} does not export ${exported}`)
19
- const Component = mod[exported];
20
- let assets = await clientManifest.inputs?.[component.src].assets();
21
- const styles = assets.filter((asset) => asset.tag === "style");
12
+ const mod = await manifest.inputs[component.src].import();
13
+ if (!mod[exported]) console.error(`Module ${component.src} does not export ${exported}`);
14
+ const Component = mod[exported];
15
+ let assets = await clientManifest.inputs?.[component.src].assets();
16
+ const styles = assets.filter(asset => asset.tag === "style");
22
17
 
23
- if (typeof window !== "undefined" && import.meta.hot) {
24
- import.meta.hot.on("css-update", (data) => {
25
- updateStyles(styles, data);
26
- });
27
- }
18
+ if (typeof window !== "undefined" && import.meta.hot) {
19
+ import.meta.hot.on("css-update", data => {
20
+ updateStyles(styles, data);
21
+ });
22
+ }
28
23
 
29
- const Comp = (props) => {
30
- if (typeof window !== "undefined") {
31
- appendStyles(styles);
32
- }
24
+ const Comp = props => {
25
+ if (typeof window !== "undefined") {
26
+ appendStyles(styles);
27
+ }
33
28
 
34
- onCleanup(() => {
35
- if (typeof window !== "undefined") {
36
- // remove style tags added by vite when a CSS file is imported
37
- cleanupStyles(styles);
38
- }
39
- });
40
- return [
41
- ...assets.map((asset) => renderAsset(asset)),
42
- createComponent(Component, props),
43
- ];
44
- };
45
- return { default: Comp };
46
- } else {
47
- const mod = await component.import();
48
- const Component = mod[exported];
49
- let assets = await clientManifest.inputs?.[component.src].assets();
50
- const styles = assets.filter((asset) => asset.tag === "style" || asset.attrs.rel === "stylesheet");
51
- const Comp = (props) => {
52
- return [
53
- ...styles.map((asset) => renderAsset(asset)),
54
- createComponent(Component, props),
55
- ];
56
- };
57
- return { default: Comp };
58
- }
59
- });
29
+ onCleanup(() => {
30
+ if (typeof window !== "undefined") {
31
+ // remove style tags added by vite when a CSS file is imported
32
+ cleanupStyles(styles);
33
+ }
34
+ });
35
+ return [...assets.map(asset => renderAsset(asset)), createComponent(Component, props)];
36
+ };
37
+ return { default: Comp };
38
+ } else {
39
+ const mod = await component.import();
40
+ const Component = mod[exported];
41
+ let assets = await clientManifest.inputs?.[component.src].assets();
42
+ const styles = assets.filter(
43
+ asset => asset.tag === "style" || asset.attrs.rel === "stylesheet"
44
+ );
45
+ if (typeof window !== "undefined") {
46
+ preloadStyles(styles);
47
+ }
48
+ const Comp = props => {
49
+ return [...styles.map(asset => renderAsset(asset)), createComponent(Component, props)];
50
+ };
51
+ return { default: Comp };
52
+ }
53
+ });
60
54
  }