@lightningjs/blits 1.19.1 → 1.20.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## v1.20.1
4
+
5
+ _14 feb 2025_
6
+
7
+ - Added error message when root element in template contains a `:for`-attribute
8
+ - Added workaround fix for shader caching issue
9
+ - Upgraded to renderer v2.12.1
10
+
11
+ ## v1.20.0
12
+
13
+ _12 feb 2025_
14
+
15
+ - Improved attribute definitions used for autocompletion in VScode extension
16
+ - Fixed calculation of `align-items` in Layout component
17
+ - Fixed issue with sorting reactive arrays
18
+ - Upgraded to renderer v2.12.0
19
+
3
20
  ## v1.19.1
4
21
 
5
22
  _3 feb 2025_
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightningjs/blits",
3
- "version": "1.19.1",
3
+ "version": "1.20.1",
4
4
  "description": "Blits: The Lightning 3 App Development Framework",
5
5
  "bin": "bin/index.js",
6
6
  "exports": {
@@ -52,7 +52,7 @@
52
52
  },
53
53
  "dependencies": {
54
54
  "@lightningjs/msdf-generator": "^1.1.1",
55
- "@lightningjs/renderer": "^2.11.1"
55
+ "@lightningjs/renderer": "^2.12.1"
56
56
  },
57
57
  "repository": {
58
58
  "type": "git",
@@ -22,6 +22,9 @@ import { Log } from '../../lib/log.js'
22
22
  import symbols from '../../lib/symbols.js'
23
23
  import Settings from '../../settings.js'
24
24
 
25
+ // temporary counter to work around shader caching issues
26
+ let counter = 0
27
+
25
28
  const createPaddingObject = (padding, direction) => {
26
29
  if (padding === undefined) {
27
30
  return { start: 0, end: 0, oppositeStart: 0, oppositeEnd: 0 }
@@ -113,7 +116,7 @@ const layoutFn = function (config) {
113
116
  if (align !== 0) {
114
117
  for (let i = 0; i < childrenLength; i++) {
115
118
  const node = children[i]
116
- node[oppositePosition] = otherDimension
119
+ node[oppositePosition] = otherDimension * align
117
120
  node[oppositeMount] = align
118
121
  }
119
122
  }
@@ -330,14 +333,21 @@ const propsTransformer = {
330
333
  if (this.element.node === undefined) {
331
334
  this.props['shader'] = renderer.createShader('DynamicShader', {
332
335
  effects: v.map((effect) => {
333
- return renderer.createEffect(effect.type, effect.props, effect.type)
336
+ // temporary add counter to work around shader caching issues
337
+ return renderer.createEffect(
338
+ effect.type,
339
+ effect.props,
340
+ effect.type + this.element.counter
341
+ )
334
342
  }),
335
343
  })
336
344
  } else {
337
345
  for (let i = 0; i < v.length; i++) {
338
- const target = this.element.node.shader.props[v[i].type]
346
+ // temporary add counter to work around shader caching issues
347
+ const target = this.element.node.shader.props[v[i].type + this.element.counter]
339
348
  const props = Object.keys(v[i].props)
340
349
 
350
+ if (target == undefined) continue
341
351
  for (let j = 0; j < props.length; j++) {
342
352
  target[props[j]] = v[i].props[props[j]]
343
353
  }
@@ -642,5 +652,6 @@ export default (config, component) => {
642
652
  scheduledTransitions: {},
643
653
  config,
644
654
  component,
655
+ counter: counter++,
645
656
  })
646
657
  }
@@ -113,6 +113,7 @@ const reactiveProxy = (original, _parent = null, _key, global) => {
113
113
  } else if (
114
114
  target[key] !== null &&
115
115
  target[key] !== undefined &&
116
+ Array.isArray(target) === false &&
116
117
  Object.getPrototypeOf(value) === Object.prototype
117
118
  ) {
118
119
  value = Object.assign(receiver[key], value)
@@ -239,6 +239,7 @@ export default (template = '', componentName, parentComponent, filePath = null)
239
239
  #2: There must be exactly one top-level element (an element at level 0). This element may either be a self-closing
240
240
  element or an opening tag followed by a closing tag. If more than one top-level element is encountered, an error
241
241
  should be thrown.
242
+ But the top-level element can not have :for attribute.
242
243
  */
243
244
  const format = (parsedData) => {
244
245
  let stack = []
@@ -254,6 +255,10 @@ export default (template = '', componentName, parentComponent, filePath = null)
254
255
  if (rootElementDefined) {
255
256
  throw TemplateStructureError('MultipleTopLevelTags', element)
256
257
  }
258
+ // Check for :for attribute on root level element
259
+ if (element[':for'] !== undefined) {
260
+ throw TemplateStructureError('ForAttributeOnRootElement', element)
261
+ }
257
262
  rootElementDefined = true
258
263
  }
259
264
 
@@ -1388,3 +1388,24 @@ test('Parse template with color and effects attributes and parsing should conver
1388
1388
  )
1389
1389
  assert.end()
1390
1390
  })
1391
+
1392
+ test('Parse template with :for attribute on root element and parsing should fail', (assert) => {
1393
+ const template = `
1394
+ <Element :for="item in $items">
1395
+ <Text content="$item.name" />
1396
+ </Element>
1397
+ `
1398
+
1399
+ try {
1400
+ parser(template)
1401
+ assert.fail('Parser should throw TemplateStructureError:ForAttributeOnRootElement')
1402
+ } catch (error) {
1403
+ assert.equal(error.name, 'TemplateStructureError', 'Parser should throw TemplateStructureError')
1404
+ assert.ok(
1405
+ error.message.startsWith('ForAttributeOnRootElement'),
1406
+ 'Parser should throw TemplateStructureError:ForAttributeOnRootElement'
1407
+ )
1408
+ }
1409
+
1410
+ assert.end()
1411
+ })
@@ -11,7 +11,8 @@
11
11
  "Element",
12
12
  "Text",
13
13
  "Layout",
14
- "RouterView"
14
+ "RouterView",
15
+ "Component"
15
16
  ]
16
17
  },
17
18
  "y": {
@@ -26,7 +27,8 @@
26
27
  "Element",
27
28
  "Text",
28
29
  "Layout",
29
- "RouterView"
30
+ "RouterView",
31
+ "Component"
30
32
  ]
31
33
  },
32
34
  "z": {
@@ -69,7 +71,6 @@
69
71
  "usedIn": [
70
72
  "Element",
71
73
  "Text",
72
- "Layout",
73
74
  "RouterView"
74
75
  ]
75
76
  },
@@ -99,7 +100,6 @@
99
100
  "usedIn": [
100
101
  "Element",
101
102
  "Text",
102
- "Layout",
103
103
  "RouterView"
104
104
  ]
105
105
  },
