solid-js 1.7.1 → 1.7.3

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) {
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) {
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) {
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) {
@@ -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.1",
4
+ "version": "1.7.3",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",
7
7
  "homepage": "https://solidjs.com",
@@ -59,7 +59,7 @@ function unwrap(item, set = new Set()) {
59
59
  function getDataNodes(target) {
60
60
  let nodes = target[$NODE];
61
61
  if (!nodes) Object.defineProperty(target, $NODE, {
62
- value: nodes = {}
62
+ value: nodes = Object.create(null)
63
63
  });
64
64
  return nodes;
65
65
  }
@@ -101,8 +101,8 @@ const proxyTraps$1 = {
101
101
  return receiver;
102
102
  }
103
103
  const nodes = getDataNodes(target);
104
- const tracked = nodes.hasOwnProperty(property);
105
- let value = tracked ? nodes[property]() : target[property];
104
+ const tracked = nodes[property];
105
+ let value = tracked ? tracked() : target[property];
106
106
  if (property === $NODE || property === "__proto__") return value;
107
107
  if (!tracked) {
108
108
  const desc = Object.getOwnPropertyDescriptor(target, property);
@@ -239,8 +239,8 @@ const proxyTraps = {
239
239
  return receiver;
240
240
  }
241
241
  const nodes = getDataNodes(target);
242
- const tracked = nodes.hasOwnProperty(property);
243
- let value = tracked ? nodes[property]() : target[property];
242
+ const tracked = nodes[property];
243
+ let value = tracked ? tracked() : target[property];
244
244
  if (property === $NODE || property === "__proto__") return value;
245
245
  if (!tracked) {
246
246
  const desc = Object.getOwnPropertyDescriptor(target, property);
@@ -421,14 +421,14 @@ function produce(fn) {
421
421
  };
422
422
  }
423
423
 
424
- exports.DEV = void 0;
425
- exports.DEV = {
424
+ const DEV = {
426
425
  $NODE,
427
426
  isWrappable,
428
427
  hooks: DevHooks
429
- };
428
+ } ;
430
429
 
431
430
  exports.$RAW = $RAW;
431
+ exports.DEV = DEV;
432
432
  exports.createMutable = createMutable;
433
433
  exports.createStore = createStore;
434
434
  exports.modifyMutable = modifyMutable;
package/store/dist/dev.js CHANGED
@@ -57,7 +57,7 @@ function unwrap(item, set = new Set()) {
57
57
  function getDataNodes(target) {
58
58
  let nodes = target[$NODE];
59
59
  if (!nodes) Object.defineProperty(target, $NODE, {
60
- value: nodes = {}
60
+ value: nodes = Object.create(null)
61
61
  });
62
62
  return nodes;
63
63
  }
@@ -99,8 +99,8 @@ const proxyTraps$1 = {
99
99
  return receiver;
100
100
  }
101
101
  const nodes = getDataNodes(target);
102
- const tracked = nodes.hasOwnProperty(property);
103
- let value = tracked ? nodes[property]() : target[property];
102
+ const tracked = nodes[property];
103
+ let value = tracked ? tracked() : target[property];
104
104
  if (property === $NODE || property === "__proto__") return value;
105
105
  if (!tracked) {
106
106
  const desc = Object.getOwnPropertyDescriptor(target, property);
@@ -237,8 +237,8 @@ const proxyTraps = {
237
237
  return receiver;
238
238
  }
239
239
  const nodes = getDataNodes(target);
240
- const tracked = nodes.hasOwnProperty(property);
241
- let value = tracked ? nodes[property]() : target[property];
240
+ const tracked = nodes[property];
241
+ let value = tracked ? tracked() : target[property];
242
242
  if (property === $NODE || property === "__proto__") return value;
243
243
  if (!tracked) {
244
244
  const desc = Object.getOwnPropertyDescriptor(target, property);
@@ -419,11 +419,10 @@ function produce(fn) {
419
419
  };
420
420
  }
421
421
 
422
- let DEV;
423
- DEV = {
422
+ const DEV = {
424
423
  $NODE,
425
424
  isWrappable,
426
425
  hooks: DevHooks
427
- };
426
+ } ;
428
427
 
429
428
  export { $RAW, DEV, createMutable, createStore, modifyMutable, produce, reconcile, unwrap };
@@ -56,7 +56,7 @@ function unwrap(item, set = new Set()) {
56
56
  function getDataNodes(target) {
57
57
  let nodes = target[$NODE];
58
58
  if (!nodes) Object.defineProperty(target, $NODE, {
59
- value: nodes = {}
59
+ value: nodes = Object.create(null)
60
60
  });
61
61
  return nodes;
62
62
  }
@@ -98,8 +98,8 @@ const proxyTraps$1 = {
98
98
  return receiver;
99
99
  }
100
100
  const nodes = getDataNodes(target);
101
- const tracked = nodes.hasOwnProperty(property);
102
- let value = tracked ? nodes[property]() : target[property];
101
+ const tracked = nodes[property];
102
+ let value = tracked ? tracked() : target[property];
103
103
  if (property === $NODE || property === "__proto__") return value;
104
104
  if (!tracked) {
105
105
  const desc = Object.getOwnPropertyDescriptor(target, property);
@@ -228,8 +228,8 @@ const proxyTraps = {
228
228
  return receiver;
229
229
  }
230
230
  const nodes = getDataNodes(target);
231
- const tracked = nodes.hasOwnProperty(property);
232
- let value = tracked ? nodes[property]() : target[property];
231
+ const tracked = nodes[property];
232
+ let value = tracked ? tracked() : target[property];
233
233
  if (property === $NODE || property === "__proto__") return value;
234
234
  if (!tracked) {
235
235
  const desc = Object.getOwnPropertyDescriptor(target, property);
@@ -405,7 +405,7 @@ function produce(fn) {
405
405
  };
406
406
  }
407
407
 
408
- let DEV;
408
+ const DEV = undefined;
409
409
 
410
410
  exports.$RAW = $RAW;
411
411
  exports.DEV = DEV;
@@ -54,7 +54,7 @@ function unwrap(item, set = new Set()) {
54
54
  function getDataNodes(target) {
55
55
  let nodes = target[$NODE];
56
56
  if (!nodes) Object.defineProperty(target, $NODE, {
57
- value: nodes = {}
57
+ value: nodes = Object.create(null)
58
58
  });
59
59
  return nodes;
60
60
  }
@@ -96,8 +96,8 @@ const proxyTraps$1 = {
96
96
  return receiver;
97
97
  }
98
98
  const nodes = getDataNodes(target);
99
- const tracked = nodes.hasOwnProperty(property);
100
- let value = tracked ? nodes[property]() : target[property];
99
+ const tracked = nodes[property];
100
+ let value = tracked ? tracked() : target[property];
101
101
  if (property === $NODE || property === "__proto__") return value;
102
102
  if (!tracked) {
103
103
  const desc = Object.getOwnPropertyDescriptor(target, property);
@@ -226,8 +226,8 @@ const proxyTraps = {
226
226
  return receiver;
227
227
  }
228
228
  const nodes = getDataNodes(target);
229
- const tracked = nodes.hasOwnProperty(property);
230
- let value = tracked ? nodes[property]() : target[property];
229
+ const tracked = nodes[property];
230
+ let value = tracked ? tracked() : target[property];
231
231
  if (property === $NODE || property === "__proto__") return value;
232
232
  if (!tracked) {
233
233
  const desc = Object.getOwnPropertyDescriptor(target, property);
@@ -403,6 +403,6 @@ function produce(fn) {
403
403
  };
404
404
  }
405
405
 
406
- let DEV;
406
+ const DEV = undefined;
407
407
 
408
408
  export { $RAW, DEV, createMutable, createStore, modifyMutable, produce, reconcile, unwrap };
@@ -2,10 +2,11 @@ export { $RAW, createStore, unwrap } from "./store.js";
2
2
  export type { ArrayFilterFn, DeepMutable, DeepReadonly, NotWrappable, Part, SetStoreFunction, SolidStore, Store, StoreNode, StorePathRange, StoreSetter } from "./store.js";
3
3
  export * from "./mutable.js";
4
4
  export * from "./modifiers.js";
5
- import { $NODE, isWrappable, DevHooks } from "./store.js";
6
- declare let DEV: {
7
- $NODE: typeof $NODE;
8
- isWrappable: typeof isWrappable;
9
- hooks: typeof DevHooks;
5
+ import { $NODE, isWrappable } from "./store.js";
6
+ export declare const DEV: {
7
+ readonly $NODE: typeof $NODE;
8
+ readonly isWrappable: typeof isWrappable;
9
+ readonly hooks: {
10
+ onStoreNodeUpdate: import("./store.js").OnStoreNodeUpdate | null;
11
+ };
10
12
  } | undefined;
11
- export { DEV };
@@ -6,7 +6,7 @@ type DataNode = {
6
6
  (): any;
7
7
  $(value?: any): void;
8
8
  };
9
- type DataNodes = Record<PropertyKey, DataNode>;
9
+ type DataNodes = Record<PropertyKey, DataNode | undefined>;
10
10
  export type OnStoreNodeUpdate = (state: StoreNode, property: PropertyKey, value: StoreNode | NotWrappable, prev: StoreNode | NotWrappable) => void;
11
11
  export interface StoreNode {
12
12
  [$NODE]?: DataNodes;
package/types/index.d.ts CHANGED
@@ -7,13 +7,15 @@ export * from "./render/index.js";
7
7
  import type { JSX } from "./jsx.js";
8
8
  type JSXElement = JSX.Element;
9
9
  export type { JSXElement, JSX };
10
- import { registerGraph, writeSignal, DevHooks } from "./reactive/signal.js";
11
- declare const DEV: {
12
- readonly hooks: typeof DevHooks;
10
+ import { registerGraph, writeSignal } from "./reactive/signal.js";
11
+ export declare const DEV: {
12
+ readonly hooks: {
13
+ afterUpdate: (() => void) | null;
14
+ afterCreateOwner: ((owner: import("./reactive/signal.js").Owner) => void) | null;
15
+ };
13
16
  readonly writeSignal: typeof writeSignal;
14
17
  readonly registerGraph: typeof registerGraph;
15
18
  } | undefined;
16
- export { DEV };
17
19
  declare global {
18
20
  var Solid$$: boolean;
19
21
  }
@@ -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
@@ -575,7 +575,9 @@ function Portal(props) {
575
575
  mount = () => props.mount || document.body,
576
576
  owner = solidJs.getOwner();
577
577
  let content;
578
+ let hydrating = !!solidJs.sharedConfig.context;
578
579
  solidJs.createEffect(() => {
580
+ if (hydrating) solidJs.getOwner().user = hydrating = false;
579
581
  content || (content = solidJs.runWithOwner(owner, () => props.children));
580
582
  const el = mount();
581
583
  if (el instanceof HTMLHeadElement) {
@@ -599,6 +601,8 @@ function Portal(props) {
599
601
  props.ref && props.ref(container);
600
602
  solidJs.onCleanup(() => el.removeChild(container));
601
603
  }
604
+ }, undefined, {
605
+ render: !hydrating
602
606
  });
603
607
  return marker;
604
608
  }
package/web/dist/dev.js CHANGED
@@ -574,7 +574,9 @@ function Portal(props) {
574
574
  mount = () => props.mount || document.body,
575
575
  owner = getOwner();
576
576
  let content;
577
+ let hydrating = !!sharedConfig.context;
577
578
  createEffect(() => {
579
+ if (hydrating) getOwner().user = hydrating = false;
578
580
  content || (content = runWithOwner(owner, () => props.children));
579
581
  const el = mount();
580
582
  if (el instanceof HTMLHeadElement) {
@@ -598,6 +600,8 @@ function Portal(props) {
598
600
  props.ref && props.ref(container);
599
601
  onCleanup(() => el.removeChild(container));
600
602
  }
603
+ }, undefined, {
604
+ render: !hydrating
601
605
  });
602
606
  return marker;
603
607
  }
@@ -512,7 +512,7 @@ function ssrSpread(props, isSVG, skipChildren) {
512
512
  const keys = Object.keys(props);
513
513
  let classResolved;
514
514
  for (let i = 0; i < keys.length; i++) {
515
- const prop = keys[i];
515
+ let prop = keys[i];
516
516
  if (prop === "children") {
517
517
  !skipChildren && console.warn(`SSR currently does not support spread children.`);
518
518
  continue;
@@ -511,7 +511,7 @@ function ssrSpread(props, isSVG, skipChildren) {
511
511
  const keys = Object.keys(props);
512
512
  let classResolved;
513
513
  for (let i = 0; i < keys.length; i++) {
514
- const prop = keys[i];
514
+ let prop = keys[i];
515
515
  if (prop === "children") {
516
516
  !skipChildren && console.warn(`SSR currently does not support spread children.`);
517
517
  continue;
package/web/dist/web.cjs CHANGED
@@ -575,7 +575,9 @@ function Portal(props) {
575
575
  mount = () => props.mount || document.body,
576
576
  owner = solidJs.getOwner();
577
577
  let content;
578
+ let hydrating = !!solidJs.sharedConfig.context;
578
579
  solidJs.createEffect(() => {
580
+ if (hydrating) solidJs.getOwner().user = hydrating = false;
579
581
  content || (content = solidJs.runWithOwner(owner, () => props.children));
580
582
  const el = mount();
581
583
  if (el instanceof HTMLHeadElement) {
@@ -599,6 +601,8 @@ function Portal(props) {
599
601
  props.ref && props.ref(container);
600
602
  solidJs.onCleanup(() => el.removeChild(container));
601
603
  }
604
+ }, undefined, {
605
+ render: !hydrating
602
606
  });
603
607
  return marker;
604
608
  }
package/web/dist/web.js CHANGED
@@ -574,7 +574,9 @@ function Portal(props) {
574
574
  mount = () => props.mount || document.body,
575
575
  owner = getOwner();
576
576
  let content;
577
+ let hydrating = !!sharedConfig.context;
577
578
  createEffect(() => {
579
+ if (hydrating) getOwner().user = hydrating = false;
578
580
  content || (content = runWithOwner(owner, () => props.children));
579
581
  const el = mount();
580
582
  if (el instanceof HTMLHeadElement) {
@@ -598,6 +600,8 @@ function Portal(props) {
598
600
  props.ref && props.ref(container);
599
601
  onCleanup(() => el.removeChild(container));
600
602
  }
603
+ }, undefined, {
604
+ render: !hydrating
601
605
  });
602
606
  return marker;
603
607
  }