vasille 3.0.2 → 3.1.0

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 (102) hide show
  1. package/README.md +5 -6
  2. package/lib/core/core.js +35 -13
  3. package/lib/core/ivalue.js +1 -2
  4. package/lib/index.js +20 -22
  5. package/lib/models/array-model.js +1 -1
  6. package/lib/models/map-model.js +2 -2
  7. package/lib/models/set-model.js +2 -2
  8. package/lib/node/app.js +7 -7
  9. package/lib/node/node.js +45 -360
  10. package/lib/node/watch.js +5 -6
  11. package/lib/{binding → runner/web/binding}/attribute.js +1 -1
  12. package/lib/{binding → runner/web/binding}/binding.js +1 -1
  13. package/lib/{binding → runner/web/binding}/class.js +1 -1
  14. package/lib/{binding → runner/web/binding}/style.js +1 -1
  15. package/lib/runner/web/runner.js +162 -0
  16. package/lib/tsconfig.tsbuildinfo +1 -1
  17. package/lib/value/expression.js +2 -2
  18. package/lib/value/pointer.js +7 -12
  19. package/lib/value/reference.js +2 -2
  20. package/lib/views/array-view.js +1 -1
  21. package/lib/views/base-view.js +3 -3
  22. package/lib/views/map-view.js +1 -1
  23. package/lib/views/repeat-node.js +5 -6
  24. package/lib/views/set-view.js +3 -3
  25. package/package.json +31 -25
  26. package/types/core/core.d.ts +14 -8
  27. package/types/index.d.ts +22 -24
  28. package/types/models/array-model.d.ts +2 -2
  29. package/types/models/map-model.d.ts +2 -2
  30. package/types/models/model.d.ts +2 -2
  31. package/types/models/set-model.d.ts +2 -2
  32. package/types/node/app.d.ts +8 -7
  33. package/types/node/node.d.ts +49 -144
  34. package/types/node/runner.d.ts +10 -0
  35. package/types/node/watch.d.ts +7 -6
  36. package/types/{binding → runner/web/binding}/attribute.d.ts +4 -4
  37. package/types/{binding → runner/web/binding}/binding.d.ts +2 -2
  38. package/types/runner/web/binding/class.d.ts +11 -0
  39. package/types/{binding → runner/web/binding}/style.d.ts +4 -4
  40. package/types/runner/web/runner.d.ts +42 -0
  41. package/types/tsconfig-types.tsbuildinfo +1 -1
  42. package/types/value/expression.d.ts +2 -2
  43. package/types/value/pointer.d.ts +1 -1
  44. package/types/value/reference.d.ts +1 -1
  45. package/types/views/array-view.d.ts +5 -5
  46. package/types/views/base-view.d.ts +7 -6
  47. package/types/views/map-view.d.ts +3 -3
  48. package/types/views/repeat-node.d.ts +8 -7
  49. package/types/views/set-view.d.ts +5 -4
  50. package/lib/core/config.js +0 -3
  51. package/lib/models/object-model.js +0 -78
  52. package/lib/spec/html.js +0 -1
  53. package/lib/spec/react.js +0 -1
  54. package/lib/spec/svg.js +0 -1
  55. package/lib/tsconfig-build.tsbuildinfo +0 -1
  56. package/lib/value/mirror.js +0 -42
  57. package/lib/views/object-view.js +0 -17
  58. package/lib-node/binding/attribute.js +0 -34
  59. package/lib-node/binding/binding.js +0 -32
  60. package/lib-node/binding/class.js +0 -46
  61. package/lib-node/binding/style.js +0 -36
  62. package/lib-node/core/config.js +0 -6
  63. package/lib-node/core/core.js +0 -101
  64. package/lib-node/core/destroyable.js +0 -14
  65. package/lib-node/core/errors.js +0 -22
  66. package/lib-node/core/ivalue.js +0 -19
  67. package/lib-node/functional/options.js +0 -2
  68. package/lib-node/functional/safety.js +0 -12
  69. package/lib-node/index.js +0 -51
  70. package/lib-node/models/array-model.js +0 -152
  71. package/lib-node/models/listener.js +0 -70
  72. package/lib-node/models/map-model.js +0 -63
  73. package/lib-node/models/model.js +0 -2
  74. package/lib-node/models/object-model.js +0 -82
  75. package/lib-node/models/set-model.js +0 -59
  76. package/lib-node/node/app.js +0 -34
  77. package/lib-node/node/node.js +0 -656
  78. package/lib-node/node/watch.js +0 -26
  79. package/lib-node/spec/html.js +0 -2
  80. package/lib-node/spec/react.js +0 -2
  81. package/lib-node/spec/svg.js +0 -2
  82. package/lib-node/tsconfig-build-node.tsbuildinfo +0 -1
  83. package/lib-node/value/expression.js +0 -65
  84. package/lib-node/value/mirror.js +0 -46
  85. package/lib-node/value/pointer.js +0 -79
  86. package/lib-node/value/reference.js +0 -50
  87. package/lib-node/views/array-view.js +0 -21
  88. package/lib-node/views/base-view.js +0 -31
  89. package/lib-node/views/map-view.js +0 -18
  90. package/lib-node/views/object-view.js +0 -21
  91. package/lib-node/views/repeat-node.js +0 -53
  92. package/lib-node/views/set-view.js +0 -22
  93. package/types/binding/class.d.ts +0 -11
  94. package/types/core/config.d.ts +0 -3
  95. package/types/functional/options.d.ts +0 -10
  96. package/types/models/object-model.d.ts +0 -38
  97. package/types/spec/html.d.ts +0 -975
  98. package/types/spec/react.d.ts +0 -4
  99. package/types/spec/svg.d.ts +0 -314
  100. package/types/value/mirror.d.ts +0 -33
  101. package/types/views/object-view.d.ts +0 -10
  102. /package/lib/{functional/options.js → node/runner.js} +0 -0