@@ -114,7 +114,6 @@
114
114
  "usedIn": [
115
115
  "Element",
116
116
  "Text",
117
- "Layout",
118
117
  "RouterView"
119
118
  ]
120
119
  },
@@ -145,7 +144,8 @@
145
144
  "Element",
146
145
  "Text",
147
146
  "Layout",
148
- "RouterView"
147
+ "RouterView",
148
+ "Component"
149
149
  ]
150
150
  },
151
151
  "rotation": {
@@ -175,7 +175,8 @@
175
175
  "Element",
176
176
  "Text",
177
177
  "Layout",
178
- "RouterView"
178
+ "RouterView",
179
+ "Component"
179
180
  ]
180
181
  },
181
182
  "mount": {
@@ -245,7 +246,6 @@
245
246
  "usedIn": [
246
247
  "Element",
247
248
  "Text",
248
- "Layout",
249
249
  "RouterView"
250
250
  ]
251
251
  },
@@ -262,7 +262,8 @@
262
262
  "reactive": true,
263
263
  "description": "The overflow attribute allows the element to extend beyond the specified height and width. Possible values are true or false.",
264
264
  "usedIn": [
265
- "Text"
265
+ "Text",
266
+ "Element"
266
267
  ]
267
268
  },
268
269
  "content": {
@@ -330,7 +331,7 @@
330
331
  "Text"
331
332
  ]
332
333
  },
333
- "wordwrap": {
334
+ "maxwidth": {
334
335
  "attrType": "regular",
335
336
  "types": [
336
337
  "number"
@@ -398,13 +399,9 @@
398
399
  "textoverflow": {
399
400
  "attrType": "regular",
400
401
  "types": [
401
- "enum"
402
- ],
403
- "values": [
404
- "true",
405
- "false"
402
+ "string"
406
403
  ],
407
- "defaultValue": "false",
404
+ "defaultValue": null,
408
405
  "reactive": true,
409
406
  "description": "The suffix to be added when text is cropped due to bounds limits. Defaults to ...",
410
407
  "usedIn": [
@@ -436,10 +433,7 @@
436
433
  "reactive": true,
437
434
  "description": "Controls how much space will be added between each Element or Component.",
438
435
  "usedIn": [
439
- "Element",
440
- "Text",
441
- "Layout",
442
- "RouterView"
436
+ "Layout"
443
437
  ]
444
438
  },
445
439
  "is": {
@@ -498,7 +492,8 @@
498
492
  "Element",
499
493
  "Text",
500
494
  "Layout",
501
- "RouterView"
495
+ "RouterView",
496
+ "Component"
502
497
  ]
503
498
  },
504
499
  "align-items": {
@@ -515,11 +510,7 @@
515
510
  "reactive": true,
516
511
  "description": "Specifies how to align children on the opposite axis.",
517
512
  "usedIn": [
518
- "Component",
519
- "Element",
520
- "Text",
521
- "Layout",
522
- "RouterView"
513
+ "Layout"
523
514
  ]
524
515
  },
525
516
  "padding": {
@@ -554,10 +545,7 @@
554
545
  "reactive": true,
555
546
  "description": "Adds spacing between the content and the edges of the Layout Component.",
556
547
  "usedIn": [
557
- "Element",
558
- "Text",
559
- "Layout",
560
- "RouterView"
548
+ "Layout"
561
549
  ]
562
550
  },
563
551
  "@loaded": {
@@ -585,5 +573,17 @@
585
573
  "Element",
586
574
  "Text"
587
575
  ]
576
+ },
577
+ "@updated": {
578
+ "attrType": "event",
579
+ "types": [
580
+ "string"
581
+ ],
582
+ "defaultValue": null,
583
+ "reactive": false,
584
+ "description": " Fires when each update in Layout children. Must be a function reference.",
585
+ "usedIn": [
586
+ "Layout"
587
+ ]
588
588
  }
589
589
  }