solid-js 1.5.0-beta.1 → 1.5.0-beta.4

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.
Files changed (41) hide show
  1. package/dist/dev.cjs +161 -145
  2. package/dist/dev.js +161 -145
  3. package/dist/server.cjs +76 -42
  4. package/dist/server.js +76 -42
  5. package/dist/solid.cjs +161 -145
  6. package/dist/solid.js +161 -145
  7. package/h/jsx-runtime/types/jsx.d.ts +3 -1
  8. package/package.json +81 -21
  9. package/store/types/index.d.ts +4 -4
  10. package/store/types/mutable.d.ts +1 -1
  11. package/store/types/server.d.ts +1 -1
  12. package/store/types/store.d.ts +2 -2
  13. package/types/index.d.ts +8 -8
  14. package/types/jsx.d.ts +4 -2
  15. package/types/reactive/array.d.ts +1 -1
  16. package/types/reactive/observable.d.ts +1 -1
  17. package/types/reactive/signal.d.ts +51 -36
  18. package/types/render/Suspense.d.ts +1 -1
  19. package/types/render/component.d.ts +1 -1
  20. package/types/render/flow.d.ts +20 -3
  21. package/types/render/index.d.ts +4 -4
  22. package/types/server/index.d.ts +3 -3
  23. package/types/server/reactive.d.ts +6 -3
  24. package/types/server/rendering.d.ts +16 -7
  25. package/universal/dist/dev.cjs +4 -1
  26. package/universal/dist/dev.js +5 -2
  27. package/universal/dist/universal.cjs +4 -1
  28. package/universal/dist/universal.js +5 -2
  29. package/universal/types/index.d.ts +1 -1
  30. package/web/dist/dev.cjs +13 -7
  31. package/web/dist/dev.js +8 -6
  32. package/web/dist/server.cjs +324 -246
  33. package/web/dist/server.js +322 -247
  34. package/web/dist/web.cjs +13 -7
  35. package/web/dist/web.js +8 -6
  36. package/web/types/client.d.ts +4 -1
  37. package/web/types/core.d.ts +2 -2
  38. package/web/types/index.d.ts +3 -3
  39. package/web/types/jsx.d.ts +1 -1
  40. package/web/types/server-mock.d.ts +4 -1
  41. package/web/types/server.d.ts +2 -0
@@ -10,227 +10,257 @@ const Aliases = {
10
10
  htmlFor: "for"
11
11
  };
12
12
 