package/lib/node/node.js CHANGED
@@ -1,25 +1,18 @@
1
- import { Reactive } from "../core/core";
2
- import { IValue } from "../core/ivalue";
3
- import { Reference } from "../value/reference";
4
- import { Expression } from "../value/expression";
5
- import { AttributeBinding } from "../binding/attribute";
6
- import { StaticClassBinding, DynamicalClassBinding } from "../binding/class";
7
- import { stringifyStyleValue, StyleBinding } from "../binding/style";
8
- import { internalError, userError } from "../core/errors";
9
- import { config } from "../core/config";
1
+ import { Reactive } from "../core/core.js";
2
+ import { IValue } from "../core/ivalue.js";
3
+ import { SetModel } from "../models/set-model.js";
4
+ import { Reference } from "../value/reference.js";
5
+ import { userError } from "../core/errors.js";
10
6
  /**
11
7
  * This class is symbolic
12
8
  * @extends Reactive
13
9
  */
14
10
  export class Root extends Reactive {
15
- constructor() {
16
- super(...arguments);
17
- /**
18
- * The children list
19
- * @type Array
20
- */
21
- this.children = new Set();
11
+ constructor(input, runner) {
12
+ super(input);
22
13
  this.lastChild = undefined;
14
+ this.runner = runner;
15
+ this.children = runner.debugUi ? new SetModel() : new Set();
23
16
  }
24
17
  /**
25
18
  * Pushes a node to children immediately
@@ -38,9 +31,12 @@ export class Root extends Reactive {
38
31
  */
39
32
  findFirstChild() {
40
33
  let first;
41
- this.children.forEach(child => {
42
- first = first || child.findFirstChild();
43
- });
34
+ for (const child of this.children) {
35
+ first = child.findFirstChild();
36
+ if (first) {
37
+ break;
38
+ }
39
+ }
44
40
  return first;
45
41
  }
46
42
  /**
@@ -49,16 +45,14 @@ export class Root extends Reactive {
49
45
  * @param cb {function (TextNode)} Callback if previous is slot name
50
46
  */
51
47
  text(text) {
52
- const node = new TextNode({ text });
48
+ const node = this.runner.textNode(text);
53
49
  this.pushNode(node);
54
50
  node.compose();
55
51
  }
56
52
  debug(text) {
57
- if (config.debugUi) {
58
- const node = new DebugNode({ text });
59
- this.pushNode(node);
60
- node.compose();
61
- }
53
+ const node = this.runner.debugNode(text);
54
+ this.pushNode(node);
55
+ node.compose();
62
56
  }
63
57
  /**
64
58
  * Defines a tag element
@@ -67,8 +61,7 @@ export class Root extends Reactive {
67
61
  * @param cb {function(Tag, *)} callback
68
62
  */
69
63
  tag(tagName, input, cb) {
70
- const tag = new Tag(input, tagName);
71
- input.slot = cb || input.slot;
64
+ const tag = this.runner.tag(tagName, input, cb);
72
65
  this.pushNode(tag);
73
66
  tag.compose();
74
67
  }
@@ -80,7 +73,7 @@ export class Root extends Reactive {
80
73
  create(node, callback) {
81
74
  this.pushNode(node);
82
75
  node.compose();
83
- callback === null || callback === void 0 ? void 0 : callback(node);
76
+ callback?.(node);
84
77
  }
85
78
  /**
86
79
  * Defines an if node
@@ -89,7 +82,7 @@ export class Root extends Reactive {
89
82
  * @return {this}
90
83
  */
91
84
  if(cond, cb) {
92
- const node = new SwitchedNode();
85
+ const node = new SwitchedNode(this.runner);
93
86
  this.pushNode(node);
94
87
  node.addCase(this.case(cond, cb));
95
88
  }
@@ -133,8 +126,8 @@ export class Root extends Reactive {
133
126
  }
134
127
  }
135
128
  export class Fragment extends Root {
136
- constructor(input, name) {
137
- super(input);
129
+ constructor(input, runner, name) {
130
+ super(input, runner);
138
131
  this.name = name;
139
132
  }
140
133
  /**
@@ -150,7 +143,7 @@ export class Fragment extends Root {
150
143
  super.pushNode(node);
151
144
  }
152
145
  /**
153
- * Append a node to end of element
146
+ * Append a node to the end of element
154
147
  * @param node {Node} node to insert
155
148
  */
156
149
  appendNode(node) {
@@ -168,10 +161,7 @@ export class Fragment extends Root {
168
161
  insertAdjacent(node) {
169
162
  const child = this.findFirstChild();
170
163
  if (child) {
171
- const parent = child.parentElement;
172
- if (parent) {
173
- child.parentElement.insertBefore(node, child);
174
- }
164
+ this.runner.insertBefore(node, child);
175
165
  }
176
166
  else if (this.next) {
177
167
  this.next.insertAdjacent(node);
@@ -204,6 +194,7 @@ export class Fragment extends Root {
204
194
  if (this.prev) {
205
195
  this.prev.next = this.next;
206
196
  }
197
+ this.parent.children.delete(this);
207
198
  }
208
199
  destroy() {
209
200
  if (this.parent.lastChild === this) {
@@ -219,26 +210,14 @@ const trueIValue = new Reference(true);
219
210
  * @extends Fragment
220
211
  */
221
212
  export class TextNode extends Fragment {
222
- constructor(input) {
223
- super(input, ":text");
213
+ constructor(input, runner) {
214
+ super(input, runner, ":text");
224
215
  }
225
- compose() {
226
- var _a, _b;
216
+ destroy() {
227
217
  const text = this.input.text;
228
- this.node = document.createTextNode((_b = (_a = (text instanceof IValue ? text.$ : text)) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : "");
229
- if (text instanceof IValue) {
230
- this.register(new Expression((v) => {
231
- var _a;
232
- this.node.replaceData(0, -1, (_a = v === null || v === void 0 ? void 0 : v.toString()) !== null && _a !== void 0 ? _a : "");
233
- }, text));
218
+ if (text instanceof IValue && this.handler) {
219
+ text.off(this.handler);
234
220
  }
235
- this.parent.appendNode(this.node);
236
- }
237
- findFirstChild() {
238
- return this.node;
239
- }
240
- destroy() {
241
- this.node.remove();
242
221
  super.destroy();
243
222
  }
244
223
  }
@@ -248,220 +227,11 @@ export class TextNode extends Fragment {
248
227
  * @extends Fragment
249
228
  */
250
229
  export class INode extends Fragment {
251
- constructor() {
252
- super(...arguments);
253
- /**
254
- * Defines if node is unmounted
255
- * @type {boolean}
256
- */
257
- this.unmounted = false;
258
- }
259
230
  get element() {
260
231
  return this.node;
261
232
  }
262
- /**
263
- * Bind attribute value
264
- * @param name {String} name of attribute
265
- * @param value {IValue} value
266
- */
267
- attr(name, value) {
268
- this.register(new AttributeBinding(this, name, value));
269
- }
270
- /**
271
- * Set attribute value
272
- * @param name {string} name of attribute
273
- * @param value {string} value
274
- */
275
- setAttr(name, value) {
276
- if (typeof value === "boolean") {
277
- if (value) {
278
- this.node.setAttribute(name, "");
279
- }
280
- }
281
- else if (value !== null && value !== undefined) {
282
- this.node.setAttribute(name, `${value}`);
283
- }
284
- return this;
285
- }
286
- /**
287
- * Adds a CSS class
288
- * @param cl {string} Class name
289
- */
290
- addClass(cl) {
291
- this.node.classList.add(cl);
292
- }
293
- /**
294
- * Adds some CSS classes
295
- * @param cl {string} classes names
296
- */
297
- removeClass(cl) {
298
- this.node.classList.remove(cl);
299
- }
300
- /**
301
- * Bind a CSS class
302
- * @param className {IValue}
303
- */
304
- bindClass(className) {
305
- this.register(new DynamicalClassBinding(this, className));
306
- }
307
- /**
308
- * Bind a floating class name
309
- * @param cond {IValue} condition
310
- * @param className {string} class name
311
- */
312
- floatingClass(cond, className) {
313
- this.register(new StaticClassBinding(this, className, cond));
314
- }
315
- /**
316
- * Defines a style attribute
317
- * @param name {String} name of style attribute
318
- * @param value {IValue} value
319
- */
320
- style(name, value) {
321
- if (this.node instanceof HTMLElement) {
322
- this.register(new StyleBinding(this, name, value));
323
- }
324
- else {
325
- throw userError("style can be applied to HTML elements only", "non-html-element");
326
- }
327
- }
328
- /**
329
- * Sets a style property value
330
- * @param prop {string} Property name
331
- * @param value {string} Property value
332
- */
333
- setStyle(prop, value) {
334
- if (this.node instanceof HTMLElement) {
335
- this.node.style.setProperty(prop, stringifyStyleValue(value));
336
- }
337
- else {
338
- throw userError("Style can be set for HTML elements only", "non-html-element");
339
- }
340
- return this;
341
- }
342
- /**
343
- * Add a listener for an event
344
- * @param name {string} Event name
345
- * @param handler {function (Event)} Event handler
346
- * @param options {Object | boolean} addEventListener options
347
- */
348
- listen(name, handler, options) {
349
- this.node.addEventListener(name, handler, options);
350
- }
351
233
  insertAdjacent(node) {
352
- const parent = this.node.parentNode;
353
- if (parent) {
354
- parent.insertBefore(node, this.node);
355
- }
356
- }
357
- /**
358
- * A v-show & ngShow alternative
359
- * @param cond {IValue} show condition
360
- */
361
- bindShow(cond) {
362
- const node = this.node;
363
- if (node instanceof HTMLElement) {
364
- let lastDisplay = node.style.display;
365
- const htmlNode = node;
366
- this.register(new Expression(cond => {
367
- if (cond) {
368
- if (htmlNode.style.display === "none") {
369
- htmlNode.style.display = lastDisplay;
370
- }
371
- }
372
- else {
373
- if (htmlNode.style.display !== "none") {
374
- lastDisplay = htmlNode.style.display;
375
- htmlNode.style.display = "none";
376
- }
377
- }
378
- }, cond));
379
- }
380
- else {
381
- throw userError("the element must be a html element", "bind-show");
382
- }
383
- }
384
- /**
385
- * bind HTML
386
- * @param value {IValue}
387
- */
388
- bindDomApi(name, value) {
389
- const node = this.node;
390
- if (node instanceof HTMLElement) {
391
- node[name] = value.$;
392
- this.watch((v) => {
393
- node[name] = v;
394
- }, value);
395
- }
396
- else {
397
- throw userError("HTML can be bound for HTML nodes only", "dom-error");
398
- }
399
- }
400
- applyAttrs(attrs) {
401
- for (const name in attrs) {
402
- const value = attrs[name];
403
- if (value instanceof IValue) {
404
- this.attr(name, value);
405
- }
406
- else {
407
- this.setAttr(name, value);
408
- }
409
- }
410
- }
411
- applyStyle(style) {
412
- for (const name in style) {
413
- const value = style[name];
414
- if (value instanceof IValue) {
415
- this.style(name, value);
416
- }
417
- else {
418
- this.setStyle(name, value);
419
- }
420
- }
421
- }
422
- applyBind(bind) {
423
- const inode = this.node;
424
- for (const k in bind) {
425
- const value = bind[k];
426
- if (!(value instanceof IValue)) {
427
- inode[k] = value;
428
- return;
429
- }
430
- this.bindDomApi(k, value);
431
- }
432
- }
433
- applyOptions(options) {
434
- options.attr && this.applyAttrs(options.attr);
435
- options.class &&
436
- options.class.forEach(item => {
437
- if (item instanceof IValue) {
438
- this.bindClass(item);
439
- }
440
- else if (typeof item == "string") {
441
- this.addClass(item);
442
- }
443
- else {
444
- for (const name in item) {
445
- const value = item[name];
446
- if (value instanceof IValue) {
447
- this.floatingClass(value, name);
448
- }
449
- else if (value && name !== "$") {
450
- this.addClass(name);
451
- }
452
- else {
453
- this.removeClass(name);
454
- }
455
- }
456
- }
457
- });
458
- options.style && this.applyStyle(options.style);
459
- if (options.events) {
460
- for (const name of Object.keys(options.events)) {
461
- this.listen(name, options.events[name]);
462
- }
463
- }
464
- options.bind && this.applyBind(options.bind);
234
+ this.runner.insertBefore(node, this.node);
465
235
  }
466
236
  }
467
237
  /**
@@ -470,88 +240,14 @@ export class INode extends Fragment {
470
240
  * @extends INode
471
241
  */
472
242
  export class Tag extends INode {
473
- constructor(input, tagName) {
474
- super(input, tagName);
475
- }
476
- compose() {
477
- var _a, _b, _c, _d;
478
- if (!this.name) {
479
- throw internalError("wrong Tag constructor call");
480
- }
481
- const node = document.createElement(this.name);
482
- this.node = node;
483
- this.applyOptions(this.input);
484
- this.parent.appendNode(node);
485
- (_b = (_a = this.input).callback) === null || _b === void 0 ? void 0 : _b.call(_a, this.node);
486
- (_d = (_c = this.input).slot) === null || _d === void 0 ? void 0 : _d.call(_c, this);
243
+ constructor(input, runner, tagName) {
244
+ super(input, runner, tagName);
487
245
  }
488
246
  findFirstChild() {
489
- return this.unmounted ? undefined : this.node;
490
- }
491
- insertAdjacent(node) {
492
- if (this.unmounted) {
493
- if (this.next) {
494
- this.next.insertAdjacent(node);
495
- }
496
- else {
497
- this.parent.appendNode(node);
498
- }
499
- }
500
- else {
501
- super.insertAdjacent(node);
502
- }
247
+ return this.node;
503
248
  }
504
249
  appendNode(node) {
505
- this.node.appendChild(node);
506
- }
507
- extent(options) {
508
- this.applyOptions(options);
509
- }
510
- /**
511
- * Mount/Unmount a node
512
- * @param cond {IValue} show condition
513
- */
514
- bindMount(cond) {
515
- this.register(new Expression(cond => {
516
- if (cond) {
517
- if (this.unmounted) {
518
- this.insertAdjacent(this.node);
519
- this.unmounted = false;
520
- }
521
- }
522
- else {
523
- if (!this.unmounted) {
524
- this.node.remove();
525
- this.unmounted = true;
526
- }
527
- }
528
- }, cond));
529
- }
530
- /**
531
- * Runs GC
532
- */
533
- destroy() {
534
- this.node.remove();
535
- super.destroy();
536
- }
537
- }
538
- /**
539
- * Represents a vasille extension node
540
- * @class Extension
541
- * @extends INode
542
- */
543
- export class Extension extends Fragment {
544
- tag(tagName, input) {
545
- var _a;
546
- let parent = this.parent;
547
- const target = tagName.toLowerCase();
548
- while (parent instanceof Fragment && !(parent instanceof Tag)) {
549
- parent = parent.parent;
550
- }
551
- if (parent instanceof Tag && parent.element.tagName.toLowerCase() === target) {
552
- parent.extent(input);
553
- (_a = input.slot) === null || _a === void 0 ? void 0 : _a.call(input, parent);
554
- }
250
+ this.runner.appendChild(this.node, node);
555
251
  }
556
252
  }
557
253
  /**
@@ -561,8 +257,8 @@ export class SwitchedNode extends Fragment {
561
257
  /**
562
258
  * Constructs a switch node and define a sync function
563
259
  */
564
- constructor() {
565
- super({}, ":switch");
260
+ constructor(runner) {
261
+ super({}, runner, ":switch");
566
262
  /**
567
263
  * Array of possible cases
568
264
  * @type {Array<{cond : IValue<unknown>, cb : function(Fragment)}>}
@@ -602,7 +298,7 @@ export class SwitchedNode extends Fragment {
602
298
  * @param cb {function(Fragment)} Call-back
603
299
  */
604
300
  createChild(cb) {
605
- const node = new Fragment({}, ":case");
301
+ const node = new Fragment({}, this.runner, ":case");
606
302
  node.parent = this;
607
303
  this.lastChild = node;
608
304
  this.children.add(node);
@@ -622,24 +318,13 @@ export class SwitchedNode extends Fragment {
622
318
  * @extends Fragment
623
319
  */
624
320
  export class DebugNode extends Fragment {
625
- constructor(input) {
626
- super(input, ":debug");
627
- }
628
- compose() {
629
- var _a, _b;
630
- const text = this.input.text;
631
- this.node = document.createComment((_b = (_a = text.$) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : "");
632
- this.register(new Expression((v) => {
633
- var _a;
634
- this.node.replaceData(0, -1, (_a = v === null || v === void 0 ? void 0 : v.toString()) !== null && _a !== void 0 ? _a : "");
635
- }, text));
636
- this.parent.appendNode(this.node);
321
+ constructor(input, runner) {
322
+ super(input, runner, ":debug");
637
323
  }
638
- /**
639
- * Runs garbage collector
640
- */
641
324
  destroy() {
642
- this.node.remove();
325
+ if (this.handler) {
326
+ this.input.text.off(this.handler);
327
+ }
643
328
  super.destroy();
644
329
  }
645
330
  }
package/lib/node/watch.js CHANGED
@@ -1,22 +1,21 @@
1
- import { Fragment } from "./node";
1
+ import { Fragment } from "./node.js";
2
2
  /**
3
3
  * Watch Node
4
4
  * @class Watch
5
5
  * @extends Fragment
6
6
  */
7
7
  export class Watch extends Fragment {
8
- constructor(input) {
9
- super(input, ":watch");
8
+ constructor(input, runner) {
9
+ super(input, runner, ":watch");
10
10
  }
11
11
  compose() {
12
12
  this.watch(value => {
13
- var _a, _b;
14
13
  this.children.forEach(child => {
15
14
  child.destroy();
16
15
  });
17
16
  this.children.clear();
18
17
  this.lastChild = undefined;
19
- (_b = (_a = this.input).slot) === null || _b === void 0 ? void 0 : _b.call(_a, this, value);
20
- }, this.input.model);
18
+ this.input.slot?.(this, value);
19
+ }, [this.input.model]);
21
20
  }
22
21
  }
@@ -1,4 +1,4 @@
1
- import { Binding } from "./binding";
1
+ import { Binding } from "./binding.js";
2
2
  /**
3
3
  * Represents an Attribute binding description
4
4
  * @class AttributeBinding
@@ -1,4 +1,4 @@
1
- import { Destroyable } from "../core/destroyable";
1
+ import { Destroyable } from "../../../core/destroyable.js";
2
2
  /**
3
3
  * Describe a common binding logic
4
4
  * @class Binding
@@ -1,4 +1,4 @@
1
- import { Binding } from "./binding";
1
+ import { Binding } from "./binding.js";
2
2
  function addClass(node, cl) {
3
3
  node.element.classList.add(cl);
4
4
  }
@@ -1,4 +1,4 @@
1
- import { Binding } from "./binding";
1
+ import { Binding } from "./binding.js";
2
2
  export function stringifyStyleValue(value) {
3
3
  if (value instanceof Array) {
4
4
  return value.map(item => `${item}px`).join(" ");