solid-js 1.7.2 → 1.7.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.
package/dist/dev.cjs CHANGED
@@ -223,7 +223,7 @@ function createEffect(fn, value, options) {
223
223
  const c = createComputation(fn, value, false, STALE, options ),
224
224
  s = SuspenseContext && lookup(Owner, SuspenseContext.id);
225
225
  if (s) c.suspense = s;
226
- c.user = true;
226
+ if (!options || !options.render) c.user = true;
227
227
  Effects ? Effects.push(c) : updateComputation(c);
228
228
  }
229
229
  function createReaction(onInvalidate, options) {
@@ -470,6 +470,7 @@ function catchError(fn, handler) {
470
470
  Owner.context = {
471
471
  [ERROR]: [handler]
472
472
  };
473
+ if (Transition && Transition.running) Transition.sources.add(Owner);
473
474
  try {
474
475
  return fn();
475
476
  } catch (err) {
@@ -1313,7 +1314,7 @@ function mergeProps(...sources) {
1313
1314
  return target;
1314
1315
  }
1315
1316
  function splitProps(props, ...keys) {
1316
- const blocked = new Set(keys.flat());
1317
+ const blocked = new Set(keys.length > 1 ? keys.flat() : keys[0]);
1317
1318
  if ($PROXY in props) {
1318
1319
  const res = keys.map(k => {
1319
1320
  return new Proxy({
package/dist/dev.js CHANGED
@@ -221,7 +221,7 @@ function createEffect(fn, value, options) {
221
221
  const c = createComputation(fn, value, false, STALE, options ),
222
222
  s = SuspenseContext && lookup(Owner, SuspenseContext.id);
223
223
  if (s) c.suspense = s;
224
- c.user = true;
224
+ if (!options || !options.render) c.user = true;
225
225
  Effects ? Effects.push(c) : updateComputation(c);
226
226
  }
227
227
  function createReaction(onInvalidate, options) {
@@ -468,6 +468,7 @@ function catchError(fn, handler) {
468
468
  Owner.context = {
469
469
  [ERROR]: [handler]
470
470
  };
471
+ if (Transition && Transition.running) Transition.sources.add(Owner);
471
472
  try {
472
473
  return fn();
473
474
  } catch (err) {
@@ -1311,7 +1312,7 @@ function mergeProps(...sources) {
1311
1312
  return target;
1312
1313
  }
1313
1314
  function splitProps(props, ...keys) {
1314
- const blocked = new Set(keys.flat());
1315
+ const blocked = new Set(keys.length > 1 ? keys.flat() : keys[0]);
1315
1316
  if ($PROXY in props) {
1316
1317
  const res = keys.map(k => {
1317
1318
  return new Proxy({
package/dist/solid.cjs CHANGED
@@ -207,7 +207,7 @@ function createEffect(fn, value, options) {
207
207
  const c = createComputation(fn, value, false, STALE),
208
208
  s = SuspenseContext && lookup(Owner, SuspenseContext.id);
209
209
  if (s) c.suspense = s;
210
- c.user = true;
210
+ if (!options || !options.render) c.user = true;
211
211
  Effects ? Effects.push(c) : updateComputation(c);
212
212
  }
213
213
  function createReaction(onInvalidate, options) {
@@ -454,6 +454,7 @@ function catchError(fn, handler) {
454
454
  Owner.context = {
455
455
  [ERROR]: [handler]
456
456
  };
457
+ if (Transition && Transition.running) Transition.sources.add(Owner);
457
458
  try {
458
459
  return fn();
459
460
  } catch (err) {
@@ -1268,7 +1269,7 @@ function mergeProps(...sources) {
1268
1269
  return target;
1269
1270
  }
1270
1271
  function splitProps(props, ...keys) {
1271
- const blocked = new Set(keys.flat());
1272
+ const blocked = new Set(keys.length > 1 ? keys.flat() : keys[0]);
1272
1273
  if ($PROXY in props) {
1273
1274
  const res = keys.map(k => {
1274
1275
  return new Proxy({
package/dist/solid.js CHANGED
@@ -205,7 +205,7 @@ function createEffect(fn, value, options) {
205
205
  const c = createComputation(fn, value, false, STALE),
206
206
  s = SuspenseContext && lookup(Owner, SuspenseContext.id);
207
207
  if (s) c.suspense = s;
208
- c.user = true;
208
+ if (!options || !options.render) c.user = true;
209
209
  Effects ? Effects.push(c) : updateComputation(c);
210
210
  }
211
211
  function createReaction(onInvalidate, options) {
@@ -452,6 +452,7 @@ function catchError(fn, handler) {
452
452
  Owner.context = {
453
453
  [ERROR]: [handler]
454
454
  };
455
+ if (Transition && Transition.running) Transition.sources.add(Owner);
455
456
  try {
456
457
  return fn();
457
458
  } catch (err) {
@@ -1266,7 +1267,7 @@ function mergeProps(...sources) {
1266
1267
  return target;
1267
1268
  }
1268
1269
  function splitProps(props, ...keys) {
1269
- const blocked = new Set(keys.flat());
1270
+ const blocked = new Set(keys.length > 1 ? keys.flat() : keys[0]);
1270
1271
  if ($PROXY in props) {
1271
1272
  const res = keys.map(k => {
1272
1273
  return new Proxy({
@@ -27,7 +27,7 @@ function parseTag( tag) {
27
27
  type: 'tag',
28
28
  name: '',
29
29
  voidElement: false,
30
- attrs: {},
30
+ attrs: [],
31
31
  children: []
32
32
  };
33
33
  const tagMatch = tag.match(/<\/?([^\s]+?)[/\s>]/);
@@ -46,7 +46,19 @@ function parseTag( tag) {
46
46
  }
47
47
  const reg = new RegExp(attrRE);
48
48
  for (const match of tag.matchAll(reg)) {
49
- res.attrs[match[1] || match[2]] = match[4] || match[5] || '';
49
+ if ((match[1] || match[2]).startsWith('use:')) {
50
+ res.attrs.push({
51
+ type: 'directive',
52
+ name: match[1] || match[2],
53
+ value: match[4] || match[5] || ''
54
+ });
55
+ } else {
56
+ res.attrs.push({
57
+ type: 'attr',
58
+ name: match[1] || match[2],
59
+ value: match[4] || match[5] || ''
60
+ });
61
+ }
50
62
  }
51
63
  return res;
52
64
  }
@@ -118,8 +130,8 @@ function parse(html) {
118
130
  }
119
131
  function attrString(attrs) {
120
132
  const buff = [];
121
- for (const key in attrs) {
122
- buff.push(key + '="' + attrs[key].replace(/"/g, '&quot;') + '"');
133
+ for (const attr of attrs) {
134
+ buff.push(attr.name + '="' + attr.value.replace(/"/g, '&quot;') + '"');
123
135
  }
124
136
  if (!buff.length) {
125
137
  return '';
@@ -148,8 +160,8 @@ function stringify(doc) {
148
160
  const cache = new Map();
149
161
  const VOID_ELEMENTS = /^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i;
150
162
  const spaces = " \\f\\n\\r\\t";
151
- const almostEverything = "[^ " + spaces + "\\/>\"'=]+";
152
- const attrName = "[ " + spaces + "]+" + almostEverything;
163
+ const almostEverything = "[^" + spaces + "\\/>\"'=]+";
164
+ const attrName = "[ " + spaces + "]+(?:use:<!--#-->|" + almostEverything + ')';
153
165
  const tagName = "<([A-Za-z$#]+[A-Za-z0-9:_-]*)((?:";
154
166
  const attrPartials = "(?:\\s*=\\s*(?:'[^']*?'|\"[^\"]*?\"|\\([^)]*?\\)|<[^>]*?>|" + almostEverything + "))?)";
155
167
  const attrSeeker = new RegExp(tagName + attrName + attrPartials + "+)([ " + spaces + "]*/?>)", "g");
@@ -161,7 +173,7 @@ function attrReplacer($0, $1, $2, $3) {
161
173
  return "<" + $1 + $2.replace(findAttributes, replaceAttributes) + $3;
162
174
  }
163
175
  function replaceAttributes($0, $1, $2) {
164
- return $1 + ($2[0] === '"' || $2[0] === "'" ? $2.replace(/<!--#-->/g, "###") : '"###"');
176
+ return $1.replace(/<!--#-->/g, "###") + ($2[0] === '"' || $2[0] === "'" ? $2.replace(/<!--#-->/g, "###") : '"###"');
165
177
  }
166
178
  function fullClosing($0, $1, $2) {
167
179
  return VOID_ELEMENTS.test($1) ? $0 : "<" + $1 + $2 + "></" + $1 + ">";
@@ -169,8 +181,17 @@ function fullClosing($0, $1, $2) {
169
181
  function toPropertyName(name) {
170
182
  return name.toLowerCase().replace(/-([a-z])/g, (_, w) => w.toUpperCase());
171
183
  }
184
+ function parseDirective(name, value, tag, options) {
185
+ if (name === 'use:###' && value === '###') {
186
+ const count = options.counter++;
187
+ options.exprs.push(`typeof exprs[${count}] === "function" ? r.use(exprs[${count}], ${tag}, exprs[${options.counter++}]) : (()=>{throw new Error("use:### must be a function")})()`);
188
+ } else {
189
+ throw new Error(`Not support syntax ${name} must be use:{function}`);
190
+ }
191
+ }
172
192
  function createHTML(r, {
173
- delegateEvents = true
193
+ delegateEvents = true,
194
+ functionBuilder = (...args) => new Function(...args)
174
195
  } = {}) {
175
196
  let uuid = 1;
176
197
  r.wrapProps = props => {
@@ -180,15 +201,19 @@ function createHTML(r, {
180
201
  }
181
202
  return props;
182
203
  };
183
- function createTemplate(statics) {
204
+ function createTemplate(statics, opt) {
184
205
  let i = 0,
185
206
  markup = "";
186
207
  for (; i < statics.length - 1; i++) {
187
208
  markup = markup + statics[i] + "<!--#-->";
188
209
  }
189
210
  markup = markup + statics[i];
190
- markup = markup.replace(selfClosing, fullClosing).replace(/<(<!--#-->)/g, "<###").replace(/\.\.\.(<!--#-->)/g, "###").replace(attrSeeker, attrReplacer).replace(/>\n+\s*/g, ">").replace(/\n+\s*</g, "<").replace(/\s+</g, " <").replace(/>\s+/g, "> ");
191
- const [html, code] = parseTemplate(parse(markup)),
211
+ const replaceList = [[selfClosing, fullClosing], [/<(<!--#-->)/g, "<###"], [/\.\.\.(<!--#-->)/g, "###"], [attrSeeker, attrReplacer], [/>\n+\s*/g, ">"], [/\n+\s*</g, "<"], [/\s+</g, " <"], [/>\s+/g, "> "]];
212
+ markup = replaceList.reduce((acc, x) => {
213
+ return acc.replace(x[0], x[1]);
214
+ }, markup);
215
+ const pars = parse(markup);
216
+ const [html, code] = parseTemplate(pars, opt.funcBuilder),
192
217
  templates = [];
193
218
  for (let i = 0; i < html.length; i++) {
194
219
  templates.push(document.createElement("template"));
@@ -322,14 +347,24 @@ function createHTML(r, {
322
347
  propGroups = [props],
323
348
  componentIdentifier = options.counter++;
324
349
  for (let i = 0; i < keys.length; i++) {
325
- const name = keys[i],
326
- value = node.attrs[name];
327
- if (name === "###") {
328
- propGroups.push(`exprs[${options.counter++}]`);
329
- propGroups.push(props = []);
330
- } else if (value === "###") {
331
- props.push(`${name}: exprs[${options.counter++}]`);
332
- } else props.push(`${name}: "${value}"`);
350
+ const {
351
+ type,
352
+ name,
353
+ value
354
+ } = node.attrs[i];
355
+ if (type === 'attr') {
356
+ if (name === "###") {
357
+ propGroups.push(`exprs[${options.counter++}]`);
358
+ propGroups.push(props = []);
359
+ } else if (value === "###") {
360
+ props.push(`${name}: exprs[${options.counter++}]`);
361
+ } else props.push(`${name}: "${value}"`);
362
+ } else if (type === 'directive') {
363
+ const tag = `_$el${uuid++}`;
364
+ const topDecl = !options.decl.length;
365
+ options.decl.push(topDecl ? "" : `${tag} = ${options.path}.${options.first ? "firstChild" : "nextSibling"}`);
366
+ parseDirective(name, value, tag, options);
367
+ }
333
368
  }
334
369
  if (node.children.length === 1 && node.children[0].type === "comment" && node.children[0].content === "#") {
335
370
  props.push(`children: () => exprs[${options.counter++}]`);
@@ -404,38 +439,58 @@ function createHTML(r, {
404
439
  const topDecl = !options.decl.length;
405
440
  const templateId = options.templateId;
406
441
  options.decl.push(topDecl ? "" : `${tag} = ${options.path}.${options.first ? "firstChild" : "nextSibling"}`);
407
- const keys = Object.keys(node.attrs);
408
442
  const isSVG = r.SVGElements.has(node.name);
409
443
  const isCE = node.name.includes("-");
410
444
  options.hasCustomElement = isCE;
411
- if (keys.includes("###")) {
445
+ if (node.attrs.some(e => e.name === "###")) {
412
446
  const spreadArgs = [];
413
447
  let current = "";
414
- for (let i = 0; i < keys.length; i++) {
415
- const name = keys[i],
416
- value = node.attrs[name];
417
- if (value.includes("###")) {
418
- let count = options.counter++;
419
- current += `${name}: ${name !== "ref" ? `typeof exprs[${count}] === "function" ? exprs[${count}]() : ` : ""}exprs[${count}],`;
420
- delete node.attrs[name];
421
- } else if (name === "###") {
422
- if (current.length) {
423
- spreadArgs.push(`()=>({${current}})`);
424
- current = "";
448
+ const newAttrs = [];
449
+ for (let i = 0; i < node.attrs.length; i++) {
450
+ const {
451
+ type,
452
+ name,
453
+ value
454
+ } = node.attrs[i];
455
+ if (type === 'attr') {
456
+ if (value.includes("###")) {
457
+ let count = options.counter++;
458
+ current += `${name}: ${name !== "ref" ? `typeof exprs[${count}] === "function" ? exprs[${count}]() : ` : ""}exprs[${count}],`;
459
+ } else if (name === "###") {
460
+ if (current.length) {
461
+ spreadArgs.push(`()=>({${current}})`);
462
+ current = "";
463
+ }
464
+ spreadArgs.push(`exprs[${options.counter++}]`);
465
+ } else {
466
+ newAttrs.push(node.attrs[i]);
425
467
  }
426
- spreadArgs.push(`exprs[${options.counter++}]`);
427
- delete node.attrs[name];
468
+ } else if (type === 'directive') {
469
+ parseDirective(name, value, tag, options);
428
470
  }
429
471
  }
430
- if (current.length) spreadArgs.push(`()=>({${current}})`);
472
+ node.attrs = newAttrs;
473
+ if (current.length) {
474
+ spreadArgs.push(`()=>({${current}})`);
475
+ }
431
476
  options.exprs.push(`r.spread(${tag},${spreadArgs.length === 1 ? `typeof ${spreadArgs[0]} === "function" ? r.mergeProps(${spreadArgs[0]}) : ${spreadArgs[0]}` : `r.mergeProps(${spreadArgs.join(",")})`},${isSVG},${!!node.children.length})`);
432
477
  } else {
433
- for (let i = 0; i < keys.length; i++) {
434
- const name = keys[i],
435
- value = node.attrs[name];
436
- if (value.includes("###")) {
437
- delete node.attrs[name];
438
- parseAttribute(node, tag, name, value, isSVG, isCE, options);
478
+ for (let i = 0; i < node.attrs.length; i++) {
479
+ const {
480
+ type,
481
+ name,
482
+ value
483
+ } = node.attrs[i];
484
+ if (type === 'directive') {
485
+ parseDirective(name, value, tag, options);
486
+ node.attrs.splice(i, 1);
487
+ i--;
488
+ } else if (type === "attr") {
489
+ if (value.includes("###")) {
490
+ node.attrs.splice(i, 1);
491
+ i--;
492
+ parseAttribute(node, tag, name, value, isSVG, isCE, options);
493
+ }
439
494
  }
440
495
  }
441
496
  }
@@ -462,7 +517,7 @@ function createHTML(r, {
462
517
  options.first = false;
463
518
  }
464
519
  }
465
- function parseTemplate(nodes) {
520
+ function parseTemplate(nodes, funcBuilder) {
466
521
  const options = {
467
522
  path: "",
468
523
  decl: [],
@@ -489,10 +544,12 @@ function createHTML(r, {
489
544
  } else parseNode(nodes[0], options);
490
545
  r.delegateEvents(Array.from(options.delegatedEvents));
491
546
  const templateNodes = [origNodes].concat(options.templateNodes);
492
- return [templateNodes.map(t => stringify(t)), new Function("tmpls", "exprs", "r", options.decl.join(",\n") + ";\n" + options.exprs.join(";\n") + (toplevel ? "" : `;\nreturn _$el${id};\n`))];
547
+ return [templateNodes.map(t => stringify(t)), funcBuilder("tmpls", "exprs", "r", options.decl.join(",\n") + ";\n" + options.exprs.join(";\n") + (toplevel ? "" : `;\nreturn _$el${id};\n`))];
493
548
  }
494
549
  function html(statics, ...args) {
495
- const templates = cache.get(statics) || createTemplate(statics);
550
+ const templates = cache.get(statics) || createTemplate(statics, {
551
+ funcBuilder: functionBuilder
552
+ });
496
553
  return templates[0].create(templates, args, r);
497
554
  }
498
555
  return html;
package/html/dist/html.js CHANGED
@@ -25,7 +25,7 @@ function parseTag( tag) {
25
25
  type: 'tag',
26
26
  name: '',
27
27
  voidElement: false,
28
- attrs: {},
28
+ attrs: [],
29
29
  children: []
30
30
  };
31
31
  const tagMatch = tag.match(/<\/?([^\s]+?)[/\s>]/);
@@ -44,7 +44,19 @@ function parseTag( tag) {
44
44
  }
45
45
  const reg = new RegExp(attrRE);
46
46
  for (const match of tag.matchAll(reg)) {
47
- res.attrs[match[1] || match[2]] = match[4] || match[5] || '';
47
+ if ((match[1] || match[2]).startsWith('use:')) {
48
+ res.attrs.push({
49
+ type: 'directive',
50
+ name: match[1] || match[2],
51
+ value: match[4] || match[5] || ''
52
+ });
53
+ } else {
54
+ res.attrs.push({
55
+ type: 'attr',
56
+ name: match[1] || match[2],
57
+ value: match[4] || match[5] || ''
58
+ });
59
+ }
48
60
  }
49
61
  return res;
50
62
  }
@@ -116,8 +128,8 @@ function parse(html) {
116
128
  }
117
129
  function attrString(attrs) {
118
130
  const buff = [];
119
- for (const key in attrs) {
120
- buff.push(key + '="' + attrs[key].replace(/"/g, '&quot;') + '"');
131
+ for (const attr of attrs) {
132
+ buff.push(attr.name + '="' + attr.value.replace(/"/g, '&quot;') + '"');
121
133
  }
122
134
  if (!buff.length) {
123
135
  return '';
@@ -146,8 +158,8 @@ function stringify(doc) {
146
158
  const cache = new Map();
147
159
  const VOID_ELEMENTS = /^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i;
148
160
  const spaces = " \\f\\n\\r\\t";
149
- const almostEverything = "[^ " + spaces + "\\/>\"'=]+";
150
- const attrName = "[ " + spaces + "]+" + almostEverything;
161
+ const almostEverything = "[^" + spaces + "\\/>\"'=]+";
162
+ const attrName = "[ " + spaces + "]+(?:use:<!--#-->|" + almostEverything + ')';
151
163
  const tagName = "<([A-Za-z$#]+[A-Za-z0-9:_-]*)((?:";
152
164
  const attrPartials = "(?:\\s*=\\s*(?:'[^']*?'|\"[^\"]*?\"|\\([^)]*?\\)|<[^>]*?>|" + almostEverything + "))?)";
153
165
  const attrSeeker = new RegExp(tagName + attrName + attrPartials + "+)([ " + spaces + "]*/?>)", "g");
@@ -159,7 +171,7 @@ function attrReplacer($0, $1, $2, $3) {
159
171
  return "<" + $1 + $2.replace(findAttributes, replaceAttributes) + $3;
160
172
  }
161
173
  function replaceAttributes($0, $1, $2) {
162
- return $1 + ($2[0] === '"' || $2[0] === "'" ? $2.replace(/<!--#-->/g, "###") : '"###"');
174
+ return $1.replace(/<!--#-->/g, "###") + ($2[0] === '"' || $2[0] === "'" ? $2.replace(/<!--#-->/g, "###") : '"###"');
163
175
  }
164
176
  function fullClosing($0, $1, $2) {
165
177
  return VOID_ELEMENTS.test($1) ? $0 : "<" + $1 + $2 + "></" + $1 + ">";
@@ -167,8 +179,17 @@ function fullClosing($0, $1, $2) {
167
179
  function toPropertyName(name) {
168
180
  return name.toLowerCase().replace(/-([a-z])/g, (_, w) => w.toUpperCase());
169
181
  }
182
+ function parseDirective(name, value, tag, options) {
183
+ if (name === 'use:###' && value === '###') {
184
+ const count = options.counter++;
185
+ options.exprs.push(`typeof exprs[${count}] === "function" ? r.use(exprs[${count}], ${tag}, exprs[${options.counter++}]) : (()=>{throw new Error("use:### must be a function")})()`);
186
+ } else {
187
+ throw new Error(`Not support syntax ${name} must be use:{function}`);
188
+ }
189
+ }
170
190
  function createHTML(r, {
171
- delegateEvents = true
191
+ delegateEvents = true,
192
+ functionBuilder = (...args) => new Function(...args)
172
193
  } = {}) {
173
194
  let uuid = 1;
174
195
  r.wrapProps = props => {
@@ -178,15 +199,19 @@ function createHTML(r, {
178
199
  }
179
200
  return props;
180
201
  };
181
- function createTemplate(statics) {
202
+ function createTemplate(statics, opt) {
182
203
  let i = 0,
183
204
  markup = "";
184
205
  for (; i < statics.length - 1; i++) {
185
206
  markup = markup + statics[i] + "<!--#-->";
186
207
  }
187
208
  markup = markup + statics[i];
188
- markup = markup.replace(selfClosing, fullClosing).replace(/<(<!--#-->)/g, "<###").replace(/\.\.\.(<!--#-->)/g, "###").replace(attrSeeker, attrReplacer).replace(/>\n+\s*/g, ">").replace(/\n+\s*</g, "<").replace(/\s+</g, " <").replace(/>\s+/g, "> ");
189
- const [html, code] = parseTemplate(parse(markup)),
209
+ const replaceList = [[selfClosing, fullClosing], [/<(<!--#-->)/g, "<###"], [/\.\.\.(<!--#-->)/g, "###"], [attrSeeker, attrReplacer], [/>\n+\s*/g, ">"], [/\n+\s*</g, "<"], [/\s+</g, " <"], [/>\s+/g, "> "]];
210
+ markup = replaceList.reduce((acc, x) => {
211
+ return acc.replace(x[0], x[1]);
212
+ }, markup);
213
+ const pars = parse(markup);
214
+ const [html, code] = parseTemplate(pars, opt.funcBuilder),
190
215
  templates = [];
191
216
  for (let i = 0; i < html.length; i++) {
192
217
  templates.push(document.createElement("template"));
@@ -320,14 +345,24 @@ function createHTML(r, {
320
345
  propGroups = [props],
321
346
  componentIdentifier = options.counter++;
322
347
  for (let i = 0; i < keys.length; i++) {
323
- const name = keys[i],
324
- value = node.attrs[name];
325
- if (name === "###") {
326
- propGroups.push(`exprs[${options.counter++}]`);
327
- propGroups.push(props = []);
328
- } else if (value === "###") {
329
- props.push(`${name}: exprs[${options.counter++}]`);
330
- } else props.push(`${name}: "${value}"`);
348
+ const {
349
+ type,
350
+ name,
351
+ value
352
+ } = node.attrs[i];
353
+ if (type === 'attr') {
354
+ if (name === "###") {
355
+ propGroups.push(`exprs[${options.counter++}]`);
356
+ propGroups.push(props = []);
357
+ } else if (value === "###") {
358
+ props.push(`${name}: exprs[${options.counter++}]`);
359
+ } else props.push(`${name}: "${value}"`);
360
+ } else if (type === 'directive') {
361
+ const tag = `_$el${uuid++}`;
362
+ const topDecl = !options.decl.length;
363
+ options.decl.push(topDecl ? "" : `${tag} = ${options.path}.${options.first ? "firstChild" : "nextSibling"}`);
364
+ parseDirective(name, value, tag, options);
365
+ }
331
366
  }
332
367
  if (node.children.length === 1 && node.children[0].type === "comment" && node.children[0].content === "#") {
333
368
  props.push(`children: () => exprs[${options.counter++}]`);
@@ -402,38 +437,58 @@ function createHTML(r, {
402
437
  const topDecl = !options.decl.length;
403
438
  const templateId = options.templateId;
404
439
  options.decl.push(topDecl ? "" : `${tag} = ${options.path}.${options.first ? "firstChild" : "nextSibling"}`);
405
- const keys = Object.keys(node.attrs);
406
440
  const isSVG = r.SVGElements.has(node.name);
407
441
  const isCE = node.name.includes("-");
408
442
  options.hasCustomElement = isCE;
409
- if (keys.includes("###")) {
443
+ if (node.attrs.some(e => e.name === "###")) {
410
444
  const spreadArgs = [];
411
445
  let current = "";
412
- for (let i = 0; i < keys.length; i++) {
413
- const name = keys[i],
414
- value = node.attrs[name];
415
- if (value.includes("###")) {
416
- let count = options.counter++;
417
- current += `${name}: ${name !== "ref" ? `typeof exprs[${count}] === "function" ? exprs[${count}]() : ` : ""}exprs[${count}],`;
418
- delete node.attrs[name];
419
- } else if (name === "###") {
420
- if (current.length) {
421
- spreadArgs.push(`()=>({${current}})`);
422
- current = "";
446
+ const newAttrs = [];
447
+ for (let i = 0; i < node.attrs.length; i++) {
448
+ const {
449
+ type,
450
+ name,
451
+ value
452
+ } = node.attrs[i];
453
+ if (type === 'attr') {
454
+ if (value.includes("###")) {
455
+ let count = options.counter++;
456
+ current += `${name}: ${name !== "ref" ? `typeof exprs[${count}] === "function" ? exprs[${count}]() : ` : ""}exprs[${count}],`;
457
+ } else if (name === "###") {
458
+ if (current.length) {
459
+ spreadArgs.push(`()=>({${current}})`);
460
+ current = "";
461
+ }
462
+ spreadArgs.push(`exprs[${options.counter++}]`);
463
+ } else {
464
+ newAttrs.push(node.attrs[i]);
423
465
  }
424
- spreadArgs.push(`exprs[${options.counter++}]`);
425
- delete node.attrs[name];
466
+ } else if (type === 'directive') {
467
+ parseDirective(name, value, tag, options);
426
468
  }
427
469
  }
428
- if (current.length) spreadArgs.push(`()=>({${current}})`);
470
+ node.attrs = newAttrs;
471
+ if (current.length) {
472
+ spreadArgs.push(`()=>({${current}})`);
473
+ }
429
474
  options.exprs.push(`r.spread(${tag},${spreadArgs.length === 1 ? `typeof ${spreadArgs[0]} === "function" ? r.mergeProps(${spreadArgs[0]}) : ${spreadArgs[0]}` : `r.mergeProps(${spreadArgs.join(",")})`},${isSVG},${!!node.children.length})`);
430
475
  } else {
431
- for (let i = 0; i < keys.length; i++) {
432
- const name = keys[i],
433
- value = node.attrs[name];
434
- if (value.includes("###")) {
435
- delete node.attrs[name];
436
- parseAttribute(node, tag, name, value, isSVG, isCE, options);
476
+ for (let i = 0; i < node.attrs.length; i++) {
477
+ const {
478
+ type,
479
+ name,
480
+ value
481
+ } = node.attrs[i];
482
+ if (type === 'directive') {
483
+ parseDirective(name, value, tag, options);
484
+ node.attrs.splice(i, 1);
485
+ i--;
486
+ } else if (type === "attr") {
487
+ if (value.includes("###")) {
488
+ node.attrs.splice(i, 1);
489
+ i--;
490
+ parseAttribute(node, tag, name, value, isSVG, isCE, options);
491
+ }
437
492
  }
438
493
  }
439
494
  }
@@ -460,7 +515,7 @@ function createHTML(r, {
460
515
  options.first = false;
461
516
  }
462
517
  }
463
- function parseTemplate(nodes) {
518
+ function parseTemplate(nodes, funcBuilder) {
464
519
  const options = {
465
520
  path: "",
466
521
  decl: [],
@@ -487,10 +542,12 @@ function createHTML(r, {
487
542
  } else parseNode(nodes[0], options);
488
543
  r.delegateEvents(Array.from(options.delegatedEvents));
489
544
  const templateNodes = [origNodes].concat(options.templateNodes);
490
- return [templateNodes.map(t => stringify(t)), new Function("tmpls", "exprs", "r", options.decl.join(",\n") + ";\n" + options.exprs.join(";\n") + (toplevel ? "" : `;\nreturn _$el${id};\n`))];
545
+ return [templateNodes.map(t => stringify(t)), funcBuilder("tmpls", "exprs", "r", options.decl.join(",\n") + ";\n" + options.exprs.join(";\n") + (toplevel ? "" : `;\nreturn _$el${id};\n`))];
491
546
  }
492
547
  function html(statics, ...args) {
493
- const templates = cache.get(statics) || createTemplate(statics);
548
+ const templates = cache.get(statics) || createTemplate(statics, {
549
+ funcBuilder: functionBuilder
550
+ });
494
551
  return templates[0].create(templates, args, r);
495
552
  }
496
553
  return html;
@@ -32,7 +32,8 @@ interface Runtime {
32
32
  export type HTMLTag = {
33
33
  (statics: TemplateStringsArray, ...args: unknown[]): Node | Node[];
34
34
  };
35
- export declare function createHTML(r: Runtime, { delegateEvents }?: {
36
- delegateEvents?: boolean | undefined;
35
+ export declare function createHTML(r: Runtime, { delegateEvents, functionBuilder }?: {
36
+ delegateEvents?: boolean;
37
+ functionBuilder?: (...args: string[]) => Function;
37
38
  }): HTMLTag;
38
39
  export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "solid-js",
3
3
  "description": "A declarative JavaScript library for building user interfaces.",
4
- "version": "1.7.2",
4
+ "version": "1.7.4",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",
7
7
  "homepage": "https://solidjs.com",
@@ -135,7 +135,10 @@ function setProperty(state, property, value, deleting = false) {
135
135
  let nodes = getDataNodes(state),
136
136
  node;
137
137
  if (node = getDataNode(nodes, property, prev)) node.$(() => value);
138
- if (Array.isArray(state) && state.length !== len) (node = getDataNode(nodes, "length", len)) && node.$(state.length);
138
+ if (Array.isArray(state) && state.length !== len) {
139
+ for (let i = state.length; i < len; i++) (node = nodes[i]) && node.$();
140
+ (node = getDataNode(nodes, "length", len)) && node.$(state.length);
141
+ }
139
142
  (node = nodes._) && node.$();
140
143
  }
141
144
  function mergeStoreNode(state, value) {
package/store/dist/dev.js CHANGED
@@ -133,7 +133,10 @@ function setProperty(state, property, value, deleting = false) {
133
133
  let nodes = getDataNodes(state),
134
134
  node;
135
135
  if (node = getDataNode(nodes, property, prev)) node.$(() => value);
136
- if (Array.isArray(state) && state.length !== len) (node = getDataNode(nodes, "length", len)) && node.$(state.length);
136
+ if (Array.isArray(state) && state.length !== len) {
137
+ for (let i = state.length; i < len; i++) (node = nodes[i]) && node.$();
138
+ (node = getDataNode(nodes, "length", len)) && node.$(state.length);
139
+ }
137
140
  (node = nodes._) && node.$();
138
141
  }
139
142
  function mergeStoreNode(state, value) {
@@ -129,7 +129,10 @@ function setProperty(state, property, value, deleting = false) {
129
129
  let nodes = getDataNodes(state),
130
130
  node;
131
131
  if (node = getDataNode(nodes, property, prev)) node.$(() => value);
132
- if (Array.isArray(state) && state.length !== len) (node = getDataNode(nodes, "length", len)) && node.$(state.length);
132
+ if (Array.isArray(state) && state.length !== len) {
133
+ for (let i = state.length; i < len; i++) (node = nodes[i]) && node.$();
134
+ (node = getDataNode(nodes, "length", len)) && node.$(state.length);
135
+ }
133
136
  (node = nodes._) && node.$();
134
137
  }
135
138
  function mergeStoreNode(state, value) {
@@ -127,7 +127,10 @@ function setProperty(state, property, value, deleting = false) {
127
127
  let nodes = getDataNodes(state),
128
128
  node;
129
129
  if (node = getDataNode(nodes, property, prev)) node.$(() => value);
130
- if (Array.isArray(state) && state.length !== len) (node = getDataNode(nodes, "length", len)) && node.$(state.length);
130
+ if (Array.isArray(state) && state.length !== len) {
131
+ for (let i = state.length; i < len; i++) (node = nodes[i]) && node.$();
132
+ (node = getDataNode(nodes, "length", len)) && node.$(state.length);
133
+ }
131
134
  (node = nodes._) && node.$();
132
135
  }
133
136
  function mergeStoreNode(state, value) {
@@ -3,11 +3,10 @@ export type { ArrayFilterFn, DeepMutable, DeepReadonly, NotWrappable, Part, SetS
3
3
  export * from "./mutable.js";
4
4
  export * from "./modifiers.js";
5
5
  import { $NODE, isWrappable } from "./store.js";
6
- declare const DEV: {
6
+ export declare const DEV: {
7
7
  readonly $NODE: typeof $NODE;
8
8
  readonly isWrappable: typeof isWrappable;
9
9
  readonly hooks: {
10
10
  onStoreNodeUpdate: import("./store.js").OnStoreNodeUpdate | null;
11
11
  };
12
12
  } | undefined;
13
- export { DEV };
package/types/index.d.ts CHANGED
@@ -8,7 +8,7 @@ import type { JSX } from "./jsx.js";
8
8
  type JSXElement = JSX.Element;
9
9
  export type { JSXElement, JSX };
10
10
  import { registerGraph, writeSignal } from "./reactive/signal.js";
11
- declare const DEV: {
11
+ export declare const DEV: {
12
12
  readonly hooks: {
13
13
  afterUpdate: (() => void) | null;
14
14
  afterCreateOwner: ((owner: import("./reactive/signal.js").Owner) => void) | null;
@@ -16,7 +16,6 @@ declare const DEV: {
16
16
  readonly writeSignal: typeof writeSignal;
17
17
  readonly registerGraph: typeof registerGraph;
18
18
  } | undefined;
19
- export { DEV };
20
19
  declare global {
21
20
  var Solid$$: boolean;
22
21
  }
package/types/jsx.d.ts CHANGED
@@ -405,7 +405,8 @@ export namespace JSX {
405
405
  | "allow-scripts"
406
406
  | "allow-storage-access-by-user-activation"
407
407
  | "allow-top-navigation"
408
- | "allow-top-navigation-by-user-activation";
408
+ | "allow-top-navigation-by-user-activation"
409
+ | "allow-top-navigation-to-custom-protocols";
409
410
  type HTMLLinkAs =
410
411
  | "audio"
411
412
  | "document"
@@ -705,8 +706,9 @@ export namespace JSX {
705
706
  contextmenu?: string;
706
707
  dir?: HTMLDir;
707
708
  draggable?: boolean;
708
- hidden?: boolean;
709
+ hidden?: boolean | "hidden" | "until-found";
709
710
  id?: string;
711
+ inert?: boolean;
710
712
  lang?: string;
711
713
  spellcheck?: boolean;
712
714
  style?: CSSProperties | string;
@@ -874,6 +876,8 @@ export namespace JSX {
874
876
  useMap?: string;
875
877
  width?: number | string;
876
878
  crossOrigin?: HTMLCrossorigin;
879
+ elementtiming: string;
880
+ fetchpriority: "high" | "low" | "auto";
877
881
  }
878
882
  interface InputHTMLAttributes<T> extends HTMLAttributes<T> {
879
883
  accept?: string;
@@ -184,7 +184,9 @@ export declare function createRenderEffect<Next, Init = Next>(fn: EffectFunction
184
184
  * @description https://www.solidjs.com/docs/latest/api#createeffect
185
185
  */
186
186
  export declare function createEffect<Next>(fn: EffectFunction<undefined | NoInfer<Next>, Next>): void;
187
- export declare function createEffect<Next, Init = Next>(fn: EffectFunction<Init | Next, Next>, value: Init, options?: EffectOptions): void;
187
+ export declare function createEffect<Next, Init = Next>(fn: EffectFunction<Init | Next, Next>, value: Init, options?: EffectOptions & {
188
+ render?: boolean;
189
+ }): void;
188
190
  /**
189
191
  * Creates a reactive computation that runs after the render phase with flexible tracking
190
192
  * ```typescript
package/web/dist/dev.cjs CHANGED
@@ -457,7 +457,7 @@ function insertExpression(parent, value, current, marker, unwrapArray) {
457
457
  appendNodes(parent, array);
458
458
  }
459
459
  current = array;
460
- } else if (value instanceof Node) {
460
+ } else if (value.nodeType) {
461
461
  if (solidJs.sharedConfig.context && value.parentNode) return current = multi ? [value] : value;
462
462
  if (Array.isArray(current)) {
463
463
  if (multi) return current = cleanChildren(parent, current, marker, value);
@@ -473,12 +473,13 @@ function normalizeIncomingArray(normalized, array, current, unwrap) {
473
473
  let dynamic = false;
474
474
  for (let i = 0, len = array.length; i < len; i++) {
475
475
  let item = array[i],
476
- prev = current && current[i];
477
- if (item instanceof Node) {
476
+ prev = current && current[i],
477
+ t;
478
+ if (item == null || item === true || item === false) ; else if ((t = typeof item) === "object" && item.nodeType) {
478
479
  normalized.push(item);
479
- } else if (item == null || item === true || item === false) ; else if (Array.isArray(item)) {
480
+ } else if (Array.isArray(item)) {
480
481
  dynamic = normalizeIncomingArray(normalized, item, prev) || dynamic;
481
- } else if ((typeof item) === "function") {
482
+ } else if (t === "function") {
482
483
  if (unwrap) {
483
484
  while (typeof item === "function") item = item();
484
485
  dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item], Array.isArray(prev) ? prev : [prev]) || dynamic;
@@ -488,10 +489,7 @@ function normalizeIncomingArray(normalized, array, current, unwrap) {
488
489
  }
489
490
  } else {
490
491
  const value = String(item);
491
- if (prev && prev.nodeType === 3) {
492
- prev.data = value;
493
- normalized.push(prev);
494
- } else normalized.push(document.createTextNode(value));
492
+ if (prev && prev.nodeType === 3 && prev.data === value) normalized.push(prev);else normalized.push(document.createTextNode(value));
495
493
  }
496
494
  }
497
495
  return dynamic;
@@ -575,7 +573,9 @@ function Portal(props) {
575
573
  mount = () => props.mount || document.body,
576
574
  owner = solidJs.getOwner();
577
575
  let content;
576
+ let hydrating = !!solidJs.sharedConfig.context;
578
577
  solidJs.createEffect(() => {
578
+ if (hydrating) solidJs.getOwner().user = hydrating = false;
579
579
  content || (content = solidJs.runWithOwner(owner, () => props.children));
580
580
  const el = mount();
581
581
  if (el instanceof HTMLHeadElement) {
@@ -599,6 +599,8 @@ function Portal(props) {
599
599
  props.ref && props.ref(container);
600
600
  solidJs.onCleanup(() => el.removeChild(container));
601
601
  }
602
+ }, undefined, {
603
+ render: !hydrating
602
604
  });
603
605
  return marker;
604
606
  }
package/web/dist/dev.js CHANGED
@@ -456,7 +456,7 @@ function insertExpression(parent, value, current, marker, unwrapArray) {
456
456
  appendNodes(parent, array);
457
457
  }
458
458
  current = array;
459
- } else if (value instanceof Node) {
459
+ } else if (value.nodeType) {
460
460
  if (sharedConfig.context && value.parentNode) return current = multi ? [value] : value;
461
461
  if (Array.isArray(current)) {
462
462
  if (multi) return current = cleanChildren(parent, current, marker, value);
@@ -472,12 +472,13 @@ function normalizeIncomingArray(normalized, array, current, unwrap) {
472
472
  let dynamic = false;
473
473
  for (let i = 0, len = array.length; i < len; i++) {
474
474
  let item = array[i],
475
- prev = current && current[i];
476
- if (item instanceof Node) {
475
+ prev = current && current[i],
476
+ t;
477
+ if (item == null || item === true || item === false) ; else if ((t = typeof item) === "object" && item.nodeType) {
477
478
  normalized.push(item);
478
- } else if (item == null || item === true || item === false) ; else if (Array.isArray(item)) {
479
+ } else if (Array.isArray(item)) {
479
480
  dynamic = normalizeIncomingArray(normalized, item, prev) || dynamic;
480
- } else if ((typeof item) === "function") {
481
+ } else if (t === "function") {
481
482
  if (unwrap) {
482
483
  while (typeof item === "function") item = item();
483
484
  dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item], Array.isArray(prev) ? prev : [prev]) || dynamic;
@@ -487,10 +488,7 @@ function normalizeIncomingArray(normalized, array, current, unwrap) {
487
488
  }
488
489
  } else {
489
490
  const value = String(item);
490
- if (prev && prev.nodeType === 3) {
491
- prev.data = value;
492
- normalized.push(prev);
493
- } else normalized.push(document.createTextNode(value));
491
+ if (prev && prev.nodeType === 3 && prev.data === value) normalized.push(prev);else normalized.push(document.createTextNode(value));
494
492
  }
495
493
  }
496
494
  return dynamic;
@@ -574,7 +572,9 @@ function Portal(props) {
574
572
  mount = () => props.mount || document.body,
575
573
  owner = getOwner();
576
574
  let content;
575
+ let hydrating = !!sharedConfig.context;
577
576
  createEffect(() => {
577
+ if (hydrating) getOwner().user = hydrating = false;
578
578
  content || (content = runWithOwner(owner, () => props.children));
579
579
  const el = mount();
580
580
  if (el instanceof HTMLHeadElement) {
@@ -598,6 +598,8 @@ function Portal(props) {
598
598
  props.ref && props.ref(container);
599
599
  onCleanup(() => el.removeChild(container));
600
600
  }
601
+ }, undefined, {
602
+ render: !hydrating
601
603
  });
602
604
  return marker;
603
605
  }
@@ -290,10 +290,10 @@ function ssrStyle(value) {
290
290
  return result;
291
291
  }
292
292
  function ssrElement(tag, props, children, needsId) {
293
- let result = `<${tag}${needsId ? ssrHydrationKey() : ""} `;
294
- const skipChildren = VOID_ELEMENTS.test(tag);
295
293
  if (props == null) props = {};else if (typeof props === "function") props = props();
294
+ const skipChildren = VOID_ELEMENTS.test(tag);
296
295
  const keys = Object.keys(props);
296
+ let result = `<${tag}${needsId ? ssrHydrationKey() : ""} `;
297
297
  let classResolved;
298
298
  for (let i = 0; i < keys.length; i++) {
299
299
  const prop = keys[i];
@@ -318,13 +318,12 @@ function ssrElement(tag, props, children, needsId) {
318
318
  }
319
319
  if (i !== keys.length - 1) result += " ";
320
320
  }
321
- if (skipChildren) {
322
- return {
323
- t: result + "/>"
324
- };
325
- }
321
+ if (skipChildren) return {
322
+ t: result + "/>"
323
+ };
324
+ if (typeof children === "function") children = children();
326
325
  return {
327
- t: result + `>${resolveSSRNode(children)}</${tag}>`
326
+ t: result + `>${resolveSSRNode(children, true)}</${tag}>`
328
327
  };
329
328
  }
330
329
  function ssrAttribute(key, value, isBoolean) {
@@ -380,7 +379,7 @@ function escape(s, attr) {
380
379
  }
381
380
  return left < s.length ? out + s.substring(left) : out;
382
381
  }
383
- function resolveSSRNode(node) {
382
+ function resolveSSRNode(node, top) {
384
383
  const t = typeof node;
385
384
  if (t === "string") return node;
386
385
  if (node == null || t === "boolean") return "";
@@ -388,7 +387,7 @@ function resolveSSRNode(node) {
388
387
  let prev = {};
389
388
  let mapped = "";
390
389
  for (let i = 0, len = node.length; i < len; i++) {
391
- if (typeof prev !== "object" && typeof node[i] !== "object") mapped += `<!--!$-->`;
390
+ if (!top && typeof prev !== "object" && typeof node[i] !== "object") mapped += `<!--!$-->`;
392
391
  mapped += resolveSSRNode(prev = node[i]);
393
392
  }
394
393
  return mapped;
@@ -414,7 +413,7 @@ function generateHydrationScript({
414
413
  eventNames = ["click", "input"],
415
414
  nonce
416
415
  } = {}) {
417
- return `<script${nonce ? ` nonce="${nonce}"` : ""}>(e=>{let 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])}))))})(window._$HY||(_$HY={events:[],completed:new WeakSet,r:{},fe(){},init(e,t){_$HY.r[e]=[new Promise((e=>t=e)),t]},set(e,t,o){(o=_$HY.r[e])&&o[1](t),_$HY.r[e]=[t]},unset(e){delete _$HY.r[e]},load:e=>_$HY.r[e]}));</script><!--xs-->`;
416
+ return `<script${nonce ? ` nonce="${nonce}"` : ""}>(e=>{let t=e=>e&&e.hasAttribute&&(e.hasAttribute("data-hk")?e:t(e.host&&e.host.nodeType?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])}))))})(window._$HY||(_$HY={events:[],completed:new WeakSet,r:{},fe(){},init(e,t){_$HY.r[e]=[new Promise((e=>t=e)),t]},set(e,t,o){(o=_$HY.r[e])&&o[1](t),_$HY.r[e]=[t]},unset(e){delete _$HY.r[e]},load:e=>_$HY.r[e]}));</script><!--xs-->`;
418
417
  }
419
418
  function Hydration(props) {
420
419
  if (!solidJs.sharedConfig.context.noHydrate) return props.children;
@@ -512,7 +511,7 @@ function ssrSpread(props, isSVG, skipChildren) {
512
511
  const keys = Object.keys(props);
513
512
  let classResolved;
514
513
  for (let i = 0; i < keys.length; i++) {
515
- const prop = keys[i];
514
+ let prop = keys[i];
516
515
  if (prop === "children") {
517
516
  !skipChildren && console.warn(`SSR currently does not support spread children.`);
518
517
  continue;
@@ -289,10 +289,10 @@ function ssrStyle(value) {
289
289
  return result;
290
290
  }
291
291
  function ssrElement(tag, props, children, needsId) {
292
- let result = `<${tag}${needsId ? ssrHydrationKey() : ""} `;
293
- const skipChildren = VOID_ELEMENTS.test(tag);
294
292
  if (props == null) props = {};else if (typeof props === "function") props = props();
293
+ const skipChildren = VOID_ELEMENTS.test(tag);
295
294
  const keys = Object.keys(props);
295
+ let result = `<${tag}${needsId ? ssrHydrationKey() : ""} `;
296
296
  let classResolved;
297
297
  for (let i = 0; i < keys.length; i++) {
298
298
  const prop = keys[i];
@@ -317,13 +317,12 @@ function ssrElement(tag, props, children, needsId) {
317
317
  }
318
318
  if (i !== keys.length - 1) result += " ";
319
319
  }
320
- if (skipChildren) {
321
- return {
322
- t: result + "/>"
323
- };
324
- }
320
+ if (skipChildren) return {
321
+ t: result + "/>"
322
+ };
323
+ if (typeof children === "function") children = children();
325
324
  return {
326
- t: result + `>${resolveSSRNode(children)}</${tag}>`
325
+ t: result + `>${resolveSSRNode(children, true)}</${tag}>`
327
326
  };
328
327
  }
329
328
  function ssrAttribute(key, value, isBoolean) {
@@ -379,7 +378,7 @@ function escape(s, attr) {
379
378
  }
380
379
  return left < s.length ? out + s.substring(left) : out;
381
380
  }
382
- function resolveSSRNode(node) {
381
+ function resolveSSRNode(node, top) {
383
382
  const t = typeof node;
384
383
  if (t === "string") return node;
385
384
  if (node == null || t === "boolean") return "";
@@ -387,7 +386,7 @@ function resolveSSRNode(node) {
387
386
  let prev = {};
388
387
  let mapped = "";
389
388
  for (let i = 0, len = node.length; i < len; i++) {
390
- if (typeof prev !== "object" && typeof node[i] !== "object") mapped += `<!--!$-->`;
389
+ if (!top && typeof prev !== "object" && typeof node[i] !== "object") mapped += `<!--!$-->`;
391
390
  mapped += resolveSSRNode(prev = node[i]);
392
391
  }
393
392
  return mapped;
@@ -413,7 +412,7 @@ function generateHydrationScript({
413
412
  eventNames = ["click", "input"],
414
413
  nonce
415
414
  } = {}) {
416
- return `<script${nonce ? ` nonce="${nonce}"` : ""}>(e=>{let 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])}))))})(window._$HY||(_$HY={events:[],completed:new WeakSet,r:{},fe(){},init(e,t){_$HY.r[e]=[new Promise((e=>t=e)),t]},set(e,t,o){(o=_$HY.r[e])&&o[1](t),_$HY.r[e]=[t]},unset(e){delete _$HY.r[e]},load:e=>_$HY.r[e]}));</script><!--xs-->`;
415
+ return `<script${nonce ? ` nonce="${nonce}"` : ""}>(e=>{let t=e=>e&&e.hasAttribute&&(e.hasAttribute("data-hk")?e:t(e.host&&e.host.nodeType?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])}))))})(window._$HY||(_$HY={events:[],completed:new WeakSet,r:{},fe(){},init(e,t){_$HY.r[e]=[new Promise((e=>t=e)),t]},set(e,t,o){(o=_$HY.r[e])&&o[1](t),_$HY.r[e]=[t]},unset(e){delete _$HY.r[e]},load:e=>_$HY.r[e]}));</script><!--xs-->`;
417
416
  }
418
417
  function Hydration(props) {
419
418
  if (!sharedConfig.context.noHydrate) return props.children;
@@ -511,7 +510,7 @@ function ssrSpread(props, isSVG, skipChildren) {
511
510
  const keys = Object.keys(props);
512
511
  let classResolved;
513
512
  for (let i = 0; i < keys.length; i++) {
514
- const prop = keys[i];
513
+ let prop = keys[i];
515
514
  if (prop === "children") {
516
515
  !skipChildren && console.warn(`SSR currently does not support spread children.`);
517
516
  continue;
package/web/dist/web.cjs CHANGED
@@ -457,7 +457,7 @@ function insertExpression(parent, value, current, marker, unwrapArray) {
457
457
  appendNodes(parent, array);
458
458
  }
459
459
  current = array;
460
- } else if (value instanceof Node) {
460
+ } else if (value.nodeType) {
461
461
  if (solidJs.sharedConfig.context && value.parentNode) return current = multi ? [value] : value;
462
462
  if (Array.isArray(current)) {
463
463
  if (multi) return current = cleanChildren(parent, current, marker, value);
@@ -473,12 +473,13 @@ function normalizeIncomingArray(normalized, array, current, unwrap) {
473
473
  let dynamic = false;
474
474
  for (let i = 0, len = array.length; i < len; i++) {
475
475
  let item = array[i],
476
- prev = current && current[i];
477
- if (item instanceof Node) {
476
+ prev = current && current[i],
477
+ t;
478
+ if (item == null || item === true || item === false) ; else if ((t = typeof item) === "object" && item.nodeType) {
478
479
  normalized.push(item);
479
- } else if (item == null || item === true || item === false) ; else if (Array.isArray(item)) {
480
+ } else if (Array.isArray(item)) {
480
481
  dynamic = normalizeIncomingArray(normalized, item, prev) || dynamic;
481
- } else if ((typeof item) === "function") {
482
+ } else if (t === "function") {
482
483
  if (unwrap) {
483
484
  while (typeof item === "function") item = item();
484
485
  dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item], Array.isArray(prev) ? prev : [prev]) || dynamic;
@@ -488,10 +489,7 @@ function normalizeIncomingArray(normalized, array, current, unwrap) {
488
489
  }
489
490
  } else {
490
491
  const value = String(item);
491
- if (prev && prev.nodeType === 3) {
492
- prev.data = value;
493
- normalized.push(prev);
494
- } else normalized.push(document.createTextNode(value));
492
+ if (prev && prev.nodeType === 3 && prev.data === value) normalized.push(prev);else normalized.push(document.createTextNode(value));
495
493
  }
496
494
  }
497
495
  return dynamic;
@@ -575,7 +573,9 @@ function Portal(props) {
575
573
  mount = () => props.mount || document.body,
576
574
  owner = solidJs.getOwner();
577
575
  let content;
576
+ let hydrating = !!solidJs.sharedConfig.context;
578
577
  solidJs.createEffect(() => {
578
+ if (hydrating) solidJs.getOwner().user = hydrating = false;
579
579
  content || (content = solidJs.runWithOwner(owner, () => props.children));
580
580
  const el = mount();
581
581
  if (el instanceof HTMLHeadElement) {
@@ -599,6 +599,8 @@ function Portal(props) {
599
599
  props.ref && props.ref(container);
600
600
  solidJs.onCleanup(() => el.removeChild(container));
601
601
  }
602
+ }, undefined, {
603
+ render: !hydrating
602
604
  });
603
605
  return marker;
604
606
  }
package/web/dist/web.js CHANGED
@@ -456,7 +456,7 @@ function insertExpression(parent, value, current, marker, unwrapArray) {
456
456
  appendNodes(parent, array);
457
457
  }
458
458
  current = array;
459
- } else if (value instanceof Node) {
459
+ } else if (value.nodeType) {
460
460
  if (sharedConfig.context && value.parentNode) return current = multi ? [value] : value;
461
461
  if (Array.isArray(current)) {
462
462
  if (multi) return current = cleanChildren(parent, current, marker, value);
@@ -472,12 +472,13 @@ function normalizeIncomingArray(normalized, array, current, unwrap) {
472
472
  let dynamic = false;
473
473
  for (let i = 0, len = array.length; i < len; i++) {
474
474
  let item = array[i],
475
- prev = current && current[i];
476
- if (item instanceof Node) {
475
+ prev = current && current[i],
476
+ t;
477
+ if (item == null || item === true || item === false) ; else if ((t = typeof item) === "object" && item.nodeType) {
477
478
  normalized.push(item);
478
- } else if (item == null || item === true || item === false) ; else if (Array.isArray(item)) {
479
+ } else if (Array.isArray(item)) {
479
480
  dynamic = normalizeIncomingArray(normalized, item, prev) || dynamic;
480
- } else if ((typeof item) === "function") {
481
+ } else if (t === "function") {
481
482
  if (unwrap) {
482
483
  while (typeof item === "function") item = item();
483
484
  dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item], Array.isArray(prev) ? prev : [prev]) || dynamic;
@@ -487,10 +488,7 @@ function normalizeIncomingArray(normalized, array, current, unwrap) {
487
488
  }
488
489
  } else {
489
490
  const value = String(item);
490
- if (prev && prev.nodeType === 3) {
491
- prev.data = value;
492
- normalized.push(prev);
493
- } else normalized.push(document.createTextNode(value));
491
+ if (prev && prev.nodeType === 3 && prev.data === value) normalized.push(prev);else normalized.push(document.createTextNode(value));
494
492
  }
495
493
  }
496
494
  return dynamic;
@@ -574,7 +572,9 @@ function Portal(props) {
574
572
  mount = () => props.mount || document.body,
575
573
  owner = getOwner();
576
574
  let content;
575
+ let hydrating = !!sharedConfig.context;
577
576
  createEffect(() => {
577
+ if (hydrating) getOwner().user = hydrating = false;
578
578
  content || (content = runWithOwner(owner, () => props.children));
579
579
  const el = mount();
580
580
  if (el instanceof HTMLHeadElement) {
@@ -598,6 +598,8 @@ function Portal(props) {
598
598
  props.ref && props.ref(container);
599
599
  onCleanup(() => el.removeChild(container));
600
600
  }
601
+ }, undefined, {
602
+ render: !hydrating
601
603
  });
602
604
  return marker;
603
605
  }