13
- var chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$';
14
- var unsafeChars = /[<>\b\f\n\r\t\0\u2028\u2029]/g;
15
- var reserved = /^(?:do|if|in|for|int|let|new|try|var|byte|case|char|else|enum|goto|long|this|void|with|await|break|catch|class|const|final|float|short|super|throw|while|yield|delete|double|export|import|native|return|switch|throws|typeof|boolean|default|extends|finally|package|private|abstract|continue|debugger|function|volatile|interface|protected|transient|implements|instanceof|synchronized)$/;
16
- var escaped = {
17
- '<': '\\u003C',
18
- '>': '\\u003E',
19
- '/': '\\u002F',
20
- '\\': '\\\\',
21
- '\b': '\\b',
22
- '\f': '\\f',
23
- '\n': '\\n',
24
- '\r': '\\r',
25
- '\t': '\\t',
26
- '\0': '\\0',
27
- '\u2028': '\\u2028',
28
- '\u2029': '\\u2029'
29
- };
30
- var objectProtoOwnPropertyNames = Object.getOwnPropertyNames(Object.prototype).sort().join('\0');
31
- function devalue(value) {
32
- var counts = new Map();
33
- function walk(thing) {
34
- if (typeof thing === 'function') {
35
- throw new Error("Cannot stringify a function");
13
+ const {
14
+ hasOwnProperty
15
+ } = Object.prototype;
16
+ const REF_START_CHARS = "hjkmoquxzABCDEFGHIJKLNPQRTUVWXYZ$_";
17
+ const REF_START_CHARS_LEN = REF_START_CHARS.length;
18
+ const REF_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$_";
19
+ const REF_CHARS_LEN = REF_CHARS.length;
20
+ const STACK = [];
21
+ const BUFFER = [""];
22
+ let ASSIGNMENTS = new Map();
23
+ let INDEX_OR_REF = new WeakMap();
24
+ let REF_COUNT = 0;
25
+ BUFFER.pop();
26
+ function stringify(root) {
27
+ if (writeProp(root, "")) {
28
+ let result = BUFFER[0];
29
+ for (let i = 1, len = BUFFER.length; i < len; i++) {
30
+ result += BUFFER[i];
36
31
  }
37
- if (counts.has(thing)) {
38
- counts.set(thing, counts.get(thing) + 1);
39
- return;
32
+ if (REF_COUNT) {
33
+ if (ASSIGNMENTS.size) {
34
+ let ref = INDEX_OR_REF.get(root);
35
+ if (typeof ref === "number") {
36
+ ref = toRefParam(REF_COUNT++);
37
+ result = ref + "=" + result;
38
+ }
39
+ for (const [assignmentRef, assignments] of ASSIGNMENTS) {
40
+ result += ";" + assignments + assignmentRef;
41
+ }
42
+ result += ";return " + ref;
43
+ ASSIGNMENTS = new Map();
44
+ } else {
45
+ result = "return " + result;
46
+ }
47
+ result = "(function(" + refParamsString() + "){" + result + "}())";
48
+ } else if (root && root.constructor === Object) {
49
+ result = "(" + result + ")";
40
50
  }
41
- counts.set(thing, 1);
42
- if (!isPrimitive(thing)) {
43
- var type = getType(thing);
44
- switch (type) {
45
- case 'Number':
46
- case 'String':
47
- case 'Boolean':
48
- case 'Date':
49
- case 'RegExp':
50
- return;
51
- case 'Array':
52
- thing.forEach(walk);
53
- break;
54
- case 'Set':
55
- case 'Map':
56
- Array.from(thing).forEach(walk);
57
- break;
58
- default:
59
- var proto = Object.getPrototypeOf(thing);
60
- if (proto !== Object.prototype && proto !== null && Object.getOwnPropertyNames(proto).sort().join('\0') !== objectProtoOwnPropertyNames) {
61
- throw new Error("Cannot stringify arbitrary non-POJOs");
62
- }
63
- if (Object.getOwnPropertySymbols(thing).length > 0) {
64
- throw new Error("Cannot stringify POJOs with symbolic keys");
65
- }
66
- Object.keys(thing).forEach(function (key) {
67
- return walk(thing[key]);
68
- });
51
+ BUFFER.length = 0;
52
+ INDEX_OR_REF = new WeakMap();
53
+ return result;
54
+ }
55
+ return "void 0";
56
+ }
57
+ function writeProp(cur, accessor) {
58
+ switch (typeof cur) {
59
+ case "string":
60
+ BUFFER.push(quote(cur, 0));
61
+ break;
62
+ case "number":
63
+ BUFFER.push(cur + "");
64
+ break;
65
+ case "boolean":
66
+ BUFFER.push(cur ? "!0" : "!1");
67
+ break;
68
+ case "object":
69
+ if (cur === null) {
70
+ BUFFER.push("null");
71
+ } else {
72
+ const ref = getRef(cur, accessor);
73
+ switch (ref) {
74
+ case true:
75
+ return false;
76
+ case false:
77
+ switch (cur.constructor) {
78
+ case Object:
79
+ writeObject(cur);
80
+ break;
81
+ case Array:
82
+ writeArray(cur);
83
+ break;
84
+ case Date:
85
+ BUFFER.push('new Date("' + cur.toISOString() + '")');
86
+ break;
87
+ case RegExp:
88
+ BUFFER.push(cur + "");
89
+ break;
90
+ case Map:
91
+ BUFFER.push("new Map(");
92
+ writeArray(Array.from(cur));
93
+ BUFFER.push(")");
94
+ break;
95
+ case Set:
96
+ BUFFER.push("new Set(");
97
+ writeArray(Array.from(cur));
98
+ BUFFER.push(")");
99
+ break;
100
+ case undefined:
101
+ BUFFER.push("Object.assign(Object.create(null),");
102
+ writeObject(cur);
103
+ BUFFER.push("))");
104
+ break;
105
+ default:
106
+ return false;
107
+ }
108
+ break;
109
+ default:
110
+ BUFFER.push(ref);
111
+ break;
112
+ }
113
+ }
114
+ break;
115
+ default:
116
+ return false;
117
+ }
118
+ return true;
119
+ }
120
+ function writeObject(obj) {
121
+ let sep = "{";
122
+ STACK.push(obj);
123
+ for (const key in obj) {
124
+ if (hasOwnProperty.call(obj, key)) {
125
+ const val = obj[key];
126
+ const escapedKey = toObjectKey(key);
127
+ BUFFER.push(sep + escapedKey + ":");
128
+ if (writeProp(val, escapedKey)) {
129
+ sep = ",";
130
+ } else {
131
+ BUFFER.pop();
69
132
  }
70
133
  }
71
134
  }
72
- walk(value);
73
- var names = new Map();
74
- Array.from(counts).filter(function (entry) {
75
- return entry[1] > 1;
76
- }).sort(function (a, b) {
77
- return b[1] - a[1];
78
- }).forEach(function (entry, i) {
79
- names.set(entry[0], getName(i));
80
- });
81
- function stringify(thing) {
82
- if (names.has(thing)) {
83
- return names.get(thing);
135
+ if (sep === "{") {
136
+ BUFFER.push("{}");
137
+ } else {
138
+ BUFFER.push("}");
139
+ }
140
+ STACK.pop();
141
+ }
142
+ function writeArray(arr) {
143
+ BUFFER.push("[");
144
+ STACK.push(arr);
145
+ writeProp(arr[0], 0);
146
+ for (let i = 1, len = arr.length; i < len; i++) {
147
+ BUFFER.push(",");
148
+ writeProp(arr[i], i);
149
+ }
150
+ STACK.pop();
151
+ BUFFER.push("]");
152
+ }
153
+ function getRef(cur, accessor) {
154
+ let ref = INDEX_OR_REF.get(cur);
155
+ if (ref === undefined) {
156
+ INDEX_OR_REF.set(cur, BUFFER.length);
157
+ return false;
158
+ }
159
+ if (typeof ref === "number") {
160
+ ref = insertAndGetRef(cur, ref);
161
+ }
162
+ if (STACK.includes(cur)) {
163
+ const parent = STACK[STACK.length - 1];
164
+ let parentRef = INDEX_OR_REF.get(parent);
165
+ if (typeof parentRef === "number") {
166
+ parentRef = insertAndGetRef(parent, parentRef);
84
167
  }
85
- if (isPrimitive(thing)) {
86
- return stringifyPrimitive(thing);
168
+ ASSIGNMENTS.set(ref, (ASSIGNMENTS.get(ref) || "") + toAssignment(parentRef, accessor) + "=");
169
+ return true;
170
+ }
171
+ return ref;
172
+ }
173
+ function toObjectKey(name) {
174
+ const invalidIdentifierPos = getInvalidIdentifierPos(name);
175
+ return invalidIdentifierPos === -1 ? name : quote(name, invalidIdentifierPos);
176
+ }
177
+ function toAssignment(parent, key) {
178
+ return parent + (typeof key === "number" || key[0] === '"' ? "[" + key + "]" : "." + key);
179
+ }
180
+ function getInvalidIdentifierPos(name) {
181
+ let char = name[0];
182
+ if (!(char >= "a" && char <= "z" || char >= "A" && char <= "Z" || char === "$" || char === "_")) {
183
+ return 0;
184
+ }
185
+ for (let i = 1, len = name.length; i < len; i++) {
186
+ char = name[i];
187
+ if (!(char >= "a" && char <= "z" || char >= "A" && char <= "Z" || char >= "0" && char <= "9" || char === "$" || char === "_")) {
188
+ return i;
87
189
  }
88
- var type = getType(thing);
89
- switch (type) {
90
- case 'Number':
91
- case 'String':
92
- case 'Boolean':
93
- return "Object(" + stringify(thing.valueOf()) + ")";
94
- case 'RegExp':
95
- return "new RegExp(" + stringifyString(thing.source) + ", \"" + thing.flags + "\")";
96
- case 'Date':
97
- return "new Date(" + thing.getTime() + ")";
98
- case 'Array':
99
- var members = thing.map(function (v, i) {
100
- return i in thing ? stringify(v) : '';
101
- });
102
- var tail = thing.length === 0 || thing.length - 1 in thing ? '' : ',';
103
- return "[" + members.join(',') + tail + "]";
104
- case 'Set':
105
- case 'Map':
106
- return "new " + type + "([" + Array.from(thing).map(stringify).join(',') + "])";
190
+ }
191
+ return -1;
192
+ }
193
+ function quote(str, startPos) {
194
+ let result = "";
195
+ let lastPos = 0;
196
+ for (let i = startPos, len = str.length; i < len; i++) {
197
+ let replacement;
198
+ switch (str[i]) {
199
+ case '"':
200
+ replacement = '\\"';
201
+ break;
202
+ case "\\":
203
+ replacement = "\\\\";
204
+ break;
205
+ case "<":
206
+ replacement = "\\x3C";
207
+ break;
208
+ case "\n":
209
+ replacement = "\\n";
210
+ break;
211
+ case "\r":
212
+ replacement = "\\r";
213
+ break;
214
+ case "\u2028":
215
+ replacement = "\\u2028";
216
+ break;
217
+ case "\u2029":
218
+ replacement = "\\u2029";
219
+ break;
107
220
  default:
108
- var obj = "{" + Object.keys(thing).map(function (key) {
109
- return safeKey(key) + ":" + stringify(thing[key]);
110
- }).join(',') + "}";
111
- var proto = Object.getPrototypeOf(thing);
112
- if (proto === null) {
113
- return Object.keys(thing).length > 0 ? "Object.assign(Object.create(null)," + obj + ")" : "Object.create(null)";
114
- }
115
- return obj;
221
+ continue;
116
222
  }
223
+ result += str.slice(lastPos, i) + replacement;
224
+ lastPos = i + 1;
117
225
  }
118
- var str = stringify(value);
119
- if (names.size) {
120
- var params_1 = [];
121
- var statements_1 = [];
122
- var values_1 = [];
123
- names.forEach(function (name, thing) {
124
- params_1.push(name);
125
- if (isPrimitive(thing)) {
126
- values_1.push(stringifyPrimitive(thing));
127
- return;
128
- }
129
- var type = getType(thing);
130
- switch (type) {
131
- case 'Number':
132
- case 'String':
133
- case 'Boolean':
134
- values_1.push("Object(" + stringify(thing.valueOf()) + ")");
135
- break;
136
- case 'RegExp':
137
- values_1.push(thing.toString());
138
- break;
139
- case 'Date':
140
- values_1.push("new Date(" + thing.getTime() + ")");
141
- break;
142
- case 'Array':
143
- values_1.push("Array(" + thing.length + ")");
144
- thing.forEach(function (v, i) {
145
- statements_1.push(name + "[" + i + "]=" + stringify(v));
146
- });
147
- break;
148
- case 'Set':
149
- values_1.push("new Set");
150
- statements_1.push(name + "." + Array.from(thing).map(function (v) {
151
- return "add(" + stringify(v) + ")";
152
- }).join('.'));
153
- break;
154
- case 'Map':
155
- values_1.push("new Map");
156
- statements_1.push(name + "." + Array.from(thing).map(function (_a) {
157
- var k = _a[0],
158
- v = _a[1];
159
- return "set(" + stringify(k) + ", " + stringify(v) + ")";
160
- }).join('.'));
161
- break;
162
- default:
163
- values_1.push(Object.getPrototypeOf(thing) === null ? 'Object.create(null)' : '{}');
164
- Object.keys(thing).forEach(function (key) {
165
- statements_1.push("" + name + safeProp(key) + "=" + stringify(thing[key]));
166
- });
167
- }
168
- });
169
- statements_1.push("return " + str);
170
- return "(function(" + params_1.join(',') + "){" + statements_1.join(';') + "}(" + values_1.join(',') + "))";
226
+ if (lastPos === startPos) {
227
+ result = str;
171
228
  } else {
172
- return str;
173
- }
174
- }
175
- function getName(num) {
176
- var name = '';
177
- do {
178
- name = chars[num % chars.length] + name;
179
- num = ~~(num / chars.length) - 1;
180
- } while (num >= 0);
181
- return reserved.test(name) ? name + "_" : name;
182
- }
183
- function isPrimitive(thing) {
184
- return Object(thing) !== thing;
185
- }
186
- function stringifyPrimitive(thing) {
187
- if (typeof thing === 'string') return stringifyString(thing);
188
- if (thing === void 0) return 'void 0';
189
- if (thing === 0 && 1 / thing < 0) return '-0';
190
- var str = String(thing);
191
- if (typeof thing === 'number') return str.replace(/^(-)?0\./, '$1.');
192
- return str;
193
- }
194
- function getType(thing) {
195
- return Object.prototype.toString.call(thing).slice(8, -1);
196
- }
197
- function escapeUnsafeChar(c) {
198
- return escaped[c] || c;
199
- }
200
- function escapeUnsafeChars(str) {
201
- return str.replace(unsafeChars, escapeUnsafeChar);
202
- }
203
- function safeKey(key) {
204
- return /^[_$a-zA-Z][_$a-zA-Z0-9]*$/.test(key) ? key : escapeUnsafeChars(JSON.stringify(key));
205
- }
206
- function safeProp(key) {
207
- return /^[_$a-zA-Z][_$a-zA-Z0-9]*$/.test(key) ? "." + key : "[" + escapeUnsafeChars(JSON.stringify(key)) + "]";
208
- }
209
- function stringifyString(str) {
210
- var result = '"';
211
- for (var i = 0; i < str.length; i += 1) {
212
- var char = str.charAt(i);
213
- var code = char.charCodeAt(0);
214
- if (char === '"') {
215
- result += '\\"';
216
- } else if (char in escaped) {
217
- result += escaped[char];
218
- } else if (code >= 0xd800 && code <= 0xdfff) {
219
- var next = str.charCodeAt(i + 1);
220
- if (code <= 0xdbff && next >= 0xdc00 && next <= 0xdfff) {
221
- result += char + str[++i];
222
- } else {
223
- result += "\\u" + code.toString(16).toUpperCase();
224
- }
225
- } else {
226
- result += char;
227
- }
229
+ result += str.slice(lastPos);
228
230
  }
229
- result += '"';
231
+ return '"' + result + '"';
232
+ }
233
+ function insertAndGetRef(obj, pos) {
234
+ const ref = toRefParam(REF_COUNT++);
235
+ INDEX_OR_REF.set(obj, ref);
236
+ if (pos) {
237
+ BUFFER[pos - 1] += ref + "=";
238
+ } else {
239
+ BUFFER[pos] = ref + "=" + BUFFER[pos];
240
+ }
241
+ return ref;
242
+ }
243
+ function refParamsString() {
244
+ let result = REF_START_CHARS[0];
245
+ for (let i = 1; i < REF_COUNT; i++) {
246
+ result += "," + toRefParam(i);
247
+ }
248
+ REF_COUNT = 0;
230
249
  return result;
231
250
  }
251
+ function toRefParam(index) {
252
+ let mod = index % REF_START_CHARS_LEN;
253
+ let ref = REF_START_CHARS[mod];
254
+ index = (index - mod) / REF_START_CHARS_LEN;
255
+ while (index > 0) {
256
+ mod = index % REF_CHARS_LEN;
257
+ ref += REF_CHARS[mod];
258
+ index = (index - mod) / REF_CHARS_LEN;
259
+ }
260
+ return ref;
261
+ }
232
262
 
233
- const REPLACE_SCRIPT = `function $df(e,t,d,l){d=document.getElementById(e),(l=document.getElementById("pl-"+e))&&l.replaceWith(...d.childNodes),d.remove(),_$HY.set(e,t||"$$$")}`;
263
+ const REPLACE_SCRIPT = `function $df(e,t,d,l){d=document.getElementById(e),(l=document.getElementById("pl-"+e))&&l.replaceWith(...d.childNodes),d.remove(),_$HY.set(e,t)}`;
234
264
  function renderToString(code, options = {}) {
235
265
  let scripts = "";
236
266
  sharedConfig.context = {
@@ -241,7 +271,7 @@ function renderToString(code, options = {}) {
241
271
  nonce: options.nonce,
242
272
  writeResource(id, p, error) {
243
273
  if (error) return scripts += `_$HY.set("${id}", ${serializeError(p)});`;
244
- scripts += `_$HY.set("${id}", ${devalue(p)});`;
274
+ scripts += `_$HY.set("${id}", ${stringify(p)});`;
245
275
  }
246
276
  };
247
277
  let html = injectAssets(sharedConfig.context.assets, resolveSSRNode(escape(code())));
@@ -268,8 +298,6 @@ function renderToStream(code, options = {}) {
268
298
  onCompleteAll,
269
299
  renderId
270
300
  } = options;
271
- const tmp = [];
272
- const tasks = [];
273
301
  const blockingResources = [];
274
302
  const registry = new Map();
275
303
  const dedupe = new WeakMap();
@@ -286,7 +314,7 @@ function renderToStream(code, options = {}) {
286
314
  }
287
315
  };
288
316
  const pushTask = task => {
289
- tasks.push(task);
317
+ tasks += task + ";";
290
318
  if (!scheduled && firstFlushed) {
291
319
  Promise.resolve().then(writeTasks);
292
320
  scheduled = true;
@@ -294,22 +322,25 @@ function renderToStream(code, options = {}) {
294
322
  };
295
323
  const writeTasks = () => {
296
324
  if (tasks.length && !completed && firstFlushed) {
297
- buffer.write(`<script${nonce ? ` nonce="${nonce}"` : ""}>${tasks.join(";")}</script>`);
298
- tasks.length = 0;
325
+ buffer.write(`<script${nonce ? ` nonce="${nonce}"` : ""}>${tasks}</script>`);
326
+ tasks = "";
299
327
  }
300
328
  scheduled = false;
301
329
  };
330
+ let context;
302
331
  let writable;
332
+ let tmp = "";
333
+ let tasks = "";
303
334
  let firstFlushed = false;
304
335
  let completed = false;
305
336
  let scriptFlushed = false;
306
337
  let scheduled = true;
307
338
  let buffer = {
308
339
  write(payload) {
309
- tmp.push(payload);
340
+ tmp += payload;
310
341
  }
311
342
  };
312
- sharedConfig.context = {
343
+ sharedConfig.context = context = {
313
344
  id: renderId || "",
314
345
  count: 0,
315
346
  async: true,
@@ -317,10 +348,18 @@ function renderToStream(code, options = {}) {
317
348
  suspense: {},
318
349
  assets: [],
319
350
  nonce,
351
+ replace(id, payloadFn) {
352
+ if (firstFlushed) return;
353
+ const placeholder = `<!${id}>`;
354
+ const first = html.indexOf(placeholder);
355
+ if (first === -1) return;
356
+ const last = html.indexOf(`<!/${id}>`, first + placeholder.length);
357
+ html = html.replace(html.slice(first, last + placeholder.length + 1), resolveSSRNode(payloadFn()));
358
+ },
320
359
  writeResource(id, p, error, wait) {
321
- if (error) return pushTask(`_$HY.set("${id}", ${serializeError(p)})`);
360
+ if (error) return pushTask(serializeSet(dedupe, id, p, serializeError));
322
361
  if (!p || typeof p !== "object" || !("then" in p)) return pushTask(serializeSet(dedupe, id, p));
323
- if (wait && !firstFlushed) blockingResources.push(p);else pushTask(`_$HY.init("${id}")`);
362
+ if (!firstFlushed) wait && blockingResources.push(p);else pushTask(`_$HY.init("${id}")`);
324
363
  p.then(d => {
325
364
  !completed && pushTask(serializeSet(dedupe, id, d));
326
365
  }).catch(() => {
@@ -330,7 +369,7 @@ function renderToStream(code, options = {}) {
330
369
  registerFragment(key) {
331
370
  if (!registry.has(key)) {
332
371
  registry.set(key, []);
333
- pushTask(`_$HY.init("${key}")`);
372
+ firstFlushed && pushTask(`_$HY.init("${key}")`);
334
373
  }
335
374
  return (value, error) => {
336
375
  if (registry.has(key)) {
@@ -340,7 +379,7 @@ function renderToStream(code, options = {}) {
340
379
  if ((value !== undefined || error) && !completed) {
341
380
  if (!firstFlushed) {
342
381
  Promise.resolve().then(() => html = replacePlaceholder(html, key, value !== undefined ? value : ""));
343
- pushTask(`${keys.length ? keys.map(k => `_$HY.unset("${k}");`) : ""}_$HY.set("${key}",${error ? serializeError(error) : '"$$$"'})`);
382
+ error && pushTask(serializeSet(dedupe, key, error, serializeError));
344
383
  } else {
345
384
  buffer.write(`<div hidden id="${key}">${value !== undefined ? value : " "}</div>`);
346
385
  pushTask(`${keys.length ? keys.map(k => `_$HY.unset("${k}")`).join(";") + ";" : ""}$df("${key}"${error ? "," + serializeError(error) : ""})${!scriptFlushed ? ";" + REPLACE_SCRIPT : ""}`);
@@ -349,16 +388,20 @@ function renderToStream(code, options = {}) {
349
388
  }
350
389
  }
351
390
  Promise.resolve().then(checkEnd);
352
- return true;
391
+ return firstFlushed;
353
392
  };
354
393
  }
355
394
  };
356
395
  let html = resolveSSRNode(escape(code()));
357
396
  function doShell() {
358
- html = injectAssets(sharedConfig.context.assets, html);
359
- if (tasks.length) html = injectScripts(html, tasks.join(";"), nonce);
397
+ html = injectAssets(context.assets, html);
398
+ for (const key in context.resources) {
399
+ if (!("data" in context.resources[key] || context.resources[key].ref[0].error)) pushTask(`_$HY.init("${key}")`);
400
+ }
401
+ for (const key of registry.keys()) pushTask(`_$HY.init("${key}")`);
402
+ if (tasks.length) html = injectScripts(html, tasks, nonce);
360
403
  buffer.write(html);
361
- tasks.length = 0;
404
+ tasks = "";
362
405
  scheduled = false;
363
406
  onCompleteShell && onCompleteShell({
364
407
  write(v) {
@@ -370,9 +413,7 @@ function renderToStream(code, options = {}) {
370
413
  then(fn) {
371
414
  function complete() {
372
415
  doShell();
373
- let mapped = "";
374
- for (let i = 0, len = tmp.length; i < len; i++) mapped += tmp[i];
375
- fn(mapped);
416
+ fn(tmp);
376
417
  }
377
418
  if (onCompleteAll) {
378
419
  ogComplete = onCompleteAll;
@@ -387,7 +428,7 @@ function renderToStream(code, options = {}) {
387
428
  Promise.allSettled(blockingResources).then(() => {
388
429
  doShell();
389
430
  buffer = writable = w;
390
- tmp.forEach(chunk => buffer.write(chunk));
431
+ buffer.write(tmp);
391
432
  firstFlushed = true;
392
433
  if (completed) writable.end();else setTimeout(checkEnd);
393
434
  });
@@ -408,7 +449,7 @@ function renderToStream(code, options = {}) {
408
449
  writer.write(encoder.encode(payload));
409
450
  }
410
451
  };
411
- tmp.forEach(chunk => buffer.write(chunk));
452
+ buffer.write(tmp);
412
453
  firstFlushed = true;
413
454
  if (completed) writable.end();else setTimeout(checkEnd);
414
455
  });
@@ -416,22 +457,16 @@ function renderToStream(code, options = {}) {
416
457
  };
417
458
  }
418
459
  function Assets(props) {
419
- sharedConfig.context.assets.push(() => NoHydration({
420
- get children() {
421
- return resolveSSRNode(props.children);
422
- }
423
- }));
424
- return ssr(`%%$${sharedConfig.context.assets.length - 1}%%`);
460
+ useAssets(() => props.children);
425
461
  }
426
462
  function HydrationScript(props) {
427
463
  const {
428
464
  nonce
429
465
  } = sharedConfig.context;
430
- sharedConfig.context.assets.push(() => generateHydrationScript({
466
+ return ssr(generateHydrationScript({
431
467
  nonce,
432
468
  ...props
433
469
  }));
434
- return ssr(`%%$${sharedConfig.context.assets.length - 1}%%`);
435
470
  }
436
471
  function NoHydration(props) {
437
472
  const c = sharedConfig.context;
@@ -443,12 +478,12 @@ function NoHydration(props) {
443
478
  function ssr(t, ...nodes) {
444
479
  if (nodes.length) {
445
480
  let result = "";
446
- for (let i = 0; i < t.length; i++) {
481
+ for (let i = 0; i < nodes.length; i++) {
447
482
  result += t[i];
448
483
  const node = nodes[i];
449
484
  if (node !== undefined) result += resolveSSRNode(node);
450
485
  }
451
- t = result;
486
+ t = result + t[nodes.length];
452
487
  }
453
488
  return {
454
489
  t
@@ -569,7 +604,7 @@ function resolveSSRNode(node) {
569
604
  for (let i = 0, len = node.length; i < len; i++) mapped += resolveSSRNode(node[i]);
570
605
  return mapped;
571
606
  }
572
- if (t === "object") return resolveSSRNode(node.t);
607
+ if (t === "object") return node.t;
573
608
  if (t === "function") return resolveSSRNode(node());
574
609
  return String(node);
575
610
  }
@@ -577,6 +612,15 @@ function getHydrationKey() {
577
612
  const hydrate = sharedConfig.context;
578
613
  return hydrate && !hydrate.noHydrate && `${hydrate.id}${hydrate.count++}`;
579
614
  }
615
+ function useAssets(fn) {
616
+ sharedConfig.context.assets.push(() => resolveSSRNode(fn()));
617
+ }
618
+ function getAssets() {
619
+ const assets = sharedConfig.context.assets;
620
+ let out = "";
621
+ for (let i = 0, len = assets.length; i < len; i++) out += assets[i]();
622
+ return out;
623
+ }
580
624
  function generateHydrationScript({
581
625
  eventNames = ["click", "input"],
582
626
  nonce
@@ -584,10 +628,10 @@ function generateHydrationScript({
584
628
  return `<script${nonce ? ` nonce="${nonce}"` : ""}>var e,t;e=window._$HY||(_$HY={events:[],completed:new WeakSet,r:{}}),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 s=o.composedPath&&o.composedPath()[0]||o.target,a=t(s);a&&!e.completed.has(a)&&e.events.push([a,o])})))),e.init=(t,o)=>{e.r[t]=[new Promise(((e,t)=>o=e)),o]},e.set=(t,o,s)=>{(s=e.r[t])&&s[1](o),e.r[t]=[o]},e.unset=t=>{delete e.r[t]},e.load=t=>e.r[t];</script><!--xs-->`;
585
629
  }
586
630
  function injectAssets(assets, html) {
587
- for (let i = 0; i < assets.length; i++) {
588
- html = html.replace(`%%$${i}%%`, assets[i]());
589
- }
590
- return html;
631
+ if (!assets || !assets.length) return html;
632
+ let out = "";
633
+ for (let i = 0, len = assets.length; i < len; i++) out += assets[i]();
634
+ return html.replace(`<head>`, `<head>` + out);
591
635
  }
592
636
  function injectScripts(html, scripts, nonce) {
593
637
  const tag = `<script${nonce ? ` nonce="${nonce}"` : ""}>${scripts}</script>`;
@@ -608,9 +652,9 @@ function serializeError(error) {
608
652
  fields[key] = value;
609
653
  }
610
654
  }
611
- return `Object.assign(new Error(${devalue(error.message)}), ${devalue(fields)})`;
655
+ return `Object.assign(new Error(${stringify(error.message)}), ${stringify(fields)})`;
612
656
  }
613
- return devalue(error);
657
+ return stringify(error);
614
658
  }
615
659
  function waitForFragments(registry, key) {
616
660
  for (const k of [...registry.keys()].reverse()) {
@@ -621,11 +665,11 @@ function waitForFragments(registry, key) {
621
665
  }
622
666
  return false;
623
667
  }
624
- function serializeSet(registry, key, value) {
668
+ function serializeSet(registry, key, value, serializer = stringify) {
625
669
  const exist = registry.get(value);
626
670
  if (exist) return `_$HY.set("${key}", _$HY.r["${exist}"][0])`;
627
671
  value !== null && typeof value === "object" && registry.set(value, key);
628
- return `_$HY.set("${key}", ${devalue(value)})`;
672
+ return `_$HY.set("${key}", ${serializer(value)})`;
629
673
  }
630
674
  function replacePlaceholder(html, key, value) {
631
675
  const nextRegex = /(<[/]?span[^>]*>)/g;
@@ -676,6 +720,37 @@ function pipeToWritable(code, writable, options = {}) {
676
720
  const stream = renderToStream(code, options);
677
721
  if (!options.onReady) stream.pipeTo(writable);
678
722
  }
723
+ function ssrSpread(props, isSVG, skipChildren) {
724
+ let result = "";
725
+ if (props == null) return results;
726
+ if (typeof props === "function") props = props();
727
+ const keys = Object.keys(props);
728
+ let classResolved;
729
+ for (let i = 0; i < keys.length; i++) {
730
+ const prop = keys[i];
731
+ if (prop === "children") {
732
+ !skipChildren && console.warn(`SSR currently does not support spread children.`);
733
+ continue;
734
+ }
735
+ const value = props[prop];
736
+ if (prop === "style") {
737
+ result += `style="${ssrStyle(value)}"`;
738
+ } else if (prop === "class" || prop === "className" || prop === "classList") {
739
+ if (classResolved) continue;
740
+ let n;
741
+ result += `class="${(n = props.class) ? n + " " : ""}${(n = props.className) ? n + " " : ""}${ssrClassList(props.classList)}"`;
742
+ classResolved = true;
743
+ } else if (BooleanAttributes.has(prop)) {
744
+ if (value) result += prop;else continue;
745
+ } else if (value == undefined || prop === "ref" || prop.slice(0, 2) === "on") {
746
+ continue;
747
+ } else {
748
+ result += `${Aliases[prop] || prop}="${escape(value, true)}"`;
749
+ }
750
+ if (i !== keys.length - 1) result += " ";
751
+ }
752
+ return result;
753
+ }
679
754
 
680
755
  const isServer = true;
681
756
  function spread() {}
@@ -693,4 +768,4 @@ function Portal(props) {
693
768
  return "";
694
769
  }
695
770
 
696
- export { Assets, Dynamic, HydrationScript, NoHydration, Portal, escape, generateHydrationScript, getHydrationKey, isServer, pipeToNodeWritable, pipeToWritable, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, spread, ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrStyle };
771
+ export { Assets, Dynamic, HydrationScript, NoHydration, Portal, escape, generateHydrationScript, getAssets, getHydrationKey, isServer, pipeToNodeWritable, pipeToWritable, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, spread, ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrSpread, ssrStyle, useAssets };