WebReflection / hyperHTML

A Fast & Light Virtual DOM Alternative
ISC License
3.06k stars 112 forks source link

Weak relation in wire method is not working #391

Closed jakubhruby closed 4 years ago

jakubhruby commented 4 years ago

I tried a snippet from hyperHTML documentation to play with weak relation in wire() method, but it doesn't seem to be working. The second generated element is a new one, not the same. Check it out: https://jsfiddle.net/5u6Lvn0h/2/

WebReflection commented 4 years ago

those are two different template literals ... try again:

const {wire, bind} = hyperHTML;

const li = info => hyperHTML.wire(info)`<li></li>`;

const info = {some: 'data'};
const sameLI = li(info)

// what if we use same template later on?
console.assert(
  sameLI === li(info),
  'same reference means exactly the same node'
);
jakubhruby commented 4 years ago

Please help me get the difference between calling wire() twice in code or twice via anonymous function. As I understand it you do not compare the content of literals, but the literal arrays (strict comparisons), am I right?

const {wire} = hyperHTML;

const info = {some: 'data'};
const notSameLI = hyperHTML.wire(info)`<li></li>`;
const sameLI = li();

function li()  {
    return hyperHTML.wire(info)`<li></li>`
}

// this works, because literal is created just once inside li() function body
console.assert(
  sameLI === li(),
  'sameLI: same reference means exactly the same node'
);

// this doesn't work, because we have two literal objects with the same content
console.assert(
  sameLI === hyperHTML.wire(info)`<li></li>`,
  'notSameLI: same reference means exactly the same node'
);

https://jsfiddle.net/t24qgs36/

WebReflection commented 4 years ago

Please help me get the difference between calling wire() twice in code or twice via anonymous function.

The issue is not wire(), but how template literals uniqueness works.

const templates = new Set;
const tag = template => { templates.add(template); };
const same = value => tag`a${value}c`;

// these two calls will use the same template literal
same(1);
same(2);
// indeed the set size is 1
console.log(templates.size);

templates.clear();

// these are two different templates literals
// even with the same value (as it's irrelevant)
tag`a${1}c`;
tag`a${1}c`;

// this will log 2
console.log(templates.size);

As I understand it you do not compare the content of literals, but the literal arrays (strict comparisons), am I right?

I compare nothing, I associate a template literal to a node. If the template literal is different, the node is different.

That's how every template literal based library works, and again, it's because of how template literals uniqueness is specified by ECMAScript standard.

WebReflection commented 4 years ago

more info here, since the behavior changed over time, and hyperHTML was born before that change: https://medium.com/@WebReflection/a-tiny-disastrous-ecmascript-change-fadc05c83e69