@solidjs/start 0.4.8 → 0.4.9

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.
@@ -13,54 +13,100 @@ import {
13
13
  } from 'seroval-plugins/web';
14
14
  import { createIslandReference } from "../server/islands";
15
15
 
16
- async function deserializeStream(id, response) {
17
- if (!response.body) {
18
- throw new Error("missing body");
16
+ class ChunkReader {
17
+ constructor(stream) {
18
+ this.reader = stream.getReader();
19
+ this.buffer = '';
20
+ this.done = false;
19
21
  }
20
- const reader = response.body.getReader();
21
-
22
- async function pop() {
23
- const result = await reader.read();
24
- if (!result.done) {
25
- const serialized = new TextDecoder().decode(result.value);
26
- const splits = serialized.split("\n");
27
- for (const split of splits) {
28
- if (split !== "") {
29
- deserialize(split);
30
- }
31
- }
32
- await pop();
22
+
23
+ async readChunk() {
24
+ // if there's no chunk, read again
25
+ const chunk = await this.reader.read();
26
+ if (!chunk.done) {
27
+ // repopulate the buffer
28
+ this.buffer += new TextDecoder().decode(chunk.value);
29
+ } else {
30
+ this.done = true;
33
31
  }
34
32
  }
35
33
 
36
- const result = await reader.read();
37
- if (result.done) {
38
- throw new Error("Unexpected end of body");
34
+ async nextValue() {
35
+ // Check if the buffer is empty
36
+ if (this.buffer === '') {
37
+ // if we are already one...
38
+ if (this.done) {
39
+ return {
40
+ done: true,
41
+ value: undefined,
42
+ };
43
+ }
44
+ // Otherwise, read a new chunk
45
+ await this.readChunk();
46
+ }
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;
39
58
  }
40
- const serialized = new TextDecoder().decode(result.value);
41
- let pending = true;
42
- let revived;
43
- const splits = serialized.split("\n");
44
- for (const split of splits) {
45
- if (split !== "") {
46
- const current = deserialize(split);
47
- if (pending) {
48
- revived = current;
49
- pending = false;
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.
68
+ if (this.done) {
69
+ throw new Error('Malformed server function stream.');
50
70
  }
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
74
+ await this.readChunk();
75
+ // Retry again
76
+ return await this.next();
51
77
  }
52
78
  }
53
79
 
54
- pop().then(
55
- () => {
56
- delete $R[id];
57
- },
58
- () => {
59
- // no-op
80
+ async drain() {
81
+ while (true) {
82
+ const result = await this.next();
83
+ if (result.done) {
84
+ break;
85
+ }
60
86
  }
61
- );
87
+ }
88
+ }
89
+
90
+ async function deserializeStream(id, response) {
91
+ if (!response.body) {
92
+ throw new Error("missing body");
93
+ }
94
+ const reader = new ChunkReader(response.body);
95
+
96
+ const result = await reader.next();
97
+
98
+ if (!result.done) {
99
+ reader.drain().then(
100
+ () => {
101
+ delete $R[id];
102
+ },
103
+ () => {
104
+ // no-op
105
+ }
106
+ );
107
+ }
62
108
 
63
- return revived;
109
+ return result.value;
64
110
  }
65
111
 
66
112
  let INSTANCE = 0;
@@ -108,7 +154,7 @@ async function fetchServerFunction(base, id, args) {
108
154
  let result;
109
155
  if (contentType && contentType.startsWith("text/plain")) {
110
156
  result = await response.text();
111
- } else if(contentType && contentType.startsWith("application/json")) {
157
+ } else if (contentType && contentType.startsWith("application/json")) {
112
158
  result = await response.json();
113
159
  } else {
114
160
  result = deserializeStream(instance, response);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidjs/start",
3
- "version": "0.4.8",
3
+ "version": "0.4.9",
4
4
  "type": "module",
5
5
  "author": "Ryan Carniato",
6
6
  "publishConfig": {
@@ -43,8 +43,8 @@
43
43
  }
44
44
  },
45
45
  "devDependencies": {
46
- "solid-js": "^1.8.10",
47
- "vinxi": "0.1.1"
46
+ "solid-js": "^1.8.11",
47
+ "vinxi": "^0.1.2"
48
48
  },
49
49
  "dependencies": {
50
50
  "@vinxi/plugin-directives": "^0.1.0",